Ver Fonte

Converting client/hooks

Kenny Mecham há 2 semanas atrás
pai
commit
71927b6597

+ 4 - 3
Sunrise/src/client/hooks/assert_handler/assert_handler_observer.cpp

@@ -7,10 +7,12 @@
 #include <cstdint>
 #include <cstdio>
 #include <cstring>
+#include <mutex>
 
 #include "../../../core/logging/log.h"
 #include "../../targets/game/assert_handler.h"
 #include "../net_tick_probe/net_tick_probe.h"
+#include "core/threading/srw_lock.h"
 
 namespace sunrise::client::hooks::assert_handler {
 namespace {
@@ -35,7 +37,7 @@ constexpr int kGraphicsHaltCategory = 6;
 /** The handler the game installed, called with the same printf-style arguments the sites use. */
 using NativeHandler = void(__cdecl*)(int, const char*, ...);
 
-SRWLOCK g_lock{SRWLOCK_INIT};
+core::threading::SrwLock g_lock{};
 /** Last message seen, so a message that repeats every frame is counted rather than written. */
 std::array<char, kTextCapacity> g_lastText{};
 std::uint32_t g_repeats{};
@@ -54,7 +56,7 @@ std::uint32_t g_seen{};
  * @return True when the caller writes a log line.
  */
 [[nodiscard]] bool admit(const char* text, std::uint32_t& seen, std::uint32_t& repeats) noexcept {
-    AcquireSRWLockExclusive(&g_lock);
+    const std::lock_guard lock(g_lock);
     ++g_seen;
     if (std::strcmp(g_lastText.data(), text) == 0) {
         ++g_repeats;
@@ -67,7 +69,6 @@ std::uint32_t g_seen{};
     }
     seen = g_seen;
     repeats = g_repeats;
-    ReleaseSRWLockExclusive(&g_lock);
     return repeats <= kRepeatHead || repeats % kRepeatStride == 0;
 }
 

+ 0 - 3
Sunrise/src/client/hooks/assert_handler/assert_handler_observer.h

@@ -4,9 +4,6 @@
 
 namespace sunrise::client::hooks::assert_handler {
 
-extern SRWLOCK g_lock;
-extern bool g_installed;
-
 /** @return Address of the internal assert handler body. */
 [[nodiscard]] void* handler_entry_point() noexcept;
 

+ 0 - 1
Sunrise/src/client/hooks/egress/internal.h

@@ -47,7 +47,6 @@ enum class HookSlot : std::size_t {
 /** Fixed handle count covers every required and OS-optional egress entry point. */
 inline constexpr std::size_t kHookCount = static_cast<std::size_t>(HookSlot::count);
 
-extern SRWLOCK g_lock;
 extern std::array<hooking::detour::Handle, kHookCount> g_handles;
 
 /**

+ 6 - 12
Sunrise/src/client/hooks/egress/lifecycle/egress_guard_lifecycle.cpp

@@ -1,16 +1,17 @@
 #include <algorithm>
 #include <array>
 #include <cstdio>
+#include <shared_mutex>
 
 #include "../../../../core/logging/log.h"
 #include "../internal.h"
-#include "../platform/abi.h"
 #include "../runtime.h"
+#include "core/threading/srw_lock.h"
 #include "internal.h"
 
 namespace sunrise::client::hooks::egress {
 
-SRWLOCK g_lock{SRWLOCK_INIT};
+core::threading::SrwLock g_lock{};
 std::array<hooking::detour::Handle, kHookCount> g_handles{};
 
 namespace {
@@ -64,13 +65,11 @@ std::size_t g_activeHookCount{};
 
 /** Installs every resolver and socket guard in one process-wide transaction. */
 bool install() noexcept {
-    AcquireSRWLockExclusive(&g_lock);
+    const std::lock_guard lock(g_lock);
     if (all_installed()) {
-        ReleaseSRWLockExclusive(&g_lock);
         return true;
     }
     if (any_installed() || !pin_owner_module() || !lifecycle::load_modules()) {
-        ReleaseSRWLockExclusive(&g_lock);
         return false;
     }
 
@@ -82,20 +81,17 @@ bool install() noexcept {
         g_activeHookCount = 0;
         g_batchAttached = false;
         lifecycle::release_modules();
-        ReleaseSRWLockExclusive(&g_lock);
         return false;
     }
     g_activeHookCount = count;
     g_batchAttached = true;
-    ReleaseSRWLockExclusive(&g_lock);
     return true;
 }
 
 /** Emits one line per guarded export, then the batch outcome. */
 void report_installation() noexcept {
-    AcquireSRWLockExclusive(&g_lock);
+    const std::lock_guard lock(g_lock);
     if (g_reported) {
-        ReleaseSRWLockExclusive(&g_lock);
         return;
     }
     g_reported = true;
@@ -118,7 +114,6 @@ void report_installation() noexcept {
                              {line.data(), static_cast<std::size_t>(written)});
         }
     }
-    ReleaseSRWLockExclusive(&g_lock);
     std::array<char, 96> summary{};
     const int written = std::snprintf(summary.data(),
                                       summary.size(),
@@ -134,9 +129,8 @@ void report_installation() noexcept {
 
 /** @return True only when every required guard detour is attached. */
 bool is_installed() noexcept {
-    AcquireSRWLockShared(&g_lock);
+    const std::shared_lock lock(g_lock);
     const bool installed = all_installed();
-    ReleaseSRWLockShared(&g_lock);
     return installed;
 }
 

+ 7 - 18
Sunrise/src/client/hooks/graphics/input/graphics_window_input.cpp

@@ -2,11 +2,13 @@
 
 #include <atomic>
 #include <bit>
+#include <shared_mutex>
 
 #include "../../../../core/ui/layout/credits/sunrise_credits_badge.h"
 #include "../../../../core/ui/modules/logs/logs.h"
 #include "../../../../core/ui/runtime/ui_visibility_runtime.h"
 #include "../renderer/renderer.h"
+#include "core/threading/srw_lock.h"
 #include "input.h"
 
 namespace sunrise::client::hooks::graphics::input {
@@ -24,7 +26,7 @@ struct Binding {
 
 Binding g_binding{};
 std::atomic_uint g_activeCallbacks{};
-SRWLOCK g_inputLock{SRWLOCK_INIT};
+core::threading::SrwLock g_inputLock{};
 
 /** Counts active procedure calls so teardown can be retried before module unload. */
 class CallbackGuard final {
@@ -48,9 +50,8 @@ public:
  * @return Original procedure for the matching record, or null when nothing matches.
  */
 [[nodiscard]] WNDPROC original_for(HWND window) noexcept {
-    AcquireSRWLockShared(&g_inputLock);
+    const std::shared_lock lock(g_inputLock);
     const WNDPROC original = g_binding.window == window ? g_binding.original : nullptr;
-    ReleaseSRWLockShared(&g_inputLock);
     return original;
 }
 
@@ -122,15 +123,13 @@ bool install(HWND window) noexcept {
     if (window == nullptr || IsWindow(window) == FALSE) {
         return false;
     }
-    AcquireSRWLockExclusive(&g_inputLock);
+    const std::lock_guard lock(g_inputLock);
     if (g_binding.installed) {
         const bool sameWindow = g_binding.window == window;
-        ReleaseSRWLockExclusive(&g_inputLock);
         return sameWindow;
     }
     if (g_activeCallbacks.load(std::memory_order_acquire) != 0) {
         // A retired procedure keeps its forwarding record until every old call returns.
-        ReleaseSRWLockExclusive(&g_inputLock);
         return false;
     }
 
@@ -138,26 +137,22 @@ bool install(HWND window) noexcept {
     const LONG_PTR original =
         SetWindowLongPtrW(window, GWLP_WNDPROC, reinterpret_cast<LONG_PTR>(&window_procedure));
     if (original == 0 && GetLastError() != ERROR_SUCCESS) {
-        ReleaseSRWLockExclusive(&g_inputLock);
         return false;
     }
     g_binding = Binding{window, std::bit_cast<WNDPROC>(original), true};
-    ReleaseSRWLockExclusive(&g_inputLock);
     return true;
 }
 
 /** Restores the original procedure only when Sunrise still owns the chain head. */
 bool uninstall() noexcept {
-    AcquireSRWLockExclusive(&g_inputLock);
+    const std::lock_guard lock(g_inputLock);
     if (!g_binding.installed) {
         const bool idle = g_activeCallbacks.load(std::memory_order_acquire) == 0;
-        ReleaseSRWLockExclusive(&g_inputLock);
         return idle;
     }
     if (IsWindow(g_binding.window) == FALSE) {
         g_binding.installed = false;
         const bool idle = g_activeCallbacks.load(std::memory_order_acquire) == 0;
-        ReleaseSRWLockExclusive(&g_inputLock);
         return idle;
     }
 
@@ -165,19 +160,16 @@ bool uninstall() noexcept {
     const LONG_PTR current = GetWindowLongPtrW(g_binding.window, GWLP_WNDPROC);
     const LONG_PTR replacement = reinterpret_cast<LONG_PTR>(&window_procedure);
     if (current == 0 && GetLastError() != ERROR_SUCCESS) {
-        ReleaseSRWLockExclusive(&g_inputLock);
         return false;
     }
     if (current == reinterpret_cast<LONG_PTR>(g_binding.original)) {
         // The window owner already put our forwarding target back itself.
         g_binding.installed = false;
         const bool idle = g_activeCallbacks.load(std::memory_order_acquire) == 0;
-        ReleaseSRWLockExclusive(&g_inputLock);
         return idle;
     }
     if (current != replacement) {
         // A later subclass owns the chain head now, so do not overwrite it.
-        ReleaseSRWLockExclusive(&g_inputLock);
         return false;
     }
 
@@ -185,19 +177,17 @@ bool uninstall() noexcept {
     const LONG_PTR replaced = SetWindowLongPtrW(
         g_binding.window, GWLP_WNDPROC, reinterpret_cast<LONG_PTR>(g_binding.original));
     if (replaced == 0 && GetLastError() != ERROR_SUCCESS) {
-        ReleaseSRWLockExclusive(&g_inputLock);
         return false;
     }
     // Keep the forwarding target until a later install replaces this retired record.
     g_binding.installed = false;
     const bool idle = g_activeCallbacks.load(std::memory_order_acquire) == 0;
-    ReleaseSRWLockExclusive(&g_inputLock);
     return idle;
 }
 
 /** Checks whether Sunrise is still installed, or still sits below a later subclass. */
 bool active(HWND window) noexcept {
-    AcquireSRWLockShared(&g_inputLock);
+    const std::shared_lock lock(g_inputLock);
     bool installed = g_binding.installed && g_binding.window == window && IsWindow(window) != FALSE
                      && IsWindowVisible(window) != FALSE;
     if (installed) {
@@ -209,7 +199,6 @@ bool active(HWND window) noexcept {
             installed = current != reinterpret_cast<LONG_PTR>(g_binding.original);
         }
     }
-    ReleaseSRWLockShared(&g_inputLock);
     return installed;
 }