#include #include #include #include #include "hook/table.h" #include "hooklib/reg.h" #include "platform/misc.h" #include "util/dprintf.h" // BlockInput // ShowCursor static BOOL WINAPI my_BlockInput(BOOL fBlockIt); static int WINAPI my_ShowCursor(BOOL bShow); static BOOL WINAPI my_GetCursorInfo(PCURSORINFO pci); static UINT WINAPI my_GetDriveTypeA(LPCSTR lpRootPathName); static HRESULT reg_read_sys_ver(void *bytes, uint32_t *nbytes); static BOOL (WINAPI *next_BlockInput)(BOOL fBlockIt); static int (WINAPI *next_ShowCursor)(BOOL bShow); static BOOL (WINAPI *next_GetCursorInfo)(PCURSORINFO pci); static UINT (WINAPI *next_GetDriveTypeA)(LPCSTR lpRootPathName); static struct misc_config config; static int real_cursor_state = 0; static const struct hook_symbol misc_hook_syms[] = { { .name = "BlockInput", .patch = my_BlockInput, .link = (void **) &next_BlockInput, }, { .name = "ShowCursor", .patch = my_ShowCursor, .link = (void **) &next_ShowCursor, }, { .name = "GetCursorInfo", .patch = my_GetCursorInfo, .link = (void **) &next_GetCursorInfo, } }; static const struct hook_symbol misc_k32_syms[] = { { .name = "GetDriveTypeA", .patch = my_GetDriveTypeA, .link = (void **) &next_GetDriveTypeA, }, }; static const struct reg_hook_val nbgi_reg[] = { { .name = L"SystemVersion", .type = REG_SZ, .read = reg_read_sys_ver } }; HRESULT misc_hook_init(const struct misc_config *cfg) { assert(cfg != NULL); memcpy(&config, cfg, sizeof(*cfg)); dprintf("Misc: init\n"); hook_table_apply( NULL, "User32.dll", misc_hook_syms, _countof(misc_hook_syms)); hook_table_apply( NULL, "kernel32.dll", misc_k32_syms, _countof(misc_k32_syms)); reg_hook_push_key( HKEY_LOCAL_MACHINE, L"SOFTWARE\\NBGI", nbgi_reg, _countof(nbgi_reg)); return S_OK; } static BOOL WINAPI my_BlockInput(BOOL fBlockIt) { if (!config.block_input_hook) { return next_BlockInput(fBlockIt); } dprintf("Misc: Block BlockInput -> %d\n", fBlockIt); return true; } static int WINAPI my_ShowCursor(BOOL bShow) { if (!config.show_cursor_hook) { return next_ShowCursor(bShow); } dprintf("Misc: Block ShowCursor -> %d\n", bShow); // Keep track for GetCursorInfo if (bShow) { return ++real_cursor_state; } else { return --real_cursor_state; } } static BOOL WINAPI my_GetCursorInfo(PCURSORINFO pci) { if (!config.show_cursor_hook) { return next_GetCursorInfo(pci); } // Game only seems to read the flags field, // so that's all we'll mess with dprintf("Misc: my_GetCursorInfo\n"); if (real_cursor_state >= 0) { pci->flags = CURSOR_SHOWING; } else { pci->flags = 0; } return true; } static HRESULT reg_read_sys_ver(void *bytes, uint32_t *nbytes) { dprintf("Misc: Get system version\n"); return reg_hook_read_wstr(bytes, nbytes, config.system_version); } static UINT WINAPI my_GetDriveTypeA(LPCSTR lpRootPathName) { dprintf("Misc: Get Drive Type for %s\n", lpRootPathName); switch (lpRootPathName[0]) { case 'C': case 'c': case 'D': case 'd': case 'E': case 'e': case 'F': case 'f': case 'G': case 'g': case 'H': case 'h': case 'I': case 'i': case 'J': case 'j': return DRIVE_FIXED; default: return next_GetDriveTypeA(lpRootPathName); } }