From d42284c4bf7a5fb80de3c35897fba29481d2c048 Mon Sep 17 00:00:00 2001 From: FunkyFr3sh Date: Tue, 19 Mar 2019 06:57:49 +0100 Subject: [PATCH] optional hotpatch support --- Makefile | 1 + cnc-ddraw.vcxproj | 3 + cnc-ddraw.vcxproj.filters | 9 ++ inc/hook.h | 51 ++++++++++ inc/main.h | 1 + inc/mouse.h | 27 ++++++ src/dinput.c | 5 +- src/hook.c | 190 ++++++++++++++++++++++++++++++++++++++ src/main.c | 57 ++++++------ src/mouse.c | 167 +++++++++------------------------ src/settings.c | 8 +- src/surface.c | 3 +- 12 files changed, 361 insertions(+), 161 deletions(-) create mode 100644 inc/hook.h create mode 100644 inc/mouse.h create mode 100644 src/hook.c diff --git a/Makefile b/Makefile index baab3fa..99e6501 100644 --- a/Makefile +++ b/Makefile @@ -16,6 +16,7 @@ FILES = src/debug.c \ src/settings.c \ src/lodepng.c \ src/dinput.c \ + src/hook.c \ src/opengl.c all: diff --git a/cnc-ddraw.vcxproj b/cnc-ddraw.vcxproj index e4f75cd..39864d4 100644 --- a/cnc-ddraw.vcxproj +++ b/cnc-ddraw.vcxproj @@ -14,6 +14,7 @@ + @@ -29,8 +30,10 @@ + + diff --git a/cnc-ddraw.vcxproj.filters b/cnc-ddraw.vcxproj.filters index 810b4c8..2423530 100644 --- a/cnc-ddraw.vcxproj.filters +++ b/cnc-ddraw.vcxproj.filters @@ -57,6 +57,9 @@ Source Files + + Source Files + @@ -101,6 +104,12 @@ Header Files + + Header Files + + + Header Files + diff --git a/inc/hook.h b/inc/hook.h new file mode 100644 index 0000000..e4251e1 --- /dev/null +++ b/inc/hook.h @@ -0,0 +1,51 @@ +#ifndef HOOK_H +#define HOOK_H + +#include + +typedef HFONT(__stdcall* CREATEFONTINDIRECTA)(CONST LOGFONT*); + +typedef BOOL (WINAPI* GETCURSORPOSPROC)(LPPOINT); +typedef BOOL(WINAPI* CLIPCURSORPROC)(const RECT*); +typedef int (WINAPI* SHOWCURSORPROC)(BOOL); +typedef HCURSOR (WINAPI* SETCURSORPROC)(HCURSOR); +typedef BOOL (WINAPI* GETWINDOWRECTPROC)(HWND, LPRECT); +typedef BOOL (WINAPI* GETCLIENTRECTPROC)(HWND, LPRECT); +typedef BOOL (WINAPI* CLIENTTOSCREENPROC)(HWND, LPPOINT); +typedef BOOL (WINAPI* SCREENTOCLIENTPROC)(HWND, LPPOINT); +typedef BOOL (WINAPI* SETCURSORPOSPROC)(int, int); +typedef HWND (WINAPI* WINDOWFROMPOINTPROC)(POINT); +typedef BOOL (WINAPI* GETCLIPCURSORPROC)(LPRECT); +typedef BOOL (WINAPI* GETCURSORINFOPROC)(PCURSORINFO); +typedef int (WINAPI* GETSYSTEMMETRICSPROC)(int); +typedef BOOL (WINAPI* SETWINDOWPOSPROC)(HWND, HWND, int, int, int, int, UINT); +typedef BOOL (WINAPI* MOVEWINDOWPROC)(HWND, int, int, int, int, BOOL); +typedef LRESULT (WINAPI* SENDMESSAGEAPROC)(HWND, UINT, WPARAM, LPARAM); +typedef LONG (WINAPI* SETWINDOWLONGAPROC)(HWND, int, LONG); + +extern GETCURSORPOSPROC real_GetCursorPos; +extern CLIPCURSORPROC real_ClipCursor; +extern SHOWCURSORPROC real_ShowCursor; +extern SETCURSORPROC real_SetCursor; +extern GETWINDOWRECTPROC real_GetWindowRect; +extern GETCLIENTRECTPROC real_GetClientRect; +extern CLIENTTOSCREENPROC real_ClientToScreen; +extern SCREENTOCLIENTPROC real_ScreenToClient; +extern SETCURSORPOSPROC real_SetCursorPos; +extern WINDOWFROMPOINTPROC real_WindowFromPoint; +extern GETCLIPCURSORPROC real_GetClipCursor; +extern GETCURSORINFOPROC real_GetCursorInfo; +extern GETSYSTEMMETRICSPROC real_GetSystemMetrics; +extern SETWINDOWPOSPROC real_SetWindowPos; +extern MOVEWINDOWPROC real_MoveWindow; +extern SENDMESSAGEAPROC real_SendMessageA; +extern SETWINDOWLONGAPROC real_SetWindowLongA; + +extern BOOL Hook_Active; + +void Hook_Init(); +void Hook_PatchIAT(HMODULE hMod, char *moduleName, char *functionName, PROC newFunction); +PROC Hook_HotPatch(PROC function, PROC newFunction); +void Hook_TryHotPatch(HMODULE hMod, char *moduleName, char *functionName, PROC newFunction, PROC *function); + +#endif diff --git a/inc/main.h b/inc/main.h index c6248a9..e3551ee 100644 --- a/inc/main.h +++ b/inc/main.h @@ -127,6 +127,7 @@ typedef struct IDirectDrawImpl BOOL accurateTimers; int bnetHack; BOOL bnetActive; + BOOL hotPatch; SpeedLimiter ticksLimiter; SpeedLimiter flipLimiter; SpeedLimiter fpsLimiter; diff --git a/inc/mouse.h b/inc/mouse.h new file mode 100644 index 0000000..dd18506 --- /dev/null +++ b/inc/mouse.h @@ -0,0 +1,27 @@ +#ifndef MOUSE_H +#define MOUSE_H + +#include + +void mouse_lock(); +void mouse_unlock(); + +BOOL WINAPI fake_GetCursorPos(LPPOINT lpPoint); +BOOL WINAPI fake_ClipCursor(const RECT *lpRect); +int WINAPI fake_ShowCursor(BOOL bShow); +HCURSOR WINAPI fake_SetCursor(HCURSOR hCursor); +BOOL WINAPI fake_GetWindowRect(HWND hWnd, LPRECT lpRect); +BOOL WINAPI fake_GetClientRect(HWND hWnd, LPRECT lpRect); +BOOL WINAPI fake_ClientToScreen(HWND hWnd, LPPOINT lpPoint); +BOOL WINAPI fake_ScreenToClient(HWND hWnd, LPPOINT lpPoint); +BOOL WINAPI fake_SetCursorPos(int X, int Y); +HWND WINAPI fake_WindowFromPoint(POINT Point); +BOOL WINAPI fake_GetClipCursor(LPRECT lpRect); +BOOL WINAPI fake_GetCursorInfo(PCURSORINFO pci); +int WINAPI fake_GetSystemMetrics(int nIndex); +BOOL WINAPI fake_SetWindowPos(HWND hWnd, HWND hWndInsertAfter, int X, int Y, int cx, int cy, UINT uFlags); +BOOL WINAPI fake_MoveWindow(HWND hWnd, int X, int Y, int nWidth, int nHeight, BOOL bRepaint); +LRESULT WINAPI fake_SendMessageA(HWND hWnd, UINT Msg, WPARAM wParam, LPARAM lParam); +LONG WINAPI fake_SetWindowLongA(HWND hWnd, int nIndex, LONG dwNewLong); + +#endif diff --git a/src/dinput.c b/src/dinput.c index 5185c53..75579e6 100644 --- a/src/dinput.c +++ b/src/dinput.c @@ -1,7 +1,6 @@ #include #include - -void HookIAT(HMODULE hMod, char *moduleName, char *functionName, PROC newFunction); +#include "hook.h" typedef HRESULT (WINAPI *DInputCreateA)(HINSTANCE, DWORD, LPDIRECTINPUTA*, LPUNKNOWN); typedef HRESULT (WINAPI *DICreateDevice)(IDirectInputA*, REFGUID, LPDIRECTINPUTDEVICEA *, LPUNKNOWN); @@ -64,5 +63,5 @@ static HRESULT WINAPI fake_DirectInputCreateA(HINSTANCE hinst, DWORD dwVersion, void dinput_init() { - HookIAT(GetModuleHandle(NULL), "dinput.dll", "DirectInputCreateA", (PROC)fake_DirectInputCreateA); + Hook_PatchIAT(GetModuleHandle(NULL), "dinput.dll", "DirectInputCreateA", (PROC)fake_DirectInputCreateA); } diff --git a/src/hook.c b/src/hook.c new file mode 100644 index 0000000..d85febe --- /dev/null +++ b/src/hook.c @@ -0,0 +1,190 @@ +#include +#include +#include "main.h" +#include "mouse.h" +#include "hook.h" + +BOOL Hook_Active; +GETCURSORPOSPROC real_GetCursorPos = GetCursorPos; +CLIPCURSORPROC real_ClipCursor = ClipCursor; +SHOWCURSORPROC real_ShowCursor = ShowCursor; +SETCURSORPROC real_SetCursor = SetCursor; +GETWINDOWRECTPROC real_GetWindowRect = GetWindowRect; +GETCLIENTRECTPROC real_GetClientRect = GetClientRect; +CLIENTTOSCREENPROC real_ClientToScreen = ClientToScreen; +SCREENTOCLIENTPROC real_ScreenToClient = ScreenToClient; +SETCURSORPOSPROC real_SetCursorPos = SetCursorPos; +WINDOWFROMPOINTPROC real_WindowFromPoint = WindowFromPoint; +GETCLIPCURSORPROC real_GetClipCursor = GetClipCursor; +GETCURSORINFOPROC real_GetCursorInfo = GetCursorInfo; +GETSYSTEMMETRICSPROC real_GetSystemMetrics = GetSystemMetrics; +SETWINDOWPOSPROC real_SetWindowPos = SetWindowPos; +MOVEWINDOWPROC real_MoveWindow = MoveWindow; +SENDMESSAGEAPROC real_SendMessageA = SendMessageA; +SETWINDOWLONGAPROC real_SetWindowLongA = SetWindowLongA; + +void Hook_PatchIAT(HMODULE hMod, char *moduleName, char *functionName, PROC newFunction) +{ + if (!hMod || hMod == INVALID_HANDLE_VALUE || !newFunction) + return; + + PIMAGE_DOS_HEADER pDosHeader = (PIMAGE_DOS_HEADER)hMod; + if (pDosHeader->e_magic != IMAGE_DOS_SIGNATURE) + return; + + PIMAGE_NT_HEADERS pNTHeaders = (PIMAGE_NT_HEADERS)((DWORD)pDosHeader + (DWORD)pDosHeader->e_lfanew); + if (pNTHeaders->Signature != IMAGE_NT_SIGNATURE) + return; + + PIMAGE_IMPORT_DESCRIPTOR pImportDescriptor = (PIMAGE_IMPORT_DESCRIPTOR)((DWORD)pDosHeader + + (DWORD)(pNTHeaders->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_IMPORT].VirtualAddress)); + + if (pImportDescriptor == (PIMAGE_IMPORT_DESCRIPTOR)pNTHeaders) + return; + + while (pImportDescriptor->FirstThunk) + { + char *impModuleName = (char *)((DWORD)pDosHeader + (DWORD)(pImportDescriptor->Name)); + + if (_stricmp(impModuleName, moduleName) == 0) + { + PIMAGE_THUNK_DATA pFirstThunk = + (PIMAGE_THUNK_DATA)((DWORD)pDosHeader + (DWORD)pImportDescriptor->FirstThunk); + + PIMAGE_THUNK_DATA pOrigFirstThunk = + (PIMAGE_THUNK_DATA)((DWORD)pDosHeader + (DWORD)pImportDescriptor->OriginalFirstThunk); + + while (pFirstThunk->u1.Function && pOrigFirstThunk->u1.AddressOfData) + { + PIMAGE_IMPORT_BY_NAME pImport = + (PIMAGE_IMPORT_BY_NAME)((DWORD)pDosHeader + pOrigFirstThunk->u1.AddressOfData); + + if ((pOrigFirstThunk->u1.Ordinal & IMAGE_ORDINAL_FLAG) == 0 && + _stricmp((const char *)pImport->Name, functionName) == 0) + { + DWORD oldProtect; + + if (VirtualProtect(&pFirstThunk->u1.Function, sizeof(DWORD), PAGE_READWRITE, &oldProtect)) + { + pFirstThunk->u1.Function = (DWORD)newFunction; + VirtualProtect(&pFirstThunk->u1.Function, sizeof(DWORD), oldProtect, &oldProtect); + } + + break; + } + + pFirstThunk++; + pOrigFirstThunk++; + } + } + + pImportDescriptor++; + } +} + +PROC Hook_HotPatch(PROC function, PROC newFunction) +{ + PROC result = function; + + unsigned short *bytes = (unsigned short *)function; + if (function && *bytes == 0xFF8B) // mov edi, edi + { + char *address = ((char *)function) - 5; + DWORD oldProtect; + + if (VirtualProtect(address, 7, PAGE_EXECUTE_READWRITE, &oldProtect)) + { + if (memcmp(address, (const char[]) { 0xCC, 0xCC, 0xCC, 0xCC, 0xCC }, 5) == 0 || + memcmp(address, (const char[]) { 0x90, 0x90, 0x90, 0x90, 0x90 }, 5) == 0) + { + address[0] = 0xE9; // long jump + *((DWORD *)(&address[1])) = ((char *)newFunction) - address - 5; + *((WORD *)(&address[5])) = 0xF9EB; // short jump to our long jump + + result = (PROC)(((char *)function) + 2); + } + + VirtualProtect(address, 7, oldProtect, &oldProtect); + } + } + + return result; +} + +void Hook_TryHotPatch(HMODULE hMod, char *moduleName, char *functionName, PROC newFunction, PROC *function) +{ + PROC org = GetProcAddress(GetModuleHandle(moduleName), functionName); + if (org) + { + *function = Hook_HotPatch(org, newFunction); + + if (*function == org) // hotpatch failed... + Hook_PatchIAT(hMod, moduleName, functionName, newFunction); + } +} + +void Hook_Init() +{ + if (!Hook_Active) + { + Hook_Active = TRUE; + + if (ddraw->hotPatch) + { + Hook_TryHotPatch( + GetModuleHandle(NULL), "user32.dll", "GetCursorPos", (PROC)fake_GetCursorPos, (PROC *)&real_GetCursorPos); + Hook_TryHotPatch( + GetModuleHandle(NULL), "user32.dll", "ClipCursor", (PROC)fake_ClipCursor, (PROC *)&real_ClipCursor); + Hook_TryHotPatch( + GetModuleHandle(NULL), "user32.dll", "ShowCursor", (PROC)fake_ShowCursor, (PROC *)&real_ShowCursor); + Hook_TryHotPatch( + GetModuleHandle(NULL), "user32.dll", "SetCursor", (PROC)fake_SetCursor, (PROC *)&real_SetCursor); + Hook_TryHotPatch( + GetModuleHandle(NULL), "user32.dll", "GetWindowRect", (PROC)fake_GetWindowRect, (PROC *)&real_GetWindowRect); + Hook_TryHotPatch( + GetModuleHandle(NULL), "user32.dll", "GetClientRect", (PROC)fake_GetClientRect, (PROC *)&real_GetClientRect); + Hook_TryHotPatch( + GetModuleHandle(NULL), "user32.dll", "ClientToScreen", (PROC)fake_ClientToScreen, (PROC *)&real_ClientToScreen); + Hook_TryHotPatch( + GetModuleHandle(NULL), "user32.dll", "ScreenToClient", (PROC)fake_ScreenToClient, (PROC *)&real_ScreenToClient); + Hook_TryHotPatch( + GetModuleHandle(NULL), "user32.dll", "SetCursorPos", (PROC)fake_SetCursorPos, (PROC *)&real_SetCursorPos); + Hook_TryHotPatch( + GetModuleHandle(NULL), "user32.dll", "GetClipCursor", (PROC)fake_GetClipCursor, (PROC *)&real_GetClipCursor); + Hook_TryHotPatch( + GetModuleHandle(NULL), "user32.dll", "WindowFromPoint", (PROC)fake_WindowFromPoint, (PROC *)&real_WindowFromPoint); + Hook_TryHotPatch( + GetModuleHandle(NULL), "user32.dll", "GetCursorInfo", (PROC)fake_GetCursorInfo, (PROC *)&real_GetCursorInfo); + Hook_TryHotPatch( + GetModuleHandle(NULL), "user32.dll", "GetSystemMetrics", (PROC)fake_GetSystemMetrics, (PROC *)&real_GetSystemMetrics); + Hook_TryHotPatch( + GetModuleHandle(NULL), "user32.dll", "SetWindowPos", (PROC)fake_SetWindowPos, (PROC *)&real_SetWindowPos); + Hook_TryHotPatch( + GetModuleHandle(NULL), "user32.dll", "MoveWindow", (PROC)fake_MoveWindow, (PROC *)&real_MoveWindow); + Hook_TryHotPatch( + GetModuleHandle(NULL), "user32.dll", "SendMessageA", (PROC)fake_SendMessageA, (PROC *)&real_SendMessageA); + Hook_TryHotPatch( + GetModuleHandle(NULL), "user32.dll", "SetWindowLongA", (PROC)fake_SetWindowLongA, (PROC *)&real_SetWindowLongA); + } + else + { + Hook_PatchIAT(GetModuleHandle(NULL), "user32.dll", "GetCursorPos", (PROC)fake_GetCursorPos); + Hook_PatchIAT(GetModuleHandle(NULL), "user32.dll", "ClipCursor", (PROC)fake_ClipCursor); + Hook_PatchIAT(GetModuleHandle(NULL), "user32.dll", "ShowCursor", (PROC)fake_ShowCursor); + Hook_PatchIAT(GetModuleHandle(NULL), "user32.dll", "SetCursor", (PROC)fake_SetCursor); + Hook_PatchIAT(GetModuleHandle(NULL), "user32.dll", "GetWindowRect", (PROC)fake_GetWindowRect); + Hook_PatchIAT(GetModuleHandle(NULL), "user32.dll", "GetClientRect", (PROC)fake_GetClientRect); + Hook_PatchIAT(GetModuleHandle(NULL), "user32.dll", "ClientToScreen", (PROC)fake_ClientToScreen); + Hook_PatchIAT(GetModuleHandle(NULL), "user32.dll", "ScreenToClient", (PROC)fake_ScreenToClient); + Hook_PatchIAT(GetModuleHandle(NULL), "user32.dll", "SetCursorPos", (PROC)fake_SetCursorPos); + Hook_PatchIAT(GetModuleHandle(NULL), "user32.dll", "GetClipCursor", (PROC)fake_GetClipCursor); + Hook_PatchIAT(GetModuleHandle(NULL), "user32.dll", "WindowFromPoint", (PROC)fake_WindowFromPoint); + Hook_PatchIAT(GetModuleHandle(NULL), "user32.dll", "GetCursorInfo", (PROC)fake_GetCursorInfo); + Hook_PatchIAT(GetModuleHandle(NULL), "user32.dll", "GetSystemMetrics", (PROC)fake_GetSystemMetrics); + Hook_PatchIAT(GetModuleHandle(NULL), "user32.dll", "SetWindowPos", (PROC)fake_SetWindowPos); + Hook_PatchIAT(GetModuleHandle(NULL), "user32.dll", "MoveWindow", (PROC)fake_MoveWindow); + Hook_PatchIAT(GetModuleHandle(NULL), "user32.dll", "SendMessageA", (PROC)fake_SendMessageA); + Hook_PatchIAT(GetModuleHandle(NULL), "user32.dll", "SetWindowLongA", (PROC)fake_SetWindowLongA); + } + } +} diff --git a/src/main.c b/src/main.c index 976a8df..611e120 100644 --- a/src/main.c +++ b/src/main.c @@ -27,15 +27,12 @@ #include "palette.h" #include "surface.h" #include "clipper.h" +#include "hook.h" +#include "mouse.h" #include "render_d3d9.h" #define IDR_MYMENU 93 -BOOL WINAPI fake_GetCursorPos(LPPOINT lpPoint); -void mouse_init(); -void mouse_lock(); -void mouse_unlock(); - BOOL screenshot(struct IDirectDrawSurfaceImpl *); void Settings_Load(); void Settings_Save(RECT *lpRect, int windowState); @@ -115,7 +112,7 @@ BOOL CALLBACK EnumChildProc(HWND hWnd, LPARAM lParam) RECT size; RECT pos; - if (GetClientRect(hWnd, &size) && GetWindowRect(hWnd, &pos) && size.right > 1 && size.bottom > 1) + if (real_GetClientRect(hWnd, &size) && real_GetWindowRect(hWnd, &pos) && size.right > 1 && size.bottom > 1) { ChildWindowExists = TRUE; @@ -552,13 +549,13 @@ HRESULT __stdcall ddraw_SetDisplayMode(IDirectDrawImpl *This, DWORD width, DWORD return DDERR_UNSUPPORTED; } - const HANDLE hbicon = LoadImage(GetModuleHandle(0), MAKEINTRESOURCE(IDR_MYMENU), IMAGE_ICON, GetSystemMetrics(SM_CXICON), GetSystemMetrics(SM_CYICON), 0); + const HANDLE hbicon = LoadImage(GetModuleHandle(0), MAKEINTRESOURCE(IDR_MYMENU), IMAGE_ICON, real_GetSystemMetrics(SM_CXICON), real_GetSystemMetrics(SM_CYICON), 0); if (hbicon) - SendMessage(This->hWnd, WM_SETICON, ICON_BIG, (LPARAM)hbicon); + real_SendMessageA(This->hWnd, WM_SETICON, ICON_BIG, (LPARAM)hbicon); - const HANDLE hsicon = LoadImage(GetModuleHandle(0), MAKEINTRESOURCE(IDR_MYMENU), IMAGE_ICON, GetSystemMetrics(SM_CXSMICON), GetSystemMetrics(SM_CYSMICON), 0); + const HANDLE hsicon = LoadImage(GetModuleHandle(0), MAKEINTRESOURCE(IDR_MYMENU), IMAGE_ICON, real_GetSystemMetrics(SM_CXSMICON), real_GetSystemMetrics(SM_CYSMICON), 0); if (hsicon) - SendMessage(This->hWnd, WM_SETICON, ICON_SMALL, (LPARAM)hsicon); + real_SendMessageA(This->hWnd, WM_SETICON, ICON_SMALL, (LPARAM)hsicon); } if (ddraw->altenter) @@ -764,23 +761,23 @@ HRESULT __stdcall ddraw_SetDisplayMode(IDirectDrawImpl *This, DWORD width, DWORD { if (!This->border) { - SetWindowLong(This->hWnd, GWL_STYLE, GetWindowLong(This->hWnd, GWL_STYLE) & ~(WS_CAPTION | WS_THICKFRAME | WS_MINIMIZE | WS_MAXIMIZE | WS_SYSMENU)); + real_SetWindowLongA(This->hWnd, GWL_STYLE, GetWindowLong(This->hWnd, GWL_STYLE) & ~(WS_CAPTION | WS_THICKFRAME | WS_MINIMIZE | WS_MAXIMIZE | WS_SYSMENU)); } else { - SetWindowLong(This->hWnd, GWL_STYLE, (GetWindowLong(This->hWnd, GWL_STYLE) | WS_OVERLAPPEDWINDOW) & ~WS_MAXIMIZEBOX); + real_SetWindowLongA(This->hWnd, GWL_STYLE, (GetWindowLong(This->hWnd, GWL_STYLE) | WS_OVERLAPPEDWINDOW) & ~WS_MAXIMIZEBOX); } if (ddraw->wine) - SetWindowLong(This->hWnd, GWL_STYLE, (GetWindowLong(This->hWnd, GWL_STYLE) | WS_MINIMIZEBOX) & ~(WS_MAXIMIZEBOX | WS_THICKFRAME)); + real_SetWindowLongA(This->hWnd, GWL_STYLE, (GetWindowLong(This->hWnd, GWL_STYLE) | WS_MINIMIZEBOX) & ~(WS_MAXIMIZEBOX | WS_THICKFRAME)); /* center the window with correct dimensions */ int x = (WindowRect.left != -32000) ? WindowRect.left : (This->mode.dmPelsWidth / 2) - (This->render.width / 2); int y = (WindowRect.top != -32000) ? WindowRect.top : (This->mode.dmPelsHeight / 2) - (This->render.height / 2); RECT dst = { x, y, This->render.width + x, This->render.height + y }; AdjustWindowRect(&dst, GetWindowLong(This->hWnd, GWL_STYLE), FALSE); - SetWindowPos(ddraw->hWnd, HWND_NOTOPMOST, 0, 0, 0, 0, SWP_NOMOVE | SWP_NOSIZE); - MoveWindow(This->hWnd, dst.left, dst.top, (dst.right - dst.left), (dst.bottom - dst.top), TRUE); + real_SetWindowPos(ddraw->hWnd, HWND_NOTOPMOST, 0, 0, 0, 0, SWP_NOMOVE | SWP_NOSIZE); + real_MoveWindow(This->hWnd, dst.left, dst.top, (dst.right - dst.left), (dst.bottom - dst.top), TRUE); if (This->renderer == render_d3d9_main) InitDirect3D9(); @@ -800,9 +797,9 @@ HRESULT __stdcall ddraw_SetDisplayMode(IDirectDrawImpl *This, DWORD width, DWORD } if (ddraw->wine) - SetWindowLong(This->hWnd, GWL_STYLE, GetWindowLong(This->hWnd, GWL_STYLE) | WS_MINIMIZEBOX); + real_SetWindowLongA(This->hWnd, GWL_STYLE, GetWindowLong(This->hWnd, GWL_STYLE) | WS_MINIMIZEBOX); - SetWindowPos(This->hWnd, HWND_TOPMOST, 0, 0, This->render.width, This->render.height, SWP_SHOWWINDOW); + real_SetWindowPos(This->hWnd, HWND_TOPMOST, 0, 0, This->render.width, This->render.height, SWP_SHOWWINDOW); LastSetWindowPosTick = timeGetTime(); mouse_lock(); @@ -840,7 +837,7 @@ void ToggleFullscreen() { mouse_unlock(); WindowState = ddraw->windowed = FALSE; - SetWindowLong(ddraw->hWnd, GWL_STYLE, GetWindowLong(ddraw->hWnd, GWL_STYLE) & ~(WS_CAPTION | WS_THICKFRAME | WS_MINIMIZE | WS_MAXIMIZE | WS_SYSMENU)); + real_SetWindowLongA(ddraw->hWnd, GWL_STYLE, GetWindowLong(ddraw->hWnd, GWL_STYLE) & ~(WS_CAPTION | WS_THICKFRAME | WS_MINIMIZE | WS_MAXIMIZE | WS_SYSMENU)); ddraw->altenter = TRUE; ddraw_SetDisplayMode(ddraw, ddraw->width, ddraw->height, ddraw->bpp); mouse_lock(); @@ -951,8 +948,8 @@ LRESULT CALLBACK WndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam) if (!ddraw->windowed) { LastSetWindowPosTick = timeGetTime(); - SetWindowPos(ddraw->hWnd, HWND_TOPMOST, 1, 1, ddraw->render.width, ddraw->render.height, SWP_SHOWWINDOW); - SetWindowPos(ddraw->hWnd, HWND_TOPMOST, 0, 0, ddraw->render.width, ddraw->render.height, SWP_SHOWWINDOW); + real_SetWindowPos(ddraw->hWnd, HWND_TOPMOST, 1, 1, ddraw->render.width, ddraw->render.height, SWP_SHOWWINDOW); + real_SetWindowPos(ddraw->hWnd, HWND_TOPMOST, 0, 0, ddraw->render.width, ddraw->render.height, SWP_SHOWWINDOW); } return 0; } @@ -1203,13 +1200,13 @@ LRESULT CALLBACK WndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam) do { RECT rc; - if (GetWindowRect(hWnd, &rc) && rc.bottom - rc.top == 479) + if (real_GetWindowRect(hWnd, &rc) && rc.bottom - rc.top == 479) hideCursor = FALSE; } while ((hWnd = FindWindowEx(HWND_DESKTOP, hWnd, "SDlgDialog", NULL))); if (hideCursor) - while (ShowCursor(FALSE) > 0); + while (real_ShowCursor(FALSE) > 0); } ddraw->bnetActive = !wParam; @@ -1282,8 +1279,8 @@ LRESULT CALLBACK WndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam) case WM_AUTORENDERER: { mouse_unlock(); - SetWindowPos(ddraw->hWnd, HWND_BOTTOM, 0, 0, 0, 0, SWP_NOMOVE | SWP_NOSIZE); - SetWindowPos(ddraw->hWnd, HWND_TOPMOST, 0, 0, 0, 0, SWP_NOMOVE | SWP_NOSIZE); + real_SetWindowPos(ddraw->hWnd, HWND_BOTTOM, 0, 0, 0, 0, SWP_NOMOVE | SWP_NOSIZE); + real_SetWindowPos(ddraw->hWnd, HWND_TOPMOST, 0, 0, 0, 0, SWP_NOMOVE | SWP_NOSIZE); if (!ddraw->wine) { ShowWindow(ddraw->hWnd, SW_MINIMIZE); @@ -1448,11 +1445,11 @@ HRESULT __stdcall ddraw_SetCooperativeLevel(IDirectDrawImpl *This, HWND hWnd, DW if (!This->WndProc) { - mouse_init(); + Hook_Init(); This->WndProc = (LRESULT(CALLBACK *)(HWND, UINT, WPARAM, LPARAM))GetWindowLong(hWnd, GWL_WNDPROC); - SetWindowLong(This->hWnd, GWL_WNDPROC, (LONG)WndProc); + real_SetWindowLongA(This->hWnd, GWL_WNDPROC, (LONG)WndProc); if (!This->render.hDC) { @@ -1470,11 +1467,11 @@ HRESULT __stdcall ddraw_SetCooperativeLevel(IDirectDrawImpl *This, HWND hWnd, DW if (ddraw->handlemouse && ddraw->windowed) { - while (ShowCursor(FALSE) > 0); //workaround for direct input games - while (ShowCursor(TRUE) < 0); + while (real_ShowCursor(FALSE) > 0); //workaround for direct input games + while (real_ShowCursor(TRUE) < 0); } - SetCursor(LoadCursor(NULL, IDC_ARROW)); + real_SetCursor(LoadCursor(NULL, IDC_ARROW)); GetWindowText(This->hWnd, (LPTSTR)&This->title, sizeof(This->title)); @@ -1593,7 +1590,7 @@ ULONG __stdcall ddraw_Release(IDirectDrawImpl *This) DeleteCriticalSection(&This->cs); /* restore old wndproc, subsequent ddraw creation will otherwise fail */ - SetWindowLong(This->hWnd, GWL_WNDPROC, (LONG)This->WndProc); + real_SetWindowLongA(This->hWnd, GWL_WNDPROC, (LONG)This->WndProc); HeapFree(GetProcessHeap(), 0, This); ddraw = NULL; return 0; diff --git a/src/mouse.c b/src/mouse.c index f4573fd..d9d19bb 100644 --- a/src/mouse.c +++ b/src/mouse.c @@ -14,27 +14,25 @@ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ -/* This is a special mouse coordinate fix for games that use GetCursorPos and expect to be in fullscreen */ - #include #include #include "main.h" #include "surface.h" +#include "hook.h" -BOOL mouse_active = FALSE; int yAdjust = 0; BOOL WINAPI fake_GetCursorPos(LPPOINT lpPoint) { POINT pt, realpt; - if (!GetCursorPos(&pt) || !ddraw) + if (!real_GetCursorPos(&pt) || !ddraw) return FALSE; realpt.x = pt.x; realpt.y = pt.y; - if(ddraw->locked && (!ddraw->windowed || ScreenToClient(ddraw->hWnd, &pt))) + if(ddraw->locked && (!ddraw->windowed || real_ScreenToClient(ddraw->hWnd, &pt))) { //fallback solution for possible ClipCursor failure int diffx = 0, diffy = 0; @@ -66,7 +64,7 @@ BOOL WINAPI fake_GetCursorPos(LPPOINT lpPoint) } if (diffx || diffy) - SetCursorPos(realpt.x - diffx, realpt.y - diffy); + real_SetCursorPos(realpt.x - diffx, realpt.y - diffy); if(ddraw->adjmouse) @@ -98,7 +96,7 @@ BOOL WINAPI fake_GetCursorPos(LPPOINT lpPoint) } if (diffx || diffy) - SetCursorPos(realpt.x - diffx, realpt.y - diffy); + real_SetCursorPos(realpt.x - diffx, realpt.y - diffy); } } @@ -127,7 +125,7 @@ int WINAPI fake_ShowCursor(BOOL bShow) static int count; if (ddraw && !ddraw->handlemouse) - return ShowCursor(bShow); + return real_ShowCursor(bShow); return bShow ? ++count : --count; } @@ -135,70 +133,11 @@ int WINAPI fake_ShowCursor(BOOL bShow) HCURSOR WINAPI fake_SetCursor(HCURSOR hCursor) { if (ddraw && !ddraw->handlemouse) - return SetCursor(hCursor); + return real_SetCursor(hCursor); return NULL; } -void HookIAT(HMODULE hMod, char *moduleName, char *functionName, PROC newFunction) -{ - if (!hMod || hMod == INVALID_HANDLE_VALUE || !newFunction) - return; - - PIMAGE_DOS_HEADER pDosHeader = (PIMAGE_DOS_HEADER)hMod; - if (pDosHeader->e_magic != IMAGE_DOS_SIGNATURE) - return; - - PIMAGE_NT_HEADERS pNTHeaders = (PIMAGE_NT_HEADERS)((DWORD)pDosHeader + (DWORD)pDosHeader->e_lfanew); - if (pNTHeaders->Signature != IMAGE_NT_SIGNATURE) - return; - - PIMAGE_IMPORT_DESCRIPTOR pImportDescriptor = (PIMAGE_IMPORT_DESCRIPTOR)((DWORD)pDosHeader + - (DWORD)(pNTHeaders->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_IMPORT].VirtualAddress)); - - if (pImportDescriptor == (PIMAGE_IMPORT_DESCRIPTOR)pNTHeaders) - return; - - while (pImportDescriptor->FirstThunk) - { - char *impModuleName = (char *)((DWORD)pDosHeader + (DWORD)(pImportDescriptor->Name)); - - if (_stricmp(impModuleName, moduleName) == 0) - { - PIMAGE_THUNK_DATA pFirstThunk = - (PIMAGE_THUNK_DATA)((DWORD)pDosHeader + (DWORD)pImportDescriptor->FirstThunk); - - PIMAGE_THUNK_DATA pOrigFirstThunk = - (PIMAGE_THUNK_DATA)((DWORD)pDosHeader + (DWORD)pImportDescriptor->OriginalFirstThunk); - - while (pFirstThunk->u1.Function && pOrigFirstThunk->u1.AddressOfData) - { - PIMAGE_IMPORT_BY_NAME pImport = - (PIMAGE_IMPORT_BY_NAME)((DWORD)pDosHeader + pOrigFirstThunk->u1.AddressOfData); - - if ((pOrigFirstThunk->u1.Ordinal & IMAGE_ORDINAL_FLAG) == 0 && - _stricmp((const char *)pImport->Name, functionName) == 0) - { - DWORD oldProtect; - - if (VirtualProtect(&pFirstThunk->u1.Function, sizeof(DWORD), PAGE_READWRITE, &oldProtect)) - { - pFirstThunk->u1.Function = (DWORD)newFunction; - VirtualProtect(&pFirstThunk->u1.Function, sizeof(DWORD), oldProtect, &oldProtect); - } - - break; - } - - pFirstThunk++; - pOrigFirstThunk++; - } - } - - pImportDescriptor++; - } -} - void mouse_lock() { RECT rc; @@ -206,15 +145,15 @@ void mouse_lock() if (ddraw->devmode) { if (ddraw->handlemouse) - while(ShowCursor(FALSE) > 0); + while(real_ShowCursor(FALSE) > 0); return; } - if (mouse_active && !ddraw->locked) + if (Hook_Active && !ddraw->locked) { // Get the window client area. - GetClientRect(ddraw->hWnd, &rc); + real_GetClientRect(ddraw->hWnd, &rc); if(ddraw->adjmouse) { @@ -230,8 +169,8 @@ void mouse_lock() // Convert the client area to screen coordinates. POINT pt = { rc.left, rc.top }; POINT pt2 = { rc.right, rc.bottom }; - ClientToScreen(ddraw->hWnd, &pt); - ClientToScreen(ddraw->hWnd, &pt2); + real_ClientToScreen(ddraw->hWnd, &pt); + real_ClientToScreen(ddraw->hWnd, &pt2); SetRect(&rc, pt.x, pt.y, pt2.x, pt2.y); @@ -239,29 +178,29 @@ void mouse_lock() if(ddraw->adjmouse) { - SetCursorPos( + real_SetCursorPos( rc.left + (ddraw->cursor.x * ddraw->render.scaleW), rc.top + ((ddraw->cursor.y - yAdjust) * ddraw->render.scaleH)); } else { - SetCursorPos(rc.left + ddraw->cursor.x, rc.top + ddraw->cursor.y - yAdjust); + real_SetCursorPos(rc.left + ddraw->cursor.x, rc.top + ddraw->cursor.y - yAdjust); } if (ddraw->handlemouse) { //SetCapture(ddraw->hWnd); - ClipCursor(&rc); - while (ShowCursor(FALSE) > 0); + real_ClipCursor(&rc); + while (real_ShowCursor(FALSE) > 0); } else { if (ddraw->hidecursor) { ddraw->hidecursor = FALSE; - ShowCursor(FALSE); + real_ShowCursor(FALSE); } - ClipCursor(&rc); + real_ClipCursor(&rc); } ddraw->locked = TRUE; @@ -275,12 +214,12 @@ void mouse_unlock() if (ddraw->devmode) { if (ddraw->handlemouse) - while(ShowCursor(TRUE) < 0); + while(real_ShowCursor(TRUE) < 0); return; } - if(!mouse_active) + if(!Hook_Active) { return; } @@ -290,34 +229,34 @@ void mouse_unlock() ddraw->locked = FALSE; // Get the window client area. - GetClientRect(ddraw->hWnd, &rc); + real_GetClientRect(ddraw->hWnd, &rc); // Convert the client area to screen coordinates. POINT pt = { rc.left, rc.top }; POINT pt2 = { rc.right, rc.bottom }; - ClientToScreen(ddraw->hWnd, &pt); - ClientToScreen(ddraw->hWnd, &pt2); + real_ClientToScreen(ddraw->hWnd, &pt); + real_ClientToScreen(ddraw->hWnd, &pt2); SetRect(&rc, pt.x, pt.y, pt2.x, pt2.y); if (ddraw->handlemouse) { - while (ShowCursor(TRUE) < 0); - SetCursor(LoadCursor(NULL, IDC_ARROW)); + while (real_ShowCursor(TRUE) < 0); + real_SetCursor(LoadCursor(NULL, IDC_ARROW)); } else { CURSORINFO ci = { .cbSize = sizeof(CURSORINFO) }; - if (GetCursorInfo(&ci) && ci.flags == 0) + if (real_GetCursorInfo(&ci) && ci.flags == 0) { ddraw->hidecursor = TRUE; - while (ShowCursor(TRUE) < 0); + while (real_ShowCursor(TRUE) < 0); } } - ClipCursor(NULL); + real_ClipCursor(NULL); //ReleaseCapture(); - SetCursorPos( + real_SetCursorPos( rc.left + ddraw->render.viewport.x + (ddraw->cursor.x * ddraw->render.scaleW), rc.top + ddraw->render.viewport.y + ((ddraw->cursor.y + yAdjust) * ddraw->render.scaleH)); } @@ -338,11 +277,11 @@ BOOL WINAPI fake_GetWindowRect(HWND hWnd, LPRECT lpRect) } else { - return GetWindowRect(hWnd, lpRect) && MapWindowPoints(HWND_DESKTOP, ddraw->hWnd, (LPPOINT)lpRect, 2); + return real_GetWindowRect(hWnd, lpRect) && MapWindowPoints(HWND_DESKTOP, ddraw->hWnd, (LPPOINT)lpRect, 2); } } - return GetWindowRect(hWnd, lpRect); + return real_GetWindowRect(hWnd, lpRect); } BOOL WINAPI fake_GetClientRect(HWND hWnd, LPRECT lpRect) @@ -357,13 +296,13 @@ BOOL WINAPI fake_GetClientRect(HWND hWnd, LPRECT lpRect) return TRUE; } - return GetClientRect(hWnd, lpRect); + return real_GetClientRect(hWnd, lpRect); } BOOL WINAPI fake_ClientToScreen(HWND hWnd, LPPOINT lpPoint) { if (ddraw && ddraw->hWnd != hWnd) - return ClientToScreen(hWnd, lpPoint) && ScreenToClient(ddraw->hWnd, lpPoint); + return real_ClientToScreen(hWnd, lpPoint) && real_ScreenToClient(ddraw->hWnd, lpPoint); return TRUE; } @@ -371,7 +310,7 @@ BOOL WINAPI fake_ClientToScreen(HWND hWnd, LPPOINT lpPoint) BOOL WINAPI fake_ScreenToClient(HWND hWnd, LPPOINT lpPoint) { if (ddraw && ddraw->hWnd != hWnd) - return ClientToScreen(ddraw->hWnd, lpPoint) && ScreenToClient(hWnd, lpPoint); + return real_ClientToScreen(ddraw->hWnd, lpPoint) && real_ScreenToClient(hWnd, lpPoint); return TRUE; } @@ -379,13 +318,13 @@ BOOL WINAPI fake_ScreenToClient(HWND hWnd, LPPOINT lpPoint) BOOL WINAPI fake_SetCursorPos(int X, int Y) { POINT pt = { X, Y }; - return ddraw && ClientToScreen(ddraw->hWnd, &pt) && SetCursorPos(pt.x, pt.y); + return ddraw && real_ClientToScreen(ddraw->hWnd, &pt) && real_SetCursorPos(pt.x, pt.y); } HWND WINAPI fake_WindowFromPoint(POINT Point) { POINT pt = { Point.x, Point.y }; - return ddraw && ClientToScreen(ddraw->hWnd, &pt) ? WindowFromPoint(pt) : NULL; + return ddraw && real_ClientToScreen(ddraw->hWnd, &pt) ? real_WindowFromPoint(pt) : NULL; } BOOL WINAPI fake_GetClipCursor(LPRECT lpRect) @@ -405,7 +344,7 @@ BOOL WINAPI fake_GetClipCursor(LPRECT lpRect) BOOL WINAPI fake_GetCursorInfo(PCURSORINFO pci) { - return pci && ddraw && GetCursorInfo(pci) && ScreenToClient(ddraw->hWnd, &pci->ptScreenPos); + return pci && ddraw && real_GetCursorInfo(pci) && real_ScreenToClient(ddraw->hWnd, &pci->ptScreenPos); } int WINAPI fake_GetSystemMetrics(int nIndex) @@ -419,7 +358,7 @@ int WINAPI fake_GetSystemMetrics(int nIndex) return ddraw->height; } - return GetSystemMetrics(nIndex); + return real_GetSystemMetrics(nIndex); } BOOL WINAPI fake_SetWindowPos(HWND hWnd, HWND hWndInsertAfter, int X, int Y, int cx, int cy, UINT uFlags) @@ -427,7 +366,7 @@ BOOL WINAPI fake_SetWindowPos(HWND hWnd, HWND hWndInsertAfter, int X, int Y, int if (ddraw && ddraw->hWnd == hWnd) return TRUE; - return SetWindowPos(hWnd, hWndInsertAfter, X, Y, cx, cy, uFlags); + return real_SetWindowPos(hWnd, hWndInsertAfter, X, Y, cx, cy, uFlags); } BOOL WINAPI fake_MoveWindow(HWND hWnd, int X, int Y, int nWidth, int nHeight, BOOL bRepaint) @@ -435,12 +374,12 @@ BOOL WINAPI fake_MoveWindow(HWND hWnd, int X, int Y, int nWidth, int nHeight, BO if (ddraw && ddraw->hWnd == hWnd) return TRUE; - return MoveWindow(hWnd, X, Y, nWidth, nHeight, bRepaint); + return real_MoveWindow(hWnd, X, Y, nWidth, nHeight, bRepaint); } LRESULT WINAPI fake_SendMessageA(HWND hWnd, UINT Msg, WPARAM wParam, LPARAM lParam) { - LRESULT result = SendMessageA(hWnd, Msg, wParam, lParam); + LRESULT result = real_SendMessageA(hWnd, Msg, wParam, lParam); if (result && ddraw && Msg == CB_GETDROPPEDCONTROLRECT) { @@ -457,27 +396,5 @@ LONG WINAPI fake_SetWindowLongA(HWND hWnd, int nIndex, LONG dwNewLong) if (ddraw && ddraw->hWnd == hWnd && nIndex == GWL_STYLE) return 0; - return SetWindowLongA(hWnd, nIndex, dwNewLong); -} - -void mouse_init() -{ - HookIAT(GetModuleHandle(NULL), "user32.dll", "GetCursorPos", (PROC)fake_GetCursorPos); - HookIAT(GetModuleHandle(NULL), "user32.dll", "ClipCursor", (PROC)fake_ClipCursor); - HookIAT(GetModuleHandle(NULL), "user32.dll", "ShowCursor", (PROC)fake_ShowCursor); - HookIAT(GetModuleHandle(NULL), "user32.dll", "SetCursor", (PROC)fake_SetCursor); - HookIAT(GetModuleHandle(NULL), "user32.dll", "GetWindowRect", (PROC)fake_GetWindowRect); - HookIAT(GetModuleHandle(NULL), "user32.dll", "GetClientRect", (PROC)fake_GetClientRect); - HookIAT(GetModuleHandle(NULL), "user32.dll", "ClientToScreen", (PROC)fake_ClientToScreen); - HookIAT(GetModuleHandle(NULL), "user32.dll", "ScreenToClient", (PROC)fake_ScreenToClient); - HookIAT(GetModuleHandle(NULL), "user32.dll", "SetCursorPos", (PROC)fake_SetCursorPos); - HookIAT(GetModuleHandle(NULL), "user32.dll", "GetClipCursor", (PROC)fake_GetClipCursor); - HookIAT(GetModuleHandle(NULL), "user32.dll", "WindowFromPoint", (PROC)fake_WindowFromPoint); - HookIAT(GetModuleHandle(NULL), "user32.dll", "GetCursorInfo", (PROC)fake_GetCursorInfo); - HookIAT(GetModuleHandle(NULL), "user32.dll", "GetSystemMetrics", (PROC)fake_GetSystemMetrics); - HookIAT(GetModuleHandle(NULL), "user32.dll", "SetWindowPos", (PROC)fake_SetWindowPos); - HookIAT(GetModuleHandle(NULL), "user32.dll", "MoveWindow", (PROC)fake_MoveWindow); - HookIAT(GetModuleHandle(NULL), "user32.dll", "SendMessageA", (PROC)fake_SendMessageA); - HookIAT(GetModuleHandle(NULL), "user32.dll", "SetWindowLongA", (PROC)fake_SetWindowLongA); - mouse_active = TRUE; + return real_SetWindowLongA(hWnd, nIndex, dwNewLong); } diff --git a/src/settings.c b/src/settings.c index f76beec..986033a 100644 --- a/src/settings.c +++ b/src/settings.c @@ -41,6 +41,8 @@ void Settings_Load() ddraw->noactivateapp = GetBool("noactivateapp", FALSE); ddraw->vhack = GetBool("vhack", FALSE); ddraw->accurateTimers = GetBool("accuratetimers", FALSE); + ddraw->hotPatch = GetBool("hotPatch", FALSE); + ddraw->bnetHack = GetBool("bnetHack", TRUE); WindowRect.right = GetInt("width", 0); WindowRect.bottom = GetInt("height", 0); @@ -49,8 +51,6 @@ void Settings_Load() ddraw->render.maxfps = GetInt("maxfps", 125); - ddraw->bnetHack = GetBool("bnetHack", TRUE); - if (ddraw->accurateTimers || ddraw->vsync) ddraw->fpsLimiter.hTimer = CreateWaitableTimer(NULL, TRUE, NULL); //can't fully set it up here due to missing ddraw->mode.dmDisplayFrequency @@ -279,6 +279,10 @@ static void CreateSettingsIni() "; Force CPU0 affinity, avoids crashes/freezing, *might* have a performance impact\n" "singlecpu=true\n" "\n" + "; Use hotpatching rather than IAT hooking\n" + "; Note: Can be used to fix issues related to new features added by cnc-ddraw such as windowed mode or stretching\n" + "hotPatch=false\n" + "\n" "; Workaround for battle.net on Diablo and Warcraft 2 BNE\n" "; Note: This hack as a negative side-effect, you can only play fullscreen with 'renderer=gdi' or via 'fullscreen=true'\n" "bnetHack=false\n" diff --git a/src/surface.c b/src/surface.c index 7e434ba..5c84db9 100644 --- a/src/surface.c +++ b/src/surface.c @@ -18,6 +18,7 @@ #include #include "main.h" +#include "hook.h" #include "surface.h" #include "scale_pattern.h" @@ -1008,7 +1009,7 @@ HRESULT __stdcall ddraw_surface_Unlock(IDirectDrawSurfaceImpl *This, LPVOID lpRe do { RECT rc; - if (GetWindowRect(hWnd, &rc)) + if (real_GetWindowRect(hWnd, &rc)) { if (rc.bottom - rc.top == 479) erase = TRUE;