forked from Dniel97/segatools
switched to new capnhook, updated unityhook, added LED 15093 to MU3
This commit is contained in:
parent
1069cfee26
commit
517469a60c
@ -5,7 +5,7 @@
|
|||||||
#include "cxbhook/led.h"
|
#include "cxbhook/led.h"
|
||||||
#include "cxbhook/cxb-dll.h"
|
#include "cxbhook/cxb-dll.h"
|
||||||
|
|
||||||
#include "hooklib/procaddr.h"
|
#include "hook/procaddr.h"
|
||||||
|
|
||||||
#include "hook/table.h"
|
#include "hook/table.h"
|
||||||
|
|
||||||
@ -56,7 +56,7 @@ HRESULT led_hook_init(struct led_config *cfg)
|
|||||||
}
|
}
|
||||||
|
|
||||||
dprintf("LED: Hook enabled.\n");
|
dprintf("LED: Hook enabled.\n");
|
||||||
return proc_addr_table_push("CommLamp.dll", lamp_syms, _countof(lamp_syms));
|
return proc_addr_table_push(NULL, "CommLamp.dll", lamp_syms, _countof(lamp_syms));
|
||||||
}
|
}
|
||||||
|
|
||||||
static int my_cCommLamp_Open(char *port)
|
static int my_cCommLamp_Open(char *port)
|
||||||
|
@ -6,7 +6,7 @@
|
|||||||
#include "cxbhook/revio.h"
|
#include "cxbhook/revio.h"
|
||||||
#include "cxbhook/cxb-dll.h"
|
#include "cxbhook/cxb-dll.h"
|
||||||
|
|
||||||
#include "hooklib/procaddr.h"
|
#include "hook/procaddr.h"
|
||||||
|
|
||||||
#include "hook/table.h"
|
#include "hook/table.h"
|
||||||
|
|
||||||
@ -89,7 +89,7 @@ HRESULT revio_hook_init(struct revio_config *cfg)
|
|||||||
}
|
}
|
||||||
|
|
||||||
dprintf("Revio: Hook enabled.\n");
|
dprintf("Revio: Hook enabled.\n");
|
||||||
return proc_addr_table_push("CommIo.dll", revio_syms, _countof(revio_syms));
|
return proc_addr_table_push(NULL, "CommIo.dll", revio_syms, _countof(revio_syms));
|
||||||
}
|
}
|
||||||
|
|
||||||
static int my_cCommIo_Open(char *port)
|
static int my_cCommIo_Open(char *port)
|
||||||
|
1
dist/fgo/segatools.ini
vendored
1
dist/fgo/segatools.ini
vendored
@ -128,7 +128,6 @@ path=
|
|||||||
; world. An improved solution will be provided later.
|
; world. An improved solution will be provided later.
|
||||||
|
|
||||||
[io4]
|
[io4]
|
||||||
; Input API selection for JVS input emulator.
|
|
||||||
; Test button virtual-key code. Default is the F1 key.
|
; Test button virtual-key code. Default is the F1 key.
|
||||||
test=0x70
|
test=0x70
|
||||||
; Service button virtual-key code. Default is the F2 key.
|
; Service button virtual-key code. Default is the F2 key.
|
||||||
|
3
dist/mu3/segatools.ini
vendored
3
dist/mu3/segatools.ini
vendored
@ -73,6 +73,9 @@ dipsw1=1
|
|||||||
enable=1
|
enable=1
|
||||||
|
|
||||||
[unity]
|
[unity]
|
||||||
|
; Enable Unity hook. This will allow you to run custom .NET code before the game
|
||||||
|
enable=1
|
||||||
|
|
||||||
; Path to a .NET DLL that should run before the game. Useful for loading
|
; Path to a .NET DLL that should run before the game. Useful for loading
|
||||||
; modding frameworks such as BepInEx.
|
; modding frameworks such as BepInEx.
|
||||||
targetAssembly=
|
targetAssembly=
|
||||||
|
@ -28,7 +28,7 @@ const struct dll_bind_sym fgo_dll_syms[] = {
|
|||||||
.sym = "fgo_io_led_init",
|
.sym = "fgo_io_led_init",
|
||||||
.off = offsetof(struct fgo_dll, led_init),
|
.off = offsetof(struct fgo_dll, led_init),
|
||||||
}, {
|
}, {
|
||||||
.sym = "fgo_io_led_set_leds",
|
.sym = "fgo_io_led_set_colors",
|
||||||
.off = offsetof(struct fgo_dll, led_set_leds),
|
.off = offsetof(struct fgo_dll, led_set_leds),
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
@ -18,7 +18,7 @@ EXPORTS
|
|||||||
fgo_io_init
|
fgo_io_init
|
||||||
fgo_io_poll
|
fgo_io_poll
|
||||||
fgo_io_led_init
|
fgo_io_led_init
|
||||||
fgo_io_led_set_leds
|
fgo_io_led_set_colors
|
||||||
fwdlusb_open
|
fwdlusb_open
|
||||||
fwdlusb_close
|
fwdlusb_close
|
||||||
fwdlusb_listupPrinter
|
fwdlusb_listupPrinter
|
||||||
|
@ -145,7 +145,7 @@ HRESULT fgo_io_led_init(void)
|
|||||||
return S_OK;
|
return S_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
void fgo_io_led_set_leds(uint8_t board, uint8_t *rgb)
|
void fgo_io_led_set_colors(uint8_t board, uint8_t *rgb)
|
||||||
{
|
{
|
||||||
return;
|
return;
|
||||||
}
|
}
|
@ -83,4 +83,4 @@ HRESULT fgo_io_led_init(void);
|
|||||||
|
|
||||||
Exact layout is TBD. */
|
Exact layout is TBD. */
|
||||||
|
|
||||||
void fgo_io_led_set_leds(uint8_t board, uint8_t *rgb);
|
void fgo_io_led_set_colors(uint8_t board, uint8_t *rgb);
|
||||||
|
@ -23,8 +23,6 @@ hooklib_lib = static_library(
|
|||||||
'fdshark.h',
|
'fdshark.h',
|
||||||
'path.c',
|
'path.c',
|
||||||
'path.h',
|
'path.h',
|
||||||
'procaddr.c',
|
|
||||||
'procaddr.h',
|
|
||||||
'reg.c',
|
'reg.c',
|
||||||
'reg.h',
|
'reg.h',
|
||||||
'setupapi.c',
|
'setupapi.c',
|
||||||
|
@ -1,125 +0,0 @@
|
|||||||
#include <windows.h>
|
|
||||||
#include <stdbool.h>
|
|
||||||
#include <stdint.h>
|
|
||||||
#include <libgen.h>
|
|
||||||
|
|
||||||
#include "hooklib/procaddr.h"
|
|
||||||
|
|
||||||
#include "hook/table.h"
|
|
||||||
|
|
||||||
#include "util/dprintf.h"
|
|
||||||
|
|
||||||
static struct proc_addr_table *proc_addr_hook_list;
|
|
||||||
static size_t proc_addr_hook_count;
|
|
||||||
static CRITICAL_SECTION proc_addr_hook_lock;
|
|
||||||
static bool proc_addr_hook_initted;
|
|
||||||
|
|
||||||
static FARPROC WINAPI my_GetProcAddress(HMODULE hModule, const char *name);
|
|
||||||
static FARPROC (WINAPI *next_GetProcAddress)(HMODULE hModule, const char *name);
|
|
||||||
static void proc_addr_hook_init(void);
|
|
||||||
|
|
||||||
static const struct hook_symbol win32_hooks[] = {
|
|
||||||
{
|
|
||||||
.name = "GetProcAddress",
|
|
||||||
.patch = my_GetProcAddress,
|
|
||||||
.link = (void **) &next_GetProcAddress
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
HRESULT proc_addr_table_push(
|
|
||||||
const char *target,
|
|
||||||
struct hook_symbol *syms,
|
|
||||||
size_t nsyms
|
|
||||||
)
|
|
||||||
{
|
|
||||||
HRESULT hr;
|
|
||||||
struct proc_addr_table *new_item;
|
|
||||||
struct proc_addr_table *new_mem;
|
|
||||||
|
|
||||||
proc_addr_hook_init();
|
|
||||||
|
|
||||||
EnterCriticalSection(&proc_addr_hook_lock);
|
|
||||||
|
|
||||||
new_mem = realloc(
|
|
||||||
proc_addr_hook_list,
|
|
||||||
(proc_addr_hook_count + 1) * sizeof(struct proc_addr_table));
|
|
||||||
|
|
||||||
if (new_mem == NULL) {
|
|
||||||
hr = E_OUTOFMEMORY;
|
|
||||||
|
|
||||||
LeaveCriticalSection(&proc_addr_hook_lock);
|
|
||||||
return hr;
|
|
||||||
}
|
|
||||||
|
|
||||||
new_item = &new_mem[proc_addr_hook_count];
|
|
||||||
new_item->name = target;
|
|
||||||
new_item->nsyms = nsyms;
|
|
||||||
new_item->syms = syms;
|
|
||||||
|
|
||||||
proc_addr_hook_list = new_mem;
|
|
||||||
proc_addr_hook_count++;
|
|
||||||
hr = S_OK;
|
|
||||||
|
|
||||||
LeaveCriticalSection(&proc_addr_hook_lock);
|
|
||||||
|
|
||||||
return hr;
|
|
||||||
}
|
|
||||||
|
|
||||||
static void proc_addr_hook_init(void)
|
|
||||||
{
|
|
||||||
if (proc_addr_hook_initted) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
dprintf("ProcAddr: Hook init\n");
|
|
||||||
proc_addr_hook_initted = true;
|
|
||||||
|
|
||||||
InitializeCriticalSection(&proc_addr_hook_lock);
|
|
||||||
|
|
||||||
hook_table_apply(
|
|
||||||
NULL,
|
|
||||||
"kernel32.dll",
|
|
||||||
win32_hooks,
|
|
||||||
_countof(win32_hooks));
|
|
||||||
}
|
|
||||||
|
|
||||||
FARPROC WINAPI my_GetProcAddress(HMODULE hModule, const char *name)
|
|
||||||
{
|
|
||||||
uintptr_t ordinal = (uintptr_t) name;
|
|
||||||
char mod_path[PATH_MAX];
|
|
||||||
char *mod_name;
|
|
||||||
const struct hook_symbol *sym;
|
|
||||||
FARPROC result = next_GetProcAddress(hModule, name);
|
|
||||||
|
|
||||||
GetModuleFileNameA(hModule, mod_path, PATH_MAX);
|
|
||||||
mod_name = basename(mod_path);
|
|
||||||
|
|
||||||
for (int i = 0; i < proc_addr_hook_count; i++) {
|
|
||||||
|
|
||||||
if (strcmp(proc_addr_hook_list[i].name, mod_name) == 0) {
|
|
||||||
|
|
||||||
for (int j = 0; j < proc_addr_hook_list[i].nsyms; j++) {
|
|
||||||
sym = &proc_addr_hook_list[i].syms[j];
|
|
||||||
|
|
||||||
if (ordinal > 0xFFFF) {
|
|
||||||
|
|
||||||
if (strcmp(sym->name, name) == 0) {
|
|
||||||
|
|
||||||
dprintf("ProcAddr: Hooking %s from %s\n", name, mod_name);
|
|
||||||
result = (FARPROC) sym->patch;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
else {
|
|
||||||
if (sym->ordinal == ordinal) {
|
|
||||||
|
|
||||||
dprintf("ProcAddr: Hooking Ord %p from %s\n", (void *)ordinal, mod_name);
|
|
||||||
result = (FARPROC) sym->patch;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return result;
|
|
||||||
}
|
|
@ -1,18 +0,0 @@
|
|||||||
#pragma once
|
|
||||||
#include <windows.h>
|
|
||||||
#include <stdbool.h>
|
|
||||||
#include <stdint.h>
|
|
||||||
|
|
||||||
#include "hook/table.h"
|
|
||||||
|
|
||||||
struct proc_addr_table {
|
|
||||||
const char *name;
|
|
||||||
size_t nsyms;
|
|
||||||
struct hook_symbol *syms;
|
|
||||||
};
|
|
||||||
|
|
||||||
HRESULT proc_addr_table_push(
|
|
||||||
const char *target,
|
|
||||||
struct hook_symbol *syms,
|
|
||||||
size_t nsyms
|
|
||||||
);
|
|
165
hooklib/reg.c
165
hooklib/reg.c
@ -7,6 +7,7 @@
|
|||||||
#include "hook/table.h"
|
#include "hook/table.h"
|
||||||
|
|
||||||
#include "hooklib/reg.h"
|
#include "hooklib/reg.h"
|
||||||
|
#include "hook/procaddr.h"
|
||||||
|
|
||||||
#include "util/dprintf.h"
|
#include "util/dprintf.h"
|
||||||
#include "util/str.h"
|
#include "util/str.h"
|
||||||
@ -99,6 +100,29 @@ static LSTATUS WINAPI hook_RegGetValueW(
|
|||||||
uint32_t *numData
|
uint32_t *numData
|
||||||
);
|
);
|
||||||
|
|
||||||
|
static LSTATUS WINAPI hook_RegQueryInfoKeyW(
|
||||||
|
HKEY hKey,
|
||||||
|
LPWSTR lpClass,
|
||||||
|
LPDWORD lpcchClass,
|
||||||
|
LPDWORD lpReserved,
|
||||||
|
LPDWORD lpcSubKeys,
|
||||||
|
LPDWORD lpcbMaxSubKeyLen,
|
||||||
|
LPDWORD lpcbMaxClassLen,
|
||||||
|
LPDWORD lpcValues,
|
||||||
|
LPDWORD lpcbMaxValueNameLen,
|
||||||
|
LPDWORD lpcbMaxValueLen,
|
||||||
|
LPDWORD lpcbSecurityDescriptor,
|
||||||
|
PFILETIME lpftLastWriteTime);
|
||||||
|
|
||||||
|
static LSTATUS WINAPI hook_RegEnumValueW(
|
||||||
|
HKEY hkey,
|
||||||
|
DWORD dwIndex,
|
||||||
|
LPWSTR lpValueName,
|
||||||
|
LPDWORD lpcchValueName,
|
||||||
|
LPDWORD lpReserved,
|
||||||
|
LPDWORD lpType,
|
||||||
|
LPBYTE lpData,
|
||||||
|
LPDWORD lpcbData);
|
||||||
/* Link pointers */
|
/* Link pointers */
|
||||||
|
|
||||||
static LSTATUS (WINAPI *next_RegOpenKeyExW)(
|
static LSTATUS (WINAPI *next_RegOpenKeyExW)(
|
||||||
@ -155,6 +179,30 @@ static LSTATUS (WINAPI *next_RegGetValueW)(
|
|||||||
uint32_t *numData
|
uint32_t *numData
|
||||||
);
|
);
|
||||||
|
|
||||||
|
static LSTATUS (WINAPI *next_RegQueryInfoKeyW)(
|
||||||
|
HKEY hKey,
|
||||||
|
LPWSTR lpClass,
|
||||||
|
LPDWORD lpcchClass,
|
||||||
|
LPDWORD lpReserved,
|
||||||
|
LPDWORD lpcSubKeys,
|
||||||
|
LPDWORD lpcbMaxSubKeyLen,
|
||||||
|
LPDWORD lpcbMaxClassLen,
|
||||||
|
LPDWORD lpcValues,
|
||||||
|
LPDWORD lpcbMaxValueNameLen,
|
||||||
|
LPDWORD lpcbMaxValueLen,
|
||||||
|
LPDWORD lpcbSecurityDescriptor,
|
||||||
|
PFILETIME lpftLastWriteTime);
|
||||||
|
|
||||||
|
static LSTATUS (WINAPI *next_RegEnumValueW)(
|
||||||
|
HKEY hkey,
|
||||||
|
DWORD dwIndex,
|
||||||
|
LPWSTR lpValueName,
|
||||||
|
LPDWORD lpcchValueName,
|
||||||
|
LPDWORD lpReserved,
|
||||||
|
LPDWORD lpType,
|
||||||
|
LPBYTE lpData,
|
||||||
|
LPDWORD lpcbData);
|
||||||
|
|
||||||
static const struct hook_symbol reg_hook_syms[] = {
|
static const struct hook_symbol reg_hook_syms[] = {
|
||||||
{
|
{
|
||||||
.name = "RegOpenKeyExW",
|
.name = "RegOpenKeyExW",
|
||||||
@ -184,6 +232,14 @@ static const struct hook_symbol reg_hook_syms[] = {
|
|||||||
.name = "RegGetValueW",
|
.name = "RegGetValueW",
|
||||||
.patch = hook_RegGetValueW,
|
.patch = hook_RegGetValueW,
|
||||||
.link = (void **) &next_RegGetValueW,
|
.link = (void **) &next_RegGetValueW,
|
||||||
|
}, {
|
||||||
|
.name = "RegQueryInfoKeyW",
|
||||||
|
.patch = hook_RegQueryInfoKeyW,
|
||||||
|
.link = (void **) &next_RegQueryInfoKeyW,
|
||||||
|
}, {
|
||||||
|
.name = "RegEnumValueW",
|
||||||
|
.patch = hook_RegEnumValueW,
|
||||||
|
.link = (void **) &next_RegEnumValueW,
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -254,11 +310,24 @@ static void reg_hook_init(void)
|
|||||||
InitializeCriticalSection(®_hook_lock);
|
InitializeCriticalSection(®_hook_lock);
|
||||||
dprintf("Reg hook init\n");
|
dprintf("Reg hook init\n");
|
||||||
|
|
||||||
|
reg_hook_insert_hooks(NULL);
|
||||||
|
|
||||||
|
proc_addr_table_push(
|
||||||
|
NULL,
|
||||||
|
"ADVAPI32.dll",
|
||||||
|
(struct hook_symbol *) reg_hook_syms,
|
||||||
|
_countof(reg_hook_syms));
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
void reg_hook_insert_hooks(HMODULE target)
|
||||||
|
{
|
||||||
hook_table_apply(
|
hook_table_apply(
|
||||||
NULL,
|
target,
|
||||||
"advapi32.dll",
|
"advapi32.dll",
|
||||||
reg_hook_syms,
|
reg_hook_syms,
|
||||||
_countof(reg_hook_syms));
|
_countof(reg_hook_syms));
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static LRESULT reg_hook_propagate_hr(HRESULT hr)
|
static LRESULT reg_hook_propagate_hr(HRESULT hr)
|
||||||
@ -331,6 +400,7 @@ static LSTATUS reg_hook_open_locked(
|
|||||||
/* Assume reg keys are referenced from a root key and not from some
|
/* Assume reg keys are referenced from a root key and not from some
|
||||||
intermediary key */
|
intermediary key */
|
||||||
key = ®_hook_keys[i];
|
key = ®_hook_keys[i];
|
||||||
|
//dprintf("Reg: %ls vs %ls\n", name, key->name);
|
||||||
|
|
||||||
if (key->root == parent && wstr_ieq(key->name, name)) {
|
if (key->root == parent && wstr_ieq(key->name, name)) {
|
||||||
break;
|
break;
|
||||||
@ -821,6 +891,99 @@ static LSTATUS WINAPI hook_RegGetValueW(
|
|||||||
return err;
|
return err;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static LSTATUS WINAPI hook_RegQueryInfoKeyW(
|
||||||
|
HKEY hKey,
|
||||||
|
LPWSTR lpClass,
|
||||||
|
LPDWORD lpcchClass,
|
||||||
|
LPDWORD lpReserved,
|
||||||
|
LPDWORD lpcSubKeys,
|
||||||
|
LPDWORD lpcbMaxSubKeyLen,
|
||||||
|
LPDWORD lpcbMaxClassLen,
|
||||||
|
LPDWORD lpcValues,
|
||||||
|
LPDWORD lpcbMaxValueNameLen,
|
||||||
|
LPDWORD lpcbMaxValueLen,
|
||||||
|
LPDWORD lpcbSecurityDescriptor,
|
||||||
|
PFILETIME lpftLastWriteTime)
|
||||||
|
{
|
||||||
|
struct reg_hook_key *key;
|
||||||
|
LSTATUS err;
|
||||||
|
|
||||||
|
EnterCriticalSection(®_hook_lock);
|
||||||
|
|
||||||
|
key = reg_hook_match_key_locked(hKey);
|
||||||
|
|
||||||
|
/* Check if this is a virtualized registry key */
|
||||||
|
|
||||||
|
if (key == NULL) {
|
||||||
|
LeaveCriticalSection(®_hook_lock);
|
||||||
|
|
||||||
|
return next_RegQueryInfoKeyW(
|
||||||
|
hKey,
|
||||||
|
lpClass,
|
||||||
|
lpcchClass,
|
||||||
|
lpReserved,
|
||||||
|
lpcSubKeys,
|
||||||
|
lpcbMaxSubKeyLen,
|
||||||
|
lpcbMaxClassLen,
|
||||||
|
lpcValues,
|
||||||
|
lpcbMaxValueNameLen,
|
||||||
|
lpcbMaxValueLen,
|
||||||
|
lpcbSecurityDescriptor,
|
||||||
|
lpftLastWriteTime);
|
||||||
|
}
|
||||||
|
|
||||||
|
// This is the only one I've seen even be changed, so it's all I'm doing
|
||||||
|
// until I see otherwise.
|
||||||
|
*lpcValues = key->nvals;
|
||||||
|
LeaveCriticalSection(®_hook_lock);
|
||||||
|
return ERROR_SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
|
static LSTATUS WINAPI hook_RegEnumValueW(
|
||||||
|
HKEY hkey,
|
||||||
|
DWORD dwIndex,
|
||||||
|
LPWSTR lpValueName,
|
||||||
|
LPDWORD lpcchValueName,
|
||||||
|
LPDWORD lpReserved,
|
||||||
|
LPDWORD lpType,
|
||||||
|
LPBYTE lpData,
|
||||||
|
LPDWORD lpcbData)
|
||||||
|
{
|
||||||
|
struct reg_hook_key *key;
|
||||||
|
HRESULT hr;
|
||||||
|
LSTATUS err;
|
||||||
|
|
||||||
|
EnterCriticalSection(®_hook_lock);
|
||||||
|
|
||||||
|
key = reg_hook_match_key_locked(hkey);
|
||||||
|
|
||||||
|
/* Check if this is a virtualized registry key */
|
||||||
|
|
||||||
|
if (key == NULL) {
|
||||||
|
LeaveCriticalSection(®_hook_lock);
|
||||||
|
|
||||||
|
return next_RegEnumValueW(
|
||||||
|
hkey,
|
||||||
|
dwIndex,
|
||||||
|
lpValueName,
|
||||||
|
lpcchValueName,
|
||||||
|
lpReserved,
|
||||||
|
lpType,
|
||||||
|
lpData,
|
||||||
|
lpcbData);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (dwIndex >= key->nvals) {
|
||||||
|
LeaveCriticalSection(®_hook_lock);
|
||||||
|
return ERROR_NO_MORE_ITEMS; // Pretty sure this is what it actually returns here?
|
||||||
|
}
|
||||||
|
|
||||||
|
wcscpy_s(lpValueName, *lpcchValueName, key->vals[dwIndex].name);
|
||||||
|
*lpcchValueName = wcslen(key->vals[dwIndex].name);
|
||||||
|
LeaveCriticalSection(®_hook_lock);
|
||||||
|
return ERROR_SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
HRESULT reg_hook_read_bin(
|
HRESULT reg_hook_read_bin(
|
||||||
void *bytes,
|
void *bytes,
|
||||||
uint32_t *nbytes,
|
uint32_t *nbytes,
|
||||||
|
@ -12,6 +12,8 @@ struct reg_hook_val {
|
|||||||
uint32_t type;
|
uint32_t type;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
void reg_hook_insert_hooks(HMODULE target);
|
||||||
|
|
||||||
HRESULT reg_hook_push_key(
|
HRESULT reg_hook_push_key(
|
||||||
HKEY root,
|
HKEY root,
|
||||||
const wchar_t *name,
|
const wchar_t *name,
|
||||||
|
@ -119,10 +119,19 @@ void touch_screen_hook_init(const struct touch_screen_config *cfg, HINSTANCE sel
|
|||||||
defaultCursor = LoadCursorA(NULL, IDC_CROSS);
|
defaultCursor = LoadCursorA(NULL, IDC_CROSS);
|
||||||
|
|
||||||
memcpy(&touch_config, cfg, sizeof(*cfg));
|
memcpy(&touch_config, cfg, sizeof(*cfg));
|
||||||
hook_table_apply(NULL, "user32.dll", touch_hooks, _countof(touch_hooks));
|
touch_hook_insert_hooks(NULL);
|
||||||
dprintf("TOUCH: hook enabled.\n");
|
dprintf("TOUCH: hook enabled.\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void touch_hook_insert_hooks(HMODULE target)
|
||||||
|
{
|
||||||
|
hook_table_apply(
|
||||||
|
target,
|
||||||
|
"user32.dll",
|
||||||
|
touch_hooks,
|
||||||
|
_countof(touch_hooks));
|
||||||
|
}
|
||||||
|
|
||||||
static HCURSOR WINAPI hook_SetCursor(HCURSOR cursor) {
|
static HCURSOR WINAPI hook_SetCursor(HCURSOR cursor) {
|
||||||
if (cursor == 0 && touch_config.cursor)
|
if (cursor == 0 && touch_config.cursor)
|
||||||
return next_SetCursor(defaultCursor);
|
return next_SetCursor(defaultCursor);
|
||||||
|
@ -14,3 +14,4 @@ struct touch_screen_config {
|
|||||||
blah blah you know the drill by now. */
|
blah blah you know the drill by now. */
|
||||||
|
|
||||||
void touch_screen_hook_init(const struct touch_screen_config *cfg, HINSTANCE self);
|
void touch_screen_hook_init(const struct touch_screen_config *cfg, HINSTANCE self);
|
||||||
|
void touch_hook_insert_hooks(HMODULE target);
|
||||||
|
@ -14,6 +14,7 @@ add_project_arguments(
|
|||||||
'-D_WIN32_WINNT=_WIN32_WINNT_WIN7',
|
'-D_WIN32_WINNT=_WIN32_WINNT_WIN7',
|
||||||
'-DMINGW_HAS_SECURE_API=1',
|
'-DMINGW_HAS_SECURE_API=1',
|
||||||
'-Wno-unused',
|
'-Wno-unused',
|
||||||
|
# '-ggdb', # Add debug information
|
||||||
language: 'c',
|
language: 'c',
|
||||||
)
|
)
|
||||||
|
|
||||||
@ -23,7 +24,6 @@ if cc.get_id() != 'msvc'
|
|||||||
add_project_arguments(
|
add_project_arguments(
|
||||||
'-ffunction-sections',
|
'-ffunction-sections',
|
||||||
'-fdata-sections',
|
'-fdata-sections',
|
||||||
'-flto', # Enable Link-Time Optimization
|
|
||||||
language: 'c',
|
language: 'c',
|
||||||
)
|
)
|
||||||
|
|
||||||
@ -32,8 +32,9 @@ if cc.get_id() != 'msvc'
|
|||||||
'-Wl,--exclude-all-symbols',
|
'-Wl,--exclude-all-symbols',
|
||||||
'-Wl,--gc-sections',
|
'-Wl,--gc-sections',
|
||||||
'-static-libgcc',
|
'-static-libgcc',
|
||||||
'-flto', # Enable Link-Time Optimization
|
# '-ggdb', # Add debug information
|
||||||
'-Wl,-s', # Strip debug symbols
|
'-lcrypt32', # Bcrypt needed for prashook
|
||||||
|
# '-Wl,-s', # Strip debug symbols
|
||||||
language: 'c',
|
language: 'c',
|
||||||
)
|
)
|
||||||
endif
|
endif
|
||||||
|
@ -28,6 +28,66 @@ void mu3_dll_config_load(
|
|||||||
filename);
|
filename);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void led15093_config_load(struct led15093_config *cfg, const wchar_t *filename)
|
||||||
|
{
|
||||||
|
assert(cfg != NULL);
|
||||||
|
assert(filename != NULL);
|
||||||
|
|
||||||
|
wchar_t tmpstr[16];
|
||||||
|
|
||||||
|
memset(cfg->board_number, ' ', sizeof(cfg->board_number));
|
||||||
|
memset(cfg->chip_number, ' ', sizeof(cfg->chip_number));
|
||||||
|
memset(cfg->boot_chip_number, ' ', sizeof(cfg->boot_chip_number));
|
||||||
|
|
||||||
|
cfg->enable = GetPrivateProfileIntW(L"led15093", L"enable", 1, filename);
|
||||||
|
cfg->port_no = GetPrivateProfileIntW(L"led15093", L"portNo", 0, filename);
|
||||||
|
cfg->high_baudrate = GetPrivateProfileIntW(L"led15093", L"highBaud", 0, filename);
|
||||||
|
cfg->fw_ver = GetPrivateProfileIntW(L"led15093", L"fwVer", 0xA0, filename);
|
||||||
|
cfg->fw_sum = GetPrivateProfileIntW(L"led15093", L"fwSum", 0xAA53, filename);
|
||||||
|
|
||||||
|
GetPrivateProfileStringW(
|
||||||
|
L"led15093",
|
||||||
|
L"boardNumber",
|
||||||
|
L"15093-06",
|
||||||
|
tmpstr,
|
||||||
|
_countof(tmpstr),
|
||||||
|
filename);
|
||||||
|
|
||||||
|
size_t n = wcstombs(cfg->board_number, tmpstr, sizeof(cfg->board_number));
|
||||||
|
for (int i = n; i < sizeof(cfg->board_number); i++)
|
||||||
|
{
|
||||||
|
cfg->board_number[i] = ' ';
|
||||||
|
}
|
||||||
|
|
||||||
|
GetPrivateProfileStringW(
|
||||||
|
L"led15093",
|
||||||
|
L"chipNumber",
|
||||||
|
L"6710A",
|
||||||
|
tmpstr,
|
||||||
|
_countof(tmpstr),
|
||||||
|
filename);
|
||||||
|
|
||||||
|
n = wcstombs(cfg->chip_number, tmpstr, sizeof(cfg->chip_number));
|
||||||
|
for (int i = n; i < sizeof(cfg->chip_number); i++)
|
||||||
|
{
|
||||||
|
cfg->chip_number[i] = ' ';
|
||||||
|
}
|
||||||
|
|
||||||
|
GetPrivateProfileStringW(
|
||||||
|
L"led15093",
|
||||||
|
L"bootChipNumber",
|
||||||
|
L"6709 ",
|
||||||
|
tmpstr,
|
||||||
|
_countof(tmpstr),
|
||||||
|
filename);
|
||||||
|
|
||||||
|
n = wcstombs(cfg->boot_chip_number, tmpstr, sizeof(cfg->boot_chip_number));
|
||||||
|
for (int i = n; i < sizeof(cfg->boot_chip_number); i++)
|
||||||
|
{
|
||||||
|
cfg->boot_chip_number[i] = ' ';
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void mu3_hook_config_load(
|
void mu3_hook_config_load(
|
||||||
struct mu3_hook_config *cfg,
|
struct mu3_hook_config *cfg,
|
||||||
const wchar_t *filename)
|
const wchar_t *filename)
|
||||||
@ -40,6 +100,7 @@ void mu3_hook_config_load(
|
|||||||
dvd_config_load(&cfg->dvd, filename);
|
dvd_config_load(&cfg->dvd, filename);
|
||||||
io4_config_load(&cfg->io4, filename);
|
io4_config_load(&cfg->io4, filename);
|
||||||
gfx_config_load(&cfg->gfx, filename);
|
gfx_config_load(&cfg->gfx, filename);
|
||||||
|
led15093_config_load(&cfg->led15093, filename);
|
||||||
vfd_config_load(&cfg->vfd, filename);
|
vfd_config_load(&cfg->vfd, filename);
|
||||||
mu3_dll_config_load(&cfg->dll, filename);
|
mu3_dll_config_load(&cfg->dll, filename);
|
||||||
unity_config_load(&cfg->unity, filename);
|
unity_config_load(&cfg->unity, filename);
|
||||||
|
@ -3,7 +3,7 @@
|
|||||||
#include <stddef.h>
|
#include <stddef.h>
|
||||||
|
|
||||||
#include "board/config.h"
|
#include "board/config.h"
|
||||||
// #include "board/led15093.h"
|
#include "board/led15093.h"
|
||||||
|
|
||||||
#include "gfxhook/gfx.h"
|
#include "gfxhook/gfx.h"
|
||||||
|
|
||||||
@ -21,7 +21,7 @@ struct mu3_hook_config {
|
|||||||
struct dvd_config dvd;
|
struct dvd_config dvd;
|
||||||
struct io4_config io4;
|
struct io4_config io4;
|
||||||
struct gfx_config gfx;
|
struct gfx_config gfx;
|
||||||
// struct led15093_config led15093;
|
struct led15093_config led15093;
|
||||||
struct vfd_config vfd;
|
struct vfd_config vfd;
|
||||||
struct mu3_dll_config dll;
|
struct mu3_dll_config dll;
|
||||||
struct unity_config unity;
|
struct unity_config unity;
|
||||||
|
@ -62,14 +62,18 @@ static DWORD CALLBACK mu3_pre_startup(void)
|
|||||||
goto fail;
|
goto fail;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
hr = mu3_dll_init(&mu3_hook_cfg.dll, mu3_hook_mod);
|
||||||
// Does not work, Unity moment
|
|
||||||
hr = led15093_hook_init(&mu3_hook_cfg.led15093, 3, 1, 1, 2);
|
if (FAILED(hr)) {
|
||||||
|
goto fail;
|
||||||
|
}
|
||||||
|
|
||||||
|
hr = led15093_hook_init(&mu3_hook_cfg.led15093,
|
||||||
|
mu3_dll.led_init, mu3_dll.led_set_leds, 3, 1, 1, 2);
|
||||||
|
|
||||||
if (FAILED(hr)) {
|
if (FAILED(hr)) {
|
||||||
return hr;
|
return hr;
|
||||||
}
|
}
|
||||||
*/
|
|
||||||
|
|
||||||
hr = sg_reader_hook_init(&mu3_hook_cfg.aime, 1, 1, mu3_hook_mod);
|
hr = sg_reader_hook_init(&mu3_hook_cfg.aime, 1, 1, mu3_hook_mod);
|
||||||
|
|
||||||
@ -83,12 +87,6 @@ static DWORD CALLBACK mu3_pre_startup(void)
|
|||||||
goto fail;
|
goto fail;
|
||||||
}
|
}
|
||||||
|
|
||||||
hr = mu3_dll_init(&mu3_hook_cfg.dll, mu3_hook_mod);
|
|
||||||
|
|
||||||
if (FAILED(hr)) {
|
|
||||||
goto fail;
|
|
||||||
}
|
|
||||||
|
|
||||||
hr = mu3_io4_hook_init(&mu3_hook_cfg.io4);
|
hr = mu3_io4_hook_init(&mu3_hook_cfg.io4);
|
||||||
|
|
||||||
if (FAILED(hr)) {
|
if (FAILED(hr)) {
|
||||||
|
@ -24,9 +24,28 @@ const struct dll_bind_sym mu3_dll_syms[] = {
|
|||||||
}, {
|
}, {
|
||||||
.sym = "mu3_io_get_lever",
|
.sym = "mu3_io_get_lever",
|
||||||
.off = offsetof(struct mu3_dll, get_lever),
|
.off = offsetof(struct mu3_dll, get_lever),
|
||||||
|
}, {
|
||||||
|
.sym = "mu3_io_led_init",
|
||||||
|
.off = offsetof(struct mu3_dll, led_init),
|
||||||
|
}, {
|
||||||
|
.sym = "mu3_io_led_set_colors",
|
||||||
|
.off = offsetof(struct mu3_dll, led_set_leds),
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/* Helper function to determine upon dll_bind failure whether the required functions were found
|
||||||
|
NOTE: relies on symbols order declared above */
|
||||||
|
static HRESULT has_enough_symbols(uint16_t version, uint8_t count)
|
||||||
|
{
|
||||||
|
if ( version <= 0x0100 && count == 5 )
|
||||||
|
return S_OK;
|
||||||
|
|
||||||
|
if ( version >= 0x0101 && count == 7 )
|
||||||
|
return S_OK;
|
||||||
|
|
||||||
|
return E_FAIL;
|
||||||
|
}
|
||||||
|
|
||||||
struct mu3_dll mu3_dll;
|
struct mu3_dll mu3_dll;
|
||||||
|
|
||||||
// Copypasta DLL binding and diagnostic message boilerplate.
|
// Copypasta DLL binding and diagnostic message boilerplate.
|
||||||
@ -86,16 +105,25 @@ HRESULT mu3_dll_init(const struct mu3_dll_config *cfg, HINSTANCE self)
|
|||||||
}
|
}
|
||||||
|
|
||||||
sym = mu3_dll_syms;
|
sym = mu3_dll_syms;
|
||||||
|
const struct dll_bind_sym *init_sym = &sym[0];
|
||||||
|
|
||||||
hr = dll_bind(&mu3_dll, src, &sym, _countof(mu3_dll_syms));
|
hr = dll_bind(&mu3_dll, src, &sym, _countof(mu3_dll_syms));
|
||||||
|
|
||||||
if (FAILED(hr)) {
|
if (FAILED(hr)) {
|
||||||
if (src != self) {
|
if (src != self) {
|
||||||
dprintf("Ongeki IO: Custom IO DLL does not provide function "
|
// Might still be ok depending on external dll API version
|
||||||
"\"%s\". Please contact your IO DLL's developer for "
|
int bind_count = sym - init_sym;
|
||||||
"further assistance.\n",
|
if (has_enough_symbols(mu3_dll.api_version, bind_count) == S_OK)
|
||||||
sym->sym);
|
{
|
||||||
|
hr = S_OK;
|
||||||
|
} else {
|
||||||
|
dprintf("Ongeki IO: Custom IO DLL does not provide function "
|
||||||
|
"\"%s\". Please contact your IO DLL's developer for "
|
||||||
|
"further assistance.\n",
|
||||||
|
sym->sym);
|
||||||
|
|
||||||
goto end;
|
goto end;
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
dprintf("Internal error: could not reflect \"%s\"\n", sym->sym);
|
dprintf("Internal error: could not reflect \"%s\"\n", sym->sym);
|
||||||
}
|
}
|
||||||
|
@ -11,6 +11,8 @@ struct mu3_dll {
|
|||||||
void (*get_opbtns)(uint8_t *opbtn);
|
void (*get_opbtns)(uint8_t *opbtn);
|
||||||
void (*get_gamebtns)(uint8_t *left, uint8_t *right);
|
void (*get_gamebtns)(uint8_t *left, uint8_t *right);
|
||||||
void (*get_lever)(int16_t *pos);
|
void (*get_lever)(int16_t *pos);
|
||||||
|
HRESULT (*led_init)(void);
|
||||||
|
void (*led_set_leds)(uint8_t board, uint8_t *rgb);
|
||||||
};
|
};
|
||||||
|
|
||||||
struct mu3_dll_config {
|
struct mu3_dll_config {
|
||||||
|
@ -23,3 +23,5 @@ EXPORTS
|
|||||||
mu3_io_get_opbtns
|
mu3_io_get_opbtns
|
||||||
mu3_io_init
|
mu3_io_init
|
||||||
mu3_io_poll
|
mu3_io_poll
|
||||||
|
mu3_io_led_init
|
||||||
|
mu3_io_led_set_colors
|
||||||
|
@ -21,7 +21,7 @@ const double MOUSE_SENSITIVITY = 0.5;
|
|||||||
|
|
||||||
uint16_t mu3_io_get_api_version(void)
|
uint16_t mu3_io_get_api_version(void)
|
||||||
{
|
{
|
||||||
return 0x0100;
|
return 0x0101;
|
||||||
}
|
}
|
||||||
|
|
||||||
HRESULT mu3_io_init(void)
|
HRESULT mu3_io_init(void)
|
||||||
@ -195,3 +195,13 @@ void mu3_io_get_lever(int16_t *pos)
|
|||||||
*pos = mu3_lever_xpos;
|
*pos = mu3_lever_xpos;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
HRESULT mu3_io_led_init(void)
|
||||||
|
{
|
||||||
|
return S_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
void mu3_io_led_set_colors(uint8_t board, uint8_t *rgb)
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
@ -1,5 +1,15 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
|
/*
|
||||||
|
MU3 CUSTOM IO API
|
||||||
|
|
||||||
|
Changelog:
|
||||||
|
|
||||||
|
- 0x0100: Initial API version (assumed if chuni_io_get_api_version is not
|
||||||
|
exported)
|
||||||
|
- 0x0101: Added mu3_io_led_init and mu3_io_set_leds
|
||||||
|
*/
|
||||||
|
|
||||||
#include <windows.h>
|
#include <windows.h>
|
||||||
|
|
||||||
#include <stdint.h>
|
#include <stdint.h>
|
||||||
@ -18,6 +28,29 @@ enum {
|
|||||||
MU3_IO_GAMEBTN_MENU = 0x10,
|
MU3_IO_GAMEBTN_MENU = 0x10,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
enum {
|
||||||
|
/* These are the bitmasks to use when checking which
|
||||||
|
lights are triggered on incoming IO4 GPIO writes. */
|
||||||
|
MU3_IO_LED_L1_R = 1 << 31,
|
||||||
|
MU3_IO_LED_L1_G = 1 << 28,
|
||||||
|
MU3_IO_LED_L1_B = 1 << 30,
|
||||||
|
MU3_IO_LED_L2_R = 1 << 27,
|
||||||
|
MU3_IO_LED_L2_G = 1 << 29,
|
||||||
|
MU3_IO_LED_L2_B = 1 << 26,
|
||||||
|
MU3_IO_LED_L3_R = 1 << 25,
|
||||||
|
MU3_IO_LED_L3_G = 1 << 24,
|
||||||
|
MU3_IO_LED_L3_B = 1 << 23,
|
||||||
|
MU3_IO_LED_R1_R = 1 << 22,
|
||||||
|
MU3_IO_LED_R1_G = 1 << 21,
|
||||||
|
MU3_IO_LED_R1_B = 1 << 20,
|
||||||
|
MU3_IO_LED_R2_R = 1 << 19,
|
||||||
|
MU3_IO_LED_R2_G = 1 << 18,
|
||||||
|
MU3_IO_LED_R2_B = 1 << 17,
|
||||||
|
MU3_IO_LED_R3_R = 1 << 16,
|
||||||
|
MU3_IO_LED_R3_G = 1 << 15,
|
||||||
|
MU3_IO_LED_R3_B = 1 << 14,
|
||||||
|
};
|
||||||
|
|
||||||
/* Get the version of the Ongeki IO API that this DLL supports. This
|
/* Get the version of the Ongeki IO API that this DLL supports. This
|
||||||
function should return a positive 16-bit integer, where the high byte is
|
function should return a positive 16-bit integer, where the high byte is
|
||||||
the major version and the low byte is the minor version (as defined by the
|
the major version and the low byte is the minor version (as defined by the
|
||||||
@ -83,3 +116,19 @@ void mu3_io_get_gamebtns(uint8_t *left, uint8_t *right);
|
|||||||
Minimum API version: 0x0100 */
|
Minimum API version: 0x0100 */
|
||||||
|
|
||||||
void mu3_io_get_lever(int16_t *pos);
|
void mu3_io_get_lever(int16_t *pos);
|
||||||
|
|
||||||
|
|
||||||
|
/* Initialize LED emulation. This function will be called before any
|
||||||
|
other mu3_io_led_*() function calls.
|
||||||
|
|
||||||
|
All subsequent calls may originate from arbitrary threads and some may
|
||||||
|
overlap with each other. Ensuring synchronization inside your IO DLL is
|
||||||
|
your responsibility. */
|
||||||
|
|
||||||
|
HRESULT mu3_io_led_init(void);
|
||||||
|
|
||||||
|
/* Update the RGB LEDs.
|
||||||
|
|
||||||
|
Exact layout is TBD. */
|
||||||
|
|
||||||
|
void mu3_io_led_set_colors(uint8_t board, uint8_t *rgb);
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
[wrap-git]
|
[wrap-git]
|
||||||
directory = capnhook
|
directory = capnhook
|
||||||
url = https://github.com/decafcode/capnhook
|
url = https://github.com/Hay1tsme/capnhook
|
||||||
revision = 69f7e3b48c2e0ff5be1d7a83cdcc2597a458357b
|
revision = 09306229f1fd09bae0e617865a26778d3537ff93
|
||||||
|
@ -8,7 +8,7 @@
|
|||||||
#include <pathcch.h>
|
#include <pathcch.h>
|
||||||
#include <psapi.h>
|
#include <psapi.h>
|
||||||
|
|
||||||
#include "hooklib/procaddr.h"
|
#include "hook/procaddr.h"
|
||||||
#include "util/dprintf.h"
|
#include "util/dprintf.h"
|
||||||
|
|
||||||
#include "doorstop.h"
|
#include "doorstop.h"
|
||||||
@ -37,7 +37,7 @@ void doorstop_mono_hook_init(const struct unity_config *cfg, HINSTANCE module) {
|
|||||||
|
|
||||||
memcpy(&unity_config, cfg, sizeof(*cfg));
|
memcpy(&unity_config, cfg, sizeof(*cfg));
|
||||||
load_mono_functions(module);
|
load_mono_functions(module);
|
||||||
proc_addr_table_push(module_name, unity_mono_syms, _countof(unity_mono_syms));
|
proc_addr_table_push(NULL, module_name, unity_mono_syms, _countof(unity_mono_syms));
|
||||||
|
|
||||||
doorstop_hook_initted = true;
|
doorstop_hook_initted = true;
|
||||||
}
|
}
|
||||||
|
@ -2,7 +2,16 @@
|
|||||||
#include <stdbool.h>
|
#include <stdbool.h>
|
||||||
|
|
||||||
#include "hook/table.h"
|
#include "hook/table.h"
|
||||||
|
#include "hook/procaddr.h"
|
||||||
|
#include "hook/iohook.h"
|
||||||
|
|
||||||
|
#include "hooklib/dll.h"
|
||||||
#include "hooklib/path.h"
|
#include "hooklib/path.h"
|
||||||
|
#include "hooklib/printer.h"
|
||||||
|
#include "hooklib/reg.h"
|
||||||
|
#include "hooklib/touch.h"
|
||||||
|
#include "hooklib/serial.h"
|
||||||
|
|
||||||
#include "util/dprintf.h"
|
#include "util/dprintf.h"
|
||||||
|
|
||||||
#include "doorstop.h"
|
#include "doorstop.h"
|
||||||
@ -15,22 +24,35 @@ static const wchar_t *target_modules[] = {
|
|||||||
L"mono.dll",
|
L"mono.dll",
|
||||||
L"mono-2.0-bdwgc.dll",
|
L"mono-2.0-bdwgc.dll",
|
||||||
L"cri_ware_unity.dll",
|
L"cri_ware_unity.dll",
|
||||||
|
L"SerialPortAPI.dll",
|
||||||
|
L"C300usb.dll",
|
||||||
|
L"C300FWDLusb.dll",
|
||||||
|
L"apmled.dll",
|
||||||
|
L"apmmount.dll",
|
||||||
};
|
};
|
||||||
|
|
||||||
static const size_t target_modules_len = _countof(target_modules);
|
static const size_t target_modules_len = _countof(target_modules);
|
||||||
|
|
||||||
static void dll_hook_insert_hooks(HMODULE target);
|
static void dll_hook_insert_hooks(HMODULE target);
|
||||||
|
|
||||||
static HMODULE WINAPI my_LoadLibraryW(const wchar_t *name);
|
static HMODULE WINAPI hook_LoadLibraryW(const wchar_t *name);
|
||||||
static HMODULE (WINAPI *next_LoadLibraryW)(const wchar_t *name);
|
static HMODULE (WINAPI *next_LoadLibraryW)(const wchar_t *name);
|
||||||
|
static HMODULE WINAPI hook_LoadLibraryExW(const wchar_t *name, HANDLE hFile, DWORD dwFlags);
|
||||||
|
static HMODULE (WINAPI *next_LoadLibraryExW)(const wchar_t *name, HANDLE hFile, DWORD dwFlags);
|
||||||
|
|
||||||
static const struct hook_symbol unity_kernel32_syms[] = {
|
static const struct hook_symbol unity_kernel32_syms[] = {
|
||||||
{
|
{
|
||||||
.name = "LoadLibraryW",
|
.name = "LoadLibraryW",
|
||||||
.patch = my_LoadLibraryW,
|
.patch = hook_LoadLibraryW,
|
||||||
.link = (void **) &next_LoadLibraryW,
|
.link = (void **) &next_LoadLibraryW,
|
||||||
},
|
}, {
|
||||||
|
.name = "LoadLibraryExW",
|
||||||
|
.patch = hook_LoadLibraryExW,
|
||||||
|
.link = (void **) &next_LoadLibraryExW,
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
void unity_hook_init(const struct unity_config *cfg, HINSTANCE self) {
|
void unity_hook_init(const struct unity_config *cfg, HINSTANCE self) {
|
||||||
assert(cfg != NULL);
|
assert(cfg != NULL);
|
||||||
|
|
||||||
@ -57,7 +79,14 @@ static void dll_hook_insert_hooks(HMODULE target) {
|
|||||||
_countof(unity_kernel32_syms));
|
_countof(unity_kernel32_syms));
|
||||||
}
|
}
|
||||||
|
|
||||||
static HMODULE WINAPI my_LoadLibraryW(const wchar_t *name) {
|
static HMODULE WINAPI hook_LoadLibraryExW(const wchar_t *name, HANDLE hFile, DWORD dwFlags)
|
||||||
|
{
|
||||||
|
// dprintf("Unity: LoadLibraryExW %ls\n", name);
|
||||||
|
return hook_LoadLibraryW(name);
|
||||||
|
}
|
||||||
|
|
||||||
|
static HMODULE WINAPI hook_LoadLibraryW(const wchar_t *name)
|
||||||
|
{
|
||||||
const wchar_t *name_end;
|
const wchar_t *name_end;
|
||||||
const wchar_t *target_module;
|
const wchar_t *target_module;
|
||||||
bool already_loaded;
|
bool already_loaded;
|
||||||
@ -107,6 +136,14 @@ static HMODULE WINAPI my_LoadLibraryW(const wchar_t *name) {
|
|||||||
|
|
||||||
dll_hook_insert_hooks(result);
|
dll_hook_insert_hooks(result);
|
||||||
path_hook_insert_hooks(result);
|
path_hook_insert_hooks(result);
|
||||||
|
|
||||||
|
// printer_hook_insert_hooks(result);
|
||||||
|
|
||||||
|
reg_hook_insert_hooks(result);
|
||||||
|
|
||||||
|
proc_addr_insert_hooks(result);
|
||||||
|
serial_hook_apply_hooks(result);
|
||||||
|
iohook_apply_hooks(result);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user