static HRESULT __stdcall myReset(IDirect3DDevice9 * idd, D3DPRESENT_PARAMETERS *param) { ods("D3D9: Chaining Reset"); DevState *ds = devMap[idd]; if (ds) { DWORD dwOldThread = ds->dwMyThread; if (dwOldThread) ods("D3D9: myReset from other thread"); ds->dwMyThread = GetCurrentThreadId(); ds->releaseAll(); ds->dwMyThread = dwOldThread; } //TODO: Move logic to HardHook. // Call base without active hook in case of no trampoline. ResetType oReset = (ResetType) hhReset.call; hhReset.restore(); HRESULT hr = oReset(idd, param); hhReset.inject(); if (ds) ds->createCleanState(); return hr; }
static ULONG __stdcall myRelease(ID3D10Device *pDevice) { //TODO: Move logic to HardHook. // Call base without active hook in case of no trampoline. ReleaseType oRelease = (ReleaseType) hhRelease.call; hhRelease.restore(); ULONG res = oRelease(pDevice); hhRelease.inject(); Mutex m; DeviceMap::iterator it = devices.find(pDevice); if (it != devices.end()) { D10State *ds = it->second; // If we are receiving a lot of subsequent releases lets eagerly drop // our state object. If the device presents something again a state // object is created again just fine anyway. if (res < ds->lHighMark / 2) { ods("D3D10: Deleting resources %u < 0.5 * %u", res, ds->lHighMark); devices.erase(it); chains.erase(ds->pSwapChain); delete ds; ods("D3D10: Deleted"); ds = NULL; } } return res; }
static HRESULT __stdcall myCreateDeviceEx(IDirect3D9Ex * id3d, UINT Adapter, D3DDEVTYPE DeviceType, HWND hFocusWindow, DWORD BehaviorFlags, D3DPRESENT_PARAMETERS *pPresentationParameters, D3DDISPLAYMODEEX* pFullscreenDisplayMode, IDirect3DDevice9Ex** ppReturnedDeviceInterface) { Mutex m; ods("D3D9: Chaining CreateDeviceEx"); // BehaviorFlags &= ~D3DCREATE_PUREDEVICE; //TODO: Move logic to HardHook. // Call base without active hook in case of no trampoline. CreateDeviceExType oCreateDeviceEx = (CreateDeviceExType) hhCreateDeviceEx.call; hhCreateDeviceEx.restore(); HRESULT hr = oCreateDeviceEx(id3d, Adapter, DeviceType, hFocusWindow, BehaviorFlags, pPresentationParameters, pFullscreenDisplayMode, ppReturnedDeviceInterface); hhCreateDeviceEx.inject(); if (FAILED(hr)) return hr; IDirect3DDevice9Ex *idd = *ppReturnedDeviceInterface; DevState *ds = new DevState; ds->dev = idd; idd->AddRef(); ds->initRefCount = idd->Release(); devMap[idd] = ds; // The offsets are dependent on the declaration order of the struct. // See IDirect3DDevice9 (2nd, 3rd, 17th, 18th functions) const unsigned int offsetAddref = 1; const unsigned int offsetRelease = 2; const unsigned int offsetReset = 16; const unsigned int offsetPresent = 17; if (bIsWin8) { hhAddRef.setupInterface(idd, offsetAddref, reinterpret_cast<voidFunc>(myWin8AddRef)); hhRelease.setupInterface(idd, offsetRelease, reinterpret_cast<voidFunc>(myWin8Release)); } else { hhAddRef.setupInterface(idd, offsetAddref, reinterpret_cast<voidFunc>(myAddRef)); hhRelease.setupInterface(idd, offsetRelease, reinterpret_cast<voidFunc>(myRelease)); } hhReset.setupInterface(idd, offsetReset, reinterpret_cast<voidFunc>(myReset)); hhPresent.setupInterface(idd, offsetPresent, reinterpret_cast<voidFunc>(myPresent)); IDirect3DSwapChain9 *pSwap = NULL; idd->GetSwapChain(0, &pSwap); if (pSwap) { // The offset is dependent on the declaration order of the struct. // See IDirect3DSwapChain9 (Present is the fourth function) const unsigned int offsetPresent = 3; hhSwapPresent.setupInterface(pSwap, offsetPresent, reinterpret_cast<voidFunc>(mySwapPresent)); pSwap->Release(); } else { ods("D3D9: Failed to get swapchain for DevEx"); } ds->createCleanState(); return hr; }
static ULONG __stdcall myWin8Release(IDirect3DDevice9 *idd) { Mutex m; DevMapType::iterator it = devMap.find(idd); DevState *ds = it != devMap.end() ? it->second : NULL; if (ds) { // Release is called very often. Thus, we do not want to always log here. #ifdef EXTENDED_OVERLAY_DEBUGOUTPUT ods("D3D9: Using own Refcount implementation for call to Release."); #endif if (ds->dwMyThread == GetCurrentThreadId()) { ds->myRefCount--; return ds->refCount; } if (ds->refCount == 1) { ds->disconnect(); ods("D3D9: Final release. MyRefs = %d, Tot = %d", ds->myRefCount, ds->refCount); if (ds->dwMyThread != 0) { ods("D3D9: finalRelease from other thread"); } // Codeblock for stashing threadid { Stash<DWORD> stashThread(&(ds->dwMyThread), GetCurrentThreadId()); ds->releaseAll(); } ods("D3D9: Final release of %p. MyRefs = %d Tot = %d", idd, ds->myRefCount, ds->refCount); devMap.erase(it); delete ds; ds = NULL; } } //TODO: Move logic to HardHook. // Call base without active hook in case of no trampoline. ReleaseType oRelease = (ReleaseType) hhRelease.call; hhRelease.restore(); ULONG res = oRelease(idd); hhRelease.inject(); if (ds) ds->refCount = res; // Release is called very often. Thus, we do not want to always log here. #ifdef EXTENDED_OVERLAY_DEBUGOUTPUT ods("D3D9: Chained Release (Win8) with result: %d", res); #endif return res; }
static HRESULT __stdcall myPresent(IDirect3DDevice9 * idd, CONST RECT* pSourceRect,CONST RECT* pDestRect,HWND hDestWindowOverride,CONST RGNDATA* pDirtyRegion) { ods("D3D9: Device Present"); myAdditions(idd); doPresent(idd); PresentType oPresent = (PresentType) hhPresent.call; hhPresent.restore(); HRESULT hr = oPresent(idd,pSourceRect,pDestRect,hDestWindowOverride,pDirtyRegion); hhPresent.inject(); return hr; }
static HRESULT __stdcall myPresent(IDirect3DDevice9 * idd, CONST RECT* pSourceRect,CONST RECT* pDestRect,HWND hDestWindowOverride,CONST RGNDATA* pDirtyRegion) { ods("D3D9: Device Present"); doPresent(idd); //TODO: Move logic to HardHook. // Call base without active hook in case of no trampoline. PresentType oPresent = (PresentType) hhPresent.call; hhPresent.restore(); HRESULT hr = oPresent(idd,pSourceRect,pDestRect,hDestWindowOverride,pDirtyRegion); hhPresent.inject(); return hr; }
static ULONG __stdcall myAddRef(ID3D10Device *pDevice) { AddRefType oAddRef = (AddRefType) hhAddRef.call; hhAddRef.restore(); LONG res = oAddRef(pDevice); hhAddRef.inject(); Mutex m; D10State *ds = devices[pDevice]; if (ds) ds->lHighMark = res; return res; }
static HRESULT __stdcall myPresentEx(IDirect3DDevice9Ex *idd, CONST RECT *pSourceRect, CONST RECT *pDestRect, HWND hDestWindowOverride, CONST RGNDATA *pDirtyRegion, DWORD dwFlags) { // Present is called for each frame. Thus, we do not want to always log here. #ifdef EXTENDED_OVERLAY_DEBUGOUTPUT ods("D3D9: Device Present Ex"); #endif doPresent(idd); PresentExType oPresentEx = (PresentExType) hhPresentEx.call; hhPresentEx.restore(); HRESULT hr = oPresentEx(idd, pSourceRect, pDestRect, hDestWindowOverride, pDirtyRegion, dwFlags); hhPresentEx.inject(); return hr; }
static ULONG __stdcall myRelease(IDirect3DDevice9 *idd) { Mutex m; ods("D3D9: Chaining Release"); DevState *ds = devMap[idd]; if (ds) { if (ds->dwMyThread == GetCurrentThreadId()) { ds->myRefCount--; return ds->refCount + ds->initRefCount; } else { ds->refCount--; } if (ds->refCount <= 1) ds->disconnect(); if (ds->refCount >= 0) return ds->refCount + ds->initRefCount; ods("D3D9: Final release is following. MyRefs = %d, Tot = %d", ds->myRefCount, ds->refCount); DWORD dwOldThread = ds->dwMyThread; if (dwOldThread) ods("D3D9: finalRelease from other thread"); ds->dwMyThread = GetCurrentThreadId(); ds->releaseAll(); ds->dwMyThread = dwOldThread; ods("D3D9: Final release. MyRefs = %d Tot = %d", ds->myRefCount, ds->refCount); devMap.erase(idd); delete ds; } //TODO: Move logic to HardHook. // Call base without active hook in case of no trampoline. ReleaseType oRelease = (ReleaseType) hhRelease.call; hhRelease.restore(); ULONG res = oRelease(idd); hhRelease.inject(); ods("D3D9: Chained Release with result %d", res); return res; }
static HRESULT __stdcall myResize(IDXGISwapChain *pSwapChain, UINT BufferCount, UINT Width, UINT Height, DXGI_FORMAT NewFormat, UINT SwapChainFlags) { HRESULT hr; D10State *ds = chains[pSwapChain]; if (ds) { devices.erase(ds->pDevice); chains.erase(pSwapChain); delete ds; } ResizeBuffersType oResize = (ResizeBuffersType) hhResize.call; hhResize.restore(); hr = oResize(pSwapChain, BufferCount, Width, Height, NewFormat, SwapChainFlags); hhResize.inject(); return hr; }
static HRESULT __stdcall myResize(IDXGISwapChain *pSwapChain, UINT BufferCount, UINT Width, UINT Height, DXGI_FORMAT NewFormat, UINT SwapChainFlags) { #ifdef EXTENDED_OVERLAY_DEBUGOUTPUT ods("DXGI: Call to Resize. Forwarding to D3D10 and D3D11 custom implementations before calling original logic ..."); #endif resizeD3D10(pSwapChain); resizeD3D11(pSwapChain); //TODO: Move logic to HardHook. // Call base without active hook in case of no trampoline. ResizeBuffersType oResize = (ResizeBuffersType) hhResize.call; hhResize.restore(); HRESULT hr = oResize(pSwapChain, BufferCount, Width, Height, NewFormat, SwapChainFlags); hhResize.inject(); return hr; }
static ULONG __stdcall myAddRef(ID3D10Device *pDevice) { //TODO: Move logic to HardHook. // Call base without active hook in case of no trampoline. AddRefType oAddRef = (AddRefType) hhAddRef.call; hhAddRef.restore(); ULONG res = oAddRef(pDevice); hhAddRef.inject(); Mutex m; DeviceMap::iterator it = devices.find(pDevice); if (it != devices.end()) { it->second->lHighMark = res; } return res; }
static HMODULE WINAPI MyLoadLibrary(const char *lpFileName) { //TODO: Move logic to HardHook. // Call base without active hook in case of no trampoline. LoadLibraryAType oLoadLibrary = (LoadLibraryAType) hhLoad.call; hhLoad.restore(); HMODULE h = oLoadLibrary(lpFileName); hhLoad.inject(); ods("Lib: Library %s loaded to %p", lpFileName, h); if (! bBlackListed) { checkHooks(); } return h; }
static HRESULT __stdcall myCreateDeviceEx(IDirect3D9Ex * id3d, UINT Adapter, D3DDEVTYPE DeviceType, HWND hFocusWindow, DWORD BehaviorFlags, D3DPRESENT_PARAMETERS *pPresentationParameters, D3DDISPLAYMODEEX* pFullscreenDisplayMode, IDirect3DDevice9Ex** ppReturnedDeviceInterface) { Mutex m; ods("D3D9: Chaining CreateDeviceEx"); // BehaviorFlags &= ~D3DCREATE_PUREDEVICE; CreateDeviceExType oCreateDeviceEx = (CreateDeviceExType) hhCreateDeviceEx.call; hhCreateDeviceEx.restore(); HRESULT hr=oCreateDeviceEx(id3d, Adapter,DeviceType,hFocusWindow,BehaviorFlags,pPresentationParameters,pFullscreenDisplayMode,ppReturnedDeviceInterface); hhCreateDeviceEx.inject(); if (FAILED(hr)) return hr; IDirect3DDevice9Ex *idd = *ppReturnedDeviceInterface; DevState *ds = new DevState; ds->dev = idd; idd->AddRef(); ds->initRefCount = idd->Release(); devMap[idd] = ds; if (bIsWin8) { hhAddRef.setupInterface(idd, 1, reinterpret_cast<voidFunc>(myWin8AddRef)); hhRelease.setupInterface(idd, 2, reinterpret_cast<voidFunc>(myWin8Release)); } else { hhAddRef.setupInterface(idd, 1, reinterpret_cast<voidFunc>(myAddRef)); hhRelease.setupInterface(idd, 2, reinterpret_cast<voidFunc>(myRelease)); } hhReset.setupInterface(idd, 16, reinterpret_cast<voidFunc>(myReset)); hhPresent.setupInterface(idd, 17, reinterpret_cast<voidFunc>(myPresent)); IDirect3DSwapChain9 *pSwap = NULL; idd->GetSwapChain(0, &pSwap); if (pSwap) { hhSwapPresent.setupInterface(pSwap, 3, reinterpret_cast<voidFunc>(mySwapPresent)); pSwap->Release(); } else { ods("D3D9: Failed to get swapchain for DevEx"); } ds->createCleanState(); return hr; }
static HRESULT __stdcall myPresent(IDirect3DDevice9 *idd, CONST RECT *pSourceRect, CONST RECT *pDestRect, HWND hDestWindowOverride,CONST RGNDATA *pDirtyRegion) { // Present is called for each frame. Thus, we do not want to always log here. #ifdef EXTENDED_OVERLAY_DEBUGOUTPUT ods("D3D9: Device Present"); #endif doPresent(idd); //TODO: Move logic to HardHook. // Call base without active hook in case of no trampoline. PresentType oPresent = (PresentType) hhPresent.call; hhPresent.restore(); HRESULT hr = oPresent(idd, pSourceRect, pDestRect, hDestWindowOverride, pDirtyRegion); hhPresent.inject(); return hr; }
static ULONG __stdcall myAddRef(IDirect3DDevice9 *idd) { Mutex m; DevState *ds = devMap[idd]; if (ds) { if (ds->dwMyThread == GetCurrentThreadId()) { ds->myRefCount++; } else ds->refCount++; return ds->refCount + ds->initRefCount; } AddRefType oAddRef = (AddRefType) hhAddRef.call; hhAddRef.restore(); LONG res = oAddRef(idd); hhAddRef.inject(); ods("D3D9: Chaining AddRef: %d", res); return res; }
static HRESULT __stdcall mySwapPresent(IDirect3DSwapChain9 * ids, CONST RECT *pSourceRect, CONST RECT *pDestRect, HWND hDestWindowOverride, CONST RGNDATA *pDirtyRegion, DWORD dwFlags) { ods("D3D9: SwapChain Present"); IDirect3DDevice9 *idd = NULL; ids->GetDevice(&idd); if (idd) { doPresent(idd); idd->Release(); } //TODO: Move logic to HardHook. // Call base without active hook in case of no trampoline. SwapPresentType oSwapPresent = (SwapPresentType) hhSwapPresent.call; hhSwapPresent.restore(); HRESULT hr = oSwapPresent(ids, pSourceRect,pDestRect,hDestWindowOverride,pDirtyRegion,dwFlags); hhSwapPresent.inject(); return hr; }
static ULONG __stdcall myRelease(IDirect3DDevice9 *idd) { Mutex m; DevState *ds = devMap[idd]; if (ds) { if (ds->dwMyThread == GetCurrentThreadId()) { ds->myRefCount--; return ds->refCount + ds->initRefCount; } else { ds->refCount--; } if (ds->refCount <= 1) ds->disconnect(); if (ds->refCount >= 0) return ds->refCount + ds->initRefCount; ods("D3D9: Final release. MyRefs = %d, Tot = %d", ds->myRefCount, ds->refCount); DWORD dwOldThread = ds->dwMyThread; if (dwOldThread) ods("finalRelease from other thread"); ds->dwMyThread = GetCurrentThreadId(); ds->releaseAll(); ds->dwMyThread = dwOldThread; resetAdditions(); ods("D3D9: Final release, MyRefs = %d Tot = %d", ds->myRefCount, ds->refCount); devMap.erase(idd); delete ds; } ReleaseType oRelease = (ReleaseType) hhRelease.call; hhRelease.restore(); LONG res = oRelease(idd); hhRelease.inject(); ods("D3D9: Chaining Release: %d", res); return res; }
static ULONG __stdcall myWin8Release(IDirect3DDevice9 *idd) { Mutex m; DevState *ds = devMap[idd]; if (ds) { if (ds->dwMyThread == GetCurrentThreadId()) { ds->myRefCount--; return ds->refCount; } if (ds->refCount == 1) { ds->disconnect(); ods("D3D9: Final release. MyRefs = %d, Tot = %d", ds->myRefCount, ds->refCount); DWORD dwOldThread = ds->dwMyThread; if (dwOldThread) ods("finalRelease from other thread"); ds->dwMyThread = GetCurrentThreadId(); ds->releaseAll(); ds->dwMyThread = dwOldThread; CustomHUD::Reset(); ods("D3D9: Final release, MyRefs = %d Tot = %d", ds->myRefCount, ds->refCount); devMap.erase(idd); delete ds; ds = NULL; } } ReleaseType oRelease = (ReleaseType) hhRelease.call; hhRelease.restore(); LONG res = oRelease(idd); if (ds) ds->refCount = res; hhRelease.inject(); ods("D3D9: Chaining Release (Win8): %d", res); return res; }
static HRESULT __stdcall myPresent(IDXGISwapChain *pSwapChain, UINT SyncInterval, UINT Flags) { // Present is called for each frame. Thus, we do not want to always log here. #ifdef EXTENDED_OVERLAY_DEBUGOUTPUT ods("DXGI: Call to Present; Drawing and then chaining the call to the original logic"); #endif // From this D3D-version-independent point, call the present logic for both // D3D 10 and 11. Those that apply will be executed adequately, those that // do not will (silently) fail. presentD3D10(pSwapChain); presentD3D11(pSwapChain); //TODO: Move logic to HardHook. // Call base without active hook in case of no trampoline. PresentType oPresent = (PresentType) hhPresent.call; hhPresent.restore(); HRESULT hr = oPresent(pSwapChain, SyncInterval, Flags); hhPresent.inject(); return hr; }
static ULONG __stdcall myRelease(ID3D10Device *pDevice) { ReleaseType oRelease = (ReleaseType) hhRelease.call; hhRelease.restore(); LONG res = oRelease(pDevice); hhRelease.inject(); Mutex m; D10State *ds = devices[pDevice]; if (ds) if (res < (ds->lHighMark / 2)) { ods("D3D10: Deleting resources %d < .5 %d", res, ds->lHighMark); devices.erase(ds->pDevice); chains.erase(ds->pSwapChain); delete ds; ods("D3D10: Deleted"); ds = NULL; } return res; }
static HRESULT __stdcall mySwapPresent(IDirect3DSwapChain9 *ids, CONST RECT *pSourceRect, CONST RECT *pDestRect, HWND hDestWindowOverride, CONST RGNDATA *pDirtyRegion, DWORD dwFlags) { // Present is called for each frame. Thus, we do not want to always log here. #ifdef EXTENDED_OVERLAY_DEBUGOUTPUT ods("D3D9: SwapChain Present"); #endif IDirect3DDevice9 *idd = NULL; ids->GetDevice(&idd); if (idd) { doPresent(idd); idd->Release(); } //TODO: Move logic to HardHook. // Call base without active hook in case of no trampoline. SwapPresentType oSwapPresent = (SwapPresentType) hhSwapPresent.call; hhSwapPresent.restore(); HRESULT hr = oSwapPresent(ids, pSourceRect, pDestRect, hDestWindowOverride, pDirtyRegion, dwFlags); hhSwapPresent.inject(); return hr; }
static HRESULT __stdcall mySwapPresent(IDirect3DSwapChain9 * ids, CONST RECT *pSourceRect, CONST RECT *pDestRect, HWND hDestWindowOverride, CONST RGNDATA *pDirtyRegion, DWORD dwFlags) { ods("D3D9: SwapChain Present"); if (bPresenting) { ods("D3D9: Not doublepresenting in chain!"); } else { IDirect3DDevice9 *idd = NULL; ids->GetDevice(&idd); if (idd) { myAdditions(idd); doPresent(idd); idd->Release(); } } SwapPresentType oSwapPresent; oSwapPresent = (SwapPresentType) hhSwapPresent.call; hhSwapPresent.restore(); HRESULT hr = oSwapPresent(ids, pSourceRect,pDestRect,hDestWindowOverride,pDirtyRegion,dwFlags); hhSwapPresent.inject(); return hr; }
static HRESULT __stdcall myPresent(IDXGISwapChain *pSwapChain, UINT SyncInterval, UINT Flags) { HRESULT hr; // ods("DXGI: Device Present"); ID3D10Device *pDevice = NULL; ods("DXGI: DrawBegin"); hr = pSwapChain->GetDevice(__uuidof(ID3D10Device), (void **) &pDevice); if (pDevice) { D10State *ds = chains[pSwapChain]; if (ds && ds->pDevice != pDevice) { ods("DXGI: SwapChain device changed"); devices.erase(ds->pDevice); delete ds; ds = NULL; } if (! ds) { ods("DXGI: New state"); ds = new D10State(pSwapChain, pDevice); chains[pSwapChain] = ds; devices[pDevice] = ds; ds->init(); } ds->draw(); pDevice->Release(); ods("DXGI: DrawEnd"); } PresentType oPresent = (PresentType) hhPresent.call; hhPresent.restore(); hr = oPresent(pSwapChain, SyncInterval, Flags); hhPresent.inject(); return hr; }
static HRESULT __stdcall myCreateDevice(IDirect3D9 *id3d, UINT Adapter, D3DDEVTYPE DeviceType, HWND hFocusWindow, DWORD BehaviorFlags, D3DPRESENT_PARAMETERS *pPresentationParameters, IDirect3DDevice9 **ppReturnedDeviceInterface) { Mutex m; ods("D3D9: Chaining CreateDevice"); // BehaviorFlags &= ~D3DCREATE_PUREDEVICE; //TODO: Move logic to HardHook. // Call base without active hook in case of no trampoline. CreateDeviceType oCreateDevice = (CreateDeviceType) hhCreateDevice.call; hhCreateDevice.restore(); HRESULT hr = oCreateDevice(id3d, Adapter, DeviceType, hFocusWindow, BehaviorFlags, pPresentationParameters, ppReturnedDeviceInterface); hhCreateDevice.inject(); if (FAILED(hr)) return hr; IDirect3DDevice9 *idd = *ppReturnedDeviceInterface; // Get real interface, please. IDirect3DDevice9 *originalDevice = findOriginalDevice(idd); if (idd != originalDevice) { ods("D3D9: Prepatched device, using original. %p => %p", idd, originalDevice); idd = originalDevice; } DevState *ds = new DevState; ds->dev = idd; idd->AddRef(); ds->initRefCount = idd->Release(); DevMapType::iterator it = devMap.find(idd); if (it != devMap.end()) { ods("Device exists in devMap already - canceling injection into device. Thread prev: %d ; new: %d", it->second->dwMyThread, GetCurrentThreadId()); delete ds; return hr; } devMap[idd] = ds; // The offsets are dependent on the declaration order of the struct. // See IDirect3DDevice9 (2nd, 3rd, 17th, 18th functions) const unsigned int offsetAddref = 1; const unsigned int offsetRelease = 2; const unsigned int offsetReset = 16; const unsigned int offsetPresent = 17; if (bIsWin8) { hhAddRef.setupInterface(idd, offsetAddref, reinterpret_cast<voidFunc>(myWin8AddRef)); hhRelease.setupInterface(idd, offsetRelease, reinterpret_cast<voidFunc>(myWin8Release)); } else { hhAddRef.setupInterface(idd, offsetAddref, reinterpret_cast<voidFunc>(myAddRef)); hhRelease.setupInterface(idd, offsetRelease, reinterpret_cast<voidFunc>(myRelease)); } hhReset.setupInterface(idd, offsetReset, reinterpret_cast<voidFunc>(myReset)); hhPresent.setupInterface(idd, offsetPresent, reinterpret_cast<voidFunc>(myPresent)); IDirect3DSwapChain9 *pSwap = NULL; idd->GetSwapChain(0, &pSwap); if (pSwap) { // The offset is dependent on the declaration order of the struct. // See IDirect3DSwapChain9 (Present is the fourth function) const unsigned int offsetPresent = 3; hhSwapPresent.setupInterface(pSwap, offsetPresent, reinterpret_cast<voidFunc>(mySwapPresent)); pSwap->Release(); } else { ods("D3D9: Failed to get swapchain"); } ds->createCleanState(); return hr; }
static HRESULT __stdcall myCreateDevice(IDirect3D9 * id3d, UINT Adapter, D3DDEVTYPE DeviceType, HWND hFocusWindow, DWORD BehaviorFlags, D3DPRESENT_PARAMETERS *pPresentationParameters, IDirect3DDevice9 **ppReturnedDeviceInterface) { ods("D3D9: Chaining CreateDevice"); Mutex m; // BehaviorFlags &= ~D3DCREATE_PUREDEVICE; CreateDeviceType oCreateDevice = (CreateDeviceType) hhCreateDevice.call; hhCreateDevice.restore(); HRESULT hr=oCreateDevice(id3d, Adapter,DeviceType,hFocusWindow,BehaviorFlags,pPresentationParameters,ppReturnedDeviceInterface); hhCreateDevice.inject(); if (FAILED(hr)) return hr; IDirect3DDevice9 *idd = *ppReturnedDeviceInterface; IDirect3DSwapChain9 *pSwap = NULL; // Get real interface, please. bool bfound; do { bfound = false; idd->GetSwapChain(0, &pSwap); if (pSwap) { IDirect3DDevice9 *idorig = NULL; if (SUCCEEDED(pSwap->GetDevice(&idorig))) { if (idorig != idd) { ods("Prepatched device, using original. %p => %p", idorig, idd); if (idd != *ppReturnedDeviceInterface) idd->Release(); idd = idorig; bfound = true; } else { idorig->Release(); } } pSwap->Release(); } } while (bfound); DevState *ds = new DevState; ds->dev = idd; idd->AddRef(); ds->initRefCount = idd->Release(); devMap[idd] = ds; if (bIsWin8) { hhAddRef.setupInterface(idd, 1, reinterpret_cast<voidFunc>(myWin8AddRef)); hhRelease.setupInterface(idd, 2, reinterpret_cast<voidFunc>(myWin8Release)); } else { hhAddRef.setupInterface(idd, 1, reinterpret_cast<voidFunc>(myAddRef)); hhRelease.setupInterface(idd, 2, reinterpret_cast<voidFunc>(myRelease)); } hhReset.setupInterface(idd, 16, reinterpret_cast<voidFunc>(myReset)); hhPresent.setupInterface(idd, 17, reinterpret_cast<voidFunc>(myPresent)); pSwap = NULL; idd->GetSwapChain(0, &pSwap); if (pSwap) { hhSwapPresent.setupInterface(pSwap, 3, reinterpret_cast<voidFunc>(mySwapPresent)); pSwap->Release(); } else { ods("D3D9: Failed to get swapchain"); } ds->createCleanState(); return hr; }