108 lines
3.5 KiB
C#
108 lines
3.5 KiB
C#
using System;
|
|
using System.Diagnostics;
|
|
using System.Runtime.InteropServices;
|
|
using Dalamud.Game.Command;
|
|
using Dalamud.Game.Gui;
|
|
using Dalamud.IoC;
|
|
using Dalamud.Logging;
|
|
using Dalamud.Plugin;
|
|
|
|
namespace MultiboxMutexer;
|
|
|
|
public sealed class Plugin : IDalamudPlugin, IDisposable
|
|
{
|
|
[Flags]
|
|
private enum ProcessAccessFlags : uint
|
|
{
|
|
All = 0x1F0FFFu,
|
|
Terminate = 1u,
|
|
CreateThread = 2u,
|
|
VMOperation = 8u,
|
|
VMRead = 0x10u,
|
|
VMWrite = 0x20u,
|
|
DupHandle = 0x40u,
|
|
SetInformation = 0x200u,
|
|
QueryInformation = 0x400u,
|
|
Synchronize = 0x100000u
|
|
}
|
|
|
|
[Flags]
|
|
private enum DuplicateOptions : uint
|
|
{
|
|
DUPLICATE_CLOSE_SOURCE = 1u,
|
|
DUPLICATE_SAME_ACCESS = 2u
|
|
}
|
|
|
|
private const uint PROCESS_DUP_HANDLE = 64u;
|
|
|
|
public string Name => "Multibox Mutexer";
|
|
|
|
public DalamudPluginInterface PluginInterface { get; }
|
|
|
|
public CommandManager CommandManager { get; }
|
|
|
|
[DllImport("kernel32.dll", SetLastError = true)]
|
|
[return: MarshalAs(UnmanagedType.Bool)]
|
|
private static extern bool CloseHandle(nint hObject);
|
|
|
|
[DllImport("kernel32.dll")]
|
|
private static extern nint OpenProcess(ProcessAccessFlags dwDesiredAccess, [MarshalAs(UnmanagedType.Bool)] bool bInheritHandle, nint dwProcessId);
|
|
|
|
[DllImport("kernel32.dll", SetLastError = true)]
|
|
[return: MarshalAs(UnmanagedType.Bool)]
|
|
private static extern bool DuplicateHandle(nint hSourceProcessHandle, nint hSourceHandle, nint hTargetProcessHandle, out nint lpTargetHandle, uint dwDesiredAccess, [MarshalAs(UnmanagedType.Bool)] bool bInheritHandle, DuplicateOptions dwOptions);
|
|
|
|
public static bool CloseHandleEx(nint pid, nint handle)
|
|
{
|
|
nint num = OpenProcess(ProcessAccessFlags.DupHandle, bInheritHandle: false, pid);
|
|
nint lpTargetHandle = IntPtr.Zero;
|
|
bool result = DuplicateHandle(num, handle, IntPtr.Zero, out lpTargetHandle, 0u, bInheritHandle: false, DuplicateOptions.DUPLICATE_CLOSE_SOURCE);
|
|
CloseHandle(num);
|
|
return result;
|
|
}
|
|
|
|
public Plugin([RequiredVersion("1.0")] DalamudPluginInterface pluginInterface, [RequiredVersion("1.0")] CommandManager commandManager, [RequiredVersion("1.0")] GameGui gameGui)
|
|
{
|
|
//IL_0026: Unknown result type (might be due to invalid IL or missing references)
|
|
//IL_0030: Expected O, but got Unknown
|
|
//IL_002b: Unknown result type (might be due to invalid IL or missing references)
|
|
//IL_0030: Unknown result type (might be due to invalid IL or missing references)
|
|
//IL_0040: Expected O, but got Unknown
|
|
PluginInterface = pluginInterface;
|
|
CommandManager = commandManager;
|
|
CommandManager.AddHandler("/mutex", new CommandInfo(new HandlerDelegate(OnCommand))
|
|
{
|
|
HelpMessage = "Fix mutex"
|
|
});
|
|
PluginLog.Debug("LOADED?", Array.Empty<object>());
|
|
Process currentProcess = Process.GetCurrentProcess();
|
|
PluginLog.Debug("CURRENT PROCESS PID: " + currentProcess.Id, Array.Empty<object>());
|
|
ReleaseAllMutexes(currentProcess);
|
|
}
|
|
|
|
public void ReleaseAllMutexes(Process proc)
|
|
{
|
|
PluginLog.Debug("MUTEXER CALLED", Array.Empty<object>());
|
|
if (HandleManager.ClearMutex())
|
|
{
|
|
PluginLog.Debug("Succesfully killed the mutex", Array.Empty<object>());
|
|
}
|
|
else
|
|
{
|
|
PluginLog.Warning("Failed to kill mutex!", Array.Empty<object>());
|
|
}
|
|
}
|
|
|
|
private void OnCommand(string command, string args)
|
|
{
|
|
PluginLog.Debug("RUNNING MUTEXER", Array.Empty<object>());
|
|
Process currentProcess = Process.GetCurrentProcess();
|
|
ReleaseAllMutexes(currentProcess);
|
|
}
|
|
|
|
public void Dispose()
|
|
{
|
|
CommandManager.RemoveHandler("/mutex");
|
|
}
|
|
}
|