// 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;
}
