diff --git a/README.md b/README.md index 0277326..7c1c54e 100644 --- a/README.md +++ b/README.md @@ -113,10 +113,6 @@ default** and covers anything the hooked path doesn't. From an in-depth review pass. Each item is fixed test-first (a failing test, then the fix) and lands as its own commit; "verify" items are confirmed real before any change, and dropped if not. -Features: -- **Stale Vulkan-layer registration cleanup** — remove a leftover `HKCU` implicit-layer entry from a - crashed prior run on host startup. - UX: - **Auto re-attach control** — keep it visible/controllable when not connected (today it can be enabled-but-invisible). diff --git a/host/src/main.cpp b/host/src/main.cpp index 78e0d36..e4ae5d4 100644 --- a/host/src/main.cpp +++ b/host/src/main.cpp @@ -35,6 +35,7 @@ #include "log_panel.hpp" #include "test_harness.hpp" #include "ui/app_chrome.hpp" +#include "vk_layer_setup.hpp" namespace { @@ -316,6 +317,10 @@ bool wait_for_hooked_frame(coop::D3D11Window& window, coop::InjectionPanel& inje int run() { + // Clear any leftover Vulkan-layer registration from a host that crashed while registered, before + // it can keep loading our DLL into every Vulkan app this session. + coop::cleanup_stale_vk_layer(); + coop::D3D11Window window; if (!window.create(L"CoopAllTheThings")) { diff --git a/host/src/vk_layer_setup.cpp b/host/src/vk_layer_setup.cpp index f6b0d61..caea6f3 100644 --- a/host/src/vk_layer_setup.cpp +++ b/host/src/vk_layer_setup.cpp @@ -76,4 +76,11 @@ void unregister_vk_layer() } } +void cleanup_stale_vk_layer() +{ + // At startup nothing of ours should be registered yet (registration is opt-in, this session). So + // a registration present now is a crash leftover -- removing it is exactly unregister_vk_layer(). + unregister_vk_layer(); +} + } // namespace coop diff --git a/host/src/vk_layer_setup.hpp b/host/src/vk_layer_setup.hpp index 3ca53e3..72768e8 100644 --- a/host/src/vk_layer_setup.hpp +++ b/host/src/vk_layer_setup.hpp @@ -21,4 +21,10 @@ bool register_vk_layer(const std::wstring& target_image); // on host shutdown as a belt-and-suspenders cleanup). void unregister_vk_layer(); +// Call once at host startup. The layer is session-scoped (registered only while the tool runs, +// unregistered on clean exit), so any registration present at startup is a leftover from a host that +// crashed/was killed while registered -- which would otherwise keep loading our DLL into EVERY Vulkan +// app until the next clean run. This removes that stale registration. No-op if nothing is registered. +void cleanup_stale_vk_layer(); + } // namespace coop