diff options
author | Michael Smith <mikesmiffy128@gmail.com> | 2024-08-03 23:40:31 +0100 |
---|---|---|
committer | Michael Smith <mikesmiffy128@gmail.com> | 2024-08-23 20:37:37 +0100 |
commit | 83da606072ce272eb053d4e1497d77e647cfecae (patch) | |
tree | 71d0110881ff8685184c5f4ab720cc8d49c24678 /src/ac.c | |
parent | acbd30e0427b16f885f96aed59881ec04eff25bc (diff) |
Revise syntax macros and add a ton of branch hints
My new programming style is branch hints. All non-confusing branches
must be hinted when I can be bothered. It's faster, sometimes, maybe.
Also, start trying to use more signed sizes in at least some of the
places where it makes sense. Unsigned sizes are surprisingly
error-prone!
Diffstat (limited to 'src/ac.c')
-rw-r--r-- | src/ac.c | 110 |
1 files changed, 59 insertions, 51 deletions
@@ -40,6 +40,7 @@ #include "gamedata.h" #include "gametype.h" #include "intdefs.h" +#include "langext.h" #include "mem.h" #include "os.h" #include "ppmagic.h" @@ -102,34 +103,37 @@ static ulong inhooktid; static ssize __stdcall kproc(int code, usize wp, ssize lp) { KBDLLHOOKSTRUCT *data = (KBDLLHOOKSTRUCT *)lp; - if (enabled && data->flags & LLKHF_INJECTED && - GetForegroundWindow() == gamewin) { - // maybe this input is reasonable, but log it for closer inspection - // TODO(rta): figure out what to do with this stuff - // something like the following, but with a proper abstraction... - //uchar buf[28 + 16], *p = buf; - //msg_putasz4(p, 2); p += 1; - // msg_putssz5(p, 8); memcpy(p + 1, "FakeKey", 7); p += 8; - // msg_putmsz4(p, 2); p += 1; - // msg_putssz5(p, 3); memcpy(p + 1, "vk", 2); p += 3; - // p += msg_putu32(p, data->vkCode); - // msg_putssz5(p, 3); memcpy(p + 1, "scan", 4); p += 5; - // p += msg_putu32(p, data->scanCode); - //++keybox->nonce; - //// append mac at end of message - //crypto_aead_lock_djb(buf, p, keybox->shr, keybox->nonce_bytes, 0, 0, - // buf, p - buf); - //democustom_write(buf, p - buf + 16); + if_cold (enabled && data->flags & LLKHF_INJECTED) { + // fast-path the next branch because alt-tabbed speed is irrelevant + if_hot (GetForegroundWindow() == gamewin) { + // maybe this input is reasonable, but log it for closer inspection + // TODO(rta): figure out what to do with this stuff + // something like the following, but with a proper abstraction... + //uchar buf[28 + 16], *p = buf; + //msg_putasz4(p, 2); p += 1; + // msg_putssz5(p, 8); memcpy(p + 1, "FakeKey", 7); p += 8; + // msg_putmsz4(p, 2); p += 1; + // msg_putssz5(p, 3); memcpy(p + 1, "vk", 2); p += 3; + // p += msg_putu32(p, data->vkCode); + // msg_putssz5(p, 3); memcpy(p + 1, "scan", 4); p += 5; + // p += msg_putu32(p, data->scanCode); + //++keybox->nonce; + //// append mac at end of message + //crypto_aead_lock_djb(buf, p, keybox->shr, keybox->nonce_bytes, 0, + // 0, buf, p - buf); + //democustom_write(buf, p - buf + 16); + } } return CallNextHookEx(0, code, wp, lp); } static ssize __stdcall mproc(int code, usize wp, ssize lp) { MSLLHOOKSTRUCT *data = (MSLLHOOKSTRUCT *)lp; - if (enabled && data->flags & LLMHF_INJECTED && - GetForegroundWindow() == gamewin) { - // no way this input would ever be reasonable. just discard it - return 1; + if_cold (enabled && data->flags & LLMHF_INJECTED) { + if_hot (GetForegroundWindow() == gamewin) { + // no way this input would ever be reasonable. just discard it + return 1; + } } return CallNextHookEx(0, code, wp, lp); } @@ -138,7 +142,7 @@ static ssize __stdcall mproc(int code, usize wp, ssize lp) { // hook gets silently removed. plus, we don't wanna incur latency anyway. static ulong __stdcall inhookthrmain(void *param) { volatile int *sig = param; - if (!SetWindowsHookExW(WH_KEYBOARD_LL, (HOOKPROC)&kproc, 0, 0) || + if_cold (!SetWindowsHookExW(WH_KEYBOARD_LL, (HOOKPROC)&kproc, 0, 0) || !SetWindowsHookExW(WH_MOUSE_LL, (HOOKPROC)&mproc, 0, 0)) { fastspin_raise(sig, 2); return -1; @@ -151,29 +155,31 @@ static ulong __stdcall inhookthrmain(void *param) { static ssize orig_wndproc; static ssize __stdcall hook_wndproc(void *wnd, uint msg, usize wp, ssize lp) { - if (msg == WM_COPYDATA && enabled) return DefWindowProcW(wnd, msg, wp, lp); + if_cold (msg == WM_COPYDATA && enabled) { + return DefWindowProcW(wnd, msg, wp, lp); + } return CallWindowProcA((WNDPROC)orig_wndproc, wnd, msg, wp, lp); } -static bool win32_init(void) { +static inline bool win32_init(void) { // note: using A instead of W to avoid some weirdness with handles... gamewin = FindWindowA("Valve001", 0); // note: error messages here are a bit cryptic on purpose, but easy to find // in the code. in other words, we're hiding in plain sight :-) - if (!gamewin) { + if_cold (!gamewin) { errmsg_errorsys("failed to find window"); return false; } orig_wndproc = SetWindowLongPtrA(gamewin, GWLP_WNDPROC, (ssize)&hook_wndproc); - if (!orig_wndproc) { // XXX: assuming 0 won't be legitimately returned + if_cold (!orig_wndproc) { // XXX: assuming 0 won't be legitimately returned errmsg_errorsys("failed to attach message handler"); return false; } return true; } -static void win32_end(void) { +static inline void win32_end(void) { // no error handling here because we'd crash either way. good luck! SetWindowLongPtrA(gamewin, GWLP_WNDPROC, orig_wndproc); } @@ -188,7 +194,7 @@ static void inhook_check(void) { if (WaitForSingleObject(inhookthr, 0) == WAIT_OBJECT_0) { ulong status; GetExitCodeThread(inhookthr, &status); - if (status) { + if_cold (status) { // XXX: if this ever happens, it's a disaster! users might not // notice their run just dying all of a sudden. with any luck it // won't matter in practice but... this kind of sucks. @@ -209,7 +215,7 @@ static void inhook_stop(void) { // assume WAIT_OBJECT_0 ulong status; GetExitCodeThread(inhookthr, &status); - if (status) { + if_cold (status) { // not much else we can do now! errmsg_errorx("message loop didn't shut down cleanly\n"); } @@ -224,17 +230,18 @@ static void inhook_stop(void) { #endif bool ac_enable(void) { - if (enabled) return true; + if (!enabled) { #ifdef _WIN32 - volatile int sig = 0; - inhook_start(&sig); - fastspin_wait(&sig); - if (sig == 2) { // else 1 for success - con_warn("** sst: ERROR starting message loop, can't continue! **"); - CloseHandle(inhookthr); - return false; - } + volatile int sig = 0; + inhook_start(&sig); + fastspin_wait(&sig); + if_cold (sig == 2) { // else 1 for success + con_warn("** sst: ERROR starting message loop, can't continue! **"); + CloseHandle(inhookthr); + return false; + } #endif + } enabled = true; return true; } @@ -248,10 +255,11 @@ HANDLE_EVENT(Tick, bool simulating) { } void ac_disable(void) { - if (!enabled) return; + if (enabled) { #ifdef _WIN32 - inhook_stop(); + inhook_stop(); #endif + } enabled = false; } @@ -308,7 +316,7 @@ static bool find_Key_Event(void) { // -> CGame::DispatchAllStoredGameMessages vfunc // -> First call instruction (either DispatchInputEvent or Key_Event) void *gameuifuncs = factory_engine("VENGINE_GAMEUIFUNCS_VERSION005", 0); - if (!gameuifuncs) { + if_cold (!gameuifuncs) { errmsg_errorx("couldn't get engine game UI interface"); return false; } @@ -355,7 +363,7 @@ ok2: } HANDLE_EVENT(AllowPluginLoading, bool loading) { - if (enabled && demorec_demonum() != -1) { + if_cold(enabled) if_hot(demorec_demonum() != -1) { con_warn("sst: plugins cannot be %s while recording a run\n", loading ? "loaded" : "unloaded"); return false; @@ -375,39 +383,39 @@ PREINIT { } INIT { - if (!find_Key_Event()) return false; + if_cold (!find_Key_Event()) return false; orig_Key_Event = (Key_Event_func)hook_inline((void *)orig_Key_Event, (void *)&hook_Key_Event); - if (!orig_Key_Event) { + if_cold (!orig_Key_Event) { errmsg_errorsys("couldn't hook Key_Event function"); return false; } #ifdef _WIN32 keybox = VirtualAlloc(0, 4096, MEM_RESERVE | MEM_COMMIT, PAGE_READWRITE); - if (!keybox) { + if_cold (!keybox) { errmsg_errorsys("couldn't allocate memory for session state"); return false; } - if (!VirtualLock(keybox, 4096)) { + if_cold (!VirtualLock(keybox, 4096)) { errmsg_errorsys("couldn't secure session state"); goto e2; } - if (WerRegisterExcludedMemoryBlock(keybox, 4096) != S_OK) { + if_cold (WerRegisterExcludedMemoryBlock(keybox, 4096) != S_OK) { // FIXME: stringify errors properly here errmsg_errorx("couldn't secure session state"); goto e2; } - if (!win32_init()) goto e; + if_cold (!win32_init()) goto e; #else keybox = mmap(0, 4096, PROT_READ | PROT_WRITE, MAP_SHARED | MAP_ANON, -1, 0); - if (keybox == MAP_FAILED) { + if_cold (keybox == MAP_FAILED) { errmsg_errorstd("couldn't allocate memory for session state"); return false; } // linux-specific madvise stuff (there are some equivalents in OpenBSD and // FreeBSD, if anyone's wondering, but we don't need to worry about those) - if (madvise(keybox, 4096, MADV_DONTFORK) == -1 || + if_cold (madvise(keybox, 4096, MADV_DONTFORK) == -1 || madvise(keybox, 4096, MADV_DONTDUMP) == - 1 || mlock(keybox, 4096) == -1) { errmsg_errorstd("couldn't secure session state"); |