diff --git a/README.MD b/README.MD index f0180318..a3f96126 100644 --- a/README.MD +++ b/README.MD @@ -9,7 +9,7 @@ Find the link to the Nuget package [here](https://www.nuget.org/packages/SabreTo The following non-project libraries (or ports thereof) are used for file handling: - [GrindCore.SharpCompress](https://github.com/Nanook/GrindCore.SharpCompress) - Common archive format extraction -- [StormLibSharp](https://github.com/robpaveza/stormlibsharp) - MoPaQ extraction [Unused in .NET Framework 2.0/3.5/4.0 and non-Windows builds due to Windows-specific libraries] +- [StormLibSharp](https://github.com/robpaveza/stormlibsharp) - MoPaQ extraction [Unused in non-Windows builds due to Windows-specific libraries] The following projects have influenced this library: diff --git a/SabreTools.Serialization/SabreTools.Serialization.csproj b/SabreTools.Serialization/SabreTools.Serialization.csproj index 96eab79e..605d3393 100644 --- a/SabreTools.Serialization/SabreTools.Serialization.csproj +++ b/SabreTools.Serialization/SabreTools.Serialization.csproj @@ -41,14 +41,6 @@ net6.0;net7.0;net8.0;net9.0 - - - - $(DefaultItemExcludes); - _EXTERNAL\** - - - diff --git a/SabreTools.Serialization/_EXTERNAL/CascLibSharp/CascApi.cs b/SabreTools.Serialization/_EXTERNAL/CascLibSharp/CascApi.cs index 92d2ca7b..0b390eee 100644 --- a/SabreTools.Serialization/_EXTERNAL/CascLibSharp/CascApi.cs +++ b/SabreTools.Serialization/_EXTERNAL/CascLibSharp/CascApi.cs @@ -168,11 +168,19 @@ namespace CascLibSharp string build = "fre"; #endif +#if NET20 || NET35 + string mainPath = Path.Combine(directory, Path.Combine("CascLib", Path.Combine(build, Path.Combine(arch, "CascLib.dll")))); +#else string mainPath = Path.Combine(directory, "CascLib", build, arch, "CascLib.dll"); +#endif if (File.Exists(mainPath)) return FromFile(mainPath); +#if NET20 || NET35 + string alternatePath = Path.Combine(directory, Path.Combine("CascLib", Path.Combine(arch, "CascLib.dll"))); +#else string alternatePath = Path.Combine(directory, "CascLib", arch, "CascLib.dll"); +#endif if (File.Exists(mainPath)) return FromFile(alternatePath); @@ -183,12 +191,23 @@ namespace CascLibSharp throw new FileNotFoundException(string.Format("Could not locate a copy of CascLib.dll to load. The following paths were tried:\n\t{0}\n\t{1}\n\t{2}\n\nEnsure that an architecture-appropriate copy of CascLib.dll is included in your project.", mainPath, alternatePath, localPath)); } +#if NET20 || NET35 + private static CascApi? _sharedInstance = null; +#else private static Lazy _sharedInstance = new Lazy(Load); +#endif public static CascApi Instance { get { +#if NET20 || NET35 + if (_sharedInstance == null) + _sharedInstance = Load(); + + return _sharedInstance; +#else return _sharedInstance.Value; +#endif } } diff --git a/SabreTools.Serialization/_EXTERNAL/CascLibSharp/CascStorageContext.cs b/SabreTools.Serialization/_EXTERNAL/CascLibSharp/CascStorageContext.cs index 27665adb..6ef5b531 100644 --- a/SabreTools.Serialization/_EXTERNAL/CascLibSharp/CascStorageContext.cs +++ b/SabreTools.Serialization/_EXTERNAL/CascLibSharp/CascStorageContext.cs @@ -11,10 +11,17 @@ namespace CascLibSharp { private CascApi _api; private CascStorageSafeHandle? _handle; +#if NET20 || NET35 + private bool? _hasListfile = null; + private CascKnownClient? _clientType = null; + private long? _fileCount = null; + private int? _gameBuild = null; +#else private Lazy _hasListfile; private Lazy _clientType; private Lazy _fileCount; private Lazy _gameBuild; +#endif /// /// Creates a new CascStorageContext for the specified path. @@ -29,10 +36,12 @@ namespace CascLibSharp throw new CascException(); _handle.Api = _api; +#if NET40_OR_GREATER || NETCOREAPP || NETSTANDARD2_0_OR_GREATER _hasListfile = new Lazy(CheckHasListfile); _clientType = new Lazy(GetClient); _fileCount = new Lazy(GetFileCount); _gameBuild = new Lazy(GetGameBuild); +#endif } /// @@ -128,7 +137,11 @@ namespace CascLibSharp if (_handle == null || _handle.IsInvalid) throw new ObjectDisposedException("CascStorageContext"); +#if NET20 || NET35 + if (this.GameClient == CascKnownClient.WorldOfWarcraft && string.IsNullOrEmpty(listFilePath)) +#else if (this.GameClient == CascKnownClient.WorldOfWarcraft && string.IsNullOrWhiteSpace(listFilePath)) +#endif throw new ArgumentNullException("listFilePath"); CascFindData cfd = new CascFindData(); @@ -158,7 +171,11 @@ namespace CascLibSharp throw new CascException(); CascStorageFeatures features = (CascStorageFeatures)storageInfo; +#if NET20 || NET35 + if ((features & CascStorageFeatures.HasListfile) != 0) +#else if (features.HasFlag(CascStorageFeatures.HasListfile)) +#endif return true; return false; @@ -209,6 +226,10 @@ namespace CascLibSharp { get { +#if NET20 || NET35 + if (_hasListfile == null) + _hasListfile = CheckHasListfile(); +#endif return _hasListfile.Value; } } @@ -220,6 +241,10 @@ namespace CascLibSharp { get { +#if NET20 || NET35 + if (_fileCount == null) + _fileCount = GetFileCount(); +#endif return _fileCount.Value; } } @@ -231,6 +256,10 @@ namespace CascLibSharp { get { +#if NET20 || NET35 + if (_gameBuild == null) + _gameBuild = GetGameBuild(); +#endif return _gameBuild.Value; } } @@ -242,6 +271,10 @@ namespace CascLibSharp { get { +#if NET20 || NET35 + if (_clientType == null) + _clientType = GetClient(); +#endif return _clientType.Value; } } diff --git a/SabreTools.Serialization/_EXTERNAL/StormLibSharp/MpqArchive.cs b/SabreTools.Serialization/_EXTERNAL/StormLibSharp/MpqArchive.cs index d3866e11..5c3671ce 100644 --- a/SabreTools.Serialization/_EXTERNAL/StormLibSharp/MpqArchive.cs +++ b/SabreTools.Serialization/_EXTERNAL/StormLibSharp/MpqArchive.cs @@ -2,7 +2,6 @@ using System.Collections.Generic; using System.ComponentModel; using System.IO; -using System.IO.MemoryMappedFiles; using StormLibSharp.Native; namespace StormLibSharp @@ -30,24 +29,6 @@ namespace StormLibSharp throw new Win32Exception(); // Implicitly calls GetLastError } - public MpqArchive(MemoryMappedFile file, FileAccess accessType) - { - _accessType = accessType; - string? fileName = Win32Methods.GetFileNameOfMemoryMappedFile(file); - if (fileName == null) - throw new ArgumentException("Could not retrieve the name of the file to initialize."); - - SFileOpenArchiveFlags flags = SFileOpenArchiveFlags.TypeIsMemoryMapped; - if (accessType == FileAccess.Read) - flags |= SFileOpenArchiveFlags.AccessReadOnly; - else - flags |= SFileOpenArchiveFlags.AccessReadWriteShare; - - // constant 2 = SFILE_OPEN_HARD_DISK_FILE - if (!NativeMethods.SFileOpenArchive(fileName, 2, flags, out _handle)) - throw new Win32Exception(); // Implicitly calls GetLastError - } - private MpqArchive(string filePath, MpqArchiveVersion version, MpqFileStreamAttributes listfileAttributes, MpqFileStreamAttributes attributesFileAttributes, int maxFileCount) { if (maxFileCount < 0) diff --git a/SabreTools.Serialization/_EXTERNAL/StormLibSharp/Native/Win32Methods.cs b/SabreTools.Serialization/_EXTERNAL/StormLibSharp/Native/Win32Methods.cs index f0d19f26..bf7ba6d0 100644 --- a/SabreTools.Serialization/_EXTERNAL/StormLibSharp/Native/Win32Methods.cs +++ b/SabreTools.Serialization/_EXTERNAL/StormLibSharp/Native/Win32Methods.cs @@ -1,57 +1,10 @@ -using System; -using System.ComponentModel; -using System.Diagnostics; -using System.IO.MemoryMappedFiles; -using System.Runtime.InteropServices; +using System.Runtime.InteropServices; namespace StormLibSharp.Native { internal static class Win32Methods { - [DllImport("kernel32", ExactSpelling = false, SetLastError = true)] - public static extern uint GetMappedFileName( - IntPtr hProcess, - IntPtr fileHandle, - IntPtr lpFilename, - uint nSize - ); - - [DllImport("kernel32", ExactSpelling = false, SetLastError = true)] - public static extern uint GetFinalPathNameByHandle( - IntPtr hFile, - IntPtr lpszFilePath, - uint cchFilePath, - uint dwFlags - ); - [DllImport("kernel32", SetLastError = false, ExactSpelling = false)] public static extern int GetLastError(); - - public static string? GetFileNameOfMemoryMappedFile(MemoryMappedFile file) - { - const uint size = 522; - IntPtr path = Marshal.AllocCoTaskMem(unchecked((int)size)); // MAX_PATH + 1 char - - string? result; - try - { - // constant 0x2 = VOLUME_NAME_NT - uint test = GetFinalPathNameByHandle(file.SafeMemoryMappedFileHandle.DangerousGetHandle(), path, size, 0x2); - if (test != 0) - throw new Win32Exception(); - - result = Marshal.PtrToStringAuto(path); - } - catch - { - uint test = GetMappedFileName(Process.GetCurrentProcess().Handle, file.SafeMemoryMappedFileHandle.DangerousGetHandle(), path, size); - if (test != 0) - throw new Win32Exception(); - - result = Marshal.PtrToStringAuto(path); - } - - return result; - } } }