From 707bcd4d821c7b3993c93961e0b91e9f6e1fcac1 Mon Sep 17 00:00:00 2001 From: goat Date: Wed, 4 Oct 2023 23:45:11 +0200 Subject: [PATCH] chore: use CsWin32 for WriteAllBytesSafe() We should start converting more to it, as time goes on --- Dalamud/Dalamud.csproj | 3 +++ Dalamud/NativeMethods.txt | 5 +++++ Dalamud/Utility/Util.cs | 31 +++++++++++++++++-------------- 3 files changed, 25 insertions(+), 14 deletions(-) create mode 100644 Dalamud/NativeMethods.txt diff --git a/Dalamud/Dalamud.csproj b/Dalamud/Dalamud.csproj index 7e11b0975..da1ef3f6a 100644 --- a/Dalamud/Dalamud.csproj +++ b/Dalamud/Dalamud.csproj @@ -70,6 +70,9 @@ + + all + diff --git a/Dalamud/NativeMethods.txt b/Dalamud/NativeMethods.txt new file mode 100644 index 000000000..18143e1af --- /dev/null +++ b/Dalamud/NativeMethods.txt @@ -0,0 +1,5 @@ +CreateFile +FILE_ACCESS_RIGHTS +MoveFileEx +FlushFileBuffers +WriteFile diff --git a/Dalamud/Utility/Util.cs b/Dalamud/Utility/Util.cs index 36918abd2..d27b79ea3 100644 --- a/Dalamud/Utility/Util.cs +++ b/Dalamud/Utility/Util.cs @@ -1,4 +1,5 @@ using System.Collections.Generic; +using System.ComponentModel; using System.Diagnostics; using System.IO; using System.IO.Compression; @@ -17,11 +18,10 @@ using Dalamud.Game.ClientState.Objects.Types; using Dalamud.Interface.Colors; using Dalamud.Interface.Utility; using Dalamud.Logging.Internal; -using Dalamud.Memory; using ImGuiNET; using Lumina.Excel.GeneratedSheets; -using PInvoke; using Serilog; +using Windows.Win32.Storage.FileSystem; namespace Dalamud.Utility; @@ -640,36 +640,39 @@ public static class Util /// /// The path of the file to write to. /// The data to write. - public static void WriteAllBytesSafe(string path, byte[] bytes) + public static unsafe void WriteAllBytesSafe(string path, byte[] bytes) { ArgumentException.ThrowIfNullOrEmpty(path); // Open the temp file var tempPath = path + ".tmp"; - using var tempFile = Kernel32 - .CreateFile(tempPath.AsSpan(), - new Kernel32.ACCESS_MASK(Kernel32.FileAccess.FILE_GENERIC_READ | Kernel32.FileAccess.FILE_GENERIC_WRITE), - Kernel32.FileShare.None, - null, - Kernel32.CreationDisposition.CREATE_ALWAYS, - Kernel32.CreateFileFlags.FILE_ATTRIBUTE_NORMAL, - Kernel32.SafeObjectHandle.Null); + using var tempFile = Windows.Win32.PInvoke.CreateFile( + tempPath, + (uint)(FILE_ACCESS_RIGHTS.FILE_GENERIC_READ | FILE_ACCESS_RIGHTS.FILE_GENERIC_WRITE), + FILE_SHARE_MODE.FILE_SHARE_NONE, + null, + FILE_CREATION_DISPOSITION.CREATE_ALWAYS, + FILE_FLAGS_AND_ATTRIBUTES.FILE_ATTRIBUTE_NORMAL, + null); if (tempFile.IsInvalid) throw new Win32Exception(); // Write the data - var bytesWritten = Kernel32.WriteFile(tempFile, new ArraySegment(bytes)); + uint bytesWritten = 0; + if (!Windows.Win32.PInvoke.WriteFile(tempFile, new ReadOnlySpan(bytes), &bytesWritten, null)) + throw new Win32Exception(); + if (bytesWritten != bytes.Length) throw new Exception($"Could not write all bytes to temp file ({bytesWritten} of {bytes.Length})"); - if (!Kernel32.FlushFileBuffers(tempFile)) + if (!Windows.Win32.PInvoke.FlushFileBuffers(tempFile)) throw new Win32Exception(); tempFile.Close(); - if (!MoveFileEx(tempPath, path, MoveFileFlags.MovefileReplaceExisting | MoveFileFlags.MovefileWriteThrough)) + if (!Windows.Win32.PInvoke.MoveFileEx(tempPath, path, MOVE_FILE_FLAGS.MOVEFILE_REPLACE_EXISTING | MOVE_FILE_FLAGS.MOVEFILE_WRITE_THROUGH)) throw new Win32Exception(); }