diff --git a/Dalamud/Game/Libc/LibcFunction.cs b/Dalamud/Game/Libc/LibcFunction.cs deleted file mode 100644 index 73ccc4399..000000000 --- a/Dalamud/Game/Libc/LibcFunction.cs +++ /dev/null @@ -1,72 +0,0 @@ -using System; -using System.Runtime.InteropServices; -using System.Text; - -using Dalamud.IoC; -using Dalamud.IoC.Internal; -using Dalamud.Plugin.Services; - -namespace Dalamud.Game.Libc; - -/// -/// This class handles creating cstrings utilizing native game methods. -/// -[PluginInterface] -[InterfaceVersion("1.0")] -[ServiceManager.EarlyLoadedService] -#pragma warning disable SA1015 -[ResolveVia] -#pragma warning restore SA1015 -internal sealed class LibcFunction : IServiceType, ILibcFunction -{ - private readonly LibcFunctionAddressResolver address; - private readonly StdStringFromCStringDelegate stdStringCtorCString; - private readonly StdStringDeallocateDelegate stdStringDeallocate; - - [ServiceManager.ServiceConstructor] - private LibcFunction(TargetSigScanner sigScanner) - { - this.address = new LibcFunctionAddressResolver(); - this.address.Setup(sigScanner); - - this.stdStringCtorCString = Marshal.GetDelegateForFunctionPointer(this.address.StdStringFromCstring); - this.stdStringDeallocate = Marshal.GetDelegateForFunctionPointer(this.address.StdStringDeallocate); - } - - // TODO: prolly callconv is not okay in x86 - [UnmanagedFunctionPointer(CallingConvention.ThisCall)] - private delegate IntPtr StdStringFromCStringDelegate(IntPtr pStdString, [MarshalAs(UnmanagedType.LPArray)] byte[] content, IntPtr size); - - // TODO: prolly callconv is not okay in x86 - [UnmanagedFunctionPointer(CallingConvention.ThisCall)] - private delegate IntPtr StdStringDeallocateDelegate(IntPtr address); - - /// - public OwnedStdString NewString(byte[] content) - { - // While 0x70 bytes in the memory should be enough in DX11 version, - // I don't trust my analysis so we're just going to allocate almost two times more than that. - var pString = Marshal.AllocHGlobal(256); - - // Initialize a string - var size = new IntPtr(content.Length); - var pReallocString = this.stdStringCtorCString(pString, content, size); - - // Log.Verbose("Prev: {Prev} Now: {Now}", pString, pReallocString); - - return new OwnedStdString(pReallocString, this.DeallocateStdString); - } - - /// - public OwnedStdString NewString(string content, Encoding? encoding = null) - { - encoding ??= Encoding.UTF8; - - return this.NewString(encoding.GetBytes(content)); - } - - private void DeallocateStdString(IntPtr address) - { - this.stdStringDeallocate(address); - } -} diff --git a/Dalamud/Game/Libc/LibcFunctionAddressResolver.cs b/Dalamud/Game/Libc/LibcFunctionAddressResolver.cs deleted file mode 100644 index 3b8742678..000000000 --- a/Dalamud/Game/Libc/LibcFunctionAddressResolver.cs +++ /dev/null @@ -1,28 +0,0 @@ -using System; - -namespace Dalamud.Game.Libc; - -/// -/// The address resolver for the class. -/// -internal sealed class LibcFunctionAddressResolver : BaseAddressResolver -{ - private delegate IntPtr StringFromCString(); - - /// - /// Gets the address of the native StdStringFromCstring method. - /// - public IntPtr StdStringFromCstring { get; private set; } - - /// - /// Gets the address of the native StdStringDeallocate method. - /// - public IntPtr StdStringDeallocate { get; private set; } - - /// - protected override void Setup64Bit(ISigScanner sig) - { - this.StdStringFromCstring = sig.ScanText("48 89 5C 24 08 48 89 74 24 10 57 48 83 EC 20 48 8D 41 22 66 C7 41 20 01 01 48 89 01 49 8B D8"); - this.StdStringDeallocate = sig.ScanText("80 79 21 00 75 12 48 8B 51 08 41 B8 33 00 00 00 48 8B 09 E9 ?? ?? ?? 00 C3"); - } -} diff --git a/Dalamud/Game/Libc/OwnedStdString.cs b/Dalamud/Game/Libc/OwnedStdString.cs deleted file mode 100644 index db92257b3..000000000 --- a/Dalamud/Game/Libc/OwnedStdString.cs +++ /dev/null @@ -1,100 +0,0 @@ -using System; -using System.Runtime.InteropServices; - -namespace Dalamud.Game.Libc; - -/// -/// An address wrapper around the class. -/// -public sealed partial class OwnedStdString -{ - private readonly DeallocatorDelegate dealloc; - - /// - /// Initializes a new instance of the class. - /// Construct a wrapper around std::string. - /// - /// - /// Violating any of these might cause an undefined hehaviour. - /// 1. This function takes the ownership of the address. - /// 2. A memory pointed by address argument is assumed to be allocated by Marshal.AllocHGlobal thus will try to call Marshal.FreeHGlobal on the address. - /// 3. std::string object pointed by address must be initialized before calling this function. - /// - /// The address of the owned std string. - /// A deallocator function. - internal OwnedStdString(IntPtr address, DeallocatorDelegate dealloc) - { - this.Address = address; - this.dealloc = dealloc; - } - - /// - /// The delegate type that deallocates a std string. - /// - /// Address to deallocate. - internal delegate void DeallocatorDelegate(IntPtr address); - - /// - /// Gets the address of the std string. - /// - public IntPtr Address { get; private set; } - - /// - /// Read the wrapped StdString. - /// - /// The StdString. - public StdString Read() => StdString.ReadFromPointer(this.Address); -} - -/// -/// Implements IDisposable. -/// -public sealed partial class OwnedStdString : IDisposable -{ - private bool isDisposed; - - /// - /// Finalizes an instance of the class. - /// - ~OwnedStdString() => this.Dispose(false); - - /// - /// Dispose of managed and unmanaged resources. - /// - public void Dispose() - { - GC.SuppressFinalize(this); - this.Dispose(true); - } - - /// - /// Dispose of managed and unmanaged resources. - /// - /// A value indicating whether this was called via Dispose or finalized. - public void Dispose(bool disposing) - { - if (this.isDisposed) - return; - - this.isDisposed = true; - - if (disposing) - { - } - - if (this.Address == IntPtr.Zero) - { - // Something got seriously fucked. - throw new AccessViolationException(); - } - - // Deallocate inner string first - this.dealloc(this.Address); - - // Free the heap - Marshal.FreeHGlobal(this.Address); - - // Better safe (running on a nullptr) than sorry. (running on a dangling pointer) - this.Address = IntPtr.Zero; - } -} diff --git a/Dalamud/Game/Libc/StdString.cs b/Dalamud/Game/Libc/StdString.cs deleted file mode 100644 index 816219a82..000000000 --- a/Dalamud/Game/Libc/StdString.cs +++ /dev/null @@ -1,68 +0,0 @@ -using System; -using System.Runtime.InteropServices; -using System.Text; - -namespace Dalamud.Game.Libc; - -/// -/// Interation with std::string. -/// -public class StdString -{ - /// - /// Initializes a new instance of the class. - /// - private StdString() - { - } - - /// - /// Gets the value of the cstring. - /// - public string Value { get; private set; } - - /// - /// Gets or sets the raw byte representation of the cstring. - /// - public byte[] RawData { get; set; } - - /// - /// Marshal a null terminated cstring from memory to a UTF-8 encoded string. - /// - /// Address of the cstring. - /// A UTF-8 encoded string. - public static StdString ReadFromPointer(IntPtr cstring) - { - unsafe - { - if (cstring == IntPtr.Zero) - { - throw new ArgumentNullException(nameof(cstring)); - } - - var innerAddress = Marshal.ReadIntPtr(cstring); - if (innerAddress == IntPtr.Zero) - { - throw new NullReferenceException("Inner reference to the cstring is null."); - } - - // Count the number of chars. String is assumed to be zero-terminated. - - var count = 0; - while (Marshal.ReadByte(innerAddress, count) != 0) - { - count += 1; - } - - // raw copy, as UTF8 string conversion is lossy - var rawData = new byte[count]; - Marshal.Copy(innerAddress, rawData, 0, count); - - return new StdString - { - RawData = rawData, - Value = Encoding.UTF8.GetString(rawData), - }; - } - } -} diff --git a/Dalamud/Plugin/Services/ILibcFunction.cs b/Dalamud/Plugin/Services/ILibcFunction.cs deleted file mode 100644 index bebd62936..000000000 --- a/Dalamud/Plugin/Services/ILibcFunction.cs +++ /dev/null @@ -1,26 +0,0 @@ -using System.Text; - -using Dalamud.Game.Libc; - -namespace Dalamud.Plugin.Services; - -/// -/// This class handles creating cstrings utilizing native game methods. -/// -public interface ILibcFunction -{ - /// - /// Create a new string from the given bytes. - /// - /// The bytes to convert. - /// An owned std string object. - public OwnedStdString NewString(byte[] content); - - /// - /// Create a new string form the given bytes. - /// - /// The bytes to convert. - /// A non-default encoding. - /// An owned std string object. - public OwnedStdString NewString(string content, Encoding? encoding = null); -}