mirror of
https://github.com/SabreTools/BinaryObjectScanner.git
synced 2026-04-27 16:50:46 +00:00
Use submodule for stormlibsharp
This also gets CascLibSharp for free. Maybe keep that in mind
This commit is contained in:
3
.gitmodules
vendored
3
.gitmodules
vendored
@@ -7,3 +7,6 @@
|
||||
[submodule "BurnOutSharp/External/hllib"]
|
||||
path = BurnOutSharp/External/hllib
|
||||
url = https://github.com/RavuAlHemio/hllib.git
|
||||
[submodule "BurnOutSharp/External/stormlibsharp"]
|
||||
path = BurnOutSharp/External/stormlibsharp
|
||||
url = https://github.com/robpaveza/stormlibsharp.git
|
||||
|
||||
@@ -38,7 +38,9 @@
|
||||
External\hllib\HLLib\**\*;
|
||||
External\LessIO\src\LessIO.Tests\**\*;
|
||||
External\libmspack4n\lib\**\*;
|
||||
External\libmspack4n\libmspack4ntest\**\*
|
||||
External\libmspack4n\libmspack4ntest\**\*;
|
||||
External\stormlibsharp\lib\**;
|
||||
External\stormlibsharp\TestConsole\**
|
||||
</DefaultItemExcludes>
|
||||
</PropertyGroup>
|
||||
|
||||
|
||||
BIN
BurnOutSharp/CascLib.dll
Normal file
BIN
BurnOutSharp/CascLib.dll
Normal file
Binary file not shown.
@@ -1,414 +0,0 @@
|
||||
using StormLibSharp.Native;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.ComponentModel;
|
||||
using System.Globalization;
|
||||
using System.IO;
|
||||
using System.IO.MemoryMappedFiles;
|
||||
using System.Linq;
|
||||
using System.Runtime.InteropServices;
|
||||
using System.Text;
|
||||
|
||||
namespace StormLibSharp
|
||||
{
|
||||
public class MpqArchive : IDisposable
|
||||
{
|
||||
private MpqArchiveSafeHandle _handle;
|
||||
private List<MpqFileStream> _openFiles = new List<MpqFileStream>();
|
||||
private FileAccess _accessType;
|
||||
private List<MpqArchiveCompactingEventHandler> _compactCallbacks = new List<MpqArchiveCompactingEventHandler>();
|
||||
private SFILE_COMPACT_CALLBACK _compactCallback;
|
||||
|
||||
#region Constructors / Factories
|
||||
public MpqArchive(string filePath, FileAccess accessType)
|
||||
{
|
||||
_accessType = accessType;
|
||||
SFileOpenArchiveFlags flags = SFileOpenArchiveFlags.TypeIsFile;
|
||||
if (accessType == FileAccess.Read)
|
||||
flags |= SFileOpenArchiveFlags.AccessReadOnly;
|
||||
else
|
||||
flags |= SFileOpenArchiveFlags.AccessReadWriteShare;
|
||||
|
||||
// constant 2 = SFILE_OPEN_HARD_DISK_FILE
|
||||
if (!NativeMethods.SFileOpenArchive(filePath, 2, flags, out _handle))
|
||||
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)
|
||||
throw new ArgumentException("maxFileCount");
|
||||
|
||||
SFileOpenArchiveFlags flags = SFileOpenArchiveFlags.TypeIsFile | SFileOpenArchiveFlags.AccessReadWriteShare;
|
||||
flags |= (SFileOpenArchiveFlags)version;
|
||||
|
||||
//SFILE_CREATE_MPQ create = new SFILE_CREATE_MPQ()
|
||||
//{
|
||||
// cbSize = unchecked((uint)Marshal.SizeOf(typeof(SFILE_CREATE_MPQ))),
|
||||
// dwMaxFileCount = unchecked((uint)maxFileCount),
|
||||
// dwMpqVersion = (uint)version,
|
||||
// dwFileFlags1 = (uint)listfileAttributes,
|
||||
// dwFileFlags2 = (uint)attributesFileAttributes,
|
||||
// dwStreamFlags = (uint)flags,
|
||||
//};
|
||||
|
||||
//if (!NativeMethods.SFileCreateArchive2(filePath, ref create, out _handle))
|
||||
// throw new Win32Exception();
|
||||
if (!NativeMethods.SFileCreateArchive(filePath, (uint)flags, int.MaxValue, out _handle))
|
||||
throw new Win32Exception();
|
||||
}
|
||||
|
||||
public static MpqArchive CreateNew(string mpqPath, MpqArchiveVersion version)
|
||||
{
|
||||
return CreateNew(mpqPath, version, MpqFileStreamAttributes.None, MpqFileStreamAttributes.None, int.MaxValue);
|
||||
}
|
||||
|
||||
public static MpqArchive CreateNew(string mpqPath, MpqArchiveVersion version, MpqFileStreamAttributes listfileAttributes,
|
||||
MpqFileStreamAttributes attributesFileAttributes, int maxFileCount)
|
||||
{
|
||||
return new MpqArchive(mpqPath, version, listfileAttributes, attributesFileAttributes, maxFileCount);
|
||||
}
|
||||
#endregion
|
||||
|
||||
#region Properties
|
||||
// TODO: Move to common location.
|
||||
// This is a global setting, not per-archive setting.
|
||||
|
||||
//public int Locale
|
||||
//{
|
||||
// get
|
||||
// {
|
||||
// throw new NotImplementedException();
|
||||
// }
|
||||
// set
|
||||
// {
|
||||
// throw new NotImplementedException();
|
||||
// }
|
||||
//}
|
||||
|
||||
public long MaxFileCount
|
||||
{
|
||||
get
|
||||
{
|
||||
VerifyHandle();
|
||||
return NativeMethods.SFileGetMaxFileCount(_handle);
|
||||
}
|
||||
set
|
||||
{
|
||||
if (value < 0 || value > uint.MaxValue)
|
||||
throw new ArgumentException("value");
|
||||
VerifyHandle();
|
||||
|
||||
if (!NativeMethods.SFileSetMaxFileCount(_handle, unchecked((uint)value)))
|
||||
throw new Win32Exception();
|
||||
}
|
||||
}
|
||||
|
||||
private void VerifyHandle()
|
||||
{
|
||||
if (_handle == null || _handle.IsInvalid)
|
||||
throw new ObjectDisposedException("MpqArchive");
|
||||
}
|
||||
|
||||
public bool IsPatchedArchive
|
||||
{
|
||||
get
|
||||
{
|
||||
VerifyHandle();
|
||||
return NativeMethods.SFileIsPatchedArchive(_handle);
|
||||
}
|
||||
}
|
||||
#endregion
|
||||
|
||||
public void Flush()
|
||||
{
|
||||
VerifyHandle();
|
||||
if (!NativeMethods.SFileFlushArchive(_handle))
|
||||
throw new Win32Exception();
|
||||
}
|
||||
|
||||
public int AddListFile(string listfileContents)
|
||||
{
|
||||
VerifyHandle();
|
||||
return NativeMethods.SFileAddListFile(_handle, listfileContents);
|
||||
}
|
||||
|
||||
public void AddFileFromDisk(string filePath, string archiveName)
|
||||
{
|
||||
VerifyHandle();
|
||||
|
||||
if (!NativeMethods.SFileAddFile(_handle, filePath, archiveName, 0))
|
||||
throw new Win32Exception();
|
||||
}
|
||||
|
||||
public void Compact(string listfile)
|
||||
{
|
||||
VerifyHandle();
|
||||
if (!NativeMethods.SFileCompactArchive(_handle, listfile, false))
|
||||
throw new Win32Exception();
|
||||
}
|
||||
|
||||
private void _OnCompact(IntPtr pvUserData, uint dwWorkType, ulong bytesProcessed, ulong totalBytes)
|
||||
{
|
||||
MpqArchiveCompactingEventArgs args = new MpqArchiveCompactingEventArgs(dwWorkType, bytesProcessed, totalBytes);
|
||||
OnCompacting(args);
|
||||
}
|
||||
|
||||
protected virtual void OnCompacting(MpqArchiveCompactingEventArgs e)
|
||||
{
|
||||
foreach (var cb in _compactCallbacks)
|
||||
{
|
||||
cb(this, e);
|
||||
}
|
||||
}
|
||||
|
||||
public event MpqArchiveCompactingEventHandler Compacting
|
||||
{
|
||||
add
|
||||
{
|
||||
VerifyHandle();
|
||||
_compactCallback = _OnCompact;
|
||||
if (!NativeMethods.SFileSetCompactCallback(_handle, _compactCallback, IntPtr.Zero))
|
||||
throw new Win32Exception();
|
||||
|
||||
_compactCallbacks.Add(value);
|
||||
}
|
||||
remove
|
||||
{
|
||||
_compactCallbacks.Remove(value);
|
||||
|
||||
VerifyHandle();
|
||||
if (_compactCallbacks.Count == 0)
|
||||
{
|
||||
if (!NativeMethods.SFileSetCompactCallback(_handle, null, IntPtr.Zero))
|
||||
{
|
||||
// Don't do anything here. Remove shouldn't fail hard.
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// TODO: Determine if SFileGetAttributes/SFileSetAttributes/SFileUpdateFileAttributes deserves a projection.
|
||||
// It's unclear - these seem to affect the (attributes) file but I can't figure out exactly what that means.
|
||||
|
||||
public void AddPatchArchive(string patchPath)
|
||||
{
|
||||
VerifyHandle();
|
||||
|
||||
if (!NativeMethods.SFileOpenPatchArchive(_handle, patchPath, null, 0))
|
||||
throw new Win32Exception();
|
||||
}
|
||||
|
||||
public void AddPatchArchives(IEnumerable<string> patchPaths)
|
||||
{
|
||||
if (patchPaths == null)
|
||||
throw new ArgumentNullException("patchPaths");
|
||||
|
||||
VerifyHandle();
|
||||
|
||||
foreach (string path in patchPaths)
|
||||
{
|
||||
// Don't sublet to AddPatchArchive to avoid having to repeatedly call VerifyHandle()
|
||||
if (!NativeMethods.SFileOpenPatchArchive(_handle, path, null, 0))
|
||||
throw new Win32Exception();
|
||||
}
|
||||
}
|
||||
|
||||
public bool HasFile(string fileToFind)
|
||||
{
|
||||
VerifyHandle();
|
||||
|
||||
return NativeMethods.SFileHasFile(_handle, fileToFind);
|
||||
}
|
||||
|
||||
public MpqFileStream OpenFile(string fileName)
|
||||
{
|
||||
VerifyHandle();
|
||||
|
||||
MpqFileSafeHandle fileHandle;
|
||||
if (!NativeMethods.SFileOpenFileEx(_handle, fileName, 0, out fileHandle))
|
||||
throw new Win32Exception();
|
||||
|
||||
MpqFileStream fs = new MpqFileStream(fileHandle, _accessType, this);
|
||||
_openFiles.Add(fs);
|
||||
return fs;
|
||||
}
|
||||
|
||||
public void ExtractFile(string fileToExtract, string destinationPath)
|
||||
{
|
||||
VerifyHandle();
|
||||
|
||||
if (!NativeMethods.SFileExtractFile(_handle, fileToExtract, destinationPath, 0))
|
||||
throw new Win32Exception();
|
||||
}
|
||||
|
||||
public MpqFileVerificationResults VerifyFile(string fileToVerify)
|
||||
{
|
||||
VerifyHandle();
|
||||
|
||||
return (MpqFileVerificationResults)NativeMethods.SFileVerifyFile(_handle, fileToVerify, 0);
|
||||
}
|
||||
|
||||
// TODO: Consider SFileVerifyRawData
|
||||
|
||||
public MpqArchiveVerificationResult VerifyArchive()
|
||||
{
|
||||
VerifyHandle();
|
||||
|
||||
return (MpqArchiveVerificationResult)NativeMethods.SFileVerifyArchive(_handle);
|
||||
}
|
||||
|
||||
|
||||
#region IDisposable implementation
|
||||
public void Dispose()
|
||||
{
|
||||
Dispose(true);
|
||||
}
|
||||
|
||||
~MpqArchive()
|
||||
{
|
||||
Dispose(false);
|
||||
}
|
||||
|
||||
protected virtual void Dispose(bool disposing)
|
||||
{
|
||||
if (disposing)
|
||||
{
|
||||
// Release owned files first.
|
||||
if (_openFiles != null)
|
||||
{
|
||||
foreach (var file in _openFiles)
|
||||
{
|
||||
file.Dispose();
|
||||
}
|
||||
|
||||
_openFiles.Clear();
|
||||
_openFiles = null;
|
||||
}
|
||||
|
||||
// Release
|
||||
if (_handle != null && !_handle.IsInvalid)
|
||||
{
|
||||
_handle.Close();
|
||||
_handle = null;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
internal void RemoveOwnedFile(MpqFileStream file)
|
||||
{
|
||||
_openFiles.Remove(file);
|
||||
}
|
||||
|
||||
#endregion
|
||||
}
|
||||
|
||||
public enum MpqArchiveVersion
|
||||
{
|
||||
Version1 = 0,
|
||||
Version2 = 0x01000000,
|
||||
Version3 = 0x02000000,
|
||||
Version4 = 0x03000000,
|
||||
}
|
||||
|
||||
[Flags]
|
||||
public enum MpqFileStreamAttributes
|
||||
{
|
||||
None = 0x0,
|
||||
}
|
||||
|
||||
[Flags]
|
||||
public enum MpqFileVerificationResults
|
||||
{
|
||||
/// <summary>
|
||||
/// There were no errors with the file.
|
||||
/// </summary>
|
||||
Verified = 0,
|
||||
/// <summary>
|
||||
/// Failed to open the file
|
||||
/// </summary>
|
||||
Error = 0x1,
|
||||
/// <summary>
|
||||
/// Failed to read all data from the file
|
||||
/// </summary>
|
||||
ReadError = 0x2,
|
||||
/// <summary>
|
||||
/// File has sector CRC
|
||||
/// </summary>
|
||||
HasSectorCrc = 0x4,
|
||||
/// <summary>
|
||||
/// Sector CRC check failed
|
||||
/// </summary>
|
||||
SectorCrcError = 0x8,
|
||||
/// <summary>
|
||||
/// File has CRC32
|
||||
/// </summary>
|
||||
HasChecksum = 0x10,
|
||||
/// <summary>
|
||||
/// CRC32 check failed
|
||||
/// </summary>
|
||||
ChecksumError = 0x20,
|
||||
/// <summary>
|
||||
/// File has data MD5
|
||||
/// </summary>
|
||||
HasMd5 = 0x40,
|
||||
/// <summary>
|
||||
/// MD5 check failed
|
||||
/// </summary>
|
||||
Md5Error = 0x80,
|
||||
/// <summary>
|
||||
/// File has raw data MD5
|
||||
/// </summary>
|
||||
HasRawMd5 = 0x100,
|
||||
/// <summary>
|
||||
/// Raw MD5 check failed
|
||||
/// </summary>
|
||||
RawMd5Error = 0x200,
|
||||
}
|
||||
|
||||
public enum MpqArchiveVerificationResult
|
||||
{
|
||||
/// <summary>
|
||||
/// There is no signature in the MPQ
|
||||
/// </summary>
|
||||
NoSignature = 0,
|
||||
/// <summary>
|
||||
/// There was an error during verifying signature (like no memory)
|
||||
/// </summary>
|
||||
VerificationFailed = 1,
|
||||
/// <summary>
|
||||
/// There is a weak signature and sign check passed
|
||||
/// </summary>
|
||||
WeakSignatureVerified = 2,
|
||||
/// <summary>
|
||||
/// There is a weak signature but sign check failed
|
||||
/// </summary>
|
||||
WeakSignatureFailed = 3,
|
||||
/// <summary>
|
||||
/// There is a strong signature and sign check passed
|
||||
/// </summary>
|
||||
StrongSignatureVerified = 4,
|
||||
/// <summary>
|
||||
/// There is a strong signature but sign check failed
|
||||
/// </summary>
|
||||
StrongSignatureFailed = 5,
|
||||
}
|
||||
}
|
||||
@@ -1,49 +0,0 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
|
||||
namespace StormLibSharp
|
||||
{
|
||||
public delegate void MpqArchiveCompactingEventHandler(MpqArchive sender, MpqArchiveCompactingEventArgs e);
|
||||
|
||||
public class MpqArchiveCompactingEventArgs : EventArgs
|
||||
{
|
||||
internal MpqArchiveCompactingEventArgs(uint dwWorkType, ulong processed, ulong total)
|
||||
{
|
||||
unchecked
|
||||
{
|
||||
WorkType = (MpqCompactingWorkType)dwWorkType;
|
||||
BytesProcessed = (long)processed;
|
||||
TotalBytes = (long)total;
|
||||
}
|
||||
}
|
||||
|
||||
public MpqCompactingWorkType WorkType
|
||||
{
|
||||
get;
|
||||
private set;
|
||||
}
|
||||
|
||||
public long BytesProcessed
|
||||
{
|
||||
get;
|
||||
private set;
|
||||
}
|
||||
|
||||
public long TotalBytes
|
||||
{
|
||||
get;
|
||||
private set;
|
||||
}
|
||||
}
|
||||
|
||||
public enum MpqCompactingWorkType
|
||||
{
|
||||
CheckingFiles = 1,
|
||||
CheckingHashTable = 2,
|
||||
CopyingNonMpqData = 3,
|
||||
CompactingFiles = 4,
|
||||
ClosingArchive = 5,
|
||||
}
|
||||
}
|
||||
@@ -1,185 +0,0 @@
|
||||
using StormLibSharp.Native;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.ComponentModel;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading;
|
||||
|
||||
namespace StormLibSharp
|
||||
{
|
||||
public class MpqFileStream : Stream
|
||||
{
|
||||
private MpqFileSafeHandle _handle;
|
||||
private FileAccess _accessType;
|
||||
private MpqArchive _owner;
|
||||
|
||||
internal MpqFileStream(MpqFileSafeHandle handle, FileAccess accessType, MpqArchive owner)
|
||||
{
|
||||
_handle = handle;
|
||||
_accessType = accessType;
|
||||
_owner = owner;
|
||||
}
|
||||
|
||||
private void VerifyHandle()
|
||||
{
|
||||
if (_handle == null || _handle.IsInvalid || _handle.IsClosed)
|
||||
throw new ObjectDisposedException("MpqFileStream");
|
||||
}
|
||||
|
||||
public override bool CanRead
|
||||
{
|
||||
get { VerifyHandle(); return true; }
|
||||
}
|
||||
|
||||
public override bool CanSeek
|
||||
{
|
||||
get { VerifyHandle(); return true; }
|
||||
}
|
||||
|
||||
public override bool CanWrite
|
||||
{
|
||||
get { VerifyHandle(); return _accessType != FileAccess.Read; }
|
||||
}
|
||||
|
||||
public override void Flush()
|
||||
{
|
||||
VerifyHandle();
|
||||
|
||||
_owner.Flush();
|
||||
}
|
||||
|
||||
public override long Length
|
||||
{
|
||||
get
|
||||
{
|
||||
VerifyHandle();
|
||||
|
||||
uint high = 0;
|
||||
uint low = NativeMethods.SFileGetFileSize(_handle, ref high);
|
||||
|
||||
ulong val = (high << 32) | low;
|
||||
return unchecked((long)val);
|
||||
}
|
||||
}
|
||||
|
||||
public override long Position
|
||||
{
|
||||
get
|
||||
{
|
||||
VerifyHandle();
|
||||
|
||||
return NativeMethods.SFileGetFilePointer(_handle);
|
||||
}
|
||||
set
|
||||
{
|
||||
Seek(value, SeekOrigin.Begin);
|
||||
}
|
||||
}
|
||||
|
||||
public override unsafe int Read(byte[] buffer, int offset, int count)
|
||||
{
|
||||
if (buffer == null)
|
||||
throw new ArgumentNullException("buffer");
|
||||
if (offset > buffer.Length || (offset + count) > buffer.Length)
|
||||
throw new ArgumentException();
|
||||
if (count < 0)
|
||||
throw new ArgumentOutOfRangeException("count");
|
||||
|
||||
VerifyHandle();
|
||||
|
||||
bool success;
|
||||
uint read;
|
||||
fixed (byte* pb = &buffer[offset])
|
||||
{
|
||||
NativeOverlapped overlapped = default(NativeOverlapped);
|
||||
success = NativeMethods.SFileReadFile(_handle, new IntPtr(pb), unchecked((uint)count), out read, ref overlapped);
|
||||
}
|
||||
|
||||
if (!success)
|
||||
{
|
||||
int lastError = Win32Methods.GetLastError();
|
||||
if (lastError != 38) // EOF
|
||||
throw new Win32Exception(lastError);
|
||||
}
|
||||
|
||||
return unchecked((int)read);
|
||||
}
|
||||
|
||||
public override long Seek(long offset, SeekOrigin origin)
|
||||
{
|
||||
VerifyHandle();
|
||||
|
||||
uint low, high;
|
||||
low = unchecked((uint)(offset & 0xffffffffu));
|
||||
high = unchecked((uint)(offset >> 32));
|
||||
return NativeMethods.SFileSetFilePointer(_handle, low, ref high, (uint)origin);
|
||||
}
|
||||
|
||||
public override void SetLength(long value)
|
||||
{
|
||||
throw new NotSupportedException();
|
||||
}
|
||||
|
||||
public override unsafe void Write(byte[] buffer, int offset, int count)
|
||||
{
|
||||
VerifyHandle();
|
||||
|
||||
if (buffer == null)
|
||||
throw new ArgumentNullException("buffer");
|
||||
if (offset > buffer.Length || (offset + count) > buffer.Length)
|
||||
throw new ArgumentException();
|
||||
if (count < 0)
|
||||
throw new ArgumentOutOfRangeException("count");
|
||||
|
||||
VerifyHandle();
|
||||
|
||||
bool success;
|
||||
fixed (byte* pb = &buffer[offset])
|
||||
{
|
||||
success = NativeMethods.SFileWriteFile(_handle, new IntPtr(pb), unchecked((uint)count), 0u);
|
||||
}
|
||||
|
||||
if (!success)
|
||||
throw new Win32Exception();
|
||||
}
|
||||
|
||||
protected override void Dispose(bool disposing)
|
||||
{
|
||||
base.Dispose(disposing);
|
||||
|
||||
if (disposing)
|
||||
{
|
||||
if (_handle != null && !_handle.IsInvalid)
|
||||
{
|
||||
_handle.Close();
|
||||
_handle = null;
|
||||
}
|
||||
|
||||
if (_owner != null)
|
||||
{
|
||||
_owner.RemoveOwnedFile(this);
|
||||
_owner = null;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// TODO: Seems like the right place for SFileGetFileInfo, but will need to determine
|
||||
// what value add these features have except for sophisticated debugging purposes
|
||||
// (like in Ladis' MPQ Editor app).
|
||||
|
||||
public int ChecksumCrc32
|
||||
{
|
||||
get
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
}
|
||||
|
||||
public byte[] GetMd5Hash()
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,17 +0,0 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Runtime.InteropServices;
|
||||
using System.Text;
|
||||
|
||||
namespace StormLibSharp.Native
|
||||
{
|
||||
[UnmanagedFunctionPointer(CallingConvention.Winapi)]
|
||||
internal delegate void SFILE_DOWNLOAD_CALLBACK(IntPtr pvUserData, ulong byteOffset, uint dwTotalBytes);
|
||||
|
||||
[UnmanagedFunctionPointer(CallingConvention.Winapi)]
|
||||
internal delegate void SFILE_COMPACT_CALLBACK(IntPtr pvUserData, uint dwWorkType, ulong bytesProcessed, ulong totalBytes);
|
||||
|
||||
[UnmanagedFunctionPointer(CallingConvention.Winapi)]
|
||||
internal delegate void SFILE_ADDFILE_CALLBACK(IntPtr pvUserData, uint dwBytesWritte, uint dwTotalBytes, bool bFinalCall);
|
||||
}
|
||||
@@ -1,26 +0,0 @@
|
||||
using Microsoft.Win32.SafeHandles;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Runtime.InteropServices;
|
||||
using System.Text;
|
||||
|
||||
namespace StormLibSharp.Native
|
||||
{
|
||||
internal sealed class MpqArchiveSafeHandle : SafeHandleZeroOrMinusOneIsInvalid
|
||||
{
|
||||
public MpqArchiveSafeHandle(IntPtr handle)
|
||||
: base(true)
|
||||
{
|
||||
this.SetHandle(handle);
|
||||
}
|
||||
|
||||
public MpqArchiveSafeHandle()
|
||||
: base(true) { }
|
||||
|
||||
protected override bool ReleaseHandle()
|
||||
{
|
||||
return NativeMethods.SFileCloseArchive(this.handle);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,27 +0,0 @@
|
||||
using Microsoft.Win32.SafeHandles;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
|
||||
namespace StormLibSharp.Native
|
||||
{
|
||||
internal sealed class MpqFileSafeHandle : SafeHandleZeroOrMinusOneIsInvalid
|
||||
{
|
||||
public MpqFileSafeHandle(IntPtr handle)
|
||||
: base(true)
|
||||
{
|
||||
this.SetHandle(handle);
|
||||
}
|
||||
|
||||
public MpqFileSafeHandle()
|
||||
: base(true)
|
||||
{
|
||||
}
|
||||
|
||||
protected override bool ReleaseHandle()
|
||||
{
|
||||
return NativeMethods.SFileCloseFile(this.handle);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,497 +0,0 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Runtime.InteropServices;
|
||||
using System.Text;
|
||||
|
||||
namespace StormLibSharp.Native
|
||||
{
|
||||
internal static class NativeMethods
|
||||
{
|
||||
private const string STORMLIB = "stormlib.dll";
|
||||
|
||||
#region Functions for manipulation with StormLib global flags
|
||||
[DllImport(STORMLIB, CallingConvention = CallingConvention.Winapi, ExactSpelling = true, PreserveSig = true, SetLastError = true, ThrowOnUnmappableChar = false)]
|
||||
public static extern uint SFileGetLocale();
|
||||
[DllImport(STORMLIB, CallingConvention = CallingConvention.Winapi, ExactSpelling = true, PreserveSig = true, SetLastError = true, ThrowOnUnmappableChar = false)]
|
||||
public static extern uint SFileSetLocale(uint lcNewLocale);
|
||||
#endregion
|
||||
|
||||
#region Functions for archive manipulation
|
||||
[DllImport(STORMLIB, CallingConvention = CallingConvention.Winapi, ExactSpelling = true, PreserveSig = true, SetLastError = true, ThrowOnUnmappableChar = false)]
|
||||
public static extern bool SFileOpenArchive(
|
||||
[MarshalAs(UnmanagedType.LPTStr)] string szMpqName,
|
||||
uint dwPriority,
|
||||
SFileOpenArchiveFlags dwFlags,
|
||||
out MpqArchiveSafeHandle phMpq
|
||||
);
|
||||
|
||||
[DllImport(STORMLIB, CallingConvention = CallingConvention.Winapi, ExactSpelling = true, PreserveSig = true, SetLastError = true, ThrowOnUnmappableChar = false)]
|
||||
public static extern bool SFileCreateArchive(
|
||||
[MarshalAs(UnmanagedType.LPTStr)] string szMpqName,
|
||||
uint dwCreateFlags,
|
||||
uint dwMaxFileCount,
|
||||
out MpqArchiveSafeHandle phMpq
|
||||
);
|
||||
|
||||
[DllImport(STORMLIB, CallingConvention = CallingConvention.Winapi, ExactSpelling = true, PreserveSig = true, SetLastError = true, ThrowOnUnmappableChar = false)]
|
||||
public static extern bool SFileCreateArchive2(
|
||||
[MarshalAs(UnmanagedType.LPTStr)] string szMpqName,
|
||||
ref SFILE_CREATE_MPQ pCreateInfo,
|
||||
out MpqArchiveSafeHandle phMpq
|
||||
);
|
||||
|
||||
[DllImport(STORMLIB, CallingConvention = CallingConvention.Winapi, ExactSpelling = true, PreserveSig = true, SetLastError = true, ThrowOnUnmappableChar = false)]
|
||||
public static extern bool SFileSetDownloadCallback(
|
||||
MpqArchiveSafeHandle hMpq,
|
||||
[MarshalAs(UnmanagedType.FunctionPtr)] SFILE_DOWNLOAD_CALLBACK pfnCallback,
|
||||
IntPtr pvUserData
|
||||
);
|
||||
|
||||
[DllImport(STORMLIB, CallingConvention = CallingConvention.Winapi, ExactSpelling = true, PreserveSig = true, SetLastError = true, ThrowOnUnmappableChar = false)]
|
||||
public static extern bool SFileFlushArchive(MpqArchiveSafeHandle hMpq);
|
||||
|
||||
[DllImport(STORMLIB, CallingConvention = CallingConvention.Winapi, ExactSpelling = true, PreserveSig = true, SetLastError = true, ThrowOnUnmappableChar = false)]
|
||||
public static extern bool SFileCloseArchive(IntPtr hMpq);
|
||||
|
||||
[DllImport(STORMLIB, CallingConvention = CallingConvention.Winapi, ExactSpelling = true, PreserveSig = true, SetLastError = true, ThrowOnUnmappableChar = false)]
|
||||
public static extern bool SFileCloseArchive(MpqArchiveSafeHandle hMpq);
|
||||
#endregion
|
||||
|
||||
#region Adds another listfile into MPQ.
|
||||
[DllImport(STORMLIB, CallingConvention = CallingConvention.Winapi, ExactSpelling = true, PreserveSig = true, SetLastError = true, ThrowOnUnmappableChar = false)]
|
||||
public static extern int SFileAddListFile(
|
||||
MpqArchiveSafeHandle hMpq,
|
||||
[MarshalAs(UnmanagedType.LPStr)] string szListFile
|
||||
);
|
||||
#endregion
|
||||
|
||||
#region Archive compacting
|
||||
[DllImport(STORMLIB, CallingConvention = CallingConvention.Winapi, ExactSpelling = true, PreserveSig = true, SetLastError = true, ThrowOnUnmappableChar = false)]
|
||||
public static extern bool SFileSetCompactCallback(
|
||||
MpqArchiveSafeHandle hMpq,
|
||||
SFILE_COMPACT_CALLBACK compactCB,
|
||||
IntPtr pvUserData
|
||||
);
|
||||
|
||||
[DllImport(STORMLIB, CallingConvention = CallingConvention.Winapi, ExactSpelling = true, PreserveSig = true, SetLastError = true, ThrowOnUnmappableChar = false)]
|
||||
public static extern bool SFileCompactArchive(
|
||||
MpqArchiveSafeHandle hMpq,
|
||||
[MarshalAs(UnmanagedType.LPStr)] string szListFile,
|
||||
bool bReserved
|
||||
);
|
||||
#endregion
|
||||
|
||||
#region Maximum file count
|
||||
[DllImport(STORMLIB, CallingConvention = CallingConvention.Winapi, ExactSpelling = true, PreserveSig = true, SetLastError = true, ThrowOnUnmappableChar = false)]
|
||||
public static extern uint SFileGetMaxFileCount(MpqArchiveSafeHandle hMpq);
|
||||
|
||||
[DllImport(STORMLIB, CallingConvention = CallingConvention.Winapi, ExactSpelling = true, PreserveSig = true, SetLastError = true, ThrowOnUnmappableChar = false)]
|
||||
public static extern bool SFileSetMaxFileCount(MpqArchiveSafeHandle hMpq, uint dwMaxFileCount);
|
||||
#endregion
|
||||
|
||||
#region Changing (attributes) file
|
||||
[DllImport(STORMLIB, CallingConvention = CallingConvention.Winapi, ExactSpelling = true, PreserveSig = true, SetLastError = true, ThrowOnUnmappableChar = false)]
|
||||
public static extern uint SFileGetAttributes(MpqArchiveSafeHandle hMpq);
|
||||
|
||||
[DllImport(STORMLIB, CallingConvention = CallingConvention.Winapi, ExactSpelling = true, PreserveSig = true, SetLastError = true, ThrowOnUnmappableChar = false)]
|
||||
public static extern bool SFileSetAttributes(MpqArchiveSafeHandle hMpq, uint dwFlags);
|
||||
|
||||
[DllImport(STORMLIB, CallingConvention = CallingConvention.Winapi, ExactSpelling = true, PreserveSig = true, SetLastError = true, ThrowOnUnmappableChar = false)]
|
||||
public static extern bool SFileUpdateFileAttributes(
|
||||
MpqArchiveSafeHandle hMpq,
|
||||
[MarshalAs(UnmanagedType.LPStr)] string szFileName
|
||||
);
|
||||
#endregion
|
||||
|
||||
#region Functions for manipulation with patch archives
|
||||
[DllImport(STORMLIB, CallingConvention = CallingConvention.Winapi, ExactSpelling = true, PreserveSig = true, SetLastError = true, ThrowOnUnmappableChar = false)]
|
||||
public static extern bool SFileOpenPatchArchive(
|
||||
MpqArchiveSafeHandle hMpq,
|
||||
[MarshalAs(UnmanagedType.LPTStr)] string szPatchMpqName,
|
||||
[MarshalAs(UnmanagedType.LPStr)] string szPatchPathPrefix,
|
||||
uint dwFlags
|
||||
);
|
||||
|
||||
[DllImport(STORMLIB, CallingConvention = CallingConvention.Winapi, ExactSpelling = true, PreserveSig = true, SetLastError = true, ThrowOnUnmappableChar = false)]
|
||||
public static extern bool SFileIsPatchedArchive(MpqArchiveSafeHandle hMpq);
|
||||
#endregion
|
||||
|
||||
#region Functions for file manipulation
|
||||
[DllImport(STORMLIB, CallingConvention = CallingConvention.Winapi, ExactSpelling = true, PreserveSig = true, SetLastError = true, ThrowOnUnmappableChar = false)]
|
||||
public static extern bool SFileHasFile(
|
||||
MpqArchiveSafeHandle hMpq,
|
||||
[MarshalAs(UnmanagedType.LPStr)] string szFileName
|
||||
);
|
||||
|
||||
[DllImport(STORMLIB, CallingConvention = CallingConvention.Winapi, ExactSpelling = true, PreserveSig = true, SetLastError = true, ThrowOnUnmappableChar = false)]
|
||||
public static extern bool SFileOpenFileEx(
|
||||
MpqArchiveSafeHandle hMpq,
|
||||
[MarshalAs(UnmanagedType.LPStr)] string szFileName,
|
||||
uint dwSearchScope,
|
||||
out MpqFileSafeHandle phFile
|
||||
);
|
||||
|
||||
[DllImport(STORMLIB, CallingConvention = CallingConvention.Winapi, ExactSpelling = true, PreserveSig = true, SetLastError = true, ThrowOnUnmappableChar = false)]
|
||||
public static extern uint SFileGetFileSize(MpqFileSafeHandle hFile, ref uint pdwFileSizeHigh);
|
||||
|
||||
public static unsafe uint SFileGetFilePointer(
|
||||
MpqFileSafeHandle hFile
|
||||
)
|
||||
{
|
||||
if (hFile.IsInvalid || hFile.IsClosed)
|
||||
throw new InvalidOperationException();
|
||||
|
||||
IntPtr handle = hFile.DangerousGetHandle();
|
||||
_TMPQFileHeader* header = (_TMPQFileHeader*)handle.ToPointer();
|
||||
return header->dwFilePos;
|
||||
}
|
||||
|
||||
//public static unsafe uint SFileGetFileSize(
|
||||
// MpqFileSafeHandle hFile
|
||||
// )
|
||||
//{
|
||||
// if (hFile.IsInvalid || hFile.IsClosed)
|
||||
// throw new InvalidOperationException();
|
||||
|
||||
// IntPtr handle = hFile.DangerousGetHandle();
|
||||
// _TMPQFileHeader* header = (_TMPQFileHeader*)handle.ToPointer();
|
||||
// return header->pFileEntry->dwFileSize;
|
||||
//}
|
||||
|
||||
[DllImport(STORMLIB, CallingConvention = CallingConvention.Winapi, ExactSpelling = true, PreserveSig = true, SetLastError = true, ThrowOnUnmappableChar = false)]
|
||||
public static extern uint SFileSetFilePointer(
|
||||
MpqFileSafeHandle hFile,
|
||||
uint lFilePos,
|
||||
ref uint plFilePosHigh,
|
||||
uint dwMoveMethod
|
||||
);
|
||||
|
||||
[DllImport(STORMLIB, CallingConvention = CallingConvention.Winapi, ExactSpelling = true, PreserveSig = true, SetLastError = true, ThrowOnUnmappableChar = false)]
|
||||
public static extern bool SFileReadFile(
|
||||
MpqFileSafeHandle hFile,
|
||||
IntPtr lpBuffer,
|
||||
uint dwToRead,
|
||||
out uint pdwRead,
|
||||
ref System.Threading.NativeOverlapped lpOverlapped
|
||||
);
|
||||
|
||||
[DllImport(STORMLIB, CallingConvention = CallingConvention.Winapi, ExactSpelling = true, PreserveSig = true, SetLastError = true, ThrowOnUnmappableChar = false)]
|
||||
public static extern bool SFileCloseFile(IntPtr hFile);
|
||||
|
||||
[DllImport(STORMLIB, CallingConvention = CallingConvention.Winapi, ExactSpelling = true, PreserveSig = true, SetLastError = true, ThrowOnUnmappableChar = false)]
|
||||
public static extern bool SFileCloseFile(MpqFileSafeHandle hFile);
|
||||
|
||||
#region Retrieving info about a file in the archive
|
||||
[DllImport(STORMLIB, CallingConvention = CallingConvention.Winapi, ExactSpelling = true, PreserveSig = true, SetLastError = true, ThrowOnUnmappableChar = false)]
|
||||
public static extern bool SFileGetFileInfo(
|
||||
IntPtr hMpqOrFile,
|
||||
SFileInfoClass InfoClass,
|
||||
IntPtr pvFileInfo,
|
||||
uint cbFileInfoSize,
|
||||
out uint pcbLengthNeeded
|
||||
);
|
||||
|
||||
[DllImport(STORMLIB, CallingConvention = CallingConvention.Winapi, ExactSpelling = true, PreserveSig = true, SetLastError = true, ThrowOnUnmappableChar = false)]
|
||||
public static extern bool SFileGetFileInfo(
|
||||
MpqArchiveSafeHandle hMpqOrFile,
|
||||
SFileInfoClass InfoClass,
|
||||
IntPtr pvFileInfo,
|
||||
uint cbFileInfoSize,
|
||||
out uint pcbLengthNeeded
|
||||
);
|
||||
|
||||
[DllImport(STORMLIB, CallingConvention = CallingConvention.Winapi, ExactSpelling = true, PreserveSig = true, SetLastError = true, ThrowOnUnmappableChar = false)]
|
||||
public static extern bool SFileGetFileInfo(
|
||||
MpqFileSafeHandle hMpqOrFile,
|
||||
SFileInfoClass InfoClass,
|
||||
IntPtr pvFileInfo,
|
||||
uint cbFileInfoSize,
|
||||
out uint pcbLengthNeeded
|
||||
);
|
||||
|
||||
[DllImport(STORMLIB, CallingConvention = CallingConvention.Winapi, ExactSpelling = true, PreserveSig = true, SetLastError = true, ThrowOnUnmappableChar = false)]
|
||||
public static extern bool SFileGetFileName(
|
||||
MpqFileSafeHandle hFile,
|
||||
[MarshalAs(UnmanagedType.LPStr)] out string szFileName
|
||||
);
|
||||
|
||||
[DllImport(STORMLIB, CallingConvention = CallingConvention.Winapi, ExactSpelling = true, PreserveSig = true, SetLastError = true, ThrowOnUnmappableChar = false)]
|
||||
public static extern bool SFileFreeFileInfo(
|
||||
IntPtr pvFileInfo,
|
||||
SFileInfoClass infoClass
|
||||
);
|
||||
#endregion
|
||||
|
||||
[DllImport(STORMLIB, CallingConvention = CallingConvention.Winapi, ExactSpelling = true, PreserveSig = true, SetLastError = true, ThrowOnUnmappableChar = false)]
|
||||
public static extern bool SFileExtractFile(
|
||||
MpqArchiveSafeHandle hMpq,
|
||||
[MarshalAs(UnmanagedType.LPStr)] string szToExtract,
|
||||
[MarshalAs(UnmanagedType.LPTStr)] string szExtracted,
|
||||
uint dwSearchScope
|
||||
);
|
||||
|
||||
#endregion
|
||||
|
||||
#region Functions for file and archive verification
|
||||
[DllImport(STORMLIB, CallingConvention = CallingConvention.Winapi, ExactSpelling = true, PreserveSig = true, SetLastError = true, ThrowOnUnmappableChar = false)]
|
||||
public static extern bool SFileGetFileChecksums(
|
||||
MpqArchiveSafeHandle hMpq,
|
||||
[MarshalAs(UnmanagedType.LPStr)] string szFileName,
|
||||
out uint pdwCrc32,
|
||||
IntPtr pMD5
|
||||
);
|
||||
|
||||
[DllImport(STORMLIB, CallingConvention = CallingConvention.Winapi, ExactSpelling = true, PreserveSig = true, SetLastError = true, ThrowOnUnmappableChar = false)]
|
||||
public static extern uint SFileVerifyFile(
|
||||
MpqArchiveSafeHandle hMpq,
|
||||
[MarshalAs(UnmanagedType.LPStr)] string szFileName,
|
||||
uint dwFlags
|
||||
);
|
||||
|
||||
[DllImport(STORMLIB, CallingConvention = CallingConvention.Winapi, ExactSpelling = true, PreserveSig = true, SetLastError = true, ThrowOnUnmappableChar = false)]
|
||||
public static extern int SFileVerifyRawData(
|
||||
MpqArchiveSafeHandle hMpq,
|
||||
uint dwWhatToVerify,
|
||||
[MarshalAs(UnmanagedType.LPStr)] string szFileName
|
||||
);
|
||||
|
||||
[DllImport(STORMLIB, CallingConvention = CallingConvention.Winapi, ExactSpelling = true, PreserveSig = true, SetLastError = true, ThrowOnUnmappableChar = false)]
|
||||
public static extern uint SFileVerifyArchive(MpqArchiveSafeHandle hMpq);
|
||||
#endregion
|
||||
|
||||
#region Functions for file searching
|
||||
[DllImport(STORMLIB, CallingConvention = CallingConvention.Winapi, ExactSpelling = true, PreserveSig = true, SetLastError = true, ThrowOnUnmappableChar = false)]
|
||||
public static extern IntPtr SFileFindFirstFile(
|
||||
MpqArchiveSafeHandle hMpq,
|
||||
[MarshalAs(UnmanagedType.LPStr)] string szMask,
|
||||
out _SFILE_FIND_DATA lpFindFileData,
|
||||
[MarshalAs(UnmanagedType.LPStr)] string szListFile
|
||||
);
|
||||
|
||||
[DllImport(STORMLIB, CallingConvention = CallingConvention.Winapi, ExactSpelling = true, PreserveSig = true, SetLastError = true, ThrowOnUnmappableChar = false)]
|
||||
public static extern bool SFileFindNextFile(
|
||||
IntPtr hFind,
|
||||
[In, Out] ref _SFILE_FIND_DATA lpFindFileData
|
||||
);
|
||||
|
||||
[DllImport(STORMLIB, CallingConvention = CallingConvention.Winapi, ExactSpelling = true, PreserveSig = true, SetLastError = true, ThrowOnUnmappableChar = false)]
|
||||
public static extern bool SFileFindClose(IntPtr hFind);
|
||||
|
||||
[DllImport(STORMLIB, CallingConvention = CallingConvention.Winapi, ExactSpelling = true, PreserveSig = true, SetLastError = true, ThrowOnUnmappableChar = false)]
|
||||
public static extern IntPtr SListFileFindFirstFile(
|
||||
MpqArchiveSafeHandle hMpq,
|
||||
[MarshalAs(UnmanagedType.LPStr)] string szListFile,
|
||||
[MarshalAs(UnmanagedType.LPStr)] string szMask,
|
||||
[In, Out] ref _SFILE_FIND_DATA lpFindFileData
|
||||
);
|
||||
|
||||
[DllImport(STORMLIB, CallingConvention = CallingConvention.Winapi, ExactSpelling = true, PreserveSig = true, SetLastError = true, ThrowOnUnmappableChar = false)]
|
||||
public static extern bool SListFileFindNextFile(
|
||||
IntPtr hFind,
|
||||
[In, Out] ref _SFILE_FIND_DATA lpFindFileData
|
||||
);
|
||||
|
||||
[DllImport(STORMLIB, CallingConvention = CallingConvention.Winapi, ExactSpelling = true, PreserveSig = true, SetLastError = true, ThrowOnUnmappableChar = false)]
|
||||
public static extern bool SListFileFindClose(IntPtr hFind);
|
||||
#endregion
|
||||
|
||||
#region Locale support
|
||||
[DllImport(STORMLIB, CallingConvention = CallingConvention.Winapi, ExactSpelling = true, PreserveSig = true, SetLastError = true, ThrowOnUnmappableChar = false)]
|
||||
public static extern int SFileEnumLocales(
|
||||
MpqArchiveSafeHandle hMpq,
|
||||
[MarshalAs(UnmanagedType.LPStr)] string szFileName,
|
||||
IntPtr plcLocales,
|
||||
ref uint pdwMaxLocales,
|
||||
uint dwSearchScope
|
||||
);
|
||||
#endregion
|
||||
|
||||
#region Support for adding files to the MPQ
|
||||
[DllImport(STORMLIB, CallingConvention = CallingConvention.Winapi, ExactSpelling = true, PreserveSig = true, SetLastError = true, ThrowOnUnmappableChar = false)]
|
||||
public static extern bool SFileCreateFile(
|
||||
MpqArchiveSafeHandle hMpq,
|
||||
[MarshalAs(UnmanagedType.LPStr)] string szArchiveName,
|
||||
ulong fileTime,
|
||||
uint dwFileSize,
|
||||
uint lcLocale,
|
||||
uint dwFlags,
|
||||
out IntPtr phFile
|
||||
);
|
||||
|
||||
[DllImport(STORMLIB, CallingConvention = CallingConvention.Winapi, ExactSpelling = true, PreserveSig = true, SetLastError = true, ThrowOnUnmappableChar = false)]
|
||||
public static extern bool SFileWriteFile(
|
||||
MpqFileSafeHandle hFile,
|
||||
IntPtr pvData,
|
||||
uint dwSize,
|
||||
uint dwCompression
|
||||
);
|
||||
|
||||
[DllImport(STORMLIB, CallingConvention = CallingConvention.Winapi, ExactSpelling = true, PreserveSig = true, SetLastError = true, ThrowOnUnmappableChar = false)]
|
||||
public static extern bool SFileFinishFile(MpqFileSafeHandle hFile);
|
||||
|
||||
[DllImport(STORMLIB, CallingConvention = CallingConvention.Winapi, ExactSpelling = true, PreserveSig = true, SetLastError = true, ThrowOnUnmappableChar = false)]
|
||||
public static extern bool SFileAddFileEx(
|
||||
MpqArchiveSafeHandle hMpq,
|
||||
[MarshalAs(UnmanagedType.LPTStr)] string szFileName,
|
||||
[MarshalAs(UnmanagedType.LPStr)] string szArchivedName,
|
||||
uint dwFlags,
|
||||
uint dwCompression,
|
||||
uint dwCompressionNext
|
||||
);
|
||||
|
||||
[DllImport(STORMLIB, CallingConvention = CallingConvention.Winapi, ExactSpelling = true, PreserveSig = true, SetLastError = true, ThrowOnUnmappableChar = false)]
|
||||
public static extern bool SFileAddFile(
|
||||
MpqArchiveSafeHandle hMpq,
|
||||
[MarshalAs(UnmanagedType.LPTStr)] string szFileName,
|
||||
[MarshalAs(UnmanagedType.LPStr)] string szArchivedName,
|
||||
uint dwFlags
|
||||
);
|
||||
|
||||
[DllImport(STORMLIB, CallingConvention = CallingConvention.Winapi, ExactSpelling = true, PreserveSig = true, SetLastError = true, ThrowOnUnmappableChar = false)]
|
||||
public static extern bool SFileAddWave(
|
||||
MpqArchiveSafeHandle hMpq,
|
||||
[MarshalAs(UnmanagedType.LPTStr)] string szFileName,
|
||||
[MarshalAs(UnmanagedType.LPStr)] string szArchivedName,
|
||||
uint dwFlags,
|
||||
uint dwQuality
|
||||
);
|
||||
|
||||
[DllImport(STORMLIB, CallingConvention = CallingConvention.Winapi, ExactSpelling = true, PreserveSig = true, SetLastError = true, ThrowOnUnmappableChar = false)]
|
||||
public static extern bool SFileRemoveFile(
|
||||
MpqArchiveSafeHandle hMpq,
|
||||
[MarshalAs(UnmanagedType.LPStr)] string szFileName,
|
||||
uint dwSearchScope
|
||||
);
|
||||
|
||||
[DllImport(STORMLIB, CallingConvention = CallingConvention.Winapi, ExactSpelling = true, PreserveSig = true, SetLastError = true, ThrowOnUnmappableChar = false)]
|
||||
public static extern bool SFileRenameFile(
|
||||
MpqArchiveSafeHandle hMpq,
|
||||
[MarshalAs(UnmanagedType.LPStr)] string szOldFileName,
|
||||
[MarshalAs(UnmanagedType.LPStr)] string szNewFileName
|
||||
);
|
||||
|
||||
[DllImport(STORMLIB, CallingConvention = CallingConvention.Winapi, ExactSpelling = true, PreserveSig = true, SetLastError = true, ThrowOnUnmappableChar = false)]
|
||||
public static extern bool SFileSetFileLocale(
|
||||
MpqFileSafeHandle hFile,
|
||||
uint lcNewLocale
|
||||
);
|
||||
|
||||
[DllImport(STORMLIB, CallingConvention = CallingConvention.Winapi, ExactSpelling = true, PreserveSig = true, SetLastError = true, ThrowOnUnmappableChar = false)]
|
||||
public static extern bool SFileSetDataCompression(uint DataCompression);
|
||||
|
||||
[DllImport(STORMLIB, CallingConvention = CallingConvention.Winapi, ExactSpelling = true, PreserveSig = true, SetLastError = true, ThrowOnUnmappableChar = false)]
|
||||
public static extern bool SFileSetAddFileCallback(
|
||||
MpqArchiveSafeHandle hMpq,
|
||||
SFILE_ADDFILE_CALLBACK AddFileCB,
|
||||
IntPtr pvUserData
|
||||
);
|
||||
#endregion
|
||||
|
||||
#region Compression and decompression
|
||||
[DllImport(STORMLIB, CallingConvention = CallingConvention.Winapi, ExactSpelling = true, PreserveSig = true, SetLastError = true, ThrowOnUnmappableChar = false)]
|
||||
public static extern int SCompImplode(
|
||||
IntPtr pvOutBuffer,
|
||||
ref int pcbOutBuffer,
|
||||
IntPtr pvInBuffer,
|
||||
int cbInBuffer
|
||||
);
|
||||
|
||||
[DllImport(STORMLIB, CallingConvention = CallingConvention.Winapi, ExactSpelling = true, PreserveSig = true, SetLastError = true, ThrowOnUnmappableChar = false)]
|
||||
public static extern int SCompExplode(
|
||||
IntPtr pvOutBuffer,
|
||||
ref int pcbOutBuffer,
|
||||
IntPtr pvInBuffer,
|
||||
int cbInBuffer
|
||||
);
|
||||
|
||||
[DllImport(STORMLIB, CallingConvention = CallingConvention.Winapi, ExactSpelling = true, PreserveSig = true, SetLastError = true, ThrowOnUnmappableChar = false)]
|
||||
public static extern int SCompCompress(
|
||||
IntPtr pvOutBuffer,
|
||||
ref int pcbOutBuffer,
|
||||
IntPtr pvInBuffer,
|
||||
int cbInBuffer,
|
||||
uint uCompressionMask,
|
||||
int nCmpType,
|
||||
int nCmpLevel
|
||||
);
|
||||
|
||||
[DllImport(STORMLIB, CallingConvention = CallingConvention.Winapi, ExactSpelling = true, PreserveSig = true, SetLastError = true, ThrowOnUnmappableChar = false)]
|
||||
public static extern int SCompDecompress(
|
||||
IntPtr pvOutBuffer,
|
||||
ref int pcbOutBuffer,
|
||||
IntPtr pvInBuffer,
|
||||
int cbInBuffer
|
||||
);
|
||||
|
||||
[DllImport(STORMLIB, CallingConvention = CallingConvention.Winapi, ExactSpelling = true, PreserveSig = true, SetLastError = true, ThrowOnUnmappableChar = false)]
|
||||
public static extern int SCompDecompress2(
|
||||
IntPtr pvOutBuffer,
|
||||
ref int pcbOutBuffer,
|
||||
IntPtr pvInBuffer,
|
||||
int cbInBuffer
|
||||
);
|
||||
|
||||
|
||||
#endregion
|
||||
}
|
||||
|
||||
#pragma warning disable 0169,0649
|
||||
internal struct SFILE_CREATE_MPQ
|
||||
{
|
||||
public uint cbSize;
|
||||
public uint dwMpqVersion;
|
||||
private IntPtr pvUserData;
|
||||
private uint cbUserData;
|
||||
public uint dwStreamFlags;
|
||||
public uint dwFileFlags1;
|
||||
public uint dwFileFlags2;
|
||||
public uint dwAttrFlags;
|
||||
public uint dwSectorSize;
|
||||
public uint dwRawChunkSize;
|
||||
public uint dwMaxFileCount;
|
||||
}
|
||||
|
||||
internal unsafe struct _SFILE_FIND_DATA
|
||||
{
|
||||
public fixed char cFileName[260]; // Full name of the found file
|
||||
|
||||
public IntPtr szPlainName; // Plain name of the found file
|
||||
public uint dwHashIndex; // Hash table index for the file
|
||||
public uint dwBlockIndex; // Block table index for the file
|
||||
public uint dwFileSize; // File size in bytes
|
||||
public uint dwFileFlags; // MPQ file flags
|
||||
public uint dwCompSize; // Compressed file size
|
||||
public uint dwFileTimeLo; // Low 32-bits of the file time (0 if not present)
|
||||
public uint dwFileTimeHi; // High 32-bits of the file time (0 if not present)
|
||||
public uint lcLocale; // Locale version
|
||||
}
|
||||
|
||||
internal unsafe struct _TFileEntry
|
||||
{
|
||||
public ulong FileNameHash;
|
||||
public ulong ByteOffset;
|
||||
public ulong FileTime;
|
||||
public uint dwHashIndex;
|
||||
public uint dwFileSize;
|
||||
public uint dwCmpSize;
|
||||
public uint dwFlags;
|
||||
public ushort lcLocale;
|
||||
public ushort wPlatform;
|
||||
public uint dwCrc32;
|
||||
public fixed byte md5[16];
|
||||
public IntPtr szFileName;
|
||||
}
|
||||
|
||||
// Provides enough of _TMPQFile to get to the file size and current position.
|
||||
internal unsafe struct _TMPQFileHeader
|
||||
{
|
||||
public IntPtr pStream;
|
||||
public IntPtr ha;
|
||||
public _TFileEntry* pFileEntry;
|
||||
public uint dwFileKey;
|
||||
public uint dwFilePos;
|
||||
}
|
||||
#pragma warning restore 0169,0649
|
||||
|
||||
}
|
||||
@@ -1,70 +0,0 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
|
||||
namespace StormLibSharp.Native
|
||||
{
|
||||
internal enum SFileInfoClass
|
||||
{
|
||||
// Info classes for archives
|
||||
SFileMpqFileName, // Name of the archive file (TCHAR [])
|
||||
SFileMpqStreamBitmap, // Array of bits, each bit means availability of one block (BYTE [])
|
||||
SFileMpqUserDataOffset, // Offset of the user data header (ULONGLONG)
|
||||
SFileMpqUserDataHeader, // Raw (unfixed) user data header (TMPQUserData)
|
||||
SFileMpqUserData, // MPQ USer data, without the header (BYTE [])
|
||||
SFileMpqHeaderOffset, // Offset of the MPQ header (ULONGLONG)
|
||||
SFileMpqHeaderSize, // Fixed size of the MPQ header
|
||||
SFileMpqHeader, // Raw (unfixed) archive header (TMPQHeader)
|
||||
SFileMpqHetTableOffset, // Offset of the HET table, relative to MPQ header (ULONGLONG)
|
||||
SFileMpqHetTableSize, // Compressed size of the HET table (ULONGLONG)
|
||||
SFileMpqHetHeader, // HET table header (TMPQHetHeader)
|
||||
SFileMpqHetTable, // HET table as pointer. Must be freed using SFileFreeFileInfo
|
||||
SFileMpqBetTableOffset, // Offset of the BET table, relative to MPQ header (ULONGLONG)
|
||||
SFileMpqBetTableSize, // Compressed size of the BET table (ULONGLONG)
|
||||
SFileMpqBetHeader, // BET table header, followed by the flags (TMPQBetHeader + DWORD[])
|
||||
SFileMpqBetTable, // BET table as pointer. Must be freed using SFileFreeFileInfo
|
||||
SFileMpqHashTableOffset, // Hash table offset, relative to MPQ header (ULONGLONG)
|
||||
SFileMpqHashTableSize64, // Compressed size of the hash table (ULONGLONG)
|
||||
SFileMpqHashTableSize, // Size of the hash table, in entries (DWORD)
|
||||
SFileMpqHashTable, // Raw (unfixed) hash table (TMPQBlock [])
|
||||
SFileMpqBlockTableOffset, // Block table offset, relative to MPQ header (ULONGLONG)
|
||||
SFileMpqBlockTableSize64, // Compressed size of the block table (ULONGLONG)
|
||||
SFileMpqBlockTableSize, // Size of the block table, in entries (DWORD)
|
||||
SFileMpqBlockTable, // Raw (unfixed) block table (TMPQBlock [])
|
||||
SFileMpqHiBlockTableOffset, // Hi-block table offset, relative to MPQ header (ULONGLONG)
|
||||
SFileMpqHiBlockTableSize64, // Compressed size of the hi-block table (ULONGLONG)
|
||||
SFileMpqHiBlockTable, // The hi-block table (USHORT [])
|
||||
SFileMpqSignatures, // Signatures present in the MPQ (DWORD)
|
||||
SFileMpqStrongSignatureOffset, // Byte offset of the strong signature, relative to begin of the file (ULONGLONG)
|
||||
SFileMpqStrongSignatureSize, // Size of the strong signature (DWORD)
|
||||
SFileMpqStrongSignature, // The strong signature (BYTE [])
|
||||
SFileMpqArchiveSize64, // Archive size from the header (ULONGLONG)
|
||||
SFileMpqArchiveSize, // Archive size from the header (DWORD)
|
||||
SFileMpqMaxFileCount, // Max number of files in the archive (DWORD)
|
||||
SFileMpqFileTableSize, // Number of entries in the file table (DWORD)
|
||||
SFileMpqSectorSize, // Sector size (DWORD)
|
||||
SFileMpqNumberOfFiles, // Number of files (DWORD)
|
||||
SFileMpqRawChunkSize, // Size of the raw data chunk for MD5
|
||||
SFileMpqStreamFlags, // Stream flags (DWORD)
|
||||
SFileMpqIsReadOnly, // Nonzero if the MPQ is read only (DWORD)
|
||||
|
||||
// Info classes for files
|
||||
SFileInfoPatchChain, // Chain of patches where the file is (TCHAR [])
|
||||
SFileInfoFileEntry, // The file entry for the file (TFileEntry)
|
||||
SFileInfoHashEntry, // Hash table entry for the file (TMPQHash)
|
||||
SFileInfoHashIndex, // Index of the hash table entry (DWORD)
|
||||
SFileInfoNameHash1, // The first name hash in the hash table (DWORD)
|
||||
SFileInfoNameHash2, // The second name hash in the hash table (DWORD)
|
||||
SFileInfoNameHash3, // 64-bit file name hash for the HET/BET tables (ULONGLONG)
|
||||
SFileInfoLocale, // File locale (DWORD)
|
||||
SFileInfoFileIndex, // Block index (DWORD)
|
||||
SFileInfoByteOffset, // File position in the archive (ULONGLONG)
|
||||
SFileInfoFileTime, // File time (ULONGLONG)
|
||||
SFileInfoFileSize, // Size of the file (DWORD)
|
||||
SFileInfoCompressedSize, // Compressed file size (DWORD)
|
||||
SFileInfoFlags, // File flags from (DWORD)
|
||||
SFileInfoEncryptionKey, // File encryption key
|
||||
SFileInfoEncryptionKeyRaw, // Unfixed value of the file key
|
||||
}
|
||||
}
|
||||
@@ -1,26 +0,0 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
|
||||
namespace StormLibSharp.Native
|
||||
{
|
||||
[Flags]
|
||||
internal enum SFileOpenArchiveFlags : uint
|
||||
{
|
||||
None = 0,
|
||||
TypeIsFile = None,
|
||||
TypeIsMemoryMapped = 1,
|
||||
TypeIsHttp = 2,
|
||||
|
||||
AccessReadOnly = 0x100,
|
||||
AccessReadWriteShare = 0x200,
|
||||
AccessUseBitmap = 0x400,
|
||||
|
||||
DontOpenListfile = 0x10000,
|
||||
DontOpenAttributes = 0x20000,
|
||||
DontSearchHeader = 0x40000,
|
||||
ForceVersion1 = 0x80000,
|
||||
CheckSectorCRC = 0x100000,
|
||||
}
|
||||
}
|
||||
@@ -1,60 +0,0 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.ComponentModel;
|
||||
using System.Diagnostics;
|
||||
using System.IO.MemoryMappedFiles;
|
||||
using System.Linq;
|
||||
using System.Runtime.InteropServices;
|
||||
using System.Text;
|
||||
|
||||
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 = null;
|
||||
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;
|
||||
}
|
||||
}
|
||||
}
|
||||
1
BurnOutSharp/External/stormlibsharp
vendored
Submodule
1
BurnOutSharp/External/stormlibsharp
vendored
Submodule
Submodule BurnOutSharp/External/stormlibsharp added at 3bf1375317
Binary file not shown.
Reference in New Issue
Block a user