0
0
Fork 0
mirror of https://github.com/mumble-voip/mumble.git synced 2025-03-15 21:14:59 +00:00
mumble-voip_mumble/overlay/d3d10.cpp

520 lines
16 KiB
C++
Raw Normal View History

2009-08-24 15:16:15 +00:00
/* Copyright (C) 2005-2009, Thorvald Natvig <thorvald@natvig.com>
All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions
are met:
- Redistributions of source code must retain the above copyright notice,
this list of conditions and the following disclaimer.
- Redistributions in binary form must reproduce the above copyright notice,
this list of conditions and the following disclaimer in the documentation
and/or other materials provided with the distribution.
- Neither the name of the Mumble Developers nor the names of its
contributors may be used to endorse or promote products derived from this
software without specific prior written permission.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR
CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#include "lib.h"
2009-08-25 16:28:10 +00:00
#include "overlay.hex"
2009-08-24 15:16:15 +00:00
#include <d3d10.h>
2009-08-25 16:11:31 +00:00
#include <d3dx10.h>
2009-08-24 15:16:15 +00:00
DXGIData *dxgi;
static bool bHooked = false;
static bool bChaining = false;
static HardHook hhPresent;
2009-08-25 16:11:31 +00:00
static HardHook hhResize;
2009-08-25 17:44:17 +00:00
static HardHook hhAddRef;
static HardHook hhRelease;
2009-08-24 15:16:15 +00:00
typedef HRESULT(__stdcall *CreateDXGIFactoryType)(REFIID, void **);
typedef HRESULT(__stdcall *D3D10CreateDeviceAndSwapChainType)(IDXGIAdapter *, D3D10_DRIVER_TYPE, HMODULE, UINT, UINT, DXGI_SWAP_CHAIN_DESC *, IDXGISwapChain **, ID3D10Device **);
2009-08-25 16:11:31 +00:00
typedef HRESULT(__stdcall *D3D10CreateStateBlockType)(ID3D10Device *, D3D10_STATE_BLOCK_MASK *, ID3D10StateBlock **);
typedef HRESULT(__stdcall *D3D10StateBlockMaskEnableAllType)(D3D10_STATE_BLOCK_MASK *);
typedef HRESULT(__stdcall *D3D10CreateEffectFromMemoryType)(void *, SIZE_T, UINT, ID3D10Device *, ID3D10EffectPool *, ID3D10Effect **);
2009-08-24 15:16:15 +00:00
typedef HRESULT(__stdcall *PresentType)(IDXGISwapChain *, UINT, UINT);
2009-08-25 16:11:31 +00:00
typedef HRESULT(__stdcall *ResizeBuffersType)(IDXGISwapChain *, UINT, UINT, UINT, DXGI_FORMAT, UINT);
2009-08-25 17:44:17 +00:00
typedef ULONG(__stdcall *AddRefType)(ID3D10Device *);
typedef ULONG(__stdcall *ReleaseType)(ID3D10Device *);
2009-08-25 16:11:31 +00:00
#define HMODREF(mod, func) func##Type p##func = (func##Type) GetProcAddress(mod, #func)
2009-09-02 15:41:45 +00:00
struct SimpleVertex {
D3DXVECTOR3 Pos;
2009-08-25 16:11:31 +00:00
};
struct D10State {
2009-08-25 17:44:17 +00:00
LONG lHighMark;
LONG initRefCount;
LONG refCount;
LONG myRefCount;
DWORD dwMyThread;
2009-08-25 16:11:31 +00:00
ID3D10Device *pDevice;
2009-08-25 17:44:17 +00:00
IDXGISwapChain *pSwapChain;
2009-08-25 16:11:31 +00:00
ID3D10StateBlock *pOrigStateBlock;
ID3D10StateBlock *pMyStateBlock;
ID3D10RenderTargetView *pRTV;
ID3D10Effect *pEffect;
ID3D10EffectTechnique *pTechnique;
ID3D10InputLayout *pVertexLayout;
ID3D10Buffer *pVertexBuffer;
ID3D10BlendState *pBlendState;
D10State(IDXGISwapChain *, ID3D10Device *);
~D10State();
2009-08-25 17:44:17 +00:00
void init();
2009-08-25 16:11:31 +00:00
void draw();
};
2009-08-25 17:44:17 +00:00
map<IDXGISwapChain *, D10State *> chains;
map<ID3D10Device *, D10State *> devices;
2009-08-25 16:11:31 +00:00
D10State::D10State(IDXGISwapChain *pSwapChain, ID3D10Device *pDevice) {
2009-08-25 17:44:17 +00:00
this->pSwapChain = pSwapChain;
this->pDevice = pDevice;
dwMyThread = 0;
refCount = 0;
myRefCount = 0;
pDevice->AddRef();
initRefCount = pDevice->Release();
}
void D10State::init() {
2009-08-25 16:11:31 +00:00
static HMODREF(GetModuleHandleW(L"D3D10.DLL"), D3D10CreateEffectFromMemory);
static HMODREF(GetModuleHandleW(L"D3D10.DLL"), D3D10CreateStateBlock);
static HMODREF(GetModuleHandleW(L"D3D10.DLL"), D3D10StateBlockMaskEnableAll);
2009-08-24 15:16:15 +00:00
2009-08-25 16:11:31 +00:00
HRESULT hr;
2009-08-25 17:44:17 +00:00
dwMyThread = GetCurrentThreadId();
2009-08-25 16:11:31 +00:00
D3D10_STATE_BLOCK_MASK StateBlockMask;
ZeroMemory(&StateBlockMask, sizeof(StateBlockMask));
pD3D10StateBlockMaskEnableAll(&StateBlockMask);
pD3D10CreateStateBlock(pDevice, &StateBlockMask, &pOrigStateBlock);
pD3D10CreateStateBlock(pDevice, &StateBlockMask, &pMyStateBlock);
pOrigStateBlock->Capture();
ID3D10Texture2D* pBackBuffer = NULL;
2009-09-02 15:41:45 +00:00
hr = pSwapChain->GetBuffer(0, __uuidof(*pBackBuffer), (LPVOID*)&pBackBuffer);
2009-08-25 16:11:31 +00:00
pDevice->ClearState();
D3D10_TEXTURE2D_DESC backBufferSurfaceDesc;
2009-09-02 15:41:45 +00:00
pBackBuffer->GetDesc(&backBufferSurfaceDesc);
2009-08-25 16:11:31 +00:00
D3D10_VIEWPORT vp;
vp.Width = backBufferSurfaceDesc.Width;
vp.Height = backBufferSurfaceDesc.Height;
vp.MinDepth = 0;
vp.MaxDepth = 1;
vp.TopLeftX = 0;
vp.TopLeftY = 0;
2009-09-02 15:41:45 +00:00
pDevice->RSSetViewports(1, &vp);
2009-08-25 16:11:31 +00:00
2009-09-02 15:41:45 +00:00
hr = pDevice->CreateRenderTargetView(pBackBuffer, NULL, &pRTV);
2009-08-25 16:11:31 +00:00
2009-09-02 15:41:45 +00:00
pDevice->OMSetRenderTargets(1, &pRTV, NULL);
2009-08-25 16:11:31 +00:00
D3D10_BLEND_DESC blend;
ZeroMemory(&blend, sizeof(blend));
blend.BlendEnable[0] = TRUE;
blend.SrcBlend = D3D10_BLEND_SRC_ALPHA;
blend.DestBlend = D3D10_BLEND_INV_SRC_ALPHA;
blend.BlendOp = D3D10_BLEND_OP_ADD;
blend.SrcBlendAlpha = D3D10_BLEND_SRC_ALPHA;
blend.DestBlendAlpha = D3D10_BLEND_INV_SRC_ALPHA;
blend.BlendOpAlpha = D3D10_BLEND_OP_ADD;
blend.RenderTargetWriteMask[0] = D3D10_COLOR_WRITE_ENABLE_ALL;
pDevice->CreateBlendState(&blend, &pBlendState);
float bf[4];
pDevice->OMSetBlendState(pBlendState, bf, 0xffffffff);
2009-08-25 16:28:10 +00:00
pD3D10CreateEffectFromMemory((void *) g_main, sizeof(g_main), 0, pDevice, NULL, &pEffect);
2009-08-25 16:11:31 +00:00
2009-09-02 15:41:45 +00:00
pTechnique = pEffect->GetTechniqueByName("Render");
2009-08-25 16:11:31 +00:00
// Define the input layout
2009-09-02 15:41:45 +00:00
D3D10_INPUT_ELEMENT_DESC layout[] = {
2009-08-25 16:11:31 +00:00
{ "POSITION", 0, DXGI_FORMAT_R32G32B32_FLOAT, 0, 0, D3D10_INPUT_PER_VERTEX_DATA, 0 },
};
2009-09-02 15:41:45 +00:00
UINT numElements = sizeof(layout) / sizeof(layout[0]);
2009-08-25 16:11:31 +00:00
// Create the input layout
D3D10_PASS_DESC PassDesc;
2009-09-02 15:41:45 +00:00
pTechnique->GetPassByIndex(0)->GetDesc(&PassDesc);
hr = pDevice->CreateInputLayout(layout, numElements, PassDesc.pIAInputSignature, PassDesc.IAInputSignatureSize, &pVertexLayout);
pDevice->IASetInputLayout(pVertexLayout);
2009-08-25 16:11:31 +00:00
// Create vertex buffer
2009-09-02 15:41:45 +00:00
SimpleVertex vertices[] = {
D3DXVECTOR3(0.0f, 0.9f, 0.5f),
D3DXVECTOR3(0.9f, -0.9f, 0.5f),
D3DXVECTOR3(-0.9f, -0.9f, 0.5f),
2009-08-25 16:11:31 +00:00
};
D3D10_BUFFER_DESC bd;
bd.Usage = D3D10_USAGE_DEFAULT;
2009-09-02 15:41:45 +00:00
bd.ByteWidth = sizeof(SimpleVertex) * 3;
2009-08-25 16:11:31 +00:00
bd.BindFlags = D3D10_BIND_VERTEX_BUFFER;
bd.CPUAccessFlags = 0;
bd.MiscFlags = 0;
D3D10_SUBRESOURCE_DATA InitData;
InitData.pSysMem = vertices;
2009-09-02 15:41:45 +00:00
hr = pDevice->CreateBuffer(&bd, &InitData, &pVertexBuffer);
2009-08-25 16:11:31 +00:00
// Set vertex buffer
2009-09-02 15:41:45 +00:00
UINT stride = sizeof(SimpleVertex);
2009-08-25 16:11:31 +00:00
UINT offset = 0;
2009-09-02 15:41:45 +00:00
pDevice->IASetVertexBuffers(0, 1, &pVertexBuffer, &stride, &offset);
2009-08-25 16:11:31 +00:00
// Set primitive topology
2009-09-02 15:41:45 +00:00
pDevice->IASetPrimitiveTopology(D3D10_PRIMITIVE_TOPOLOGY_TRIANGLELIST);
2009-08-25 16:11:31 +00:00
pMyStateBlock->Capture();
pOrigStateBlock->Apply();
pBackBuffer->Release();
2009-08-25 17:44:17 +00:00
dwMyThread = 0;
2009-08-25 16:11:31 +00:00
}
D10State::~D10State() {
pBlendState->Release();
pVertexBuffer->Release();
pVertexLayout->Release();
pEffect->Release();
pRTV->Release();
pMyStateBlock->ReleaseAllDeviceObjects();
pMyStateBlock->Release();
pOrigStateBlock->ReleaseAllDeviceObjects();
pOrigStateBlock->Release();
}
void D10State::draw() {
2009-08-25 17:44:17 +00:00
dwMyThread = GetCurrentThreadId();
2009-08-25 16:11:31 +00:00
pOrigStateBlock->Capture();
pMyStateBlock->Apply();
// Render a triangle
D3D10_TECHNIQUE_DESC techDesc;
2009-09-02 15:41:45 +00:00
pTechnique->GetDesc(&techDesc);
for (UINT p = 0; p < techDesc.Passes; ++p) {
2009-08-25 16:11:31 +00:00
// ods("Pass %d", p);
2009-09-02 15:41:45 +00:00
pTechnique->GetPassByIndex(p)->Apply(0);
pDevice->Draw(3, 0);
2009-08-25 16:11:31 +00:00
}
pOrigStateBlock->Apply();
2009-08-25 17:44:17 +00:00
dwMyThread = 0;
2009-08-25 16:11:31 +00:00
}
2009-08-24 15:16:15 +00:00
2009-08-25 16:11:31 +00:00
static HRESULT __stdcall myPresent(IDXGISwapChain *pSwapChain, UINT SyncInterval, UINT Flags) {
HRESULT hr;
// ods("DXGI: Device Present");
ID3D10Device *pDevice = NULL;
2009-08-25 17:44:17 +00:00
ods("DXGI: DrawBegin");
2009-08-25 16:11:31 +00:00
hr = pSwapChain->GetDevice(__uuidof(ID3D10Device), (void **) &pDevice);
if (pDevice) {
2009-08-25 17:44:17 +00:00
D10State *ds = chains[pSwapChain];
2009-08-25 16:11:31 +00:00
if (ds && ds->pDevice != pDevice) {
ods("DXGI: SwapChain device changed");
delete ds;
2009-08-25 17:44:17 +00:00
devices.erase(ds->pDevice);
2009-08-25 16:11:31 +00:00
ds = NULL;
}
if (! ds) {
2009-08-25 17:44:17 +00:00
ods("DXGI: New state");
2009-08-25 16:11:31 +00:00
ds = new D10State(pSwapChain, pDevice);
2009-08-25 17:44:17 +00:00
chains[pSwapChain] = ds;
devices[pDevice] = ds;
ds->init();
2009-08-25 16:11:31 +00:00
}
ds->draw();
pDevice->Release();
2009-08-25 17:44:17 +00:00
ods("DXGI: DrawEnd");
2009-08-25 16:11:31 +00:00
}
PresentType oPresent = (PresentType) hhPresent.call;
2009-08-24 15:16:15 +00:00
hhPresent.restore();
2009-08-25 16:11:31 +00:00
hr = oPresent(pSwapChain, SyncInterval, Flags);
2009-08-24 15:16:15 +00:00
hhPresent.inject();
return hr;
}
2009-08-25 16:11:31 +00:00
static HRESULT __stdcall myResize(IDXGISwapChain *pSwapChain, UINT BufferCount, UINT Width, UINT Height, DXGI_FORMAT NewFormat, UINT SwapChainFlags) {
HRESULT hr;
2009-08-25 17:44:17 +00:00
D10State *ds = chains[pSwapChain];
2009-08-25 16:11:31 +00:00
if (ds) {
2009-08-25 17:44:17 +00:00
devices.erase(ds->pDevice);
chains.erase(pSwapChain);
2009-08-25 16:11:31 +00:00
delete ds;
}
ResizeBuffersType oResize = (ResizeBuffersType) hhResize.call;
hhResize.restore();
hr = oResize(pSwapChain, BufferCount, Width, Height, NewFormat, SwapChainFlags);
hhResize.inject();
return hr;
}
2009-08-25 17:44:17 +00:00
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 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);
2009-08-25 17:44:17 +00:00
devices.erase(ds->pDevice);
chains.erase(ds->pSwapChain);
delete ds;
ods("D3D10: Deleted");
ds = NULL;
}
return res;
}
static void HookAddRelease(voidFunc vfAdd, voidFunc vfRelease) {
ods("D3D10: Injecting device add/remove");
hhAddRef.setup(vfAdd, reinterpret_cast<voidFunc>(myAddRef));
hhRelease.setup(vfRelease, reinterpret_cast<voidFunc>(myRelease));
}
2009-08-25 16:11:31 +00:00
2009-08-24 15:16:15 +00:00
static void HookPresentRaw(voidFunc vfPresent) {
hhPresent.setup(vfPresent, reinterpret_cast<voidFunc>(myPresent));
}
2009-08-25 16:11:31 +00:00
static void HookResizeRaw(voidFunc vfResize) {
ods("DXGI: Injecting ResizeBuffers Raw");
hhResize.setup(vfResize, reinterpret_cast<voidFunc>(myResize));
}
2009-08-24 15:16:15 +00:00
void checkDXGIHook(bool preonly) {
if (bChaining) {
return;
ods("DXGI: Causing a chain");
}
bChaining = true;
HMODULE hDXGI = GetModuleHandleW(L"DXGI.DLL");
2009-08-25 17:44:17 +00:00
HMODULE hD3D10 = GetModuleHandleW(L"D3D10CORE.DLL");
2009-08-24 15:16:15 +00:00
2009-08-25 17:44:17 +00:00
if (hDXGI && hD3D10) {
2009-08-24 15:16:15 +00:00
if (! bHooked) {
wchar_t procname[2048];
GetModuleFileNameW(NULL, procname, 2048);
fods("DXGI: Hookcheck '%ls'", procname);
bHooked = true;
// 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 *>(&checkDXGIHook), &hSelf);
// Can we use the prepatch data?
GetModuleFileNameW(hDXGI, procname, 2048);
2009-08-25 17:44:17 +00:00
if (_wcsicmp(dxgi->wcDXGIFileName, procname) == 0) {
2009-08-24 15:16:15 +00:00
unsigned char *raw = (unsigned char *) hDXGI;
HookPresentRaw((voidFunc)(raw + dxgi->iOffsetPresent));
2009-08-25 16:11:31 +00:00
HookResizeRaw((voidFunc)(raw + dxgi->iOffsetResize));
2009-08-25 17:44:17 +00:00
GetModuleFileNameW(hD3D10, procname, 2048);
if (_wcsicmp(dxgi->wcD3D10FileName, procname) == 0) {
unsigned char *raw = (unsigned char *) hD3D10;
HookAddRelease((voidFunc)(raw + dxgi->iOffsetAddRef), (voidFunc)(raw + dxgi->iOffsetRelease));
}
2009-08-24 15:16:15 +00:00
} else if (! preonly) {
fods("DXGI Interface changed, can't rawpatch");
} else {
bHooked = false;
}
}
}
bChaining = false;
}
extern "C" __declspec(dllexport) void __cdecl PrepareDXGI() {
ods("Preparing static data for DXGI Injection");
HMODULE hD3D10 = LoadLibrary("D3D10.DLL");
HMODULE hDXGI = LoadLibrary("DXGI.DLL");
HRESULT hr;
2009-08-25 17:44:17 +00:00
dxgi->wcDXGIFileName[0] = 0;
dxgi->wcD3D10FileName[0] = 0;
2009-08-24 15:16:15 +00:00
dxgi->iOffsetPresent = 0;
2009-08-25 17:44:17 +00:00
dxgi->iOffsetResize = 0;
dxgi->iOffsetAddRef = 0;
dxgi->iOffsetRelease = 0;
2009-08-24 15:16:15 +00:00
if (hDXGI != NULL && hD3D10 != NULL) {
CreateDXGIFactoryType pCreateDXGIFactory = reinterpret_cast<CreateDXGIFactoryType>(GetProcAddress(hDXGI, "CreateDXGIFactory"));
ods("Got %p", pCreateDXGIFactory);
if (pCreateDXGIFactory) {
IDXGIFactory * pFactory;
2009-09-02 15:41:45 +00:00
hr = pCreateDXGIFactory(__uuidof(IDXGIFactory), (void**)(&pFactory));
2009-08-24 15:16:15 +00:00
if (pFactory) {
2009-09-02 15:41:45 +00:00
HWND hwnd = CreateWindowW(L"STATIC", L"Mumble DXGI Window", WS_OVERLAPPEDWINDOW,
CW_USEDEFAULT, CW_USEDEFAULT, 640, 480, 0,
NULL, NULL, 0);
2009-08-24 15:16:15 +00:00
IDXGIAdapter *pAdapter = NULL;
pFactory->EnumAdapters(0, &pAdapter);
D3D10CreateDeviceAndSwapChainType pD3D10CreateDeviceAndSwapChain = reinterpret_cast<D3D10CreateDeviceAndSwapChainType>(GetProcAddress(hD3D10, "D3D10CreateDeviceAndSwapChain"));
IDXGISwapChain *pSwapChain = NULL;
ID3D10Device *pDevice = NULL;
DXGI_SWAP_CHAIN_DESC desc;
ZeroMemory(&desc, sizeof(desc));
2009-09-02 15:41:45 +00:00
RECT rcWnd;
GetClientRect(hwnd, &rcWnd);
2009-08-24 15:16:15 +00:00
desc.BufferDesc.Width = rcWnd.right - rcWnd.left;
desc.BufferDesc.Height = rcWnd.bottom - rcWnd.top;
ods("W %d H %d", desc.BufferDesc.Width, desc.BufferDesc.Height);
desc.BufferDesc.RefreshRate.Numerator = 60;
desc.BufferDesc.RefreshRate.Denominator = 1;
desc.BufferDesc.Format = DXGI_FORMAT_R8G8B8A8_UNORM_SRGB;
desc.BufferDesc.ScanlineOrdering = DXGI_MODE_SCANLINE_ORDER_UNSPECIFIED;
desc.BufferDesc.Scaling = DXGI_MODE_SCALING_CENTERED;
desc.SampleDesc.Count = 1;
desc.SampleDesc.Quality = 0;
desc.BufferUsage = DXGI_USAGE_RENDER_TARGET_OUTPUT;
desc.BufferCount = 2;
desc.OutputWindow = hwnd;
desc.Windowed = true;
desc.SwapEffect = DXGI_SWAP_EFFECT_DISCARD;
hr = pD3D10CreateDeviceAndSwapChain(pAdapter, D3D10_DRIVER_TYPE_HARDWARE, NULL, 0, D3D10_SDK_VERSION, &desc, &pSwapChain, &pDevice);
if (pDevice && pSwapChain) {
2009-09-02 15:41:45 +00:00
HMODULE hRef;
void ***vtbl = (void ***) pSwapChain;
void *pPresent = (*vtbl)[8];
if (! GetModuleHandleEx(GET_MODULE_HANDLE_EX_FLAG_FROM_ADDRESS | GET_MODULE_HANDLE_EX_FLAG_UNCHANGED_REFCOUNT, (char *) pPresent, &hRef)) {
ods("DXGI: Failed to get module for Present");
} else {
GetModuleFileNameW(hRef, dxgi->wcDXGIFileName, 2048);
unsigned char *b = (unsigned char *) pPresent;
unsigned char *a = (unsigned char *) hRef;
dxgi->iOffsetPresent = b-a;
ods("DXGI: Successfully found Present offset: %ls: %d", dxgi->wcDXGIFileName, dxgi->iOffsetPresent);
}
void *pResize = (*vtbl)[13];
if (! GetModuleHandleEx(GET_MODULE_HANDLE_EX_FLAG_FROM_ADDRESS | GET_MODULE_HANDLE_EX_FLAG_UNCHANGED_REFCOUNT, (char *) pResize, &hRef)) {
ods("DXGI: Failed to get module for ResizeBuffers");
} else {
wchar_t buff[2048];
GetModuleFileNameW(hRef, buff, 2048);
if (wcscmp(buff, dxgi->wcDXGIFileName) == 0) {
unsigned char *b = (unsigned char *) pResize;
2009-08-24 15:16:15 +00:00
unsigned char *a = (unsigned char *) hRef;
2009-09-02 15:41:45 +00:00
dxgi->iOffsetResize = b-a;
ods("DXGI: Successfully found ResizeBuffers offset: %ls: %d", dxgi->wcDXGIFileName, dxgi->iOffsetPresent);
2009-08-25 16:11:31 +00:00
}
2009-09-02 15:41:45 +00:00
}
vtbl = (void ***) pDevice;
void *pAddRef = (*vtbl)[1];
if (! GetModuleHandleEx(GET_MODULE_HANDLE_EX_FLAG_FROM_ADDRESS | GET_MODULE_HANDLE_EX_FLAG_UNCHANGED_REFCOUNT, (char *) pAddRef, &hRef)) {
ods("D3D10: Failed to get module for AddRef");
} else {
GetModuleFileNameW(hRef, dxgi->wcD3D10FileName, 2048);
unsigned char *b = (unsigned char *) pAddRef;
unsigned char *a = (unsigned char *) hRef;
dxgi->iOffsetAddRef = b-a;
ods("D3D10: Successfully found AddRef offset: %ls: %d", dxgi->wcD3D10FileName, dxgi->iOffsetAddRef);
}
void *pRelease = (*vtbl)[2];
if (! GetModuleHandleEx(GET_MODULE_HANDLE_EX_FLAG_FROM_ADDRESS | GET_MODULE_HANDLE_EX_FLAG_UNCHANGED_REFCOUNT, (char *) pRelease, &hRef)) {
ods("D3D10: Failed to get module for Release");
} else {
wchar_t buff[2048];
GetModuleFileNameW(hRef, buff, 2048);
if (wcscmp(buff, dxgi->wcD3D10FileName) == 0) {
unsigned char *b = (unsigned char *) pRelease;
2009-08-25 17:44:17 +00:00
unsigned char *a = (unsigned char *) hRef;
2009-09-02 15:41:45 +00:00
dxgi->iOffsetRelease = b-a;
ods("D3D10: Successfully found Release offset: %ls: %d", dxgi->wcD3D10FileName, dxgi->iOffsetRelease);
2009-08-24 15:16:15 +00:00
}
2009-09-02 15:41:45 +00:00
}
2009-08-24 15:16:15 +00:00
}
if (pDevice)
pDevice->Release();
if (pSwapChain)
pSwapChain->Release();
DestroyWindow(hwnd);
pFactory->Release();
}
}
}
}