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

@@ -0,0 +1,32 @@
// Process-wide registry of the individual hooks the DLL installs, with a call
// counter per hook. Each hook module (XInput, focus, audio) registers its hooks
// once and bumps the counter from its detour; the worker thread publishes the
// table to the host over IPC for the Injection panel's hook list.
#pragma once
#include <cstdint>
#include "coop/protocol.hpp"
#include "ipc_client.hpp"
namespace coop::hook
{
// Find-or-create a registry slot for `name` in `subsystem`; returns a stable id
// (>= 0) used with the calls below, or -1 if the table is full. Idempotent: the
// same name returns the same id, so install/remove cycles keep one slot.
int hook_register(const char* name, std::uint32_t subsystem);
// Mark a hook installed / removed (drives the "installed" column).
void hook_set_installed(int id, bool installed);
// Bump a hook's call counter. Cheap (relaxed atomic); safe on any thread.
void hook_note_call(int id);
// Snapshot the registry into the host's HookStatus back-channel.
void hook_publish(IpcClient& ipc);
// Forget everything (DLL detach).
void hook_registry_reset();
} // namespace coop::hook