From 19464ec08019b72ffb1e942b92656b7af0ca7fc3 Mon Sep 17 00:00:00 2001 From: srkizer Date: Sat, 20 Jul 2024 00:04:11 +0900 Subject: [PATCH] use what already was working instead (#1950) --- Dalamud.Boot/hooks.cpp | 9 ++ Dalamud/Support/CurrentProcessModules.cs | 129 ++--------------------- 2 files changed, 17 insertions(+), 121 deletions(-) diff --git a/Dalamud.Boot/hooks.cpp b/Dalamud.Boot/hooks.cpp index 1b1280cf08..295d427aee 100644 --- a/Dalamud.Boot/hooks.cpp +++ b/Dalamud.Boot/hooks.cpp @@ -5,6 +5,14 @@ #include "ntdll.h" #include "logging.h" +namespace { + int s_dllChanged = 0; +} + +extern "C" __declspec(dllexport) int* GetDllChangedStorage() { + return &s_dllChanged; +} + hooks::getprocaddress_singleton_import_hook::getprocaddress_singleton_import_hook() : m_pfnGetProcAddress(GetProcAddress) , m_thunk("kernel32!GetProcAddress(Singleton Import Hook)", @@ -71,6 +79,7 @@ void hooks::getprocaddress_singleton_import_hook::initialize() { m_getProcAddressHandler = set_handler(L"kernel32.dll", "GetProcAddress", m_thunk.get_thunk(), [this](void*) {}); LdrRegisterDllNotification(0, [](ULONG notiReason, const LDR_DLL_NOTIFICATION_DATA* pData, void* context) { + s_dllChanged = 1; if (notiReason == LDR_DLL_NOTIFICATION_REASON_LOADED) { const auto dllName = unicode::convert(pData->Loaded.FullDllName->Buffer); diff --git a/Dalamud/Support/CurrentProcessModules.cs b/Dalamud/Support/CurrentProcessModules.cs index bc0abcf504..e1e3465b31 100644 --- a/Dalamud/Support/CurrentProcessModules.cs +++ b/Dalamud/Support/CurrentProcessModules.cs @@ -1,145 +1,32 @@ -using System.Collections.Concurrent; using System.Diagnostics; using System.Runtime.InteropServices; -using System.Threading; -using System.Threading.Tasks; using Serilog; -using TerraFX.Interop.Windows; - namespace Dalamud.Support; /// Tracks the loaded process modules. -[ServiceManager.EarlyLoadedService] -internal sealed unsafe partial class CurrentProcessModules : IInternalDisposableService +internal static unsafe partial class CurrentProcessModules { - private static readonly ConcurrentQueue LogQueue = new(); - private static readonly SemaphoreSlim LogSemaphore = new(0); - private static Process? process; - private static nint cookie; - - private readonly CancellationTokenSource logTaskStop = new(); - private readonly Task logTask; - - [ServiceManager.ServiceConstructor] - private CurrentProcessModules() - { - var res = LdrRegisterDllNotification(0, &DllNotificationCallback, 0, out cookie); - if (res != STATUS.STATUS_SUCCESS) - { - Log.Error("{what}: LdrRegisterDllNotification failure: 0x{err}", nameof(CurrentProcessModules), res); - cookie = 0; - this.logTask = Task.CompletedTask; - return; - } - - this.logTask = Task.Factory.StartNew( - () => - { - while (!this.logTaskStop.IsCancellationRequested) - { - LogSemaphore.Wait(); - while (LogQueue.TryDequeue(out var log)) - Log.Verbose(log); - } - }, - this.logTaskStop.Token, - TaskCreationOptions.LongRunning, - TaskScheduler.Default); - } - - private enum LdrDllNotificationReason : uint - { - Loaded = 1, - Unloaded = 2, - } /// Gets all the loaded modules, up to date. public static ProcessModuleCollection ModuleCollection { get { - if (cookie == 0) + ref var t = ref *GetDllChangedStorage(); + if (t != 0) { - // This service has not been initialized; return a fresh copy without storing it. - return Process.GetCurrentProcess().Modules; - } - - if (process is null) + t = 0; + process = null; Log.Verbose("{what}: Fetchling fresh copy of current process modules.", nameof(CurrentProcessModules)); + } return (process ??= Process.GetCurrentProcess()).Modules; } } - /// - void IInternalDisposableService.DisposeService() - { - if (Interlocked.Exchange(ref cookie, 0) is var copy and not 0) - LdrUnregisterDllNotification(copy); - if (!this.logTask.IsCompleted) - { - this.logTaskStop.Cancel(); - LogSemaphore.Release(); - this.logTask.Wait(); - } - } - - [UnmanagedCallersOnly] - private static void DllNotificationCallback( - LdrDllNotificationReason reason, - LdrDllNotificationData* data, - nint context) => process = null; - - /// - /// Registers for notification when a DLL is first loaded. - /// This notification occurs before dynamic linking takes place.

- /// Docs. - ///
- /// This parameter must be zero. - /// A pointer to a callback function to call when the DLL is loaded. - /// A pointer to context data for the callback function. - /// A pointer to a variable to receive an identifier for the callback function. - /// This identifier is used to unregister the notification callback function. - /// Returns an NTSTATUS or error code. - [LibraryImport("ntdll.dll", SetLastError = true)] - private static partial int LdrRegisterDllNotification( - uint flags, - delegate* unmanaged - notificationFunction, - nint context, - out nint cookie); - - /// - /// Cancels DLL load notification previously registered by calling the LdrRegisterDllNotification function.
- ///
- /// Docs. - ///
- /// A pointer to the callback identifier received from the LdrRegisterDllNotification call - /// that registered for notification. - /// - /// Returns an NTSTATUS or error code. - [LibraryImport("ntdll.dll", SetLastError = true)] - private static partial int LdrUnregisterDllNotification(nint cookie); - - [StructLayout(LayoutKind.Sequential)] - private struct LdrDllNotificationData - { - /// Reserved. - public uint Flags; - - /// The full path name of the DLL module. - public UNICODE_STRING* FullDllName; - - /// The base file name of the DLL module. - public UNICODE_STRING* BaseDllName; - - /// A pointer to the base address for the DLL in memory. - public nint DllBase; - - /// The size of the DLL image, in bytes. - public uint SizeOfImage; - } + [LibraryImport("Dalamud.Boot.dll")] + private static partial int* GetDllChangedStorage(); }