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>
152 lines
4.1 KiB
C++
152 lines
4.1 KiB
C++
// 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;
|
|
}
|