void hookD3D9(HMODULE hD3D, bool preonly) { const int procnamesize = 2048; char procname[procnamesize]; GetModuleFileName(NULL, procname, procnamesize); ods("D3D9: hookD3D9 in App %s", procname); // Add a ref to ourselves; we do NOT want to get unloaded directly from this process. GetModuleHandleEx(GET_MODULE_HANDLE_EX_FLAG_FROM_ADDRESS, reinterpret_cast<char *>(&HookCreate), &hSelf); bHooked = true; // Can we use the prepatch data? GetModuleFileName(hD3D, procname, procnamesize); if (_stricmp(d3dd->cFileName, procname) == 0) { unsigned char *raw = (unsigned char *) hD3D; HookCreateRaw((voidFunc)(raw + d3dd->iOffsetCreate)); if (d3dd->iOffsetCreateEx) HookCreateRawEx((voidFunc)(raw + d3dd->iOffsetCreateEx)); } else if (! preonly) { ods("D3D9: Interface changed, can't rawpatch"); pDirect3DCreate9 d3dcreate9 = reinterpret_cast<pDirect3DCreate9>(GetProcAddress(hD3D, "Direct3DCreate9")); if (d3dcreate9) { ods("D3D9: Got %p for Direct3DCreate9", d3dcreate9); IDirect3D9 *id3d9 = d3dcreate9(D3D_SDK_VERSION); if (id3d9) { HookCreate(id3d9); id3d9->Release(); } else { ods("D3D9: Failed call to Direct3DCreate9"); } } else { ods("D3D9: Library without Direct3DCreate9?"); } } else { bHooked = false; } }
// Creates a Direct3D9 object and initializes adapters. // If succeeded, returns S_OK, otherwise returns the error code. HRESULT D3DPipelineManager::InitD3D(void) { typedef IDirect3D9 * WINAPI FnDirect3DCreate9(UINT SDKVersion); hLibD3D9 = ::LoadLibrary(TEXT("d3d9.dll")); if (hLibD3D9 == NULL) { J2dRlsTraceLn(J2D_TRACE_ERROR, "InitD3D: no d3d9.dll"); return E_FAIL; } FnDirect3DCreate9 *d3dcreate9 = NULL; d3dcreate9 = (FnDirect3DCreate9*) ::GetProcAddress(hLibD3D9, "Direct3DCreate9"); if (d3dcreate9 == NULL) { J2dRlsTraceLn(J2D_TRACE_ERROR, "InitD3D: no Direct3DCreate9"); ::FreeLibrary(hLibD3D9); return E_FAIL; } pd3d9 = d3dcreate9(D3D_SDK_VERSION); if (pd3d9 == NULL) { J2dRlsTraceLn(J2D_TRACE_ERROR, "InitD3D: unable to create IDirect3D9 object"); ::FreeLibrary(hLibD3D9); return E_FAIL; } HRESULT res; if (FAILED(res = InitAdapters())) { J2dRlsTraceLn(J2D_TRACE_ERROR, "InitD3D: failed to init adapters"); ReleaseD3D(); return res; } return S_OK; }
static void hookD3D9(HMODULE hD3D, bool preonly) { char procname[MODULEFILEPATH_BUFLEN]; GetModuleFileName(NULL, procname, ARRAY_NUM_ELEMENTS(procname)); ods("D3D9: hookD3D9 in App '%s'", procname); // Add a ref to ourselves; we do NOT want to get unloaded directly from this process. HMODULE hTempSelf = NULL; GetModuleHandleEx(GET_MODULE_HANDLE_EX_FLAG_FROM_ADDRESS, reinterpret_cast<char *>(&hookD3D9), &hTempSelf); bHooked = true; // Can we use the prepatch data? wchar_t modulename[MODULEFILEPATH_BUFLEN]; GetModuleFileNameW(hD3D, modulename, ARRAY_NUM_ELEMENTS(modulename)); if (_wcsicmp(d3dd->wcFileName, modulename) == 0) { // The module seems to match the one we prepared d3dd for. unsigned char *raw = (unsigned char *) hD3D; HookCreateRaw((voidFunc)(raw + d3dd->iOffsetCreate)); if (d3dd->iOffsetCreateEx) { HookCreateRawEx((voidFunc)(raw + d3dd->iOffsetCreateEx)); } } else if (! preonly) { ods("D3D9: Interface changed, can't rawpatch. Current: %ls ; Previously: %ls", modulename, d3dd->wcFileName); pDirect3DCreate9 d3dcreate9 = reinterpret_cast<pDirect3DCreate9>(GetProcAddress(hD3D, "Direct3DCreate9")); if (d3dcreate9) { ods("D3D9: Got %p for Direct3DCreate9", d3dcreate9); IDirect3D9 *id3d9 = d3dcreate9(D3D_SDK_VERSION); if (id3d9) { HookCreate(id3d9); id3d9->Release(); } else { ods("D3D9: Failed call to Direct3DCreate9"); } } else { ods("D3D9: Library without Direct3DCreate9?"); } pDirect3DCreate9Ex d3dcreate9ex = reinterpret_cast<pDirect3DCreate9Ex>(GetProcAddress(hD3D, "Direct3DCreate9Ex")); if (d3dcreate9ex) { ods("D3D9: Got %p for Direct3DCreate9Ex", d3dcreate9ex); IDirect3D9Ex** id3d9ex = 0; HRESULT hr = d3dcreate9ex(D3D_SDK_VERSION, id3d9ex); if (SUCCEEDED(hr)) { HookCreateEx(*id3d9ex); (*id3d9ex)->Release(); } else { switch (hr) { case D3DERR_OUTOFVIDEOMEMORY: ods("D3D11: Direct3DCreate9Ex returned with out of memory error."); break; case D3DERR_NOTAVAILABLE: ods("D3D11: Direct3DCreate9Ex is not available."); break; default: ods("D3D11: Unexpected return result from Direct3DCreate9Ex"); break; } } } } else { bHooked = false; } }
extern "C" __declspec(dllexport) void __cdecl PrepareD3D9() { if (! d3dd) return; ods("D3D9: Preparing static data for D3D9 Injection"); HMODULE hD3D = LoadLibrary("D3D9.DLL"); if (hD3D != NULL) { GetModuleFileNameW(hD3D, d3dd->wcFileName, ARRAY_NUM_ELEMENTS(d3dd->wcFileName)); std::string d3d9FnName("Direct3DCreate9"); pDirect3DCreate9 d3dcreate9 = reinterpret_cast<pDirect3DCreate9>(GetProcAddress(hD3D, d3d9FnName.c_str())); if (! d3dcreate9) { ods(("D3D9: Library without " + d3d9FnName).c_str()); } else { if (!IsFnInModule(reinterpret_cast<voidFunc>(d3dcreate9), d3dd->wcFileName, "D3D9", d3d9FnName)) { ods(("D3D9: " + d3d9FnName + " is not in D3D9 library").c_str()); } else { IDirect3D9 *id3d9 = d3dcreate9(D3D_SDK_VERSION); if (id3d9) { void ***vtbl = (void ***) id3d9; void *pCreate = (*vtbl)[VTABLE_OFFSET_ID3D_CREATEDEVICE]; if (!IsFnInModule(reinterpret_cast<voidFunc>(pCreate), d3dd->wcFileName, "D3D9", "CreateDevice")) { ods("D3D9: CreateDevice is not in D3D9 library"); } else { unsigned char *fn = reinterpret_cast<unsigned char *>(pCreate); unsigned char *base = reinterpret_cast<unsigned char *>(hD3D); d3dd->iOffsetCreate = fn - base; ods("D3D9: Successfully found prepatch offset: %p %p %p: %d", hD3D, d3dcreate9, pCreate, d3dd->iOffsetCreate); } id3d9->Release(); } } } std::string d3d9exFnName("Direct3DCreate9Ex"); pDirect3DCreate9Ex d3dcreate9ex = reinterpret_cast<pDirect3DCreate9Ex>(GetProcAddress(hD3D, d3d9exFnName.c_str())); if (! d3dcreate9ex) { ods(("D3D9: Library without " + d3d9exFnName).c_str()); } else { if (!IsFnInModule(reinterpret_cast<voidFunc>(d3dcreate9ex), d3dd->wcFileName, "D3D9", d3d9exFnName)) { ods(("D3D9: " + d3d9exFnName + " is not in D3D9 library").c_str()); } else { IDirect3D9Ex *id3d9 = NULL; d3dcreate9ex(D3D_SDK_VERSION, &id3d9); if (id3d9) { void ***vtbl = (void ***) id3d9; void *pCreateEx = (*vtbl)[VTABLE_OFFSET_ID3D_CREATEDEVICE_EX]; if (!IsFnInModule(reinterpret_cast<voidFunc>(pCreateEx), d3dd->wcFileName, "D3D9", "CreateDeviceEx")) { ods("D3D9: CreateDeviceEx is not in D3D9 library"); } else { unsigned char *fn = reinterpret_cast<unsigned char *>(pCreateEx); unsigned char *base = reinterpret_cast<unsigned char *>(hD3D); d3dd->iOffsetCreateEx = fn - base; ods("D3D9: Successfully found prepatch ex offset: %p %p %p: %d", hD3D, d3dcreate9ex, pCreateEx, d3dd->iOffsetCreateEx); } id3d9->Release(); } } } FreeLibrary(hD3D); } }