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;
- }
}
}