mirror of
https://github.com/gwdevhub/gMod.git
synced 2026-07-15 15:09:30 +00:00
f07e180b53
* remove more unnecessary code * todo? * 1.5.5.0 * change GetHash from in_out parameter to return the hash * remove ForceReload bool for textures * remove textureserver, place logic in textureclient, not yet finished next up change FileToMod and shit to use modded_textures map * fix debug compilation errors * fix typo * should_update boolean, replace the entire MergeUpdate logic later * tidy up d3d9_dll.cpp and bits (#12) * define `ASSERT` Added minhook lib to tidy up hooks Remove cruft from dx9_dll.cpp * Bug fix * Another typo --------- Co-authored-by: Jon <> * gitignore * Proxy functions, cache dx9 device type * simplify LoadModsFromFile * move minhook dependency to fetch content * Make it work * Tweaked debug for file reads * Fixed inverse check * unordered_map * set should_update (yikes) * simplify libzippp.cmake * remove unnecessary code * rename project files (keep uMod_ prefix only for d3d9 classes) * remove unused Nothing() function * remove unnecessary fields * remove some code duplication refactor methods together * refactor SwitchTextures and UnswitchTextures together * move loaded_size into function * enable libzippp encryption again * copy data from opened zipentry and then delete the entry * fix hash bug in volume textures * const * change uMod_TextureClient to TextureClient * revert libzippp.cmake * 1.5.6
204 lines
5.8 KiB
C++
204 lines
5.8 KiB
C++
#include "dll_main.h"
|
|
|
|
#include <array>
|
|
#include <Windows.h>
|
|
#include "Main.h"
|
|
#include <Psapi.h>
|
|
|
|
#include "MinHook.h"
|
|
|
|
namespace {
|
|
|
|
using Direct3DCreate9_type = IDirect3D9* (APIENTRY*)(UINT);
|
|
using Direct3DCreate9Ex_type = HRESULT(APIENTRY*)(UINT SDKVersion, IDirect3D9Ex** ppD3D);
|
|
|
|
// Pointer to original address of Direct3DCreate9
|
|
Direct3DCreate9_type Direct3DCreate9_fn = nullptr;
|
|
Direct3DCreate9_type Direct3DCreate9_ret = nullptr;
|
|
|
|
// Pointer to original address of Direct3DCreate9
|
|
Direct3DCreate9Ex_type Direct3DCreate9Ex_fn = nullptr;
|
|
Direct3DCreate9Ex_type Direct3DCreate9Ex_ret = nullptr;
|
|
|
|
static FILE* stdout_proxy;
|
|
static FILE* stderr_proxy;
|
|
|
|
/*
|
|
* global variable which are linked external
|
|
*/
|
|
unsigned int gl_ErrorState = 0u;
|
|
|
|
// If not nullptr, we're responsible for freeing this library on termination
|
|
HMODULE gl_hOriginalDll = nullptr;
|
|
|
|
// If this hModule called d3d9.dll?
|
|
bool IsD3d9Module(HMODULE hModule, HANDLE hProcess)
|
|
{
|
|
TCHAR szModuleName[MAX_PATH];
|
|
GetModuleBaseName(hProcess, hModule, szModuleName, sizeof(szModuleName) / sizeof(TCHAR));
|
|
return strcmp(szModuleName, TEXT("d3d9.dll")) == 0;
|
|
}
|
|
// Does this module contain exported function calls for creating a d3d9 device?
|
|
bool HasD3d9Methods(HMODULE hModule, HANDLE hProcess)
|
|
{
|
|
return GetProcAddress(hModule, "Direct3DCreate9")
|
|
&& GetProcAddress(hModule, "Direct3DCreate9Ex");
|
|
}
|
|
|
|
|
|
HMODULE FindLoadedDll()
|
|
{
|
|
HMODULE hModules[1024];
|
|
HANDLE hProcess;
|
|
DWORD cbNeeded;
|
|
unsigned int i;
|
|
|
|
// Get a handle to the current process.
|
|
hProcess = GetCurrentProcess();
|
|
if (!EnumProcessModules(hProcess, hModules, sizeof(hModules), &cbNeeded))
|
|
return nullptr;
|
|
for (i = 0; i < (cbNeeded / sizeof(HMODULE)); i++) {
|
|
if (IsD3d9Module(hModules[i], hProcess)
|
|
|| HasD3d9Methods(hModules[i], hProcess)) {
|
|
return hModules[i];
|
|
}
|
|
}
|
|
return nullptr;
|
|
}
|
|
}
|
|
|
|
unsigned int gl_ErrorState = 0;
|
|
HINSTANCE gl_hThisInstance = nullptr;
|
|
|
|
/*
|
|
* dll entry routine, here we initialize or clean up
|
|
*/
|
|
BOOL WINAPI DllMain(HINSTANCE hModule, DWORD ul_reason_for_call, LPVOID lpReserved)
|
|
{
|
|
UNREFERENCED_PARAMETER(lpReserved);
|
|
|
|
switch (ul_reason_for_call) {
|
|
case DLL_PROCESS_ATTACH: {
|
|
#ifdef _DEBUG
|
|
AllocConsole();
|
|
SetConsoleTitleA("gMod Console");
|
|
freopen_s(&stdout_proxy, "CONOUT$", "w", stdout);
|
|
freopen_s(&stderr_proxy, "CONOUT$", "w", stderr);
|
|
#endif
|
|
InitInstance(hModule);
|
|
break;
|
|
}
|
|
case DLL_PROCESS_DETACH: {
|
|
ExitInstance();
|
|
break;
|
|
}
|
|
default: break;
|
|
}
|
|
|
|
return true;
|
|
}
|
|
|
|
void InitInstance(HINSTANCE hModule)
|
|
{
|
|
DisableThreadLibraryCalls(hModule); //reduce overhead
|
|
gl_hThisInstance = hModule;
|
|
Message("InitInstance: %p\n", hModule);
|
|
|
|
const auto d3d9_dll = LoadOriginalDll();
|
|
ASSERT(d3d9_dll);
|
|
|
|
Direct3DCreate9_fn = reinterpret_cast<Direct3DCreate9_type>(GetProcAddress(d3d9_dll, "Direct3DCreate9"));
|
|
ASSERT(Direct3DCreate9_fn);
|
|
|
|
Direct3DCreate9Ex_fn = reinterpret_cast<Direct3DCreate9Ex_type>(GetProcAddress(d3d9_dll, "Direct3DCreate9Ex"));
|
|
ASSERT(Direct3DCreate9Ex_fn);
|
|
|
|
MH_Initialize();
|
|
|
|
if (Direct3DCreate9_fn) {
|
|
MH_CreateHook(Direct3DCreate9_fn, uMod_Direct3DCreate9, (void**)&Direct3DCreate9_ret);
|
|
MH_EnableHook(Direct3DCreate9_fn);
|
|
}
|
|
|
|
if (Direct3DCreate9Ex_fn) {
|
|
MH_CreateHook(Direct3DCreate9Ex_fn, uMod_Direct3DCreate9Ex, (void**)&Direct3DCreate9Ex_ret);
|
|
MH_EnableHook(Direct3DCreate9Ex_fn);
|
|
}
|
|
|
|
}
|
|
void ExitInstance()
|
|
{
|
|
if(Direct3DCreate9_fn)
|
|
MH_DisableHook(Direct3DCreate9_fn);
|
|
if(Direct3DCreate9Ex_fn)
|
|
MH_DisableHook(Direct3DCreate9Ex_fn);
|
|
|
|
MH_Uninitialize();
|
|
|
|
// Release the system's d3d9.dll
|
|
if (gl_hOriginalDll != nullptr) {
|
|
FreeLibrary(gl_hOriginalDll);
|
|
gl_hOriginalDll = nullptr;
|
|
}
|
|
|
|
#ifdef _DEBUG
|
|
if (stdout_proxy)
|
|
fclose(stdout_proxy);
|
|
if (stderr_proxy)
|
|
fclose(stderr_proxy);
|
|
FreeConsole();
|
|
#endif
|
|
}
|
|
|
|
HMODULE LoadOriginalDll()
|
|
{
|
|
HMODULE found = FindLoadedDll();
|
|
if (found)
|
|
return found;
|
|
|
|
char buffer[MAX_PATH];
|
|
GetSystemDirectory(buffer, MAX_PATH); //get the system directory, we need to open the original d3d9.dll
|
|
|
|
// Append dll name
|
|
strcat_s(buffer, MAX_PATH, "\\d3d9.dll");
|
|
gl_hOriginalDll = LoadLibrary(buffer);
|
|
found = FindLoadedDll();
|
|
ASSERT(found && found == gl_hOriginalDll);
|
|
|
|
return found;
|
|
}
|
|
|
|
/*
|
|
* We inject the dll into the game, thus we retour the original Direct3DCreate9 function to our MyDirect3DCreate9 function
|
|
*/
|
|
|
|
IDirect3D9* APIENTRY uMod_Direct3DCreate9(UINT SDKVersion)
|
|
{
|
|
Message("uMod_Direct3DCreate9: original %p, uMod %p\n", Direct3DCreate9_fn, uMod_Direct3DCreate9);
|
|
|
|
ASSERT(Direct3DCreate9_ret);
|
|
|
|
IDirect3D9* pIDirect3D9_orig = Direct3DCreate9_ret(SDKVersion); //creating the original IDirect3D9 object
|
|
ASSERT(pIDirect3D9_orig);
|
|
|
|
return new uMod_IDirect3D9(pIDirect3D9_orig); //return our object instead of the "real one"
|
|
}
|
|
|
|
HRESULT APIENTRY uMod_Direct3DCreate9Ex(UINT SDKVersion, IDirect3D9Ex** ppD3D)
|
|
{
|
|
Message("uMod_Direct3DCreate9Ex: original %p, uMod %p\n", Direct3DCreate9Ex_fn, uMod_Direct3DCreate9Ex);
|
|
|
|
ASSERT(Direct3DCreate9Ex_ret);
|
|
|
|
IDirect3D9Ex* pIDirect3D9Ex_orig = nullptr;
|
|
HRESULT ret = Direct3DCreate9Ex_ret(SDKVersion, &pIDirect3D9Ex_orig); //creating the original IDirect3D9 object
|
|
|
|
if (ret != S_OK)
|
|
return ret;
|
|
|
|
// @Cleanup: should be we freeing pIDirect3D9Ex at the end of our own lifecycle?
|
|
uMod_IDirect3D9Ex* pIDirect3D9Ex = new uMod_IDirect3D9Ex(pIDirect3D9Ex_orig);
|
|
ppD3D = (IDirect3D9Ex**)&pIDirect3D9Ex;
|
|
return ret;
|
|
}
|