2010-03-01 83 views
3

試圖製作一個Fraps類型的程序。查看評論失敗的地方。C++ d3d hooking - COM vtable

#include "precompiled.h" 

typedef IDirect3D9* (STDMETHODCALLTYPE* Direct3DCreate9_t)(UINT SDKVersion); 
Direct3DCreate9_t RealDirect3DCreate9 = NULL; 

typedef HRESULT (STDMETHODCALLTYPE* CreateDevice_t)(UINT Adapter, D3DDEVTYPE DeviceType, HWND hFocusWindow, 
    DWORD BehaviorFlags, D3DPRESENT_PARAMETERS* pPresentationParameters, 
    IDirect3DDevice9** ppReturnedDeviceInterface); 
CreateDevice_t RealD3D9CreateDevice = NULL; 

HRESULT STDMETHODCALLTYPE HookedD3D9CreateDevice(UINT Adapter, D3DDEVTYPE DeviceType, HWND hFocusWindow, 
    DWORD BehaviorFlags, D3DPRESENT_PARAMETERS* pPresentationParameters, 
    IDirect3DDevice9** ppReturnedDeviceInterface) 
{ 
    // this call makes it jump to HookedDirect3DCreate9 and crashes. i'm doing something wrong 
    HRESULT ret = RealD3D9CreateDevice(Adapter, DeviceType, hFocusWindow, BehaviorFlags, 
     pPresentationParameters, ppReturnedDeviceInterface); 

    return ret; 
} 

IDirect3D9* STDMETHODCALLTYPE HookedDirect3DCreate9(UINT SDKVersion) 
{ 
    MessageBox(0, L"Creating d3d", L"", 0); 

    IDirect3D9* d3d = RealDirect3DCreate9(SDKVersion); 

    UINT_PTR* pVTable = (UINT_PTR*)(*((UINT_PTR*)d3d)); 
    RealD3D9CreateDevice = (CreateDevice_t)pVTable[16]; 

    DetourTransactionBegin(); 
    DetourUpdateThread(GetCurrentThread()); 
    DetourAttach(&(PVOID&)RealD3D9CreateDevice, HookedD3D9CreateDevice); 
    if (DetourTransactionCommit() != ERROR_SUCCESS) 
    { 
     MessageBox(0, L"failed to create createdev hook", L"", 0); 
    } 

    return d3d; 
} 

bool APIENTRY DllMain(HINSTANCE hModule, DWORD fdwReason, LPVOID lpReserved) 
{ 
    if (fdwReason == DLL_PROCESS_ATTACH) 
    { 
     MessageBox(0, L"", L"", 0); 

     RealDirect3DCreate9 = (Direct3DCreate9_t)GetProcAddress(GetModuleHandle(L"d3d9.dll"), "Direct3DCreate9"); 

     DetourTransactionBegin(); 
     DetourUpdateThread(GetCurrentThread()); 
     DetourAttach(&(PVOID&)RealDirect3DCreate9, HookedDirect3DCreate9); 
     DetourTransactionCommit(); 
    } 

    // TODO detach hooks 

    return true; 
} 

回答

5

IDirect3D9::CreateDevice C接口的簽名是:

STDMETHOD(CreateDevice)(
    THIS_ 
    UINT Adapter,D3DDEVTYPE DeviceType,HWND hFocusWindow, 
    DWORD BehaviorFlags,D3DPRESENT_PARAMETERS* pPresentationParameters, 
    IDirect3DDevice9** ppReturnedDeviceInterface) PURE; 

它展開:

typedef HRESULT (STDMETHODCALLTYPE* CreateDevice_t)(
    IDirect3D9 FAR *This, // you forgot this. 
    UINT Adapter, D3DDEVTYPE DeviceType, HWND hFocusWindow, 
    DWORD BehaviorFlags, D3DPRESENT_PARAMETERS* pPresentationParameters, 
    IDirect3DDevice9** ppReturnedDeviceInterface); 

換句話說,你聲明的形實轉換爲CreateDevice不正確。

而不是直接索引到IDirect3D9 vtable,您可能只想#define CINTERFACE並訪問您想通過d3d->lpVtbl->CreateDevice覆蓋的功能。

+0

太棒了!有用!謝謝。 – Mango

+0

@Mango,你也可以隨時接受答案:) – MSN

+0

對不起,前些日子我沒有註冊。註冊並接受了答案。再次感謝。 – Mango