Hook registry: list installed hooks + call counts in Injection panel

Add a process-wide hook registry (hook/src/hook_registry) that every hook
module registers its hooks with and bumps a counter from each detour. The
XInput, focus-spoof, and audio render-hooks now register their individual
hooks (XInputGetState/Ex/Caps/SetState; GetForegroundWindow/GetActiveWindow/
GetFocus/WndProc guard; IMMDevice::Activate, IAudioClient::Initialize/
GetService, IAudioRenderClient::GetBuffer/ReleaseBuffer) and count calls.

The worker publishes the table to the host each tick over a new HookStatus
field (protocol v4 -> v5: HookEntry[] + count). The Injection panel shows it
as a collapsible table grouped by subsystem with an installed flag and call
count per hook; coop_audio_probe prints the same table headless.

Verified against Phantom Brave: 13 hooks listed with live counts (focus APIs
polled heavily, GetBuffer/ReleaseBuffer ticking with the audio render loop).
All four tests pass.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
2026-06-19 20:09:39 +02:00
parent 565934e8cf
commit 1f905940ef
16 changed files with 371 additions and 14 deletions

View File

@@ -233,6 +233,16 @@ int wmain(int argc, wchar_t** argv)
}
}
// Dump the hook registry so the installed-hooks list can be verified headless.
static const char* kSubsys[] = {"Input", "Focus", "Audio"};
std::printf("\nInstalled hooks (%u):\n", status.hook_entry_count);
for (std::uint32_t i = 0; i < status.hook_entry_count && i < coop::kMaxHookEntries; ++i)
{
const coop::HookEntry& e = status.hook_entries[i];
std::printf(" [%-5s] %-34s %s calls=%llu\n", e.subsystem < 3 ? kSubsys[e.subsystem] : "?", e.name,
e.installed ? "ON " : "off", static_cast<unsigned long long>(e.calls));
}
std::printf("\nDone. Leaving the hook loaded in the game.\n");
block->magic = 0; // invalidate so a late hook read won't trust stale data
return 0;