Files
CoopAllTheThings/tests/focus_spoof_test.cpp
BlackMark 30eccf749d Apply clang-format across the whole tree
Run clang-format (the repo's .clang-format: LLVM base, 120 cols, tabs,
Allman functions) over every source file so the tree is formatter-clean.
Whitespace only -- no behavior change; full x64 + x86 suites pass.

Also set SortIncludes: false in .clang-format. Windows include order is
load-bearing (windows.h must precede tlhelp32.h / mmreg.h / xinput.h /
dinput.h; winsock2.h must precede windows.h), and the default
alphabetical sort reorders tlhelp32.h ahead of windows.h -- a build
break. Leaving order alone keeps the manual, correct grouping.
2026-07-12 11:52:53 +02:00

107 lines
3.8 KiB
C++

// In-process self-test for the focus-spoof subsystem (hook/src/focus_spoof.cpp). It plays game +
// host: creates a top-level window (which find_main_window picks up), installs the spoof, and checks
// that the focus-query APIs now report that window as foreground/active/focused even though the test
// isn't actually the foreground app -- and that removal restores them. Also checks the cursor-release
// gating: with clipping disallowed (the default), a ClipCursor request is swallowed. No game, no Steam.
#include <cstdio>
#include <windows.h>
#include "coop/protocol.hpp"
#include "coop/shared_memory.hpp"
#include "ipc_client.hpp"
#include "focus_spoof.hpp"
using namespace coop;
namespace {
int g_failures = 0;
void check(bool ok, const char* what)
{
std::printf("%s %s\n", ok ? " ok:" : "FAIL:", what);
if (!ok) {
++g_failures;
}
}
void pump()
{
MSG msg;
while (PeekMessageW(&msg, nullptr, 0, 0, PM_REMOVE)) {
TranslateMessage(&msg);
DispatchMessageW(&msg);
}
}
} // namespace
int main()
{
SharedMemory shm;
if (!shm.create(shared_memory_name(GetCurrentProcessId()), sizeof(SharedBlock))) {
std::printf("FAIL: create shared memory\n");
return 1;
}
auto* block = shm.as<SharedBlock>();
block->version = kProtocolVersion;
block->sequence.store(0, std::memory_order_relaxed);
block->magic = kProtocolMagic; // allow_cursor_clip stays 0 (zero-filled) -> release the cursor
hook::IpcClient ipc;
check(ipc.connect(10, 5), "IPC client connect");
// A real top-level window for find_main_window to pick up.
WNDCLASSEXW wc{};
wc.cbSize = sizeof(wc);
wc.lpfnWndProc = DefWindowProcW;
wc.hInstance = GetModuleHandleW(nullptr);
wc.lpszClassName = L"coop_focus_test";
RegisterClassExW(&wc);
HWND win = CreateWindowExW(0, wc.lpszClassName, L"CoopFocusTest", WS_OVERLAPPEDWINDOW, 0, 0, 320, 240, nullptr,
nullptr, wc.hInstance, nullptr);
ShowWindow(win, SW_SHOW);
pump();
// Install, retrying a few times in case the window isn't enumerable yet.
bool installed = false;
for (int i = 0; i < 20 && !installed; ++i) {
installed = hook::install_focus_spoof(ipc);
if (!installed) {
pump();
Sleep(20);
}
}
if (!installed) {
std::printf("SKIP: focus spoof could not find the test window\n");
DestroyWindow(win);
UnregisterClassW(wc.lpszClassName, wc.hInstance);
return 0;
}
// The spoof must report OUR window as foreground/active/focused, even though the test process is
// not the real foreground app (so a coincidental match is unlikely).
check(GetForegroundWindow() == win, "GetForegroundWindow spoofed to the game window");
check(GetActiveWindow() == win, "GetActiveWindow spoofed to the game window");
check(GetFocus() == win, "GetFocus spoofed to the game window");
check(block->status.focus_spoof != 0, "status reports focus spoof active");
// Cursor release: with clipping disallowed (default), a ClipCursor request must be swallowed.
RECT want{10, 10, 50, 50};
ClipCursor(&want); // goes through the hook
RECT got{};
GetClipCursor(&got);
check(!(got.left == want.left && got.top == want.top && got.right == want.right && got.bottom == want.bottom),
"ClipCursor swallowed while cursor release is active (clip not applied)");
// Removal: the spoof is torn down. Check the deterministic signal (the status flag) rather than
// GetForegroundWindow's value -- a shown test window may legitimately BE the real foreground, so
// the un-hooked API can still return it.
hook::remove_focus_spoof();
check(block->status.focus_spoof == 0, "status reports focus spoof inactive after removal");
ClipCursor(nullptr); // tidy up
DestroyWindow(win);
UnregisterClassW(wc.lpszClassName, wc.hInstance);
std::printf(g_failures == 0 ? "FOCUS SPOOF TEST PASS\n" : "FOCUS SPOOF TEST FAILED (%d)\n", g_failures);
return g_failures == 0 ? 0 : 1;
}