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

View file

@ -0,0 +1,96 @@
// LobbyHook.cpp : Defines the entry point for the DLL application.
//
#include "stdafx.h"
#include "forcelib.h"
#include "apihook.h"
bool bInject;
BOOL __stdcall Replacement_CreateProcessA( LPCSTR a0, LPSTR a1, LPSECURITY_ATTRIBUTES a2, LPSECURITY_ATTRIBUTES a3, BOOL a4, DWORD a5, LPVOID a6, LPCSTR a7, LPSTARTUPINFO a8, LPPROCESS_INFORMATION a9 );
static cHookDescriptor _hooks[] =
{
{ eByName, _T( "kernel32.dll" ), _T( "CreateProcessA" ), 93, reinterpret_cast< DWORD >( Replacement_CreateProcessA ), 0 },
};
BOOL __stdcall Replacement_CreateProcessA( LPCSTR a0, LPSTR a1, LPSECURITY_ATTRIBUTES a2, LPSECURITY_ATTRIBUTES a3, BOOL a4, DWORD a5,LPVOID a6, LPCSTR a7, LPSTARTUPINFO a8, LPPROCESS_INFORMATION a9 )
{
static long s_recursion = 0;
bInject = strstr( a1, "client.exe" ) ? true : false;
BOOL bResult;
if( s_recursion++ == 0 && bInject)
{
HKEY key = NULL;
char szDllPath[ MAX_PATH ];
memset( szDllPath, 0, sizeof( szDllPath ) );
HRESULT hr = RegOpenKeyEx( HKEY_LOCAL_MACHINE, _T("Software\\Decal\\Agent"), 0, KEY_READ, &key );
if( hr == ERROR_SUCCESS )
{
DWORD dwChars = MAX_PATH - 1;
if( RegQueryValueEx( key, "AgentPath", NULL, NULL, (LPBYTE) szDllPath, &dwChars ) == ERROR_SUCCESS )
strcat( szDllPath, "\\Inject.dll" );
RegCloseKey (key);
}
PROCESS_INFORMATION ProcInfo;
memset( &ProcInfo, 0, sizeof( PROCESS_INFORMATION ) );
bResult = CreateProcess( const_cast< char * >( a0 ),
a1, a2, a3, a4, CREATE_SUSPENDED, /* a5 - Creation Flags */
a6, const_cast< char * >( a7 ), a8, &ProcInfo /* a9 - Proc Info */ );
if (FindWindow (NULL, "Decal Agent") != NULL)
{
ForceLibrary( szDllPath, &ProcInfo );
}
ResumeThread( ProcInfo.hThread );
}
else
{
bResult = CreateProcess( a0, a1, a2, a3, a4, a5, a6, a7, a8, a9 );
}
s_recursion--;
return bResult;
}
HANDLE g_hLobbySemaphore = NULL;
BOOL APIENTRY DllMain( HANDLE hModule, DWORD dwCallReason, LPVOID lpReserved )
{
switch( dwCallReason )
{
case DLL_PROCESS_ATTACH:
{
// Alright, we're loaded into the lobby process.
// Hook CreateProcessA and bail.
hookFunctionsByExport( "AsheronsCall.dll", _hooks, 1, true );
TCHAR tszBuffer [256];
_stprintf (tszBuffer, _T("__LOBBYHOOK_%d"), ::GetCurrentProcessId ());
g_hLobbySemaphore = ::CreateSemaphore (NULL, 0, 1, tszBuffer);
break;
}
case DLL_PROCESS_DETACH:
{
// Detaching
// Unhook CreateProcessA and bail.
hookFunctionsByExport( "AsheronsCall.dll", _hooks, 1, false );
::CloseHandle (g_hLobbySemaphore);
break;
}
}
return TRUE;
}