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:
commit
d1442e3747
1382 changed files with 170725 additions and 0 deletions
152
Native/DecalDat/DatService.cpp
Normal file
152
Native/DecalDat/DatService.cpp
Normal file
|
|
@ -0,0 +1,152 @@
|
|||
// DatService.cpp : Implementation of cDatService
|
||||
#include "stdafx.h"
|
||||
#include "DecalDat.h"
|
||||
#include "DatService.h"
|
||||
|
||||
#include "DatLibrary.h"
|
||||
|
||||
#include <ApiHook.h>
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
// cDatService
|
||||
|
||||
HANDLE WINAPI CreateFileF( LPCTSTR lpFileName, DWORD dwDesiredAccess, DWORD dwShareMode, LPSECURITY_ATTRIBUTES lpSecurityAttributes,
|
||||
DWORD dwCreationDisposition, DWORD dwFlagsAndAttributes, HANDLE hTemplateFile )
|
||||
{
|
||||
dwShareMode |= FILE_SHARE_READ | FILE_SHARE_WRITE;
|
||||
return cDatService::g_fn_CreateFile( lpFileName, dwDesiredAccess, dwShareMode, lpSecurityAttributes,
|
||||
dwCreationDisposition, dwFlagsAndAttributes, hTemplateFile );
|
||||
}
|
||||
|
||||
static cHookDescriptor _hooks[] = {
|
||||
{ eByName, _T( "kernel32.dll" ), _T( "CreateFileA" ), 0, reinterpret_cast< DWORD >( CreateFileF ), 0 },
|
||||
};
|
||||
|
||||
cDatService::cFileFilter *cDatService::getFilter( LPTSTR szFilter, int nLength )
|
||||
{
|
||||
std::string strFilter( szFilter, nLength );
|
||||
|
||||
for( cFileFilterList::iterator i = m_filters.begin(); i != m_filters.end(); ++ i )
|
||||
{
|
||||
if( strFilter == i->m_strName )
|
||||
return &(*(i));
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
HRESULT cDatService::createFilter( cDatService::cFileFilter *pFilter, REFIID iid, LPVOID *ppvItf )
|
||||
{
|
||||
static _bstr_t _strFilter( _T( "FileFilters" ) );
|
||||
|
||||
CComPtr< IDecalEnum > pEnumFilter;
|
||||
if( m_pDecal->get_Configuration( _strFilter, pFilter->m_clsid, &pEnumFilter ) != S_OK )
|
||||
return E_FAIL;
|
||||
|
||||
return pEnumFilter->CreateInstance( iid, ppvItf );
|
||||
}
|
||||
|
||||
HRESULT cDatService::onInitialize()
|
||||
{
|
||||
USES_CONVERSION;
|
||||
|
||||
static _bstr_t _strPortal( _T( "%ac%\\portal.dat" ) ),
|
||||
_strCell( _T( "%ac%\\cell.dat" ) );
|
||||
|
||||
if( g_p == NULL )
|
||||
{
|
||||
hookFunctions( _hooks, 1, true );
|
||||
g_fn_CreateFile = reinterpret_cast< fn_CreateFile >( _hooks[ 0 ].m_pOldFunction );
|
||||
g_p = this;
|
||||
}
|
||||
|
||||
CComObject< cDatLibrary > *pComCell, *pComPortal;
|
||||
CComObject< cDatLibrary >::CreateInstance( &pComCell );
|
||||
CComObject< cDatLibrary >::CreateInstance( &pComPortal );
|
||||
|
||||
pComCell->AddRef();
|
||||
pComPortal->AddRef();
|
||||
|
||||
m_pCell = pComCell;
|
||||
m_pPortal = pComPortal;
|
||||
|
||||
m_pCell->load( this, _strCell, eCell, 256 );
|
||||
m_pPortal->load( this, _strPortal, ePortal, 1024 );
|
||||
|
||||
// Load the list of filters
|
||||
static _bstr_t _strFilter( _T( "FileFilters" ) ),
|
||||
_strPrefix( _T( "Prefix" ) ),
|
||||
_strCache( _T( "Cache" ) );
|
||||
CComPtr< IDecalEnum > pEnum;
|
||||
|
||||
m_pDecal->get_Configuration( _strFilter, GUID_NULL, &pEnum );
|
||||
|
||||
while( pEnum->Next() == S_OK )
|
||||
{
|
||||
CComVariant vPrefix, vCache;
|
||||
cFileFilter;
|
||||
|
||||
cFileFilter ff;
|
||||
pEnum->get_ComClass( &ff.m_clsid );
|
||||
|
||||
HRESULT hRes = pEnum->get_Property( _strPrefix, &vPrefix );
|
||||
if( !SUCCEEDED( hRes ) || vPrefix.vt != VT_BSTR )
|
||||
{
|
||||
_ASSERT( FALSE );
|
||||
continue;
|
||||
}
|
||||
|
||||
hRes = pEnum->get_Property( _strCache, &vCache );
|
||||
if( !SUCCEEDED( hRes ) || vCache.vt != VT_I4 )
|
||||
{
|
||||
_ASSERT( FALSE );
|
||||
continue;
|
||||
}
|
||||
|
||||
ff.m_bCache = !!vCache.lVal;
|
||||
|
||||
LPTSTR szPrefix = OLE2T( vPrefix.bstrVal );
|
||||
::_tcslwr( szPrefix );
|
||||
ff.m_strName = szPrefix;
|
||||
|
||||
m_filters.push_back( ff );
|
||||
}
|
||||
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
void cDatService::onTerminate()
|
||||
{
|
||||
m_cache.clear();
|
||||
m_filters.clear();
|
||||
|
||||
if( g_p == this )
|
||||
{
|
||||
hookFunctions( _hooks, 1, false );
|
||||
g_p = NULL;
|
||||
}
|
||||
|
||||
m_pCell->Release();
|
||||
m_pPortal->Release();
|
||||
|
||||
m_pCell = NULL;
|
||||
m_pPortal = NULL;
|
||||
}
|
||||
|
||||
cDatService *cDatService::g_p = NULL;
|
||||
cDatService::fn_CreateFile cDatService::g_fn_CreateFile = NULL;
|
||||
|
||||
STDMETHODIMP cDatService::Lookup( BSTR strName, IUnknown **ppItf )
|
||||
{
|
||||
static _bstr_t _strPortal( _T( "portal" ) ),
|
||||
_strCell( _T( "cell" ) );
|
||||
|
||||
if( ::VarBstrCmp( strName, _strPortal, 0, NORM_IGNORECASE ) == VARCMP_EQ )
|
||||
return m_pPortal->QueryInterface( IID_IUnknown, reinterpret_cast< void ** >( ppItf ) );
|
||||
|
||||
if( ::VarBstrCmp( strName, _strCell, 0, NORM_IGNORECASE ) == VARCMP_EQ )
|
||||
return m_pCell->QueryInterface( IID_IUnknown, reinterpret_cast< void ** >( ppItf ) );
|
||||
|
||||
// None of the above
|
||||
return E_INVALIDARG;
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue