bananatools/platform/misc.c

168 lines
3.7 KiB
C

#include <windows.h>
#include <winuser.h>
#include <assert.h>
#include <stdint.h>
#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);
}
}