Per-subsystem hook control: install/remove input, focus, audio at runtime
Add a host->hook control channel (protocol v5 -> v6: HookControl in SharedBlock, per-subsystem "disabled" flags, 0 = install so the zero-filled default is unchanged). The worker now reconciles each subsystem every tick: install what's requested-and-missing, remove what's no longer wanted -- so the audio hooks re-attach the ring and republish format on a reinstall, and XInput/focus clear their stale status flags on removal. Injection panel: a checkbox per subsystem (input forwarding / focus spoof / audio render-hook) toggles it at runtime, showing the requested vs actual installed state from the registry, plus DLL heartbeat liveness. The hook-status section now keys off whether a DLL was injected (host-side) rather than the input-hook "attached" flag, so it stays visible with input unhooked. Guards for dependent features: the synthetic-input control is disabled when input forwarding is off, and the Audio panel explains that mirroring uses loopback (echo) when the render-hook is off. Verified against Phantom Brave via coop_audio_probe: starting with audio requested off installs only input+focus (8 hooks, no capture); re-enabling at runtime installs the audio hooks (13) and capture starts immediately. All four tests pass. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
@@ -98,6 +98,7 @@ int wmain(int argc, wchar_t** argv)
|
||||
const unsigned long pid = std::wcstoul(argv[1], nullptr, 10);
|
||||
const int seconds = (argc >= 3) ? std::max(1, _wtoi(argv[2])) : 20;
|
||||
const int ring_delay_ms = (argc >= 4) ? std::max(0, _wtoi(argv[3])) : 1500;
|
||||
const bool audio_enabled = (argc >= 5) ? _wtoi(argv[4]) != 0 : true; // arg5=0 tests unhooking audio
|
||||
if (pid == 0)
|
||||
{
|
||||
std::printf("ERROR: invalid pid.\n");
|
||||
@@ -115,6 +116,12 @@ int wmain(int argc, wchar_t** argv)
|
||||
block->version = coop::kProtocolVersion;
|
||||
block->pad_count = 0;
|
||||
block->sequence.store(0, std::memory_order_relaxed);
|
||||
if (!audio_enabled)
|
||||
{
|
||||
// Request the hook NOT install the audio subsystem (control-channel test).
|
||||
block->control.subsystem_disabled[coop::HookSubsys_Audio].store(1, std::memory_order_release);
|
||||
std::printf("Audio subsystem requested OFF (control channel test).\n");
|
||||
}
|
||||
block->magic = coop::kProtocolMagic;
|
||||
|
||||
// Enable the hook's file trace (%TEMP%\coop_hook.log) for this debug session.
|
||||
@@ -183,6 +190,15 @@ int wmain(int argc, wchar_t** argv)
|
||||
{
|
||||
Sleep(500);
|
||||
|
||||
// If audio started disabled, re-enable it at the midpoint to demonstrate
|
||||
// runtime hooking ("hook with a button press"): the worker should install
|
||||
// the audio hooks and capture should start within a tick or two.
|
||||
if (!audio_enabled && t == seconds)
|
||||
{
|
||||
block->control.subsystem_disabled[coop::HookSubsys_Audio].store(0, std::memory_order_release);
|
||||
std::printf(">>> re-enabling audio subsystem at runtime <<<\n");
|
||||
}
|
||||
|
||||
// Consume everything available and find the peak sample magnitude.
|
||||
double peak = 0.0;
|
||||
std::uint32_t got = 0;
|
||||
|
||||
Reference in New Issue
Block a user