diff --git a/chunihook/dllmain.c b/chunihook/dllmain.c index 8fef87e..22268cf 100644 --- a/chunihook/dllmain.c +++ b/chunihook/dllmain.c @@ -13,7 +13,6 @@ #include "hook/process.h" -#include "hooklib/clock.h" #include "hooklib/gfx.h" #include "hooklib/serial.h" #include "hooklib/spike.h" @@ -48,8 +47,6 @@ static DWORD CALLBACK chuni_pre_startup(void) /* Hook Win32 APIs */ - clock_read_hook_init(); - clock_write_hook_init(); gfx_hook_init(); serial_hook_init(); diff --git a/divahook/dllmain.c b/divahook/dllmain.c index a77053a..84f8177 100644 --- a/divahook/dllmain.c +++ b/divahook/dllmain.c @@ -13,7 +13,6 @@ #include "hook/process.h" -#include "hooklib/clock.h" #include "hooklib/gfx.h" #include "hooklib/serial.h" #include "hooklib/spike.h" @@ -36,7 +35,6 @@ static DWORD CALLBACK diva_pre_startup(void) /* Hook Win32 APIs */ - clock_write_hook_init(); serial_hook_init(); /* Initialize emulation hooks */ diff --git a/hooklib/clock.h b/hooklib/clock.h deleted file mode 100644 index 78a854b..0000000 --- a/hooklib/clock.h +++ /dev/null @@ -1,4 +0,0 @@ -#pragma once - -void clock_read_hook_init(void); -void clock_write_hook_init(void); diff --git a/hooklib/meson.build b/hooklib/meson.build index 94a863b..3f49065 100644 --- a/hooklib/meson.build +++ b/hooklib/meson.build @@ -7,8 +7,6 @@ hooklib_lib = static_library( capnhook.get_variable('hook_dep'), ], sources : [ - 'clock.c', - 'clock.h', 'dll.c', 'dll.h', 'dns.c', diff --git a/idzhook/dllmain.c b/idzhook/dllmain.c index 93cc3b1..cbe5f54 100644 --- a/idzhook/dllmain.c +++ b/idzhook/dllmain.c @@ -9,7 +9,6 @@ #include "hook/process.h" -#include "hooklib/clock.h" #include "hooklib/gfx.h" #include "hooklib/serial.h" #include "hooklib/spike.h" @@ -35,7 +34,6 @@ static DWORD CALLBACK idz_pre_startup(void) /* Hook Win32 APIs */ - clock_write_hook_init(); serial_hook_init(); /* Initialize emulation hooks */ diff --git a/minihook/dllmain.c b/minihook/dllmain.c index a9d6b82..9f25ada 100644 --- a/minihook/dllmain.c +++ b/minihook/dllmain.c @@ -5,9 +5,9 @@ #include "hook/process.h" -#include "hooklib/clock.h" #include "hooklib/spike.h" +#include "platform/clock.h" #include "platform/config.h" #include "platform/nusec.h" @@ -17,17 +17,17 @@ static process_entry_t app_startup; static DWORD CALLBACK app_pre_startup(void) { - struct nusec_config nusec_cfg; + struct clock_config clock_cfg; struct ds_config ds_cfg; + struct nusec_config nusec_cfg; dprintf("--- Begin %s ---\n", __func__); - nusec_config_load(&nusec_cfg, L".\\segatools.ini"); + clock_config_load(&clock_cfg, L".\\segatools.ini"); ds_config_load(&ds_cfg, L".\\segatools.ini"); + nusec_config_load(&nusec_cfg, L".\\segatools.ini"); - // TODO make use of clock read hook configurable - clock_read_hook_init(); - clock_write_hook_init(); + clock_hook_init(&clock_cfg); nusec_hook_init(&nusec_cfg, "SSSS", "AAV0"); ds_hook_init(&ds_cfg); diff --git a/mu3hook/dllmain.c b/mu3hook/dllmain.c index b5204cf..6f02f14 100644 --- a/mu3hook/dllmain.c +++ b/mu3hook/dllmain.c @@ -6,7 +6,6 @@ #include "hook/process.h" -#include "hooklib/clock.h" #include "hooklib/serial.h" #include "hooklib/spike.h" @@ -31,7 +30,6 @@ static DWORD CALLBACK mu3_pre_startup(void) /* Hook Win32 APIs */ - clock_write_hook_init(); serial_hook_init(); /* Initialize emulation hooks */ diff --git a/hooklib/clock.c b/platform/clock.c similarity index 81% rename from hooklib/clock.c rename to platform/clock.c index d5d0b9e..e92ce3e 100644 --- a/hooklib/clock.c +++ b/platform/clock.c @@ -1,9 +1,13 @@ #include +#include #include #include "hook/table.h" +#include "platform/clock.h" +#include "platform/config.h" + #include "util/dprintf.h" static void WINAPI my_GetSystemTimeAsFileTime(FILETIME *out); @@ -16,13 +20,18 @@ static BOOL WINAPI my_SetTimeZoneInformation(TIME_ZONE_INFORMATION *tzinfo); static BOOL (WINAPI * next_GetSystemTimeAsFileTime)(FILETIME *out); static int64_t clock_current_day; +static bool clock_time_warp; -static const struct hook_symbol clock_read_hook_syms[] = { +static const struct hook_symbol clock_base_hook_syms[] = { { .name = "GetSystemTimeAsFileTime", .patch = my_GetSystemTimeAsFileTime, .link = (void **) &next_GetSystemTimeAsFileTime, - }, { + } +}; + +static const struct hook_symbol clock_read_hook_syms[] = { + { .name = "GetLocalTime", .patch = my_GetLocalTime, }, { @@ -65,6 +74,12 @@ static void WINAPI my_GetSystemTimeAsFileTime(FILETIME *out) int64_t fake_jiffies_biased; int64_t fake_jiffies; + if (!clock_time_warp) { + next_GetSystemTimeAsFileTime(out); + + return; + } + if (out == NULL) { SetLastError(ERROR_INVALID_PARAMETER); @@ -207,20 +222,39 @@ static BOOL WINAPI my_SetTimeZoneInformation(TIME_ZONE_INFORMATION *in) return TRUE; } -void clock_read_hook_init(void) +HRESULT clock_hook_init(const struct clock_config *cfg) { - hook_table_apply( - NULL, - "kernel32.dll", - clock_read_hook_syms, - _countof(clock_read_hook_syms)); -} + assert(cfg != NULL); -void clock_write_hook_init(void) -{ - hook_table_apply( - NULL, - "kernel32.dll", - clock_write_hook_syms, - _countof(clock_write_hook_syms)); + clock_time_warp = cfg->timewarp; + + if (cfg->timezone || cfg->timewarp || !cfg->writeable) { + /* All the clock hooks require the core GSTAFT hook to be installed */ + /* Note the ! up there btw. */ + + hook_table_apply( + NULL, + "kernel32.dll", + clock_base_hook_syms, + _countof(clock_base_hook_syms)); + } + + if (cfg->timezone) { + hook_table_apply( + NULL, + "kernel32.dll", + clock_read_hook_syms, + _countof(clock_read_hook_syms)); + } + + if (!cfg->writeable) { + /* Install hook if this config parameter is FALSE! */ + hook_table_apply( + NULL, + "kernel32.dll", + clock_write_hook_syms, + _countof(clock_write_hook_syms)); + } + + return S_OK; } diff --git a/platform/clock.h b/platform/clock.h new file mode 100644 index 0000000..902c58c --- /dev/null +++ b/platform/clock.h @@ -0,0 +1,7 @@ +#pragma once + +#include + +#include "platform/config.h" + +HRESULT clock_hook_init(const struct clock_config *cfg); diff --git a/platform/config.c b/platform/config.c index 5906287..1c49620 100644 --- a/platform/config.c +++ b/platform/config.c @@ -17,6 +17,7 @@ void alls_config_load(struct alls_config *cfg, const wchar_t *filename) assert(filename != NULL); amvideo_config_load(&cfg->amvideo, filename); + clock_config_load(&cfg->clock, filename); dns_config_load(&cfg->dns, filename); hwmon_config_load(&cfg->hwmon, filename); misc_config_load(&cfg->misc, filename); @@ -31,6 +32,7 @@ void nu_config_load(struct nu_config *cfg, const wchar_t *filename) assert(filename != NULL); amvideo_config_load(&cfg->amvideo, filename); + clock_config_load(&cfg->clock, filename); dns_config_load(&cfg->dns, filename); hwmon_config_load(&cfg->hwmon, filename); misc_config_load(&cfg->misc, filename); @@ -46,6 +48,20 @@ void amvideo_config_load(struct amvideo_config *cfg, const wchar_t *filename) cfg->enable = GetPrivateProfileIntW(L"amvideo", L"enable", 1, filename); } +void clock_config_load(struct clock_config *cfg, const wchar_t *filename) +{ + assert(cfg != NULL); + assert(filename != NULL); + + cfg->timezone = GetPrivateProfileIntW(L"clock", L"timezone", 1, filename); + cfg->timewarp = GetPrivateProfileIntW(L"clock", L"timewarp", 0, filename); + cfg->writeable = GetPrivateProfileIntW( + L"clock", + L"writeable", + 0, + filename); +} + void dns_config_load(struct dns_config *cfg, const wchar_t *filename) { wchar_t default_[128]; diff --git a/platform/config.h b/platform/config.h index d954292..58fb3e7 100644 --- a/platform/config.h +++ b/platform/config.h @@ -10,6 +10,12 @@ struct amvideo_config { bool enable; }; +struct clock_config { + bool timezone; + bool timewarp; + bool writeable; +}; + struct dns_config { bool enable; wchar_t router[128]; @@ -51,6 +57,7 @@ struct vfs_config { struct nu_config { struct amvideo_config amvideo; + struct clock_config clock; struct dns_config dns; struct hwmon_config hwmon; struct misc_config misc; @@ -60,6 +67,7 @@ struct nu_config { struct alls_config { struct amvideo_config amvideo; + struct clock_config clock; struct dns_config dns; struct hwmon_config hwmon; struct misc_config misc; @@ -72,6 +80,7 @@ void alls_config_load(struct alls_config *cfg, const wchar_t *filename); void nu_config_load(struct nu_config *cfg, const wchar_t *filename); void amvideo_config_load(struct amvideo_config *cfg, const wchar_t *filename); +void clock_config_load(struct clock_config *cfg, const wchar_t *filename); void dns_config_load(struct dns_config *cfg, const wchar_t *filename); void hwmon_config_load(struct hwmon_config *cfg, const wchar_t *filename); void misc_config_load(struct misc_config *cfg, const wchar_t *filename); diff --git a/platform/meson.build b/platform/meson.build index 67d0a6e..b63a108 100644 --- a/platform/meson.build +++ b/platform/meson.build @@ -9,6 +9,8 @@ platform_lib = static_library( sources : [ 'amvideo.c', 'amvideo.h', + 'clock.c', + 'clock.h', 'config.c', 'config.h', 'dns.c', diff --git a/platform/platform.c b/platform/platform.c index 28c40a6..8af9f57 100644 --- a/platform/platform.c +++ b/platform/platform.c @@ -3,6 +3,7 @@ #include #include "platform/amvideo.h" +#include "platform/clock.h" #include "platform/config.h" #include "platform/dns.h" #include "platform/hwmon.h" @@ -31,6 +32,12 @@ HRESULT platform_hook_init_alls( return hr; } + hr = clock_hook_init(&cfg->clock); + + if (FAILED(hr)) { + return hr; + } + hr = dns_platform_hook_init(&cfg->dns); if (FAILED(hr)) { @@ -85,6 +92,12 @@ HRESULT platform_hook_init_nu( return hr; } + hr = clock_hook_init(&cfg->clock); + + if (FAILED(hr)) { + return hr; + } + hr = dns_platform_hook_init(&cfg->dns); if (FAILED(hr)) {