diff --git a/SabreTools.Serialization/_EXTERNAL/CascLibSharp/CascApi.cs b/SabreTools.Serialization/_EXTERNAL/CascLibSharp/CascApi.cs deleted file mode 100644 index 0f6568fd..00000000 --- a/SabreTools.Serialization/_EXTERNAL/CascLibSharp/CascApi.cs +++ /dev/null @@ -1,239 +0,0 @@ -using System; -using System.ComponentModel; -using System.IO; -using System.Reflection; -using System.Runtime.InteropServices; -using CascLibSharp.Native; - -namespace CascLibSharp -{ - internal sealed class CascApi - { - #region Imported method signature type definitions - - [return: MarshalAs(UnmanagedType.I1)] - [UnmanagedFunctionPointer(CallingConvention.Winapi)] - internal delegate bool FnCascOpenStorage( - [MarshalAs(UnmanagedType.LPTStr)] string szDataPath, - uint dwFlags, - out CascStorageSafeHandle phStorage); - - [return: MarshalAs(UnmanagedType.I1)] - [UnmanagedFunctionPointer(CallingConvention.Winapi)] - internal delegate bool FnCascGetStorageInfo( - CascStorageSafeHandle hStorage, - CascStorageInfoClass infoClass, - ref uint pvStorageInfo, - IntPtr cbStorageInfo, - ref uint pcbLengthNeeded); - - [return: MarshalAs(UnmanagedType.I1)] - [UnmanagedFunctionPointer(CallingConvention.Winapi)] - internal delegate bool FnCascCloseStorage(IntPtr hStorage); - - [return: MarshalAs(UnmanagedType.I1)] - [UnmanagedFunctionPointer(CallingConvention.Winapi)] - internal delegate bool FnCascOpenFileByIndexKey( - CascStorageSafeHandle hStorage, - ref QueryKey pIndexKey, - uint dwFlags, - out CascStorageFileSafeHandle phFile); - - [return: MarshalAs(UnmanagedType.I1)] - [UnmanagedFunctionPointer(CallingConvention.Winapi)] - internal delegate bool FnCascOpenFileByEncodingKey( - CascStorageSafeHandle hStorage, - ref QueryKey pEncodingKey, - uint dwFlags, - out CascStorageFileSafeHandle phFile); - - [return: MarshalAs(UnmanagedType.I1)] - [UnmanagedFunctionPointer(CallingConvention.Winapi)] - internal delegate bool FnCascOpenFile( - CascStorageSafeHandle hStorage, - [MarshalAs(UnmanagedType.LPStr)] string szFileName, - uint dwLocale, - uint dwFlags, - out CascStorageFileSafeHandle phFile); - - [UnmanagedFunctionPointer(CallingConvention.Winapi)] - internal delegate uint FnCascGetFileSize( - CascStorageFileSafeHandle hFile, - out uint pdwFileSizeHigh); - [UnmanagedFunctionPointer(CallingConvention.Winapi)] - internal delegate uint FnCascSetFilePointer( - CascStorageFileSafeHandle hFile, - uint lFilePos, - ref uint plFilePosHigh, - SeekOrigin dwMoveMethod); - - [return: MarshalAs(UnmanagedType.I1)] - [UnmanagedFunctionPointer(CallingConvention.Winapi)] - internal delegate bool FnCascReadFile( - CascStorageFileSafeHandle hFile, - IntPtr lpBuffer, - uint dwToRead, - out uint dwRead); - - [return: MarshalAs(UnmanagedType.I1)] - [UnmanagedFunctionPointer(CallingConvention.Winapi)] - internal delegate bool FnCascCloseFile(IntPtr hFile); - - [UnmanagedFunctionPointer(CallingConvention.Winapi)] - internal delegate CascFileEnumerationSafeHandle FnCascFindFirstFile( - CascStorageSafeHandle hStorage, - [MarshalAs(UnmanagedType.LPStr)] string szMask, - ref CascFindData pFindData, - [MarshalAs(UnmanagedType.LPTStr)] string? szListFile); - - [return: MarshalAs(UnmanagedType.I1)] - [UnmanagedFunctionPointer(CallingConvention.Winapi)] - internal delegate bool FnCascFindNextFile( - CascFileEnumerationSafeHandle hFind, - ref CascFindData pFindData); - - [return: MarshalAs(UnmanagedType.I1)] - [UnmanagedFunctionPointer(CallingConvention.Winapi)] - internal delegate bool FnCascFindClose(IntPtr hFind); - - #endregion - - #region Field and method defs - - public readonly FnCascOpenStorage? CascOpenStorage; - public readonly FnCascGetStorageInfo? CascGetStorageInfo; - public readonly FnCascCloseStorage? CascCloseStorage; - - public readonly FnCascOpenFileByIndexKey? CascOpenFileByIndexKey; - public readonly FnCascOpenFileByEncodingKey? CascOpenFileByEncodingKey; - public readonly FnCascOpenFile? CascOpenFile; - - public readonly FnCascGetFileSize? CascGetFileSizeBase; - public long CascGetFileSize(CascStorageFileSafeHandle hFile) - { - uint low = CascGetFileSizeBase!(hFile, out uint high); - long result = (high << 32) | low; - - return result; - } - public readonly FnCascSetFilePointer? CascSetFilePointerBase; - public long CascSetFilePointer(CascStorageFileSafeHandle hFile, long filePos, SeekOrigin moveMethod) - { - uint low, high; - unchecked - { - low = (uint)(filePos & 0xffffffff); - high = (uint)(((ulong)filePos & 0xffffffff00000000) >> 32); - } - - low = CascSetFilePointerBase!(hFile, low, ref high, moveMethod); - - long result = (high << 32) | low; - - return result; - } - public readonly FnCascReadFile? CascReadFile; - public readonly FnCascCloseFile? CascCloseFile; - - public readonly FnCascFindFirstFile? CascFindFirstFile; - public readonly FnCascFindNextFile? CascFindNextFile; - public readonly FnCascFindClose? CascFindClose; - - #endregion - - internal CascApi(IntPtr hModule) - { - SetFn(ref CascOpenStorage, hModule, "CascOpenStorage"); - SetFn(ref CascGetStorageInfo, hModule, "CascGetStorageInfo"); - SetFn(ref CascCloseStorage, hModule, "CascCloseStorage"); - - SetFn(ref CascOpenFileByIndexKey, hModule, "CascOpenFileByIndexKey"); - SetFn(ref CascOpenFileByEncodingKey, hModule, "CascOpenFileByEncodingKey"); - SetFn(ref CascOpenFile, hModule, "CascOpenFile"); - SetFn(ref CascGetFileSizeBase, hModule, "CascGetFileSize"); - SetFn(ref CascSetFilePointerBase, hModule, "CascSetFilePointer"); - SetFn(ref CascReadFile, hModule, "CascReadFile"); - SetFn(ref CascCloseFile, hModule, "CascCloseFile"); - - SetFn(ref CascFindFirstFile, hModule, "CascFindFirstFile"); - SetFn(ref CascFindNextFile, hModule, "CascFindNextFile"); - SetFn(ref CascFindClose, hModule, "CascFindClose"); - } - - private static void SetFn(ref T? target, IntPtr hModule, string procName) - where T : class - { - IntPtr procAddr = NativeMethods.GetProcAddress(hModule, procName); - if (procAddr == IntPtr.Zero) - throw new Win32Exception(); - - target = Marshal.GetDelegateForFunctionPointer(procAddr, typeof(T)) as T; - } - - private static CascApi Load() - { - string myPath = Assembly.GetExecutingAssembly().Location; - string directory = Path.GetDirectoryName(myPath) ?? string.Empty; - string arch = IntPtr.Size == 8 ? "x64" : "x86"; -#if DEBUG - string build = "dbg"; -#else - 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); - - string localPath = Path.Combine(directory, "CascLib.dll"); - if (File.Exists(localPath)) - return FromFile(localPath); - - 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 readonly Lazy _sharedInstance = new(Load); -#endif - public static CascApi Instance - { - get - { -#if NET20 || NET35 - if (_sharedInstance == null) - _sharedInstance = Load(); - - return _sharedInstance; -#else - return _sharedInstance.Value; -#endif - } - } - - public static CascApi FromFile(string filePath) - { - if (!File.Exists(filePath)) - throw new FileNotFoundException("The CascLib.dll library could not be loaded at the specified path.", filePath); - - IntPtr hMod = NativeMethods.LoadLibraryEx(filePath, IntPtr.Zero, 0); - if (hMod == IntPtr.Zero) - throw new Win32Exception(); - - return new CascApi(hMod); - } - } -} diff --git a/SabreTools.Serialization/_EXTERNAL/CascLibSharp/CascException.cs b/SabreTools.Serialization/_EXTERNAL/CascLibSharp/CascException.cs deleted file mode 100644 index 83a94531..00000000 --- a/SabreTools.Serialization/_EXTERNAL/CascLibSharp/CascException.cs +++ /dev/null @@ -1,51 +0,0 @@ -using System.ComponentModel; -using System.Runtime.InteropServices; - -namespace CascLibSharp -{ - /// - /// Represents an exception raised as part of a CASC operation. - /// - public class CascException : Win32Exception - { - /// - /// Creates a new CascException based on the last Win32 error. - /// - public CascException() - : base(Marshal.GetLastWin32Error()) - { - - } - - /// - /// Creates a new CascException based on the specified Win32 error code. - /// - /// A Win32 error code. - public CascException(int errorCode) - : base(errorCode) - { - - } - - /// - /// Creates a new CascException based on the specified message. - /// - /// The error message. - public CascException(string message) - : base(message) - { - - } - - /// - /// Creates a new CascException based on the specified Win32 error code and custom error message. - /// - /// A Win32 error code. - /// The error message. - public CascException(int errorCode, string message) - : base(errorCode, message) - { - - } - } -} diff --git a/SabreTools.Serialization/_EXTERNAL/CascLibSharp/CascFileStream.cs b/SabreTools.Serialization/_EXTERNAL/CascLibSharp/CascFileStream.cs deleted file mode 100644 index 3ab5e5f9..00000000 --- a/SabreTools.Serialization/_EXTERNAL/CascLibSharp/CascFileStream.cs +++ /dev/null @@ -1,164 +0,0 @@ -using System; -using System.Diagnostics; -using System.IO; -using CascLibSharp.Native; - -namespace CascLibSharp -{ - /// - /// Provides a view of the data in a file contained within CASC storage. - /// - public class CascFileStream : Stream - { - private readonly CascStorageFileSafeHandle _handle; - private readonly CascApi _api; - - internal CascFileStream(CascStorageFileSafeHandle? handle, CascApi? api) - { - Debug.Assert(handle != null); - Debug.Assert(!handle!.IsInvalid); - Debug.Assert(api != null); - - _api = api!; - _handle = handle; - } - - private void AssertValidHandle() - { - if (_handle == null || _handle.IsInvalid) - throw new ObjectDisposedException("CascFileStream"); - } - - /// - /// Gets whether this Stream may be read. Always returns true as long as the Stream has not been disposed. - /// - public override bool CanRead - { - get { return _handle != null && !_handle.IsInvalid; } - } - - /// - /// Gets whether this Stream may seek. Always returns true as long as the Stream has not been disposed. - /// - public override bool CanSeek - { - get { return _handle != null && !_handle.IsInvalid; } - } - - /// - /// Gets whether this Stream may write. Always returns false. - /// - public override bool CanWrite - { - get { return false; } - } - - /// - /// Flushes writes to the backing store. This method always throws because writing is not supported. - /// - /// Always thrown. - public override void Flush() - { - throw new NotSupportedException(); - } - - /// - /// Gets the length of the Stream. - /// - /// Thrown if the Stream has been disposed. - public override long Length - { - get - { - AssertValidHandle(); - return _api!.CascGetFileSize(_handle); - } - } - - /// - /// Gets or sets the current position within the Stream. - /// - /// Thrown if the Stream has been disposed. - /// Thrown if the attempt to seek fails. - public override long Position - { - get - { - AssertValidHandle(); - return _api!.CascSetFilePointer(_handle, 0, SeekOrigin.Current); - } - set - { - AssertValidHandle(); - long result = _api!.CascSetFilePointer(_handle, value, SeekOrigin.Begin); - if (result != value) - throw new CascException(); - } - } - - /// - /// Reads data into the buffer. - /// - /// The destination into which the data should be read. - /// The offset into the buffer to read from the current position of the Stream. - /// The number of bytes to read. - /// The number of bytes actually read. - /// Thrown if the Stream has been disposed. - /// Thrown if the CASC provider fails to read. - public override unsafe int Read(byte[] buffer, int offset, int count) - { - AssertValidHandle(); - long len = Length; - if (offset < 0 || offset > len) - throw new ArgumentException(nameof(offset)); - if (count < 0) - throw new ArgumentException(nameof(count)); - if (offset + count > len) - throw new ArgumentException(nameof(count)); - - uint read = 0; - fixed (byte* pBuffer = &buffer[0]) - { - if (!_api.CascReadFile!(_handle, new IntPtr((void*)pBuffer), unchecked((uint)count), out read)) - throw new CascException(); - } - - return unchecked((int)read); - } - - /// - /// Seeks to a specific position within the Stream. - /// - /// The offset from the specified origin to seek. - /// The relative location (beginning, current, or end) from which to seek. - /// The new position in the stream. - /// Thrown if the Stream has been disposed. - public override long Seek(long offset, SeekOrigin origin) - { - AssertValidHandle(); - return _api.CascSetFilePointer(_handle, offset, origin); - } - - /// - /// Sets the length of the Stream. Always throws because writing is not supported. - /// - /// The new length of the Stream. - /// Always thrown. - public override void SetLength(long value) - { - throw new NotSupportedException(); - } - - /// - /// Writes the specified data to the Stream. Always throws because writing is not supported. - /// - /// The data to write. - /// The starting position in the buffer. - /// The number of bytes. - /// Always thrown. - public override void Write(byte[] buffer, int offset, int count) - { - throw new NotSupportedException(); - } - } -} diff --git a/SabreTools.Serialization/_EXTERNAL/CascLibSharp/CascFoundFile.cs b/SabreTools.Serialization/_EXTERNAL/CascLibSharp/CascFoundFile.cs deleted file mode 100644 index d8c966f0..00000000 --- a/SabreTools.Serialization/_EXTERNAL/CascLibSharp/CascFoundFile.cs +++ /dev/null @@ -1,75 +0,0 @@ -using System; -using System.Runtime.InteropServices; - -namespace CascLibSharp -{ - /// - /// Represents a file found in a CASC container search. - /// - public class CascFoundFile - { -#if NET20 || NET35 || NET40 - private readonly WeakReference _ownerContext; -#else - private readonly WeakReference _ownerContext; -#endif - - internal CascFoundFile(string? fileName, IntPtr plainName, byte[] encodingKey, CascLocales locales, long fileSize, CascStorageContext ownerContext) - { - FileName = fileName; - PlainFileName = Marshal.PtrToStringAnsi(plainName); - EncodingKey = encodingKey; - Locales = locales; - FileSize = fileSize; - -#if NET20 || NET35 || NET40 - _ownerContext = new WeakReference(ownerContext); -#else - _ownerContext = new WeakReference(ownerContext); -#endif - } - - /// - /// Gets the full path to this file. - /// - public string? FileName { get; private set; } - - /// - /// Gets the plain (no directory-qualified) file name of this file. - /// - public string? PlainFileName { get; private set; } - - /// - /// Gets the CASC encoding key for this file. - /// - public byte[] EncodingKey { get; private set; } - - /// - /// Gets the locales supported by this resource. - /// - public CascLocales Locales { get; private set; } - - /// - /// Gets the length of the file in bytes. - /// - public long FileSize { get; private set; } - - /// - /// Opens the found file for reading. - /// - /// A CascFileStream, which acts as a Stream for a CASC stored file. - public CascFileStream Open() - { -#if NET20 || NET35 || NET40 - CascStorageContext? context = _ownerContext.Target as CascStorageContext; - if (context == null) - throw new ObjectDisposedException("The owning context has been closed."); -#else - if (!_ownerContext.TryGetTarget(out CascStorageContext? context) || context == null) - throw new ObjectDisposedException("The owning context has been closed."); -#endif - - return context.OpenFileByEncodingKey(EncodingKey); - } - } -} diff --git a/SabreTools.Serialization/_EXTERNAL/CascLibSharp/CascStorageContext.cs b/SabreTools.Serialization/_EXTERNAL/CascLibSharp/CascStorageContext.cs deleted file mode 100644 index 417cc08f..00000000 --- a/SabreTools.Serialization/_EXTERNAL/CascLibSharp/CascStorageContext.cs +++ /dev/null @@ -1,453 +0,0 @@ -using System; -using System.Collections.Generic; -using CascLibSharp.Native; - -namespace CascLibSharp -{ - /// - /// Represents a CASC storage directory. - /// - public class CascStorageContext : IDisposable - { - private readonly 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 readonly Lazy _hasListfile; - private readonly Lazy _clientType; - private readonly Lazy _fileCount; - private readonly Lazy _gameBuild; -#endif - - /// - /// Creates a new CascStorageContext for the specified path. - /// - /// The path to a game's data directory. - /// An example directory is c:\Program Files (x86)\Heroes of the Storm\HeroesData. - public CascStorageContext(string dataPath) - { - _api = CascApi.Instance; - - if (!_api.CascOpenStorage!(dataPath, 0, out _handle) || _handle.IsInvalid) - 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 - } - - /// - /// Opens a file by its fully-qualified name. - /// - /// The name of the file. - /// The file's locale (defaults to English-United States). - /// A CascFileStream, which implements a Stream. - /// Thrown if the CascStorageContext has been disposed. - /// Thrown if the file does not exist within the CASC storage container. - public CascFileStream OpenFile(string fileName, CascLocales locale = CascLocales.EnUs) - { - if (_handle == null || _handle.IsInvalid) - throw new ObjectDisposedException("CascStorageContext"); - - CascStorageFileSafeHandle hFile; - if (!_api.CascOpenFile!(_handle, fileName, (uint)locale, 0, out hFile)) - throw new CascException(); - - hFile.Api = _api; - - return new CascFileStream(hFile, _api); - } - - /// - /// Opens a file by its index key. - /// - /// - /// An index key is a binary representation of a file. I do not know what it comes from; I know that it's used to identify files inside of CASC, - /// but I don't know how someone obtains the index key. They are not produced in the public API of CascLib. - /// - /// The index key to search. - /// A CascFileStream, which implements a Stream. - /// Thrown if the CascStorageContext has been disposed. - /// Thrown if the file does not exist within the CASC storage container. - public CascFileStream OpenFileByIndexKey(byte[] indexKey) - { - if (_handle == null || _handle.IsInvalid) - throw new ObjectDisposedException("CascStorageContext"); - - using CoTaskMem mem = CoTaskMem.FromBytes(indexKey); - - var qk = new QueryKey(); - qk.cbData = unchecked((uint)indexKey.Length); - qk.pbData = mem.Pointer; - - CascStorageFileSafeHandle hFile; - if (!_api.CascOpenFileByIndexKey!(_handle, ref qk, 0, out hFile)) - throw new CascException(); - - hFile.Api = _api; - - return new CascFileStream(hFile, _api); - } - - /// - /// Opens a file by its encoding key. - /// - /// A 16-byte key representing the file. Encoding keys may be obtained via . - /// A CascFileStream, which implements a Stream. - /// Thrown if the CascStorageContext has been disposed. - /// Thrown if the file does not exist within the CASC storage container. - public CascFileStream OpenFileByEncodingKey(byte[] encodingKey) - { - if (_handle == null || _handle.IsInvalid) - throw new ObjectDisposedException("CascStorageContext"); - - using CoTaskMem mem = CoTaskMem.FromBytes(encodingKey); - - var qk = new QueryKey(); - qk.cbData = unchecked((uint)encodingKey.Length); - qk.pbData = mem.Pointer; - - CascStorageFileSafeHandle hFile; - if (!_api.CascOpenFileByEncodingKey!(_handle, ref qk, 0, out hFile)) - throw new CascException(); - - hFile.Api = _api; - - return new CascFileStream(hFile, _api); - } - - /// - /// Searches the files in the CASC container for files that match the specified pattern. - /// - /// The mask to search. * and ? are valid tokens for substitution. - /// A path to a listfile. Required if the CASC container is for World of Warcraft. - /// An enumeration of matching file references in the CASC container. - public IEnumerable SearchFiles(string mask, string? listFilePath = null) - { - if (_handle == null || _handle.IsInvalid) - throw new ObjectDisposedException("CascStorageContext"); - -#if NET20 || NET35 - if (GameClient == CascKnownClient.WorldOfWarcraft && string.IsNullOrEmpty(listFilePath)) -#else - if (GameClient == CascKnownClient.WorldOfWarcraft && string.IsNullOrWhiteSpace(listFilePath)) -#endif - throw new ArgumentNullException("listFilePath"); - - var cfd = new CascFindData(); - using var handle = _api.CascFindFirstFile!(_handle, mask, ref cfd, listFilePath); - if (handle.IsInvalid) - yield break; - - handle.Api = _api; - - yield return cfd.ToFoundFile(this); - - while (_api.CascFindNextFile!(handle, ref cfd)) - { - yield return cfd.ToFoundFile(this); - } - } - - private bool CheckHasListfile() - { - if (_handle == null || _handle.IsInvalid) - throw new ObjectDisposedException("CascStorageContext"); - - uint storageInfo = 0, lengthNeeded = 4; - if (!_api.CascGetStorageInfo!(_handle, CascStorageInfoClass.Features, ref storageInfo, new IntPtr(4), ref lengthNeeded)) - 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; - } - - private CascKnownClient GetClient() - { - if (_handle == null || _handle.IsInvalid) - throw new ObjectDisposedException("CascStorageContext"); - - uint storageInfo = 0, lengthNeeded = 4; - if (!_api.CascGetStorageInfo!(_handle, CascStorageInfoClass.GameInfo, ref storageInfo, new IntPtr(4), ref lengthNeeded)) - throw new CascException(); - - CascGameId gameId = (CascGameId)storageInfo; - - return gameId.ToKnownClient(); - } - - private long GetFileCount() - { - if (_handle == null || _handle.IsInvalid) - throw new ObjectDisposedException("CascStorageContext"); - - uint storageInfo = 0, lengthNeeded = 4; - if (!_api.CascGetStorageInfo!(_handle, CascStorageInfoClass.Features, ref storageInfo, new IntPtr(4), ref lengthNeeded)) - throw new CascException(); - - return storageInfo; - } - - private int GetGameBuild() - { - if (_handle == null || _handle.IsInvalid) - throw new ObjectDisposedException("CascStorageContext"); - - uint storageInfo = 0, lengthNeeded = 4; - if (!_api.CascGetStorageInfo!(_handle, CascStorageInfoClass.Features, ref storageInfo, new IntPtr(4), ref lengthNeeded)) - throw new CascException(); - - return unchecked((int)storageInfo); - } - - /// - /// Gets whether the CASC container has a listfile or if one must be supplied while searching. - /// - public bool HasListfile - { - get - { -#if NET20 || NET35 - if (_hasListfile == null) - _hasListfile = CheckHasListfile(); -#endif - return _hasListfile.Value; - } - } - - /// - /// Gets the number of files in the CASC container. - /// - public long FileCount - { - get - { -#if NET20 || NET35 - if (_fileCount == null) - _fileCount = GetFileCount(); -#endif - return _fileCount.Value; - } - } - - /// - /// Gets the build number of the game. - /// - public int GameBuild - { - get - { -#if NET20 || NET35 - if (_gameBuild == null) - _gameBuild = GetGameBuild(); -#endif - return _gameBuild.Value; - } - } - - /// - /// Gets the game client of the container, if it can be determined. - /// - public CascKnownClient GameClient - { - get - { -#if NET20 || NET35 - if (_clientType == null) - _clientType = GetClient(); -#endif - return _clientType.Value; - } - } - - #region IDisposable implementation - - /// - /// Finalizes the storage context. - /// - ~CascStorageContext() - { - Dispose(false); - } - - /// - /// Disposes the object. - /// - public void Dispose() - { - Dispose(true); - GC.SuppressFinalize(this); - } - - /// - /// Disposes the object, cleaning up the unmanaged objects. - /// - /// True if this is being called via the Dispose() method; false if it's being called by the finalizer. - protected virtual void Dispose(bool disposing) - { - if (disposing) - { - if (_handle != null && !_handle.IsInvalid) - { - _handle.Close(); - _handle = null; - } - } - } - - #endregion - } - - /// - /// Known locales supported by CASC. - /// - [Flags] - public enum CascLocales - { - /// - /// All available locales. - /// - All = -1, - - /// - /// No locales. - /// - /// - None = 0, - /// - /// Unknown - /// - Unknown1 = 1, - - /// - /// English, United States - /// - EnUs = 2, - - /// - /// Korean, South Korea - /// - KoKr = 4, - - /// - /// Reserved (unknown) - /// - Reserved = 8, - - /// - /// French, France - /// - FrFr = 0x10, - - /// - /// German, Germany - /// - DeDe = 0x20, - - /// - /// Chinese, China - /// - ZhCn = 0x40, - - /// - /// Spanish, Spain - /// - EsEs = 0x80, - - /// - /// Chinese, Taiwan - /// - ZhTw = 0x100, - - /// - /// English, Great Britain - /// - EnGb = 0x200, - - /// - /// English, China - /// - EnCn = 0x400, - - /// - /// English, Taiwan - /// - EnTw = 0x800, - - /// - /// Spanish, Mexico - /// - EsMx = 0x1000, - - /// - /// Russian, Russia - /// - RuRu = 0x2000, - - /// - /// Portuguese, Brazil - /// - PtBr = 0x4000, - - /// - /// Italian, Italy - /// - ItIt = 0x8000, - - /// - /// Portuguese, Portugal - /// - PtPt = 0x10000, - } - - /// - /// Known clients supporting CASC - /// - public enum CascKnownClient - { - /// - /// The game client was unrecognized. - /// - Unknown = -1, - - /// - /// Heroes of the Storm - /// - HeroesOfTheStorm = 0, - - /// - /// Diablo 3 - /// - Diablo3 = 1, - - /// - /// World of Warcraft - /// - WorldOfWarcraft = 2, - - /// - /// Overwatch - /// - Overwatch = 3, - - /// - /// Starcraft 2 - /// - Starcraft2 = 4, - } -} diff --git a/SabreTools.Serialization/_EXTERNAL/CascLibSharp/Native/CascFileEnumerationSafeHandle.cs b/SabreTools.Serialization/_EXTERNAL/CascLibSharp/Native/CascFileEnumerationSafeHandle.cs deleted file mode 100644 index 41ea1269..00000000 --- a/SabreTools.Serialization/_EXTERNAL/CascLibSharp/Native/CascFileEnumerationSafeHandle.cs +++ /dev/null @@ -1,29 +0,0 @@ -using System; -using Microsoft.Win32.SafeHandles; - -namespace CascLibSharp.Native -{ - internal class CascFileEnumerationSafeHandle : SafeHandleZeroOrMinusOneIsInvalid - { - public CascFileEnumerationSafeHandle() - : base(true) { } - - public CascFileEnumerationSafeHandle(IntPtr handle) - : this() - { - SetHandle(handle); - } - - protected override bool ReleaseHandle() - { - var api = Api ?? CascApi.Instance; - return api.CascFindClose!(DangerousGetHandle()); - } - - internal CascApi? Api - { - get; - set; - } - } -} diff --git a/SabreTools.Serialization/_EXTERNAL/CascLibSharp/Native/CascStorageFileSafeHandle.cs b/SabreTools.Serialization/_EXTERNAL/CascLibSharp/Native/CascStorageFileSafeHandle.cs deleted file mode 100644 index c72cc2da..00000000 --- a/SabreTools.Serialization/_EXTERNAL/CascLibSharp/Native/CascStorageFileSafeHandle.cs +++ /dev/null @@ -1,32 +0,0 @@ -using System; -using Microsoft.Win32.SafeHandles; - -namespace CascLibSharp.Native -{ - internal class CascStorageFileSafeHandle : SafeHandleZeroOrMinusOneIsInvalid - { - public CascStorageFileSafeHandle() - : base(true) - { - - } - - public CascStorageFileSafeHandle(IntPtr handle) - : this() - { - SetHandle(handle); - } - - protected override bool ReleaseHandle() - { - var api = Api ?? CascApi.Instance; - return api.CascCloseFile!(DangerousGetHandle()); - } - - internal CascApi? Api - { - get; - set; - } - } -} diff --git a/SabreTools.Serialization/_EXTERNAL/CascLibSharp/Native/CascStorageSafeHandle.cs b/SabreTools.Serialization/_EXTERNAL/CascLibSharp/Native/CascStorageSafeHandle.cs deleted file mode 100644 index 1360e96a..00000000 --- a/SabreTools.Serialization/_EXTERNAL/CascLibSharp/Native/CascStorageSafeHandle.cs +++ /dev/null @@ -1,32 +0,0 @@ -using System; -using Microsoft.Win32.SafeHandles; - -namespace CascLibSharp.Native -{ - internal class CascStorageSafeHandle : SafeHandleZeroOrMinusOneIsInvalid - { - public CascStorageSafeHandle() - : base(true) - { - - } - - public CascStorageSafeHandle(IntPtr handle) - : this() - { - SetHandle(handle); - } - - protected override bool ReleaseHandle() - { - var api = Api ?? CascApi.Instance; - return api.CascCloseStorage!(DangerousGetHandle()); - } - - internal CascApi? Api - { - get; - set; - } - } -} diff --git a/SabreTools.Serialization/_EXTERNAL/CascLibSharp/Native/CoTaskMem.cs b/SabreTools.Serialization/_EXTERNAL/CascLibSharp/Native/CoTaskMem.cs deleted file mode 100644 index a65eb891..00000000 --- a/SabreTools.Serialization/_EXTERNAL/CascLibSharp/Native/CoTaskMem.cs +++ /dev/null @@ -1,60 +0,0 @@ -using System; -using System.Runtime.InteropServices; - -namespace CascLibSharp.Native -{ - internal sealed class CoTaskMem : IDisposable - { - private IntPtr _mem; - private int _size; - - public CoTaskMem(int size) - { - _mem = Marshal.AllocCoTaskMem(size); - if (_mem == IntPtr.Zero) - throw new OutOfMemoryException(); - - _size = size; - } - - public static CoTaskMem FromBytes(byte[] b) - { - var result = new CoTaskMem(b.Length); - Marshal.Copy(b, 0, result._mem, b.Length); - - return result; - } - - public IntPtr Pointer - { - get - { - if (_mem == IntPtr.Zero) - throw new ObjectDisposedException("CoTaskMem"); - - return _mem; - } - } - - public void Dispose() - { - Dispose(true); - GC.SuppressFinalize(this); - } - - private void Dispose(bool disposing) - { - if (_mem != IntPtr.Zero) - { - Marshal.FreeCoTaskMem(_mem); - _mem = IntPtr.Zero; - _size = 0; - } - } - - ~CoTaskMem() - { - Dispose(false); - } - } -} diff --git a/SabreTools.Serialization/_EXTERNAL/CascLibSharp/Native/NativeMethods.cs b/SabreTools.Serialization/_EXTERNAL/CascLibSharp/Native/NativeMethods.cs deleted file mode 100644 index 78069085..00000000 --- a/SabreTools.Serialization/_EXTERNAL/CascLibSharp/Native/NativeMethods.cs +++ /dev/null @@ -1,116 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Runtime.InteropServices; - -namespace CascLibSharp.Native -{ - internal static class NativeMethods - { - [DllImport("kernel32", SetLastError = true)] - public static extern IntPtr GetProcAddress(IntPtr hModule, string procName); - - [DllImport("kernel32", SetLastError = true)] - public static extern IntPtr LoadLibraryEx(string lpFileName, IntPtr hFile, uint dwFlags); - } - - internal enum CascStorageInfoClass - { - FileCount, - Features, - GameInfo, - GameBuild, - } - - internal enum CascStorageFeatures - { - None = 0x0, - HasListfile = 0x1, - } - - /* - * #define CASC_GAME_HOTS 0x00010000 // Heroes of the Storm -#define CASC_GAME_WOW6 0x00020000 // World of Warcraft - Warlords of Draenor -#define CASC_GAME_DIABLO3 0x00030000 // Diablo 3 since PTR 2.2.0 -#define CASC_GAME_OVERWATCH 0x00040000 // Overwatch since PTR 24919* - */ - internal enum CascGameId - { - Hots = 0x00010000, - Wow6 = 0x00020000, - Diablo3 = 0x00030000, - Overwatch = 0x00040000, - Starcraft2 = 0x00050000, - } - - internal static class GameConverterExtensions - { - private static readonly Dictionary GameClientMap = new() - { - { CascGameId.Hots, CascKnownClient.HeroesOfTheStorm }, - { CascGameId.Wow6, CascKnownClient.WorldOfWarcraft }, - { CascGameId.Diablo3, CascKnownClient.Diablo3 }, - { CascGameId.Overwatch, CascKnownClient.Overwatch }, - { CascGameId.Starcraft2, CascKnownClient.Starcraft2 }, - }; - - private static readonly Dictionary ClientGameMap = new() - { - { CascKnownClient.HeroesOfTheStorm, CascGameId.Hots }, - { CascKnownClient.WorldOfWarcraft, CascGameId.Wow6 }, - { CascKnownClient.Diablo3, CascGameId.Diablo3 }, - { CascKnownClient.Overwatch, CascGameId.Overwatch }, - { CascKnownClient.Starcraft2, CascGameId.Starcraft2 }, - }; - - public static CascKnownClient ToKnownClient(this CascGameId gameId) - { - if (!GameClientMap.TryGetValue(gameId, out CascKnownClient result)) - result = CascKnownClient.Unknown; - - return result; - } - - public static CascGameId ToGameId(this CascKnownClient knownClient) - { - if (!ClientGameMap.TryGetValue(knownClient, out CascGameId result)) - throw new ArgumentException("Invalid client."); - - return result; - } - } - internal struct QueryKey - { - public IntPtr pbData; - public uint cbData; - } - - internal unsafe struct CascFindData - { - const int MAX_PATH = 260; - - public fixed byte szFileName[MAX_PATH]; - public IntPtr szPlainName; - //public ulong FileNameHash; - public fixed byte EncodingKey[16]; - //public uint dwPackageIndex; - public uint dwLocaleFlags; - public uint dwFileSize; - - public unsafe CascFoundFile ToFoundFile(CascStorageContext ownerContext) - { - string? fileName = null; - fixed (void* pFileName = szFileName) - { - fileName = Marshal.PtrToStringAnsi(new IntPtr(pFileName)); - } - - byte[] encodingKey = new byte[16]; - fixed (void* pEncodingKey = EncodingKey) - { - Marshal.Copy(new IntPtr(pEncodingKey), encodingKey, 0, 16); - } - - return new CascFoundFile(fileName, szPlainName, encodingKey, (CascLocales)dwLocaleFlags, dwFileSize, ownerContext); - } - } -} diff --git a/SabreTools.Serialization/_EXTERNAL/README.MD b/SabreTools.Serialization/_EXTERNAL/README.MD index 06c3af9a..efd71839 100644 --- a/SabreTools.Serialization/_EXTERNAL/README.MD +++ b/SabreTools.Serialization/_EXTERNAL/README.MD @@ -1,10 +1,9 @@ # External Library Notes -This directory contains multiple external libraries. Here is the status of each: +This directory contains external libraries. | Directory | Library | Status | | --------- | ------- | ------ | -| CascLibSharp | [stormlibsharp](https://github.com/robpaveza/stormlibsharp) | Direct code duplicate | | StormLibSharp | [stormlibsharp](https://github.com/robpaveza/stormlibsharp) | Direct code duplicate | -**CascLibSharp** and **StormLibSharp** have multiple changes made to accomodate modern .NET versions. The original code is MIT licensed. +**StormLibSharp** has multiple changes made to accomodate modern .NET versions. The original code is MIT licensed. diff --git a/SabreTools.Serialization/runtimes/win-x64/native/CascLib.dll b/SabreTools.Serialization/runtimes/win-x64/native/CascLib.dll deleted file mode 100644 index cc5b7a4f..00000000 Binary files a/SabreTools.Serialization/runtimes/win-x64/native/CascLib.dll and /dev/null differ diff --git a/SabreTools.Serialization/runtimes/win-x86/native/CascLib.dll b/SabreTools.Serialization/runtimes/win-x86/native/CascLib.dll deleted file mode 100644 index e4b4ff14..00000000 Binary files a/SabreTools.Serialization/runtimes/win-x86/native/CascLib.dll and /dev/null differ