diff --git a/Dalamud.Bootstrap/Bootstrapper.cs b/Dalamud.Bootstrap/Bootstrapper.cs index 26dd30c7b..15c63d6d7 100644 --- a/Dalamud.Bootstrap/Bootstrapper.cs +++ b/Dalamud.Bootstrap/Bootstrapper.cs @@ -4,6 +4,7 @@ using System.IO.Pipes; using CoreHook.BinaryInjection.RemoteInjection; using CoreHook.BinaryInjection.RemoteInjection.Configuration; using CoreHook.IPC.Platform; +using Dalamud.Bootstrap.SqexArg; namespace Dalamud.Bootstrap { @@ -16,7 +17,7 @@ namespace Dalamud.Bootstrap m_options = options; } - public void Launch(string exePath) + public void Launch(string exePath, string? commandLine) { throw new NotImplementedException("TODO"); } @@ -43,8 +44,9 @@ namespace Dalamud.Bootstrap // Acquire the process handle and read the command line using var process = Process.Open(pid); - var arguments = process.ReadCommandLine(); + var commandLine = process.ReadCommandLine(); + var argument = ArgumentDecoder.Decode(commandLine[1]); // TODO: // .... if arg1 exists // DecodeSqexArg(arguments[1]); @@ -54,8 +56,7 @@ namespace Dalamud.Bootstrap // AddArgs(args, "T", newTick) // str = ToString() // EncodeSqexArg(str, newKey) - - + process.Terminate(); throw new NotImplementedException("TODO"); @@ -94,7 +95,7 @@ namespace Dalamud.Bootstrap // Could not inject Dalamud for whatever reason; it could be process is not actually running, insufficient os privilege, or whatever the thing SE put in their game; // Therefore there's not much we can do on this side; You have to trobleshoot by yourself somehow. - throw new BootstrapException(pid, message, ex); + throw new ProcessException(message, pid, ex); } } } diff --git a/Dalamud.Bootstrap/Exceptions.cs b/Dalamud.Bootstrap/Exceptions.cs index 39602ab80..e62cdb996 100644 --- a/Dalamud.Bootstrap/Exceptions.cs +++ b/Dalamud.Bootstrap/Exceptions.cs @@ -1,4 +1,5 @@ using System; +using System.ComponentModel; namespace Dalamud.Bootstrap { @@ -14,8 +15,26 @@ namespace Dalamud.Bootstrap internal BootstrapException(string message, Exception innerException) : base(message, innerException) { } } - public class NtException : BootstrapException + public class ProcessException : BootstrapException { + public uint Pid { get; } + internal ProcessException() : base() { } + + internal ProcessException(string message) : base(message) { } + + internal ProcessException(string message, Exception innerException) : base(message, innerException) { } + + internal ProcessException(string message, uint pid) : base(message) => Pid = pid; + + internal ProcessException(string message, uint pid, Exception innerException) : base(message, innerException) => Pid = pid; + + internal static ProcessException ThrowLastOsError(uint pid) + { + var inner = new Win32Exception(); + + const string message = ""; + throw new ProcessException(message, pid, inner); + } } } diff --git a/Dalamud.Bootstrap/SqexArg/ArgumentBuilder.cs b/Dalamud.Bootstrap/SqexArg/ArgumentBuilder.cs index 46b47f0c0..bff5de6a4 100644 --- a/Dalamud.Bootstrap/SqexArg/ArgumentBuilder.cs +++ b/Dalamud.Bootstrap/SqexArg/ArgumentBuilder.cs @@ -42,7 +42,7 @@ namespace Dalamud.Bootstrap.SqexArg public override string ToString() { - var buffer = new StringBuilder(256); + var buffer = new StringBuilder(300); foreach (var kv in m_dict) { diff --git a/Dalamud.Bootstrap/SqexArg/ArgumentDecoder.cs b/Dalamud.Bootstrap/SqexArg/ArgumentDecoder.cs index 1f181bd07..0b162bbd8 100644 --- a/Dalamud.Bootstrap/SqexArg/ArgumentDecoder.cs +++ b/Dalamud.Bootstrap/SqexArg/ArgumentDecoder.cs @@ -4,7 +4,7 @@ namespace Dalamud.Bootstrap.SqexArg { internal static class ArgumentDecoder { - public static void Decode(ReadOnlySpan argument, uint key) + public static ArgumentBuilder Decode(ReadOnlySpan argument, uint key) { // 1. strip //**sqex003 and **// // 2. extract checksum @@ -31,7 +31,7 @@ namespace Dalamud.Bootstrap.SqexArg // stuff - + throw new NotImplementedException("TODO"); } private static void DecodeUrlSafeBase64(ReadOnlySpan content) diff --git a/Dalamud.Bootstrap/Windows/Process.cs b/Dalamud.Bootstrap/Windows/Process.cs index 8c68d242e..9972b934e 100644 --- a/Dalamud.Bootstrap/Windows/Process.cs +++ b/Dalamud.Bootstrap/Windows/Process.cs @@ -42,17 +42,19 @@ namespace Dalamud.Bootstrap if (handle.IsInvalid) { - throw new Win32Exception(); + ProcessException.ThrowLastOsError(pid); } return new Process(handle); } + private uint GetPid() => Win32.GetProcessId(m_handle); + public void Terminate(uint exitCode = 0) { if (!Win32.TerminateProcess(m_handle, exitCode)) { - throw new Win32Exception(); + ProcessException.ThrowLastOsError(GetPid()); } } @@ -72,7 +74,7 @@ namespace Dalamud.Bootstrap if (!Win32.ReadProcessMemory(m_handle, (void*)address, pDest, (IntPtr)destination.Length, &bytesRead)) { - throw new Win32Exception(); + ProcessException.ThrowLastOsError(GetPid()); } // this is okay as the length of the span can't be longer than int.Max @@ -91,7 +93,7 @@ namespace Dalamud.Bootstrap if (bytesRead == 0) { // prolly page fault; there's not much we can do here - throw new Win32Exception(); + ProcessException.ThrowLastOsError(GetPid()); } totalBytesRead += bytesRead; @@ -128,7 +130,10 @@ namespace Dalamud.Bootstrap if (!status.Success) { - throw new NtException(status); + var message = $"A call to NtQueryInformationProcess failed. (Status: {status})"; + var pid = GetPid(); + + throw new ProcessException(message, pid); } return info.PebBaseAddress; @@ -150,7 +155,7 @@ namespace Dalamud.Bootstrap } } - private static string[] ParseCommandLine(ReadOnlySpan commandLine) + private string[] ParseCommandLine(ReadOnlySpan commandLine) { unsafe { @@ -166,7 +171,7 @@ namespace Dalamud.Bootstrap if (argv == null) { - throw new Win32Exception(); + ProcessException.ThrowLastOsError(GetPid()); } try diff --git a/Dalamud.Bootstrap/Windows/Win32.cs b/Dalamud.Bootstrap/Windows/Win32.cs index 89a45f458..6fa8104a9 100644 --- a/Dalamud.Bootstrap/Windows/Win32.cs +++ b/Dalamud.Bootstrap/Windows/Win32.cs @@ -29,6 +29,9 @@ namespace Dalamud.Bootstrap.Windows [DllImport("shell32", CallingConvention = CallingConvention.Winapi, SetLastError = true)] public static extern char** CommandLineToArgvW(void* lpCmdLine, int* pNumArgs); + + [DllImport("kernel32", CallingConvention = CallingConvention.Winapi)] + public static extern uint GetProcessId(SafeProcessHandle hProcess); } [StructLayout(LayoutKind.Sequential)] @@ -63,6 +66,8 @@ namespace Dalamud.Bootstrap.Windows /// Equivalent to NT_ERROR /// public bool Error => 0xC0000000 <= Value; + + public override string ToString() => $"0x{Value:X8}"; } [StructLayout(LayoutKind.Sequential)] diff --git a/Dalamud.Injector/Program.cs b/Dalamud.Injector/Program.cs index 1a29af1d0..1f608f3cb 100644 --- a/Dalamud.Injector/Program.cs +++ b/Dalamud.Injector/Program.cs @@ -26,13 +26,21 @@ namespace Dalamud.Injector RootDirectory = rootDirectory, }); - // .. boot.Relaunch(options.Pid); } private static void Launch(LaunchOptions options) { + var binDirectory = options.BinaryDirectory ?? GetDefaultBinaryDirectory(); + var rootDirectory = options.RootDirectory ?? GetDefaultRootDirectory(); + var boot = new Bootstrapper(new BootstrapperOptions + { + BinaryDirectory = binDirectory, + RootDirectory = rootDirectory, + }); + + boot.Launch(options.ExecutablePath, options.CommandLine); } private static string GetDefaultBinaryDirectory()