Initial commit: Complete open-source Decal rebuild

All 5 phases of the open-source Decal rebuild:

Phase 1: 14 decompiled .NET projects (Interop.*, Adapter, FileService, DecalUtil)
Phase 2: 10 native DLLs rewritten as C# COM servers with matching GUIDs
  - DecalDat, DHS, SpellFilter, DecalInput, DecalNet, DecalFilters
  - Decal.Core, DecalControls, DecalRender, D3DService
Phase 3: C++ shims for Inject.DLL (D3D9 hooking) and LauncherHook.DLL
Phase 4: DenAgent WinForms tray application
Phase 5: WiX installer and build script

25 C# projects building with 0 errors.
Native C++ projects require VS 2022 + Windows SDK (x86).

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
erik 2026-02-08 18:27:56 +01:00
commit d1442e3747
1382 changed files with 170725 additions and 0 deletions

152
Native/Decal/DecalRes.cpp Normal file
View file

@ -0,0 +1,152 @@
// DecalRes.cpp : Implementation of cDecalRes
#include "stdafx.h"
#include "Decal.h"
#include "DecalRes.h"
/////////////////////////////////////////////////////////////////////////////
// cDecalRes
HRESULT cDecalRes::getLibID( MSXML::IXMLDOMDocumentPtr &pdoc, GUID *pGUID )
{
_variant_t vlib = pdoc->selectSingleNode( _T( "/*/@lib" ) )->text;
if( vlib.vt == VT_NULL )
{
// lib is a required field
_ASSERT( FALSE );
return E_FAIL;
}
return ::CLSIDFromString( vlib.bstrVal, pGUID );
}
bool cDecalRes::getTypelibFilename( MSXML::IXMLDOMDocumentPtr &pdoc, BSTR *pbstrFilename )
{
USES_CONVERSION;
GUID libid;
HRESULT hRes = getLibID( pdoc, &libid );
if( FAILED( hRes ) )
return SUCCEEDED ( hRes );
// Look up the path of the typelib in the registry
hRes = ::QueryPathOfRegTypeLib( libid, 1, 0, 0, pbstrFilename );
if( SUCCEEDED( hRes ) )
return true;
// Otherwise, manufacture a type library filename
RegKey key;
key.Open( HKEY_LOCAL_MACHINE, _T( "Software\\Decal\\Agent" ) );
TCHAR szPath[ MAX_PATH ];
DWORD dwPath = MAX_PATH;
key.QueryStringValue (_T("PluginPath"), szPath, &dwPath);
if( szPath[ ::_tcslen( szPath ) - 1 ] != _T( '\\' ) )
::_tcscat( szPath, _T( "\\" ) );
_variant_t vName = pdoc->selectSingleNode( _T( "/*/@name" ) )->text;
if( vName.vt == VT_NULL )
::_tcscat( szPath, _T( "ErrorUnnamedTypelib.tlb" ) );
else
{
::_tcscat( szPath, OLE2T( vName.bstrVal ) );
::_tcscat( szPath, _T( ".tlb" ) );
}
*pbstrFilename = T2BSTR( szPath );
return false;
}
HRESULT cDecalRes::initTypelib( MSXML::IXMLDOMDocumentPtr &pdoc, BSTR strFilename )
{
HRESULT hRes = ::CreateTypeLib2( SYS_WIN32, strFilename, &m_pLib );
if( FAILED( hRes ) )
return hRes;
GUID libid;
hRes = getLibID( pdoc, &libid );
if( FAILED( hRes ) )
return hRes;
m_pLib->SetGuid( libid );
_variant_t vName = pdoc->selectSingleNode( _T( "/*/@name" ) )->text;
if( vName.vt == VT_NULL )
{
// Name is a required field
_ASSERT( FALSE );
return E_FAIL;
}
m_pLib->SetName( vName.bstrVal );
m_pLib->SetVersion( 1, 0 );
// One initialized typelib
return S_OK;
}
HRESULT cDecalRes::scanTemplate( MSXML::IXMLDOMElementPtr &ptemp, ITypeInfo **ppCoClass, ITypeInfo **ppSource )
{
// Get the IDs for the coclass, default interface and default source interface
_variant_t vIDCoClass = ptemp->getAttribute( _T( "class" ) ),
vIDEvent = ptemp->getAttribute( _T( "event" ) ),
vName = ptemp->getAttribute( _T( "name" ) );
if( vIDCoClass.vt == VT_NULL || vIDEvent.vt == VT_NULL || vName.vt == VT_NULL )
{
// Both of these are required
_ASSERT( FALSE );
return E_FAIL;
}
// Next convert them to GUIDs
CLSID idClass;
IID idEvent;
if( FAILED( ::CLSIDFromString( vIDCoClass.bstrVal, &idClass ) ) ||
FAILED( ::CLSIDFromString( vIDEvent.bstrVal, &idEvent ) ) )
{
// They must be converted to guids
_ASSERT( FALSE );
return E_FAIL;
}
// Now we make the coclass typeinfo, default source typeinfo, get the default interface typeinfo
// and slap them all together
CComPtr< ICreateTypeInfo > pCoClass;
m_pLib->CreateTypeInfo( vName.bstrVal, TKIND_COCLASS, &pCoClass );
pCoClass->SetGuid( idClass );
pCoClass->QueryInterface( ppCoClass );
CComPtr< ITypeInfo > pDefaultItf;
GetTypeInfo( 0, 0, &pDefaultItf );
HREFTYPE hrefDefaultItf;
pCoClass->AddRefTypeInfo( pDefaultItf, &hrefDefaultItf );
pCoClass->AddImplType( 0, hrefDefaultItf );
pCoClass->SetImplTypeFlags( 0, IMPLTYPEFLAG_FDEFAULT );
CComPtr< ICreateTypeInfo > pSourceItf;
_bstr_t strEvent( _T( "_" ) );
strEvent += vName.bstrVal;
strEvent += _T( "Events" );
m_pLib->CreateTypeInfo( strEvent, TKIND_DISPATCH, &pSourceItf );
pSourceItf->SetGuid( idEvent );
HREFTYPE hrefSourceItf;
pSourceItf->QueryInterface( ppSource );
pCoClass->AddRefTypeInfo( *ppSource, &hrefSourceItf );
pCoClass->AddImplType( 1, hrefSourceItf );
pCoClass->SetImplTypeFlags( 1, IMPLTYPEFLAG_FDEFAULT | IMPLTYPEFLAG_FSOURCE );
// Still incomplete
return S_OK;
}