197 lines
4.5 KiB
C
197 lines
4.5 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 int my_snprintf(char *const buffer, const size_t buffer_count, const char *const format, ...);
|
|
static int (*next_snprintf)(char *const buffer, const size_t buffer_count, const char *const format, ...);
|
|
|
|
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 hook_symbol misc_msvcr120_syms[] = {
|
|
{
|
|
.name = "_snprintf",
|
|
.patch = my_snprintf,
|
|
.link = (void **) &next_snprintf,
|
|
},
|
|
};
|
|
|
|
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));
|
|
|
|
hook_table_apply(
|
|
NULL,
|
|
"MSVCR120.dll",
|
|
misc_msvcr120_syms,
|
|
_countof(misc_msvcr120_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);
|
|
}
|
|
}
|
|
|
|
static int my_snprintf(char *const buffer, const size_t buffer_count, const char *const format, ...)
|
|
{
|
|
va_list ap;
|
|
int ret = 0;
|
|
|
|
va_start(ap, format);
|
|
ret = next_snprintf(buffer, buffer_count, format, ap);
|
|
OutputDebugStringA(buffer);
|
|
return ret;
|
|
}
|