Skip to content

Commit

Permalink
use what already was working instead (#1950)
Browse files Browse the repository at this point in the history
  • Loading branch information
Soreepeong committed Jul 19, 2024
1 parent 5af935b commit 19464ec
Show file tree
Hide file tree
Showing 2 changed files with 17 additions and 121 deletions.
9 changes: 9 additions & 0 deletions Dalamud.Boot/hooks.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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)",
Expand Down Expand Up @@ -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<std::string>(pData->Loaded.FullDllName->Buffer);

Expand Down
129 changes: 8 additions & 121 deletions Dalamud/Support/CurrentProcessModules.cs
Original file line number Diff line number Diff line change
@@ -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;

/// <summary>Tracks the loaded process modules.</summary>
[ServiceManager.EarlyLoadedService]
internal sealed unsafe partial class CurrentProcessModules : IInternalDisposableService
internal static unsafe partial class CurrentProcessModules
{
private static readonly ConcurrentQueue<string> 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,
}

/// <summary>Gets all the loaded modules, up to date.</summary>
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;
}
}

/// <inheritdoc/>
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;

/// <summary>
/// Registers for notification when a DLL is first loaded.
/// This notification occurs before dynamic linking takes place.<br /><br />
/// <a href="https://learn.microsoft.com/en-us/windows/win32/devnotes/ldrregisterdllnotification">Docs.</a>
/// </summary>
/// <param name="flags">This parameter must be zero.</param>
/// <param name="notificationFunction">A pointer to a callback function to call when the DLL is loaded.</param>
/// <param name="context">A pointer to context data for the callback function.</param>
/// <param name="cookie">A pointer to a variable to receive an identifier for the callback function.
/// This identifier is used to unregister the notification callback function.</param>
/// <returns>Returns an NTSTATUS or error code.</returns>
[LibraryImport("ntdll.dll", SetLastError = true)]
private static partial int LdrRegisterDllNotification(
uint flags,
delegate* unmanaged<LdrDllNotificationReason, LdrDllNotificationData*, nint, void>
notificationFunction,
nint context,
out nint cookie);

/// <summary>
/// Cancels DLL load notification previously registered by calling the LdrRegisterDllNotification function.<br />
/// <br />
/// <a href="https://learn.microsoft.com/en-us/windows/win32/devnotes/ldrunregisterdllnotification">Docs.</a>
/// </summary>
/// <param name="cookie">A pointer to the callback identifier received from the LdrRegisterDllNotification call
/// that registered for notification.
/// </param>
/// <returns>Returns an NTSTATUS or error code.</returns>
[LibraryImport("ntdll.dll", SetLastError = true)]
private static partial int LdrUnregisterDllNotification(nint cookie);

[StructLayout(LayoutKind.Sequential)]
private struct LdrDllNotificationData
{
/// <summary>Reserved.</summary>
public uint Flags;

/// <summary>The full path name of the DLL module.</summary>
public UNICODE_STRING* FullDllName;

/// <summary>The base file name of the DLL module.</summary>
public UNICODE_STRING* BaseDllName;

/// <summary>A pointer to the base address for the DLL in memory.</summary>
public nint DllBase;

/// <summary>The size of the DLL image, in bytes.</summary>
public uint SizeOfImage;
}
[LibraryImport("Dalamud.Boot.dll")]
private static partial int* GetDllChangedStorage();
}

0 comments on commit 19464ec

Please sign in to comment.