From 1170d0dd123ed0d7db4a23616285596106cd6766 Mon Sep 17 00:00:00 2001
From: FunkyFr3sh <cc.red.alert.1@googlemail.com>
Date: Sat, 15 Oct 2022 18:28:23 +0200
Subject: [PATCH] #179 hook GetDiskFreeSpaceA

---
 inc/hook.h         |  5 +++++
 inc/winapi_hooks.h | 13 +++++++++++++
 src/config.c       |  4 ++++
 src/hook.c         |  3 +++
 src/winapi_hooks.c | 33 +++++++++++++++++++++++++++++++++
 5 files changed, 58 insertions(+)

diff --git a/inc/hook.h b/inc/hook.h
index f40aed5..725ad40 100644
--- a/inc/hook.h
+++ b/inc/hook.h
@@ -35,16 +35,20 @@ typedef BOOL(WINAPI* DESTROYWINDOWPROC)(HWND);
 typedef int (WINAPI* MAPWINDOWPOINTSPROC)(HWND, HWND, LPPOINT, UINT);
 typedef BOOL (WINAPI* SHOWWINDOWPROC)(HWND, int);
 typedef BOOL(WINAPI* STRETCHBLTPROC)(HDC, int, int, int, int, HDC, int, int, int, int, DWORD);
+
 typedef int (WINAPI* SETDIBITSTODEVICEPROC)(
     HDC, int, int, DWORD, DWORD, int, int, UINT, UINT, const VOID*, const BITMAPINFO*, UINT);
+
 typedef int (WINAPI* STRETCHDIBITSPROC)(
     HDC, int, int, int, int, int, int, int, int, const VOID*, const BITMAPINFO*, UINT, DWORD);
+
 typedef HHOOK(WINAPI* SETWINDOWSHOOKEXAPROC)(int, HOOKPROC, HINSTANCE, DWORD);
 typedef int (WINAPI* GETDEVICECAPSPROC)(HDC, int);
 typedef HMODULE(WINAPI* LOADLIBRARYAPROC)(LPCSTR);
 typedef HMODULE(WINAPI* LOADLIBRARYWPROC)(LPCWSTR);
 typedef HMODULE(WINAPI* LOADLIBRARYEXAPROC)(LPCSTR, HANDLE, DWORD);
 typedef HMODULE(WINAPI* LOADLIBRARYEXWPROC)(LPCWSTR, HANDLE, DWORD);
+typedef BOOL(WINAPI* GETDISKFREESPACEAPROC)(LPCSTR, LPDWORD, LPDWORD, LPDWORD, LPDWORD);
 typedef HRESULT(WINAPI* COCREATEINSTANCEPROC)(REFCLSID, LPUNKNOWN, DWORD, REFIID, LPVOID*);
 
 extern GETCURSORPOSPROC real_GetCursorPos;
@@ -79,6 +83,7 @@ extern LOADLIBRARYAPROC real_LoadLibraryA;
 extern LOADLIBRARYWPROC real_LoadLibraryW;
 extern LOADLIBRARYEXAPROC real_LoadLibraryExA;
 extern LOADLIBRARYEXWPROC real_LoadLibraryExW;
+extern GETDISKFREESPACEAPROC real_GetDiskFreeSpaceA;
 extern COCREATEINSTANCEPROC real_CoCreateInstance;
 
 extern int g_hook_method;
diff --git a/inc/winapi_hooks.h b/inc/winapi_hooks.h
index 6b47029..4dc1f93 100644
--- a/inc/winapi_hooks.h
+++ b/inc/winapi_hooks.h
@@ -29,19 +29,32 @@ int WINAPI fake_MapWindowPoints(HWND hWndFrom, HWND hWndTo, LPPOINT lpPoints, UI
 BOOL WINAPI fake_ShowWindow(HWND hWnd, int nCmdShow);
 HHOOK WINAPI fake_SetWindowsHookExA(int idHook, HOOKPROC lpfn, HINSTANCE hmod, DWORD dwThreadId);
 int WINAPI fake_GetDeviceCaps(HDC hdc, int index);
+
 BOOL WINAPI fake_StretchBlt(
     HDC hdcDest, int xDest, int yDest, int wDest, int hDest, HDC hdcSrc, int xSrc, int ySrc, int wSrc, int hSrc, DWORD rop);
+
 int WINAPI fake_SetDIBitsToDevice(
     HDC, int, int, DWORD, DWORD, int, int, UINT, UINT, const VOID*, const BITMAPINFO*, UINT);
+
 int WINAPI fake_StretchDIBits(
     HDC, int, int, int, int, int, int, int, int, const VOID*, const BITMAPINFO*, UINT, DWORD);
+
 HMODULE WINAPI fake_LoadLibraryA(LPCSTR lpLibFileName);
 HMODULE WINAPI fake_LoadLibraryW(LPCWSTR lpLibFileName);
 HMODULE WINAPI fake_LoadLibraryExA(LPCSTR lpLibFileName, HANDLE hFile, DWORD dwFlags);
 HMODULE WINAPI fake_LoadLibraryExW(LPCWSTR lpLibFileName, HANDLE hFile, DWORD dwFlags);
+
+BOOL WINAPI fake_GetDiskFreeSpaceA(
+    LPCSTR lpRootPathName,
+    LPDWORD lpSectorsPerCluster,
+    LPDWORD lpBytesPerSector,
+    LPDWORD lpNumberOfFreeClusters,
+    LPDWORD lpTotalNumberOfClusters);
+
 HWND WINAPI fake_CreateWindowExA(
     DWORD dwExStyle, LPCSTR lpClassName, LPCSTR lpWindowName, DWORD dwStyle, int X, int Y,
     int nWidth, int nHeight, HWND hWndParent, HMENU hMenu, HINSTANCE hInstance, LPVOID lpParam);
+
 HRESULT WINAPI fake_CoCreateInstance(
     REFCLSID rclsid, LPUNKNOWN pUnkOuter, DWORD dwClsContext, REFIID riid, LPVOID* ppv);
 
diff --git a/src/config.c b/src/config.c
index b873355..ec25a0b 100644
--- a/src/config.c
+++ b/src/config.c
@@ -372,6 +372,8 @@ static void cfg_create_ini()
             "allow_wmactivate=false\n"
             "dinputhook=false\n"
             "flipclear=false\n"
+            "limit_disk_space=false\n"
+            "fixmousehook=false\n"
             "bpp=0\n"
             "\n"
             "\n"
@@ -733,10 +735,12 @@ static void cfg_create_ini()
             "; Fallout\n"
             "[falloutw]\n"
             "dinputhook=true\n"
+            "limit_disk_space=true\n"
             "\n"
             "; Fallout 2\n"
             "[FALLOUT2]\n"
             "dinputhook=true\n"
+            "limit_disk_space=true\n"
             "\n"
             "; Fairy Tale About Father Frost, Ivan and Nastya\n"
             "[mrazik]\n"
diff --git a/src/hook.c b/src/hook.c
index 1c2ebf8..a958b42 100644
--- a/src/hook.c
+++ b/src/hook.c
@@ -49,6 +49,7 @@ LOADLIBRARYAPROC real_LoadLibraryA = LoadLibraryA;
 LOADLIBRARYWPROC real_LoadLibraryW = LoadLibraryW;
 LOADLIBRARYEXAPROC real_LoadLibraryExA = LoadLibraryExA;
 LOADLIBRARYEXWPROC real_LoadLibraryExW = LoadLibraryExW;
+GETDISKFREESPACEAPROC real_GetDiskFreeSpaceA = GetDiskFreeSpaceA;
 COCREATEINSTANCEPROC real_CoCreateInstance = CoCreateInstance;
 
 static HOOKLIST g_hooks[] =
@@ -576,6 +577,7 @@ void hook_early_init()
     hook_patch_iat(GetModuleHandle(NULL), FALSE, "user32.dll", "ClipCursor", (PROC)fake_ClipCursor); //NexusTK
     hook_patch_iat(GetModuleHandle("AcGenral"), FALSE, "user32.dll", "SetWindowsHookExA", (PROC)fake_SetWindowsHookExA);
     hook_patch_iat(GetModuleHandle(NULL), FALSE, "user32.dll", "SetWindowsHookExA", (PROC)fake_SetWindowsHookExA);
+    hook_patch_iat(GetModuleHandle(NULL), FALSE, "kernel32.dll", "GetDiskFreeSpaceA", (PROC)fake_GetDiskFreeSpaceA);
 }
 
 void hook_exit()
@@ -633,4 +635,5 @@ void hook_exit()
     hook_patch_iat(GetModuleHandle(NULL), TRUE, "user32.dll", "ClipCursor", (PROC)fake_ClipCursor); //NexusTK
     hook_patch_iat(GetModuleHandle("AcGenral"), TRUE, "user32.dll", "SetWindowsHookExA", (PROC)fake_SetWindowsHookExA);
     hook_patch_iat(GetModuleHandle(NULL), TRUE, "user32.dll", "SetWindowsHookExA", (PROC)fake_SetWindowsHookExA);
+    hook_patch_iat(GetModuleHandle(NULL), TRUE, "kernel32.dll", "GetDiskFreeSpaceA", (PROC)fake_GetDiskFreeSpaceA);
 }
diff --git a/src/winapi_hooks.c b/src/winapi_hooks.c
index 5ecb408..935a461 100644
--- a/src/winapi_hooks.c
+++ b/src/winapi_hooks.c
@@ -776,6 +776,39 @@ HMODULE WINAPI fake_LoadLibraryExW(LPCWSTR lpLibFileName, HANDLE hFile, DWORD dw
     return hmod;
 }
 
+BOOL WINAPI fake_GetDiskFreeSpaceA(
+    LPCSTR lpRootPathName,
+    LPDWORD lpSectorsPerCluster,
+    LPDWORD lpBytesPerSector,
+    LPDWORD lpNumberOfFreeClusters,
+    LPDWORD lpTotalNumberOfClusters)
+{
+    BOOL result = 
+        real_GetDiskFreeSpaceA(
+            lpRootPathName,
+            lpSectorsPerCluster,
+            lpBytesPerSector,
+            lpNumberOfFreeClusters,
+            lpTotalNumberOfClusters);
+
+    if (cfg_get_bool("limit_disk_space", FALSE))
+    {
+        if (lpSectorsPerCluster)
+            *lpSectorsPerCluster = 0x00000040;
+
+        if (lpBytesPerSector) 
+            *lpBytesPerSector = 0x00000200;
+
+        if (lpNumberOfFreeClusters) 
+            *lpNumberOfFreeClusters = 0x0000FFF6;
+
+        if (lpTotalNumberOfClusters) 
+            *lpTotalNumberOfClusters = 0x0000FFF6;
+    }
+
+    return result; 
+}
+
 BOOL WINAPI fake_DestroyWindow(HWND hWnd)
 {
     BOOL result = real_DestroyWindow(hWnd);