commit
f93bccd42c
|
@ -19,8 +19,8 @@ using System.Runtime.InteropServices;
|
||||||
public sealed class HLLib
|
public sealed class HLLib
|
||||||
{
|
{
|
||||||
#region Constants
|
#region Constants
|
||||||
public const int HL_VERSION_NUMBER = ((2 << 24) | (4 << 16) | (4 << 8) | 0);
|
public const int HL_VERSION_NUMBER = ((2 << 24) | (4 << 16) | (5 << 8) | 0);
|
||||||
public const string HL_VERSION_STRING = "2.4.4";
|
public const string HL_VERSION_STRING = "2.4.5";
|
||||||
|
|
||||||
public const uint HL_ID_INVALID = 0xffffffff;
|
public const uint HL_ID_INVALID = 0xffffffff;
|
||||||
|
|
||||||
|
@ -206,6 +206,7 @@ public sealed class HLLib
|
||||||
HL_SGA_ITEM_MODIFIED,
|
HL_SGA_ITEM_MODIFIED,
|
||||||
HL_SGA_ITEM_TYPE,
|
HL_SGA_ITEM_TYPE,
|
||||||
HL_SGA_ITEM_CRC,
|
HL_SGA_ITEM_CRC,
|
||||||
|
HL_SGA_ITEM_VERIFICATION,
|
||||||
HL_SGA_ITEM_COUNT,
|
HL_SGA_ITEM_COUNT,
|
||||||
|
|
||||||
HL_VBSP_PACKAGE_VERSION = 0,
|
HL_VBSP_PACKAGE_VERSION = 0,
|
||||||
|
|
|
@ -29,5 +29,5 @@ using System.Runtime.InteropServices;
|
||||||
// Build Number
|
// Build Number
|
||||||
// Revision
|
// Revision
|
||||||
//
|
//
|
||||||
[assembly: AssemblyVersion("2.4.4.0")]
|
[assembly: AssemblyVersion("2.4.5.0")]
|
||||||
[assembly: AssemblyFileVersion("2.4.4.0")]
|
[assembly: AssemblyFileVersion("2.4.5.0")]
|
||||||
|
|
|
@ -51,8 +51,8 @@ END
|
||||||
//
|
//
|
||||||
|
|
||||||
VS_VERSION_INFO VERSIONINFO
|
VS_VERSION_INFO VERSIONINFO
|
||||||
FILEVERSION 2,4,4,0
|
FILEVERSION 2,4,5,0
|
||||||
PRODUCTVERSION 2,4,4,0
|
PRODUCTVERSION 2,4,5,0
|
||||||
FILEFLAGSMASK 0x17L
|
FILEFLAGSMASK 0x17L
|
||||||
#ifdef _DEBUG
|
#ifdef _DEBUG
|
||||||
FILEFLAGS 0x1L
|
FILEFLAGS 0x1L
|
||||||
|
@ -69,12 +69,12 @@ BEGIN
|
||||||
BEGIN
|
BEGIN
|
||||||
VALUE "Comments", "Half-Life Package Extraction Utility"
|
VALUE "Comments", "Half-Life Package Extraction Utility"
|
||||||
VALUE "FileDescription", "HLExtract Application"
|
VALUE "FileDescription", "HLExtract Application"
|
||||||
VALUE "FileVersion", "2.4.4"
|
VALUE "FileVersion", "2.4.5"
|
||||||
VALUE "InternalName", "HLExtract"
|
VALUE "InternalName", "HLExtract"
|
||||||
VALUE "LegalCopyright", "Copyright (C) 2006-2013 Ryan Gregg"
|
VALUE "LegalCopyright", "Copyright (C) 2006-2013 Ryan Gregg"
|
||||||
VALUE "OriginalFilename", "HLExtract.exe"
|
VALUE "OriginalFilename", "HLExtract.exe"
|
||||||
VALUE "ProductName", " HLExtract Application"
|
VALUE "ProductName", " HLExtract Application"
|
||||||
VALUE "ProductVersion", "2.4.4"
|
VALUE "ProductVersion", "2.4.5"
|
||||||
END
|
END
|
||||||
END
|
END
|
||||||
BLOCK "VarFileInfo"
|
BLOCK "VarFileInfo"
|
||||||
|
|
|
@ -207,6 +207,17 @@ hlULong HLLib::CRC32(const hlByte *lpBuffer, hlUInt uiBufferSize, hlULong uiCRC)
|
||||||
return uiCRC ^ 0xffffffffUL;
|
return uiCRC ^ 0xffffffffUL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
inline hlULong LeftRoate(hlULong value, hlUInt bits)
|
||||||
|
{
|
||||||
|
return (value << bits) | (value >> (32 - bits));
|
||||||
|
}
|
||||||
|
|
||||||
|
inline hlULong SwapEndian(hlULong value)
|
||||||
|
{
|
||||||
|
value = ((value << 8) & 0xFF00FF00UL) | ((value >> 8) & 0x00FF00FFUL);
|
||||||
|
return (value << 16) | (value >> 16);
|
||||||
|
}
|
||||||
|
|
||||||
const hlULong lpMD5Table[4][16] =
|
const hlULong lpMD5Table[4][16] =
|
||||||
{
|
{
|
||||||
{
|
{
|
||||||
|
@ -251,11 +262,6 @@ const hlByte lpMD5Padding[64] =
|
||||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||||
};
|
};
|
||||||
|
|
||||||
hlULong LeftRoate(hlULong value, hlUInt bits)
|
|
||||||
{
|
|
||||||
return (value << bits) | (value >> (32 - bits));
|
|
||||||
}
|
|
||||||
|
|
||||||
hlVoid HLLib::MD5_Initialize(MD5Context& context)
|
hlVoid HLLib::MD5_Initialize(MD5Context& context)
|
||||||
{
|
{
|
||||||
context.lpState[0] = 0x67452301UL;
|
context.lpState[0] = 0x67452301UL;
|
||||||
|
@ -286,7 +292,7 @@ hlVoid HLLib::MD5_Update(MD5Context& context, const hlByte *lpBuffer, hlUInt uiB
|
||||||
// Round 1.
|
// Round 1.
|
||||||
for(hlULong i = 0; i < 16; ++i)
|
for(hlULong i = 0; i < 16; ++i)
|
||||||
{
|
{
|
||||||
hlULong x = (b & c) | ((~b) & d);
|
hlULong x = d ^ (b & (c ^ d));
|
||||||
|
|
||||||
hlULong t = d;
|
hlULong t = d;
|
||||||
d = c;
|
d = c;
|
||||||
|
@ -360,5 +366,144 @@ hlVoid HLLib::MD5_Finalize(MD5Context& context, hlByte (&lpDigest)[16])
|
||||||
|
|
||||||
MD5_Update(context, reinterpret_cast<hlByte*>(&uiLengthInBits), sizeof(uiLengthInBits));
|
MD5_Update(context, reinterpret_cast<hlByte*>(&uiLengthInBits), sizeof(uiLengthInBits));
|
||||||
|
|
||||||
memcpy(lpDigest, context.lpState, sizeof(lpDigest));
|
for(hlULong i = 0; i < sizeof(context.lpState) / sizeof(context.lpState[0]); ++i)
|
||||||
|
{
|
||||||
|
reinterpret_cast<hlULong*>(lpDigest)[i] = context.lpState[i];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
hlVoid HLLib::SHA1_Initialize(SHA1Context& context)
|
||||||
|
{
|
||||||
|
context.lpState[0] = 0x67452301UL;
|
||||||
|
context.lpState[1] = 0xEFCDAB89UL;
|
||||||
|
context.lpState[2] = 0x98BADCFEUL;
|
||||||
|
context.lpState[3] = 0x10325476UL;
|
||||||
|
context.lpState[4] = 0xC3D2E1F0UL;
|
||||||
|
context.uiLength = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
hlVoid HLLib::SHA1_Update(SHA1Context& context, const hlByte *lpBuffer, hlUInt uiBufferSize)
|
||||||
|
{
|
||||||
|
hlULong uiBlockLength = context.uiLength % sizeof(context.lpBlock);
|
||||||
|
while(uiBlockLength + uiBufferSize >= sizeof(context.lpBlock))
|
||||||
|
{
|
||||||
|
hlULong uiCopyLength = std::min(static_cast<hlULong>(uiBufferSize), static_cast<hlULong>(sizeof(context.lpBlock) - uiBlockLength));
|
||||||
|
memcpy(reinterpret_cast<hlByte*>(context.lpBlock) + uiBlockLength, lpBuffer, uiCopyLength);
|
||||||
|
context.uiLength += uiCopyLength;
|
||||||
|
|
||||||
|
lpBuffer += uiCopyLength;
|
||||||
|
uiBufferSize -= uiCopyLength;
|
||||||
|
|
||||||
|
{
|
||||||
|
hlULong a = context.lpState[0];
|
||||||
|
hlULong b = context.lpState[1];
|
||||||
|
hlULong c = context.lpState[2];
|
||||||
|
hlULong d = context.lpState[3];
|
||||||
|
hlULong e = context.lpState[4];
|
||||||
|
|
||||||
|
hlULong i;
|
||||||
|
hlULong lpExtendedBlock[80];
|
||||||
|
|
||||||
|
// Input needs to be big-endian.
|
||||||
|
for(i = 0; i < 16; ++i)
|
||||||
|
{
|
||||||
|
lpExtendedBlock[i] = SwapEndian(context.lpBlock[i]);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Extend the 16 dwords to 80.
|
||||||
|
for(; i < 80; ++i)
|
||||||
|
{
|
||||||
|
lpExtendedBlock[i] = LeftRoate(lpExtendedBlock[i - 3] ^ lpExtendedBlock[i - 8] ^ lpExtendedBlock[i - 14] ^ lpExtendedBlock[i - 16], 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Round 1.
|
||||||
|
for(i = 0; i < 20; ++i)
|
||||||
|
{
|
||||||
|
hlULong x = d ^ (b & (c ^ d));
|
||||||
|
|
||||||
|
hlULong t = LeftRoate(a, 5) + x + e + 0x5A827999UL + lpExtendedBlock[i];
|
||||||
|
e = d;
|
||||||
|
d = c;
|
||||||
|
c = LeftRoate(b, 30);
|
||||||
|
b = a;
|
||||||
|
a = t;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Round 2.
|
||||||
|
for(; i < 40; ++i)
|
||||||
|
{
|
||||||
|
hlULong x = b ^ c ^ d;
|
||||||
|
|
||||||
|
hlULong t = LeftRoate(a, 5) + x + e + 0x6ED9EBA1UL + lpExtendedBlock[i];
|
||||||
|
e = d;
|
||||||
|
d = c;
|
||||||
|
c = LeftRoate(b, 30);
|
||||||
|
b = a;
|
||||||
|
a = t;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Round 3.
|
||||||
|
for(; i < 60; ++i)
|
||||||
|
{
|
||||||
|
hlULong x = (b & c) | ((b | c) & d);
|
||||||
|
|
||||||
|
hlULong t = LeftRoate(a, 5) + x + e + 0x8F1BBCDCUL + lpExtendedBlock[i];
|
||||||
|
e = d;
|
||||||
|
d = c;
|
||||||
|
c = LeftRoate(b, 30);
|
||||||
|
b = a;
|
||||||
|
a = t;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Round 4.
|
||||||
|
for(; i < 80; ++i)
|
||||||
|
{
|
||||||
|
hlULong x = b ^ c ^ d;
|
||||||
|
|
||||||
|
hlULong t = LeftRoate(a, 5) + x + e + 0xCA62C1D6UL + lpExtendedBlock[i];
|
||||||
|
e = d;
|
||||||
|
d = c;
|
||||||
|
c = LeftRoate(b, 30);
|
||||||
|
b = a;
|
||||||
|
a = t;
|
||||||
|
}
|
||||||
|
|
||||||
|
context.lpState[0] += a;
|
||||||
|
context.lpState[1] += b;
|
||||||
|
context.lpState[2] += c;
|
||||||
|
context.lpState[3] += d;
|
||||||
|
context.lpState[4] += e;
|
||||||
|
}
|
||||||
|
|
||||||
|
uiBlockLength = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
memcpy(reinterpret_cast<hlByte*>(context.lpBlock) + uiBlockLength, lpBuffer, uiBufferSize);
|
||||||
|
context.uiLength += uiBufferSize;
|
||||||
|
}
|
||||||
|
|
||||||
|
hlVoid HLLib::SHA1_Finalize(SHA1Context& context, hlByte (&lpDigest)[20])
|
||||||
|
{
|
||||||
|
hlULongLong uiLengthInBits = 8ULL * static_cast<hlULongLong>(context.uiLength);
|
||||||
|
|
||||||
|
hlULong uiBlockLength = context.uiLength % sizeof(context.lpBlock);
|
||||||
|
if(uiBlockLength < sizeof(context.lpBlock) - sizeof(hlULongLong))
|
||||||
|
{
|
||||||
|
SHA1_Update(context, lpMD5Padding, sizeof(context.lpBlock) - sizeof(uiLengthInBits) - uiBlockLength);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
SHA1_Update(context, lpMD5Padding, 2 * sizeof(context.lpBlock) - sizeof(uiLengthInBits) - uiBlockLength);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Length needs to be big-endian.
|
||||||
|
uiLengthInBits = (uiLengthInBits << 32) | (uiLengthInBits >> 32);
|
||||||
|
uiLengthInBits = static_cast<hlULongLong>(SwapEndian(static_cast<hlULong>(uiLengthInBits & 0xFFFFFFFFULL))) | static_cast<hlULongLong>(SwapEndian(static_cast<hlULong>(uiLengthInBits >> 32))) << 32;
|
||||||
|
SHA1_Update(context, reinterpret_cast<hlByte*>(&uiLengthInBits), sizeof(uiLengthInBits));
|
||||||
|
|
||||||
|
for(hlULong i = 0; i < sizeof(context.lpState) / sizeof(context.lpState[0]); ++i)
|
||||||
|
{
|
||||||
|
// Output needs to be big-endian.
|
||||||
|
reinterpret_cast<hlULong*>(lpDigest)[i] = SwapEndian(context.lpState[i]);
|
||||||
|
}
|
||||||
}
|
}
|
124
HLLib/Checksum.h
124
HLLib/Checksum.h
|
@ -30,6 +30,130 @@ namespace HLLib
|
||||||
hlVoid MD5_Initialize(MD5Context& context);
|
hlVoid MD5_Initialize(MD5Context& context);
|
||||||
hlVoid MD5_Update(MD5Context& context, const hlByte *lpBuffer, hlUInt uiBufferSize);
|
hlVoid MD5_Update(MD5Context& context, const hlByte *lpBuffer, hlUInt uiBufferSize);
|
||||||
hlVoid MD5_Finalize(MD5Context& context, hlByte (&lpDigest)[16]);
|
hlVoid MD5_Finalize(MD5Context& context, hlByte (&lpDigest)[16]);
|
||||||
|
|
||||||
|
struct SHA1Context
|
||||||
|
{
|
||||||
|
hlULong lpState[5];
|
||||||
|
hlULong lpBlock[16];
|
||||||
|
hlULong uiLength;
|
||||||
|
};
|
||||||
|
|
||||||
|
hlVoid SHA1_Initialize(SHA1Context& context);
|
||||||
|
hlVoid SHA1_Update(SHA1Context& context, const hlByte *lpBuffer, hlUInt uiBufferSize);
|
||||||
|
hlVoid SHA1_Finalize(SHA1Context& context, hlByte (&lpDigest)[20]);
|
||||||
|
|
||||||
|
class Checksum
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
virtual ~Checksum()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
virtual hlULong GetDigestSize() const = 0;
|
||||||
|
virtual void Initialize() = 0;
|
||||||
|
virtual void Update(const hlByte *lpBuffer, hlUInt uiBufferSize) = 0;
|
||||||
|
virtual bool Finalize(const hlByte *lpHash) = 0;
|
||||||
|
};
|
||||||
|
|
||||||
|
class CRC32Checksum : public Checksum
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
CRC32Checksum()
|
||||||
|
{
|
||||||
|
Initialize();
|
||||||
|
}
|
||||||
|
|
||||||
|
virtual hlULong GetDigestSize() const
|
||||||
|
{
|
||||||
|
return sizeof(this->uiChecksum);
|
||||||
|
}
|
||||||
|
|
||||||
|
virtual void Initialize()
|
||||||
|
{
|
||||||
|
this->uiChecksum = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
virtual void Update(const hlByte *lpBuffer, hlUInt uiBufferSize)
|
||||||
|
{
|
||||||
|
this->uiChecksum = CRC32(lpBuffer, uiBufferSize, this->uiChecksum);
|
||||||
|
}
|
||||||
|
|
||||||
|
virtual bool Finalize(const hlByte *lpHash)
|
||||||
|
{
|
||||||
|
return *reinterpret_cast<const hlULong*>(lpHash) == this->uiChecksum;
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
hlULong uiChecksum;
|
||||||
|
};
|
||||||
|
|
||||||
|
class MD5Checksum : public Checksum
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
MD5Checksum()
|
||||||
|
{
|
||||||
|
Initialize();
|
||||||
|
}
|
||||||
|
|
||||||
|
virtual hlULong GetDigestSize() const
|
||||||
|
{
|
||||||
|
return sizeof(this->context.lpState);
|
||||||
|
}
|
||||||
|
|
||||||
|
virtual void Initialize()
|
||||||
|
{
|
||||||
|
MD5_Initialize(this->context);
|
||||||
|
}
|
||||||
|
|
||||||
|
virtual void Update(const hlByte *lpBuffer, hlUInt uiBufferSize)
|
||||||
|
{
|
||||||
|
MD5_Update(this->context, lpBuffer, uiBufferSize);
|
||||||
|
}
|
||||||
|
|
||||||
|
virtual bool Finalize(const hlByte *lpHash)
|
||||||
|
{
|
||||||
|
hlByte lpDigest[16];
|
||||||
|
MD5_Finalize(this->context, lpDigest);
|
||||||
|
return memcmp(lpHash, lpDigest, sizeof(lpDigest)) == 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
MD5Context context;
|
||||||
|
};
|
||||||
|
|
||||||
|
class SHA1Checksum : public Checksum
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
SHA1Checksum()
|
||||||
|
{
|
||||||
|
Initialize();
|
||||||
|
}
|
||||||
|
|
||||||
|
virtual hlULong GetDigestSize() const
|
||||||
|
{
|
||||||
|
return sizeof(this->context.lpState);
|
||||||
|
}
|
||||||
|
|
||||||
|
virtual void Initialize()
|
||||||
|
{
|
||||||
|
SHA1_Initialize(this->context);
|
||||||
|
}
|
||||||
|
|
||||||
|
virtual void Update(const hlByte *lpBuffer, hlUInt uiBufferSize)
|
||||||
|
{
|
||||||
|
SHA1_Update(this->context, lpBuffer, uiBufferSize);
|
||||||
|
}
|
||||||
|
|
||||||
|
virtual bool Finalize(const hlByte *lpHash)
|
||||||
|
{
|
||||||
|
hlByte lpDigest[20];
|
||||||
|
SHA1_Finalize(this->context, lpDigest);
|
||||||
|
return memcmp(lpHash, lpDigest, sizeof(lpDigest)) == 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
SHA1Context context;
|
||||||
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -51,8 +51,8 @@ END
|
||||||
//
|
//
|
||||||
|
|
||||||
VS_VERSION_INFO VERSIONINFO
|
VS_VERSION_INFO VERSIONINFO
|
||||||
FILEVERSION 2,4,4,0
|
FILEVERSION 2,4,5,0
|
||||||
PRODUCTVERSION 2,4,4,0
|
PRODUCTVERSION 2,4,5,0
|
||||||
FILEFLAGSMASK 0x17L
|
FILEFLAGSMASK 0x17L
|
||||||
#ifdef _DEBUG
|
#ifdef _DEBUG
|
||||||
FILEFLAGS 0x1L
|
FILEFLAGS 0x1L
|
||||||
|
@ -69,12 +69,12 @@ BEGIN
|
||||||
BEGIN
|
BEGIN
|
||||||
VALUE "Comments", "Half-Life Package Library"
|
VALUE "Comments", "Half-Life Package Library"
|
||||||
VALUE "FileDescription", "HLLib Dynamic Link Library"
|
VALUE "FileDescription", "HLLib Dynamic Link Library"
|
||||||
VALUE "FileVersion", "2.4.4"
|
VALUE "FileVersion", "2.4.5"
|
||||||
VALUE "InternalName", "HLLib"
|
VALUE "InternalName", "HLLib"
|
||||||
VALUE "LegalCopyright", "Copyright (C) 2006-2013 Ryan Gregg"
|
VALUE "LegalCopyright", "Copyright (C) 2006-2013 Ryan Gregg"
|
||||||
VALUE "OriginalFilename", "HLLib.dll"
|
VALUE "OriginalFilename", "HLLib.dll"
|
||||||
VALUE "ProductName", " HLLib Dynamic Link Library"
|
VALUE "ProductName", " HLLib Dynamic Link Library"
|
||||||
VALUE "ProductVersion", "2.4.4"
|
VALUE "ProductVersion", "2.4.5"
|
||||||
END
|
END
|
||||||
END
|
END
|
||||||
BLOCK "VarFileInfo"
|
BLOCK "VarFileInfo"
|
||||||
|
|
|
@ -27,7 +27,8 @@ using namespace HLLib;
|
||||||
#define HL_SGA_CHECKSUM_LENGTH 0x00008000
|
#define HL_SGA_CHECKSUM_LENGTH 0x00008000
|
||||||
|
|
||||||
const char *CSGAFile::lpAttributeNames[] = { "Major Version", "Minor Version", "File MD5", "Name", "Header MD5" };
|
const char *CSGAFile::lpAttributeNames[] = { "Major Version", "Minor Version", "File MD5", "Name", "Header MD5" };
|
||||||
const char *CSGAFile::lpItemAttributeNames[] = { "Section Alias", "Section Name", "Modified", "Type", "CRC" };
|
const char *CSGAFile::lpItemAttributeNames[] = { "Section Alias", "Section Name", "Modified", "Type", "CRC", "Verification" };
|
||||||
|
const char *CSGAFile::lpVerificationNames[] = { "None", "CRC", "CRC Blocks", "MD5 Blocks", "SHA1 Blocks" };
|
||||||
|
|
||||||
CSGAFile::CSGAFile() : CPackage(), pHeaderView(0), pHeader(0), pDirectory(0)
|
CSGAFile::CSGAFile() : CPackage(), pHeaderView(0), pHeader(0), pDirectory(0)
|
||||||
{
|
{
|
||||||
|
@ -56,17 +57,18 @@ const hlChar *CSGAFile::GetDescription() const
|
||||||
|
|
||||||
hlBool CSGAFile::MapDataStructures()
|
hlBool CSGAFile::MapDataStructures()
|
||||||
{
|
{
|
||||||
if(sizeof(SGAHeader) > this->pMapping->GetMappingSize())
|
hlULongLong uiMaxHeaderSize = std::max(sizeof(SGAHeader4), sizeof(SGAHeader6));
|
||||||
|
if(uiMaxHeaderSize > this->pMapping->GetMappingSize())
|
||||||
{
|
{
|
||||||
LastError.SetErrorMessage("Invalid file: the file map is too small for it's header.");
|
LastError.SetErrorMessage("Invalid file: the file map is too small for it's header.");
|
||||||
return hlFalse;
|
return hlFalse;
|
||||||
}
|
}
|
||||||
|
|
||||||
if(!this->pMapping->Map(this->pHeaderView, 0, sizeof(SGAHeader)))
|
if(!this->pMapping->Map(this->pHeaderView, 0, uiMaxHeaderSize))
|
||||||
{
|
{
|
||||||
return hlFalse;
|
return hlFalse;
|
||||||
}
|
}
|
||||||
this->pHeader = static_cast<const SGAHeader *>(this->pHeaderView->GetView());
|
this->pHeader = static_cast<const SGAHeaderBase *>(this->pHeaderView->GetView());
|
||||||
|
|
||||||
if(memcmp(this->pHeader->lpSignature, "_ARCHIVE", 8) != 0)
|
if(memcmp(this->pHeader->lpSignature, "_ARCHIVE", 8) != 0)
|
||||||
{
|
{
|
||||||
|
@ -74,26 +76,53 @@ hlBool CSGAFile::MapDataStructures()
|
||||||
return hlFalse;
|
return hlFalse;
|
||||||
}
|
}
|
||||||
|
|
||||||
if((this->pHeader->uiMajorVersion != 4 || this->pHeader->uiMinorVersion != 0) && (this->pHeader->uiMajorVersion != 5 || this->pHeader->uiMinorVersion != 0))
|
if((this->pHeader->uiMajorVersion != 4 || this->pHeader->uiMinorVersion != 0) &&
|
||||||
|
(this->pHeader->uiMajorVersion != 5 || this->pHeader->uiMinorVersion != 0) &&
|
||||||
|
(this->pHeader->uiMajorVersion != 6 || this->pHeader->uiMinorVersion != 0) &&
|
||||||
|
(this->pHeader->uiMajorVersion != 7 || this->pHeader->uiMinorVersion != 0))
|
||||||
{
|
{
|
||||||
LastError.SetErrorMessageFormated("Invalid SGA version (v%hu.%hu): you have a version of a SGA file that HLLib does not know how to read. Check for product updates.", this->pHeader->uiMajorVersion, this->pHeader->uiMinorVersion);
|
LastError.SetErrorMessageFormated("Invalid SGA version (v%hu.%hu): you have a version of a SGA file that HLLib does not know how to read. Check for product updates.", this->pHeader->uiMajorVersion, this->pHeader->uiMinorVersion);
|
||||||
return hlFalse;
|
return hlFalse;
|
||||||
}
|
}
|
||||||
|
|
||||||
if(this->pHeader->uiHeaderLength > this->pMapping->GetMappingSize())
|
|
||||||
{
|
|
||||||
LastError.SetErrorMessage("Invalid file: the file map is too small for it's extended header.");
|
|
||||||
return hlFalse;
|
|
||||||
}
|
|
||||||
|
|
||||||
switch(this->pHeader->uiMajorVersion)
|
switch(this->pHeader->uiMajorVersion)
|
||||||
{
|
{
|
||||||
case 4:
|
case 4:
|
||||||
|
if(static_cast<const CSGADirectory4::SGAHeader*>(this->pHeader)->uiHeaderLength > this->pMapping->GetMappingSize())
|
||||||
|
{
|
||||||
|
LastError.SetErrorMessage("Invalid file: the file map is too small for it's extended header.");
|
||||||
|
return hlFalse;
|
||||||
|
}
|
||||||
|
|
||||||
this->pDirectory = new CSGADirectory4(*this);
|
this->pDirectory = new CSGADirectory4(*this);
|
||||||
break;
|
break;
|
||||||
case 5:
|
case 5:
|
||||||
|
if(static_cast<const CSGADirectory5::SGAHeader*>(this->pHeader)->uiHeaderLength > this->pMapping->GetMappingSize())
|
||||||
|
{
|
||||||
|
LastError.SetErrorMessage("Invalid file: the file map is too small for it's extended header.");
|
||||||
|
return hlFalse;
|
||||||
|
}
|
||||||
|
|
||||||
this->pDirectory = new CSGADirectory5(*this);
|
this->pDirectory = new CSGADirectory5(*this);
|
||||||
break;
|
break;
|
||||||
|
case 6:
|
||||||
|
if(static_cast<const CSGADirectory6::SGAHeader*>(this->pHeader)->uiHeaderLength > this->pMapping->GetMappingSize())
|
||||||
|
{
|
||||||
|
LastError.SetErrorMessage("Invalid file: the file map is too small for it's extended header.");
|
||||||
|
return hlFalse;
|
||||||
|
}
|
||||||
|
|
||||||
|
this->pDirectory = new CSGADirectory6(*this);
|
||||||
|
break;
|
||||||
|
case 7:
|
||||||
|
if(static_cast<const CSGADirectory7::SGAHeader*>(this->pHeader)->uiHeaderLength > this->pMapping->GetMappingSize())
|
||||||
|
{
|
||||||
|
LastError.SetErrorMessage("Invalid file: the file map is too small for it's extended header.");
|
||||||
|
return hlFalse;
|
||||||
|
}
|
||||||
|
|
||||||
|
this->pDirectory = new CSGADirectory7(*this);
|
||||||
|
break;
|
||||||
default:
|
default:
|
||||||
assert(false);
|
assert(false);
|
||||||
return hlFalse;
|
return hlFalse;
|
||||||
|
@ -185,17 +214,35 @@ hlBool CSGAFile::GetAttributeInternal(HLPackageAttribute eAttribute, HLAttribute
|
||||||
hlAttributeSetUnsignedInteger(&Attribute, this->lpAttributeNames[eAttribute], this->pHeader->uiMinorVersion, hlFalse);
|
hlAttributeSetUnsignedInteger(&Attribute, this->lpAttributeNames[eAttribute], this->pHeader->uiMinorVersion, hlFalse);
|
||||||
return hlTrue;
|
return hlTrue;
|
||||||
case HL_SGA_PACKAGE_MD5_FILE:
|
case HL_SGA_PACKAGE_MD5_FILE:
|
||||||
BufferToHexString(this->pHeader->lpFileMD5, 16, lpBuffer, sizeof(lpBuffer));
|
if(this->pHeader->uiMajorVersion >= 4 && this->pHeader->uiMajorVersion <= 5)
|
||||||
hlAttributeSetString(&Attribute, this->lpAttributeNames[eAttribute], lpBuffer);
|
{
|
||||||
return hlTrue;
|
BufferToHexString(static_cast<const SGAHeader4 *>(this->pHeader)->lpFileMD5, 16, lpBuffer, sizeof(lpBuffer));
|
||||||
|
hlAttributeSetString(&Attribute, this->lpAttributeNames[eAttribute], lpBuffer);
|
||||||
|
return hlTrue;
|
||||||
|
}
|
||||||
|
return hlFalse;
|
||||||
case HL_SGA_PACKAGE_NAME:
|
case HL_SGA_PACKAGE_NAME:
|
||||||
WStringToString(this->pHeader->lpName, lpBuffer, sizeof(lpBuffer));
|
if(this->pHeader->uiMajorVersion >= 4 && this->pHeader->uiMajorVersion <= 5)
|
||||||
hlAttributeSetString(&Attribute, this->lpAttributeNames[eAttribute], lpBuffer);
|
{
|
||||||
return hlTrue;
|
WStringToString(static_cast<const SGAHeader4 *>(this->pHeader)->lpName, lpBuffer, sizeof(lpBuffer));
|
||||||
|
hlAttributeSetString(&Attribute, this->lpAttributeNames[eAttribute], lpBuffer);
|
||||||
|
return hlTrue;
|
||||||
|
}
|
||||||
|
if(this->pHeader->uiMajorVersion >= 6 && this->pHeader->uiMajorVersion <= 6)
|
||||||
|
{
|
||||||
|
WStringToString(static_cast<const SGAHeader6 *>(this->pHeader)->lpName, lpBuffer, sizeof(lpBuffer));
|
||||||
|
hlAttributeSetString(&Attribute, this->lpAttributeNames[eAttribute], lpBuffer);
|
||||||
|
return hlTrue;
|
||||||
|
}
|
||||||
|
return hlFalse;
|
||||||
case HL_SGA_PACKAGE_MD5_HEADER:
|
case HL_SGA_PACKAGE_MD5_HEADER:
|
||||||
BufferToHexString(this->pHeader->lpHeaderMD5, 16, lpBuffer, sizeof(lpBuffer));
|
if(this->pHeader->uiMajorVersion >= 4 && this->pHeader->uiMajorVersion <= 5)
|
||||||
hlAttributeSetString(&Attribute, this->lpAttributeNames[eAttribute], lpBuffer);
|
{
|
||||||
return hlTrue;
|
BufferToHexString(static_cast<const SGAHeader4 *>(this->pHeader)->lpHeaderMD5, 16, lpBuffer, sizeof(lpBuffer));
|
||||||
|
hlAttributeSetString(&Attribute, this->lpAttributeNames[eAttribute], lpBuffer);
|
||||||
|
return hlTrue;
|
||||||
|
}
|
||||||
|
return hlFalse;
|
||||||
default:
|
default:
|
||||||
return hlFalse;
|
return hlFalse;
|
||||||
}
|
}
|
||||||
|
@ -221,59 +268,77 @@ CSGAFile::ISGADirectory::~ISGADirectory()
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
template<typename TSGADirectoryHeader, typename TSGASection, typename TSGAFolder, typename TSGAFile, typename TSGAFileHeader>
|
template<typename TSGAHeader, typename TSGADirectoryHeader, typename TSGASection, typename TSGAFolder, typename TSGAFile>
|
||||||
CSGAFile::CSGADirectory<TSGADirectoryHeader, TSGASection, TSGAFolder, TSGAFile, TSGAFileHeader>::CSGADirectory(CSGAFile& File) : File(File), pHeaderDirectoryView(0), pDirectoryHeader(0), lpSections(0), lpFolders(0), lpFiles(0), lpStringTable(0)
|
CSGAFile::CSGASpecializedDirectory<TSGAHeader, TSGADirectoryHeader, TSGASection, TSGAFolder, TSGAFile>::CSGASpecializedDirectory(CSGAFile& File) : File(File), pHeaderDirectoryView(0), pDirectoryHeader(0), lpSections(0), lpFolders(0), lpFiles(0), lpStringTable(0)
|
||||||
{
|
{
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
template<typename TSGADirectoryHeader, typename TSGASection, typename TSGAFolder, typename TSGAFile, typename TSGAFileHeader>
|
template<typename TSGAHeader, typename TSGADirectoryHeader, typename TSGASection, typename TSGAFolder>
|
||||||
CSGAFile::CSGADirectory<TSGADirectoryHeader, TSGASection, TSGAFolder, TSGAFile, TSGAFileHeader>::~CSGADirectory()
|
CSGAFile::CSGASpecializedDirectory<TSGAHeader, TSGADirectoryHeader, TSGASection, TSGAFolder, CSGAFile::SGAFile4>::CSGASpecializedDirectory(CSGAFile& File) : File(File), pHeaderDirectoryView(0), pDirectoryHeader(0), lpSections(0), lpFolders(0), lpFiles(0), lpStringTable(0)
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
template<typename TSGAHeader, typename TSGADirectoryHeader, typename TSGASection, typename TSGAFolder>
|
||||||
|
CSGAFile::CSGASpecializedDirectory<TSGAHeader, TSGADirectoryHeader, TSGASection, TSGAFolder, CSGAFile::SGAFile6>::CSGASpecializedDirectory(CSGAFile& File) : File(File), pHeaderDirectoryView(0), pDirectoryHeader(0), lpSections(0), lpFolders(0), lpFiles(0), lpStringTable(0)
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
template<typename TSGAHeader, typename TSGADirectoryHeader, typename TSGASection, typename TSGAFolder, typename TSGAFile>
|
||||||
|
CSGAFile::CSGADirectory<TSGAHeader, TSGADirectoryHeader, TSGASection, TSGAFolder, TSGAFile>::CSGADirectory(CSGAFile& File) : CSGASpecializedDirectory<TSGAHeader, TSGADirectoryHeader, TSGASection, TSGAFolder, TSGAFile>(File)
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
template<typename TSGAHeader, typename TSGADirectoryHeader, typename TSGASection, typename TSGAFolder, typename TSGAFile>
|
||||||
|
CSGAFile::CSGADirectory<TSGAHeader, TSGADirectoryHeader, TSGASection, TSGAFolder, TSGAFile>::~CSGADirectory()
|
||||||
{
|
{
|
||||||
this->UnmapDataStructures();
|
this->UnmapDataStructures();
|
||||||
}
|
}
|
||||||
|
|
||||||
template<typename TSGADirectoryHeader, typename TSGASection, typename TSGAFolder, typename TSGAFile, typename TSGAFileHeader>
|
template<typename TSGAHeader, typename TSGADirectoryHeader, typename TSGASection, typename TSGAFolder, typename TSGAFile>
|
||||||
hlBool CSGAFile::CSGADirectory<TSGADirectoryHeader, TSGASection, TSGAFolder, TSGAFile, TSGAFileHeader>::MapDataStructures()
|
hlBool CSGAFile::CSGADirectory<TSGAHeader, TSGADirectoryHeader, TSGASection, TSGAFolder, TSGAFile>::MapDataStructures()
|
||||||
{
|
{
|
||||||
if(!this->File.pMapping->Map(this->pHeaderDirectoryView, sizeof(SGAHeader), this->File.pHeader->uiHeaderLength))
|
if(!this->File.pMapping->Map(this->pHeaderDirectoryView, sizeof(SGAHeader), static_cast<const SGAHeader *>(this->File.pHeader)->uiHeaderLength))
|
||||||
{
|
{
|
||||||
return hlFalse;
|
return hlFalse;
|
||||||
}
|
}
|
||||||
|
|
||||||
this->pDirectoryHeader = static_cast<const TSGADirectoryHeader *>(this->pHeaderDirectoryView->GetView());
|
this->pDirectoryHeader = static_cast<const SGADirectoryHeader *>(this->pHeaderDirectoryView->GetView());
|
||||||
|
|
||||||
if(this->pDirectoryHeader->uiSectionCount > 0 && this->pDirectoryHeader->uiSectionOffset + sizeof(TSGASection) * this->pDirectoryHeader->uiSectionCount > this->File.pHeader->uiHeaderLength)
|
if(this->pDirectoryHeader->uiSectionCount > 0 && this->pDirectoryHeader->uiSectionOffset + sizeof(SGASection) * this->pDirectoryHeader->uiSectionCount > static_cast<const SGAHeader *>(this->File.pHeader)->uiHeaderLength)
|
||||||
{
|
{
|
||||||
LastError.SetErrorMessage("Invalid file: the file map is too small for section data.");
|
LastError.SetErrorMessage("Invalid file: the file map is too small for section data.");
|
||||||
return hlFalse;
|
return hlFalse;
|
||||||
}
|
}
|
||||||
if(this->pDirectoryHeader->uiFolderCount > 0 && this->pDirectoryHeader->uiFolderOffset + sizeof(TSGAFolder) * this->pDirectoryHeader->uiFolderCount > this->File.pHeader->uiHeaderLength)
|
if(this->pDirectoryHeader->uiFolderCount > 0 && this->pDirectoryHeader->uiFolderOffset + sizeof(SGAFolder) * this->pDirectoryHeader->uiFolderCount > static_cast<const SGAHeader *>(this->File.pHeader)->uiHeaderLength)
|
||||||
{
|
{
|
||||||
LastError.SetErrorMessage("Invalid file: the file map is too small for folder data.");
|
LastError.SetErrorMessage("Invalid file: the file map is too small for folder data.");
|
||||||
return hlFalse;
|
return hlFalse;
|
||||||
}
|
}
|
||||||
if(this->pDirectoryHeader->uiFileCount > 0 && this->pDirectoryHeader->uiFileOffset + sizeof(TSGAFile) * this->pDirectoryHeader->uiFileCount > this->File.pHeader->uiHeaderLength)
|
if(this->pDirectoryHeader->uiFileCount > 0 && this->pDirectoryHeader->uiFileOffset + sizeof(SGAFile) * this->pDirectoryHeader->uiFileCount > static_cast<const SGAHeader *>(this->File.pHeader)->uiHeaderLength)
|
||||||
{
|
{
|
||||||
LastError.SetErrorMessage("Invalid file: the file map is too small for file data.");
|
LastError.SetErrorMessage("Invalid file: the file map is too small for file data.");
|
||||||
return hlFalse;
|
return hlFalse;
|
||||||
}
|
}
|
||||||
if(this->pDirectoryHeader->uiStringTableOffset > this->File.pHeader->uiHeaderLength)
|
if(this->pDirectoryHeader->uiStringTableOffset > static_cast<const SGAHeader *>(this->File.pHeader)->uiHeaderLength)
|
||||||
{
|
{
|
||||||
LastError.SetErrorMessage("Invalid file: the file map is too small for string table data.");
|
LastError.SetErrorMessage("Invalid file: the file map is too small for string table data.");
|
||||||
return hlFalse;
|
return hlFalse;
|
||||||
}
|
}
|
||||||
|
|
||||||
this->lpSections = reinterpret_cast<const TSGASection *>(reinterpret_cast<const hlByte *>(this->pDirectoryHeader) + this->pDirectoryHeader->uiSectionOffset);
|
this->lpSections = reinterpret_cast<const SGASection *>(reinterpret_cast<const hlByte *>(this->pDirectoryHeader) + this->pDirectoryHeader->uiSectionOffset);
|
||||||
this->lpFolders = reinterpret_cast<const TSGAFolder *>(reinterpret_cast<const hlByte *>(this->pDirectoryHeader) + this->pDirectoryHeader->uiFolderOffset);
|
this->lpFolders = reinterpret_cast<const SGAFolder *>(reinterpret_cast<const hlByte *>(this->pDirectoryHeader) + this->pDirectoryHeader->uiFolderOffset);
|
||||||
this->lpFiles = reinterpret_cast<const TSGAFile *>(reinterpret_cast<const hlByte *>(this->pDirectoryHeader) + this->pDirectoryHeader->uiFileOffset);
|
this->lpFiles = reinterpret_cast<const SGAFile *>(reinterpret_cast<const hlByte *>(this->pDirectoryHeader) + this->pDirectoryHeader->uiFileOffset);
|
||||||
this->lpStringTable = reinterpret_cast<const hlChar *>(reinterpret_cast<const hlByte *>(this->pDirectoryHeader) + this->pDirectoryHeader->uiStringTableOffset);
|
this->lpStringTable = reinterpret_cast<const hlChar *>(reinterpret_cast<const hlByte *>(this->pDirectoryHeader) + this->pDirectoryHeader->uiStringTableOffset);
|
||||||
|
|
||||||
return hlTrue;
|
return hlTrue;
|
||||||
}
|
}
|
||||||
|
|
||||||
template<typename TSGADirectoryHeader, typename TSGASection, typename TSGAFolder, typename TSGAFile, typename TSGAFileHeader>
|
template<typename TSGAHeader, typename TSGADirectoryHeader, typename TSGASection, typename TSGAFolder, typename TSGAFile>
|
||||||
hlVoid CSGAFile::CSGADirectory<TSGADirectoryHeader, TSGASection, TSGAFolder, TSGAFile, TSGAFileHeader>::UnmapDataStructures()
|
hlVoid CSGAFile::CSGADirectory<TSGAHeader, TSGADirectoryHeader, TSGASection, TSGAFolder, TSGAFile>::UnmapDataStructures()
|
||||||
{
|
{
|
||||||
this->pDirectoryHeader = 0;
|
this->pDirectoryHeader = 0;
|
||||||
this->lpSections = 0;
|
this->lpSections = 0;
|
||||||
|
@ -284,8 +349,8 @@ hlVoid CSGAFile::CSGADirectory<TSGADirectoryHeader, TSGASection, TSGAFolder, TSG
|
||||||
this->File.pMapping->Unmap(this->pHeaderDirectoryView);
|
this->File.pMapping->Unmap(this->pHeaderDirectoryView);
|
||||||
}
|
}
|
||||||
|
|
||||||
template<typename TSGADirectoryHeader, typename TSGASection, typename TSGAFolder, typename TSGAFile, typename TSGAFileHeader>
|
template<typename TSGAHeader, typename TSGADirectoryHeader, typename TSGASection, typename TSGAFolder, typename TSGAFile>
|
||||||
CDirectoryFolder *CSGAFile::CSGADirectory<TSGADirectoryHeader, TSGASection, TSGAFolder, TSGAFile, TSGAFileHeader>::CreateRoot()
|
CDirectoryFolder *CSGAFile::CSGADirectory<TSGAHeader, TSGADirectoryHeader, TSGASection, TSGAFolder, TSGAFile>::CreateRoot()
|
||||||
{
|
{
|
||||||
CDirectoryFolder *pRoot = new CDirectoryFolder(&File);
|
CDirectoryFolder *pRoot = new CDirectoryFolder(&File);
|
||||||
|
|
||||||
|
@ -310,8 +375,8 @@ CDirectoryFolder *CSGAFile::CSGADirectory<TSGADirectoryHeader, TSGASection, TSGA
|
||||||
return pRoot;
|
return pRoot;
|
||||||
}
|
}
|
||||||
|
|
||||||
template<typename TSGADirectoryHeader, typename TSGASection, typename TSGAFolder, typename TSGAFile, typename TSGAFileHeader>
|
template<typename TSGAHeader, typename TSGADirectoryHeader, typename TSGASection, typename TSGAFolder, typename TSGAFile>
|
||||||
hlVoid CSGAFile::CSGADirectory<TSGADirectoryHeader, TSGASection, TSGAFolder, TSGAFile, TSGAFileHeader>::CreateFolder(CDirectoryFolder *pParent, hlUInt uiFolderIndex)
|
hlVoid CSGAFile::CSGADirectory<TSGAHeader, TSGADirectoryHeader, TSGASection, TSGAFolder, TSGAFile>::CreateFolder(CDirectoryFolder *pParent, hlUInt uiFolderIndex)
|
||||||
{
|
{
|
||||||
const hlChar* lpName = this->lpStringTable + this->lpFolders[uiFolderIndex].uiNameOffset;
|
const hlChar* lpName = this->lpStringTable + this->lpFolders[uiFolderIndex].uiNameOffset;
|
||||||
if(*lpName != '\0')
|
if(*lpName != '\0')
|
||||||
|
@ -351,8 +416,108 @@ hlVoid CSGAFile::CSGADirectory<TSGADirectoryHeader, TSGASection, TSGAFolder, TSG
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
template<typename TSGADirectoryHeader, typename TSGASection, typename TSGAFolder, typename TSGAFile, typename TSGAFileHeader>
|
template<typename TSGAHeader, typename TSGADirectoryHeader, typename TSGASection, typename TSGAFolder>
|
||||||
hlBool CSGAFile::CSGADirectory<TSGADirectoryHeader, TSGASection, TSGAFolder, TSGAFile, TSGAFileHeader>::GetItemAttributeInternal(const CDirectoryItem *pItem, HLPackageAttribute eAttribute, HLAttribute &Attribute) const
|
hlBool CSGAFile::CSGASpecializedDirectory<TSGAHeader, TSGADirectoryHeader, TSGASection, TSGAFolder, CSGAFile::SGAFile4>::GetItemAttributeInternal(const CDirectoryItem *pItem, HLPackageAttribute eAttribute, HLAttribute &Attribute) const
|
||||||
|
{
|
||||||
|
if(pItem->GetID() != HL_ID_INVALID)
|
||||||
|
{
|
||||||
|
switch(pItem->GetType())
|
||||||
|
{
|
||||||
|
case HL_ITEM_FILE:
|
||||||
|
{
|
||||||
|
const CDirectoryFile *pFile = static_cast<const CDirectoryFile *>(pItem);
|
||||||
|
const SGAFile &File = this->lpFiles[pFile->GetID()];
|
||||||
|
switch(eAttribute)
|
||||||
|
{
|
||||||
|
case HL_SGA_ITEM_CRC:
|
||||||
|
{
|
||||||
|
Mapping::CView *pFileHeaderView = 0;
|
||||||
|
if(this->File.pMapping->Map(pFileHeaderView, static_cast<const SGAHeader *>(this->File.pHeader)->uiFileDataOffset + File.uiOffset - sizeof(SGAFileHeader), sizeof(SGAFileHeader)))
|
||||||
|
{
|
||||||
|
const SGAFileHeader* pFileHeader = static_cast<const SGAFileHeader *>(pFileHeaderView->GetView());
|
||||||
|
hlAttributeSetUnsignedInteger(&Attribute, CSGAFile::lpItemAttributeNames[eAttribute], pFileHeader->uiCRC32, hlTrue);
|
||||||
|
this->File.pMapping->Unmap(pFileHeaderView);
|
||||||
|
return hlTrue;
|
||||||
|
}
|
||||||
|
return hlFalse;
|
||||||
|
}
|
||||||
|
case HL_SGA_ITEM_VERIFICATION:
|
||||||
|
{
|
||||||
|
hlAttributeSetString(&Attribute, CSGAFile::lpItemAttributeNames[eAttribute], CSGAFile::lpVerificationNames[CSGAFile::VERIFICATION_CRC]);
|
||||||
|
return hlTrue;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return hlFalse;
|
||||||
|
}
|
||||||
|
|
||||||
|
template<typename TSGAHeader, typename TSGADirectoryHeader, typename TSGASection, typename TSGAFolder>
|
||||||
|
hlBool CSGAFile::CSGASpecializedDirectory<TSGAHeader, TSGADirectoryHeader, TSGASection, TSGAFolder, CSGAFile::SGAFile6>::GetItemAttributeInternal(const CDirectoryItem *pItem, HLPackageAttribute eAttribute, HLAttribute &Attribute) const
|
||||||
|
{
|
||||||
|
if(pItem->GetID() != HL_ID_INVALID)
|
||||||
|
{
|
||||||
|
switch(pItem->GetType())
|
||||||
|
{
|
||||||
|
case HL_ITEM_FILE:
|
||||||
|
{
|
||||||
|
const CDirectoryFile *pFile = static_cast<const CDirectoryFile *>(pItem);
|
||||||
|
const SGAFile &File = this->lpFiles[pFile->GetID()];
|
||||||
|
switch(eAttribute)
|
||||||
|
{
|
||||||
|
case HL_SGA_ITEM_CRC:
|
||||||
|
{
|
||||||
|
hlAttributeSetUnsignedInteger(&Attribute, CSGAFile::lpItemAttributeNames[eAttribute], File.uiCRC32, hlTrue);
|
||||||
|
return hlTrue;
|
||||||
|
}
|
||||||
|
case HL_SGA_ITEM_VERIFICATION:
|
||||||
|
{
|
||||||
|
hlAttributeSetString(&Attribute, CSGAFile::lpItemAttributeNames[eAttribute], CSGAFile::lpVerificationNames[CSGAFile::VERIFICATION_CRC]);
|
||||||
|
return hlTrue;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return hlFalse;
|
||||||
|
}
|
||||||
|
|
||||||
|
template<typename TSGAHeader, typename TSGADirectoryHeader, typename TSGASection, typename TSGAFolder, typename TSGAFile>
|
||||||
|
hlBool CSGAFile::CSGASpecializedDirectory<TSGAHeader, TSGADirectoryHeader, TSGASection, TSGAFolder, TSGAFile>::GetItemAttributeInternal(const CDirectoryItem *pItem, HLPackageAttribute eAttribute, HLAttribute &Attribute) const
|
||||||
|
{
|
||||||
|
if(pItem->GetID() != HL_ID_INVALID)
|
||||||
|
{
|
||||||
|
switch(pItem->GetType())
|
||||||
|
{
|
||||||
|
case HL_ITEM_FILE:
|
||||||
|
{
|
||||||
|
const CDirectoryFile *pFile = static_cast<const CDirectoryFile *>(pItem);
|
||||||
|
const SGAFile &File = this->lpFiles[pFile->GetID()];
|
||||||
|
switch(eAttribute)
|
||||||
|
{
|
||||||
|
case HL_SGA_ITEM_CRC:
|
||||||
|
{
|
||||||
|
hlAttributeSetUnsignedInteger(&Attribute, CSGAFile::lpItemAttributeNames[eAttribute], File.uiCRC32, hlTrue);
|
||||||
|
return hlTrue;
|
||||||
|
}
|
||||||
|
case HL_SGA_ITEM_VERIFICATION:
|
||||||
|
{
|
||||||
|
hlAttributeSetString(&Attribute, CSGAFile::lpItemAttributeNames[eAttribute], CSGAFile::lpVerificationNames[File.uiDummy0 < CSGAFile::VERIFICATION_COUNT ? File.uiDummy0 : CSGAFile::VERIFICATION_NONE]);
|
||||||
|
return hlTrue;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return hlFalse;
|
||||||
|
}
|
||||||
|
|
||||||
|
template<typename TSGAHeader, typename TSGADirectoryHeader, typename TSGASection, typename TSGAFolder, typename TSGAFile>
|
||||||
|
hlBool CSGAFile::CSGADirectory<TSGAHeader, TSGADirectoryHeader, TSGASection, TSGAFolder, TSGAFile>::GetItemAttributeInternal(const CDirectoryItem *pItem, HLPackageAttribute eAttribute, HLAttribute &Attribute) const
|
||||||
{
|
{
|
||||||
if(pItem->GetID() != HL_ID_INVALID)
|
if(pItem->GetID() != HL_ID_INVALID)
|
||||||
{
|
{
|
||||||
|
@ -393,7 +558,7 @@ hlBool CSGAFile::CSGADirectory<TSGADirectoryHeader, TSGASection, TSGAFolder, TSG
|
||||||
case HL_ITEM_FILE:
|
case HL_ITEM_FILE:
|
||||||
{
|
{
|
||||||
const CDirectoryFile *pFile = static_cast<const CDirectoryFile *>(pItem);
|
const CDirectoryFile *pFile = static_cast<const CDirectoryFile *>(pItem);
|
||||||
const TSGAFile &File = this->lpFiles[pFile->GetID()];
|
const SGAFile &File = this->lpFiles[pFile->GetID()];
|
||||||
switch(eAttribute)
|
switch(eAttribute)
|
||||||
{
|
{
|
||||||
case HL_SGA_ITEM_SECTION_ALIAS:
|
case HL_SGA_ITEM_SECTION_ALIAS:
|
||||||
|
@ -436,31 +601,19 @@ hlBool CSGAFile::CSGADirectory<TSGADirectoryHeader, TSGASection, TSGAFolder, TSG
|
||||||
hlAttributeSetUnsignedInteger(&Attribute, CSGAFile::lpItemAttributeNames[eAttribute], File.uiType, hlFalse);
|
hlAttributeSetUnsignedInteger(&Attribute, CSGAFile::lpItemAttributeNames[eAttribute], File.uiType, hlFalse);
|
||||||
return hlTrue;
|
return hlTrue;
|
||||||
}
|
}
|
||||||
case HL_SGA_ITEM_CRC:
|
|
||||||
{
|
|
||||||
Mapping::CView *pFileHeaderView = 0;
|
|
||||||
if(this->File.pMapping->Map(pFileHeaderView, this->File.pHeader->uiFileDataOffset + File.uiOffset - sizeof(TSGAFileHeader), sizeof(TSGAFileHeader)))
|
|
||||||
{
|
|
||||||
const TSGAFileHeader* pFileHeader = static_cast<const TSGAFileHeader *>(pFileHeaderView->GetView());
|
|
||||||
hlAttributeSetUnsignedInteger(&Attribute, CSGAFile::lpItemAttributeNames[eAttribute], pFileHeader->uiCRC32, hlTrue);
|
|
||||||
this->File.pMapping->Unmap(pFileHeaderView);
|
|
||||||
return hlTrue;
|
|
||||||
}
|
|
||||||
return hlFalse;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return hlFalse;
|
return CSGASpecializedDirectory<TSGAHeader, TSGADirectoryHeader, TSGASection, TSGAFolder, TSGAFile>::GetItemAttributeInternal(pItem, eAttribute, Attribute);
|
||||||
}
|
}
|
||||||
|
|
||||||
template<typename TSGADirectoryHeader, typename TSGASection, typename TSGAFolder, typename TSGAFile, typename TSGAFileHeader>
|
template<typename TSGAHeader, typename TSGADirectoryHeader, typename TSGASection, typename TSGAFolder, typename TSGAFile>
|
||||||
hlBool CSGAFile::CSGADirectory<TSGADirectoryHeader, TSGASection, TSGAFolder, TSGAFile, TSGAFileHeader>::GetFileExtractableInternal(const CDirectoryFile *pFile, hlBool &bExtractable) const
|
hlBool CSGAFile::CSGADirectory<TSGAHeader, TSGADirectoryHeader, TSGASection, TSGAFolder, TSGAFile>::GetFileExtractableInternal(const CDirectoryFile *pFile, hlBool &bExtractable) const
|
||||||
{
|
{
|
||||||
#if !USE_ZLIB
|
#if !USE_ZLIB
|
||||||
const TSGAFile &File = this->lpFiles[pFile->GetID()];
|
const SGAFile &File = this->lpFiles[pFile->GetID()];
|
||||||
|
|
||||||
bExtractable = File.uiType == 0;
|
bExtractable = File.uiType == 0;
|
||||||
#else
|
#else
|
||||||
|
@ -470,10 +623,10 @@ hlBool CSGAFile::CSGADirectory<TSGADirectoryHeader, TSGASection, TSGAFolder, TSG
|
||||||
return hlTrue;
|
return hlTrue;
|
||||||
}
|
}
|
||||||
|
|
||||||
template<typename TSGADirectoryHeader, typename TSGASection, typename TSGAFolder, typename TSGAFile, typename TSGAFileHeader>
|
template<typename TSGAHeader, typename TSGADirectoryHeader, typename TSGASection, typename TSGAFolder>
|
||||||
hlBool CSGAFile::CSGADirectory<TSGADirectoryHeader, TSGASection, TSGAFolder, TSGAFile, TSGAFileHeader>::GetFileValidationInternal(const CDirectoryFile *pFile, HLValidation &eValidation) const
|
hlBool CSGAFile::CSGASpecializedDirectory<TSGAHeader, TSGADirectoryHeader, TSGASection, TSGAFolder, CSGAFile::SGAFile4>::GetFileValidationInternal(const CDirectoryFile *pFile, HLValidation &eValidation) const
|
||||||
{
|
{
|
||||||
const TSGAFile &File = this->lpFiles[pFile->GetID()];
|
const SGAFile &File = this->lpFiles[pFile->GetID()];
|
||||||
|
|
||||||
#if !USE_ZLIB
|
#if !USE_ZLIB
|
||||||
if(File.uiType != 0)
|
if(File.uiType != 0)
|
||||||
|
@ -484,11 +637,11 @@ hlBool CSGAFile::CSGADirectory<TSGADirectoryHeader, TSGASection, TSGAFolder, TSG
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
Mapping::CView *pFileHeaderDataView = 0;
|
Mapping::CView *pFileHeaderDataView = 0;
|
||||||
if(this->File.pMapping->Map(pFileHeaderDataView, this->File.pHeader->uiFileDataOffset + File.uiOffset - sizeof(TSGAFileHeader), File.uiSizeOnDisk + sizeof(TSGAFileHeader)))
|
if(this->File.pMapping->Map(pFileHeaderDataView, static_cast<const SGAHeader *>(this->File.pHeader)->uiFileDataOffset + File.uiOffset - sizeof(SGAFileHeader), File.uiSizeOnDisk + sizeof(SGAFileHeader)))
|
||||||
{
|
{
|
||||||
hlULong uiChecksum = 0;
|
hlULong uiChecksum = 0;
|
||||||
const TSGAFileHeader* pFileHeader = static_cast<const TSGAFileHeader*>(pFileHeaderDataView->GetView());
|
const SGAFileHeader* pFileHeader = static_cast<const SGAFileHeader*>(pFileHeaderDataView->GetView());
|
||||||
const hlByte* lpBuffer = reinterpret_cast<const hlByte *>(pFileHeader) + sizeof(TSGAFileHeader);
|
const hlByte* lpBuffer = reinterpret_cast<const hlByte *>(pFileHeader) + sizeof(SGAFileHeader);
|
||||||
#if USE_ZLIB
|
#if USE_ZLIB
|
||||||
hlByte *lpInflateBuffer = 0;
|
hlByte *lpInflateBuffer = 0;
|
||||||
if(File.uiType != 0)
|
if(File.uiType != 0)
|
||||||
|
@ -535,7 +688,10 @@ hlBool CSGAFile::CSGADirectory<TSGADirectoryHeader, TSGASection, TSGAFolder, TSG
|
||||||
#if USE_ZLIB
|
#if USE_ZLIB
|
||||||
delete []lpInflateBuffer;
|
delete []lpInflateBuffer;
|
||||||
#endif
|
#endif
|
||||||
eValidation = static_cast<hlULong>(pFileHeader->uiCRC32) == uiChecksum ? HL_VALIDATES_OK : HL_VALIDATES_CORRUPT;
|
if(eValidation == HL_VALIDATES_ASSUMED_OK)
|
||||||
|
{
|
||||||
|
eValidation = static_cast<hlULong>(pFileHeader->uiCRC32) == uiChecksum ? HL_VALIDATES_OK : HL_VALIDATES_CORRUPT;
|
||||||
|
}
|
||||||
|
|
||||||
this->File.pMapping->Unmap(pFileHeaderDataView);
|
this->File.pMapping->Unmap(pFileHeaderDataView);
|
||||||
}
|
}
|
||||||
|
@ -547,41 +703,166 @@ hlBool CSGAFile::CSGADirectory<TSGADirectoryHeader, TSGASection, TSGAFolder, TSG
|
||||||
return hlTrue;
|
return hlTrue;
|
||||||
}
|
}
|
||||||
|
|
||||||
template<typename TSGADirectoryHeader, typename TSGASection, typename TSGAFolder, typename TSGAFile, typename TSGAFileHeader>
|
template<typename TSGAHeader, typename TSGADirectoryHeader, typename TSGASection, typename TSGAFolder>
|
||||||
hlBool CSGAFile::CSGADirectory<TSGADirectoryHeader, TSGASection, TSGAFolder, TSGAFile, TSGAFileHeader>::GetFileSizeInternal(const CDirectoryFile *pFile, hlUInt &uiSize) const
|
hlBool CSGAFile::CSGASpecializedDirectory<TSGAHeader, TSGADirectoryHeader, TSGASection, TSGAFolder, CSGAFile::SGAFile6>::GetFileValidationInternal(const CDirectoryFile *pFile, HLValidation &eValidation) const
|
||||||
{
|
{
|
||||||
const TSGAFile &File = this->lpFiles[pFile->GetID()];
|
const SGAFile &File = this->lpFiles[pFile->GetID()];
|
||||||
|
|
||||||
|
Mapping::CView *pFileHeaderDataView = 0;
|
||||||
|
if(this->File.pMapping->Map(pFileHeaderDataView, static_cast<const SGAHeader *>(this->File.pHeader)->uiFileDataOffset + File.uiOffset, File.uiSizeOnDisk))
|
||||||
|
{
|
||||||
|
hlULong uiChecksum = 0;
|
||||||
|
const hlByte* lpBuffer = reinterpret_cast<const hlByte *>(pFileHeaderDataView->GetView());
|
||||||
|
hlULongLong uiTotalBytes = 0, uiFileBytes = File.uiSizeOnDisk;
|
||||||
|
|
||||||
|
hlBool bCancel = hlFalse;
|
||||||
|
hlValidateFileProgress(const_cast<CDirectoryFile *>(pFile), uiTotalBytes, uiFileBytes, &bCancel);
|
||||||
|
|
||||||
|
while(uiTotalBytes < uiFileBytes)
|
||||||
|
{
|
||||||
|
if(bCancel)
|
||||||
|
{
|
||||||
|
eValidation = HL_VALIDATES_CANCELED;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
hlUInt uiBufferSize = static_cast<hlUInt>(uiTotalBytes + HL_SGA_CHECKSUM_LENGTH <= uiFileBytes ? HL_SGA_CHECKSUM_LENGTH : uiFileBytes - uiTotalBytes);
|
||||||
|
uiChecksum = CRC32(lpBuffer, uiBufferSize, uiChecksum);
|
||||||
|
|
||||||
|
lpBuffer += uiBufferSize;
|
||||||
|
uiTotalBytes += static_cast<hlULongLong>(uiBufferSize);
|
||||||
|
|
||||||
|
hlValidateFileProgress(const_cast<CDirectoryFile *>(pFile), uiTotalBytes, uiFileBytes, &bCancel);
|
||||||
|
}
|
||||||
|
if(eValidation == HL_VALIDATES_ASSUMED_OK)
|
||||||
|
{
|
||||||
|
eValidation = static_cast<hlULong>(File.uiCRC32) == uiChecksum ? HL_VALIDATES_OK : HL_VALIDATES_CORRUPT;
|
||||||
|
}
|
||||||
|
|
||||||
|
this->File.pMapping->Unmap(pFileHeaderDataView);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
eValidation = HL_VALIDATES_ERROR;
|
||||||
|
}
|
||||||
|
|
||||||
|
return hlTrue;
|
||||||
|
}
|
||||||
|
|
||||||
|
template<typename TSGAHeader, typename TSGADirectoryHeader, typename TSGASection, typename TSGAFolder, typename TSGAFile>
|
||||||
|
hlBool CSGAFile::CSGASpecializedDirectory<TSGAHeader, TSGADirectoryHeader, TSGASection, TSGAFolder, TSGAFile>::GetFileValidationInternal(const CDirectoryFile *pFile, HLValidation &eValidation) const
|
||||||
|
{
|
||||||
|
const SGAFile &File = this->lpFiles[pFile->GetID()];
|
||||||
|
|
||||||
|
Mapping::CView *pFileHeaderDataView = 0;
|
||||||
|
if(this->File.pMapping->Map(pFileHeaderDataView, static_cast<const SGAHeader *>(this->File.pHeader)->uiFileDataOffset + File.uiOffset, File.uiSizeOnDisk))
|
||||||
|
{
|
||||||
|
hlULong uiChecksum = 0;
|
||||||
|
const hlByte* lpBuffer = reinterpret_cast<const hlByte *>(pFileHeaderDataView->GetView());
|
||||||
|
hlULongLong uiTotalBytes = 0, uiFileBytes = File.uiSizeOnDisk;
|
||||||
|
hlULongLong uiBlockSize = this->pDirectoryHeader->uiBlockSize;
|
||||||
|
if(uiBlockSize == 0)
|
||||||
|
{
|
||||||
|
uiBlockSize = HL_SGA_CHECKSUM_LENGTH;
|
||||||
|
}
|
||||||
|
|
||||||
|
Checksum* checksum = 0;
|
||||||
|
switch(File.uiDummy0)
|
||||||
|
{
|
||||||
|
case CSGAFile::VERIFICATION_CRC_BLOCKS:
|
||||||
|
checksum = new CRC32Checksum();
|
||||||
|
break;
|
||||||
|
case CSGAFile::VERIFICATION_MD5_BLOCKS:
|
||||||
|
checksum = new MD5Checksum();
|
||||||
|
break;
|
||||||
|
case CSGAFile::VERIFICATION_SHA1_BLOCKS:
|
||||||
|
checksum = new SHA1Checksum();
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
const hlByte *lpHashTable = reinterpret_cast<const hlByte *>(this->pDirectoryHeader) + this->pDirectoryHeader->uiHashTableOffset + File.uiHashOffset;
|
||||||
|
|
||||||
|
hlBool bCancel = hlFalse;
|
||||||
|
hlValidateFileProgress(const_cast<CDirectoryFile *>(pFile), uiTotalBytes, uiFileBytes, &bCancel);
|
||||||
|
|
||||||
|
while(uiTotalBytes < uiFileBytes)
|
||||||
|
{
|
||||||
|
if(bCancel)
|
||||||
|
{
|
||||||
|
eValidation = HL_VALIDATES_CANCELED;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
hlUInt uiBufferSize = static_cast<hlUInt>(uiTotalBytes + uiBlockSize <= uiFileBytes ? uiBlockSize : uiFileBytes - uiTotalBytes);
|
||||||
|
uiChecksum = CRC32(lpBuffer, uiBufferSize, uiChecksum);
|
||||||
|
if(checksum != 0)
|
||||||
|
{
|
||||||
|
checksum->Initialize();
|
||||||
|
checksum->Update(lpBuffer, uiBufferSize);
|
||||||
|
if(!checksum->Finalize(lpHashTable))
|
||||||
|
{
|
||||||
|
eValidation = HL_VALIDATES_CORRUPT;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
lpHashTable += checksum->GetDigestSize();
|
||||||
|
}
|
||||||
|
|
||||||
|
lpBuffer += uiBufferSize;
|
||||||
|
uiTotalBytes += static_cast<hlULongLong>(uiBufferSize);
|
||||||
|
|
||||||
|
hlValidateFileProgress(const_cast<CDirectoryFile *>(pFile), uiTotalBytes, uiFileBytes, &bCancel);
|
||||||
|
}
|
||||||
|
if(eValidation == HL_VALIDATES_ASSUMED_OK)
|
||||||
|
{
|
||||||
|
eValidation = static_cast<hlULong>(File.uiCRC32) == uiChecksum ? HL_VALIDATES_OK : HL_VALIDATES_CORRUPT;
|
||||||
|
}
|
||||||
|
|
||||||
|
delete checksum;
|
||||||
|
|
||||||
|
this->File.pMapping->Unmap(pFileHeaderDataView);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
eValidation = HL_VALIDATES_ERROR;
|
||||||
|
}
|
||||||
|
|
||||||
|
return hlTrue;
|
||||||
|
}
|
||||||
|
|
||||||
|
template<typename TSGAHeader, typename TSGADirectoryHeader, typename TSGASection, typename TSGAFolder, typename TSGAFile>
|
||||||
|
hlBool CSGAFile::CSGADirectory<TSGAHeader, TSGADirectoryHeader, TSGASection, TSGAFolder, TSGAFile>::GetFileSizeInternal(const CDirectoryFile *pFile, hlUInt &uiSize) const
|
||||||
|
{
|
||||||
|
const SGAFile &File = this->lpFiles[pFile->GetID()];
|
||||||
|
|
||||||
uiSize = File.uiSize;
|
uiSize = File.uiSize;
|
||||||
|
|
||||||
return hlTrue;
|
return hlTrue;
|
||||||
}
|
}
|
||||||
|
|
||||||
template<typename TSGADirectoryHeader, typename TSGASection, typename TSGAFolder, typename TSGAFile, typename TSGAFileHeader>
|
template<typename TSGAHeader, typename TSGADirectoryHeader, typename TSGASection, typename TSGAFolder, typename TSGAFile>
|
||||||
hlBool CSGAFile::CSGADirectory<TSGADirectoryHeader, TSGASection, TSGAFolder, TSGAFile, TSGAFileHeader>::GetFileSizeOnDiskInternal(const CDirectoryFile *pFile, hlUInt &uiSize) const
|
hlBool CSGAFile::CSGADirectory<TSGAHeader, TSGADirectoryHeader, TSGASection, TSGAFolder, TSGAFile>::GetFileSizeOnDiskInternal(const CDirectoryFile *pFile, hlUInt &uiSize) const
|
||||||
{
|
{
|
||||||
const TSGAFile &File = this->lpFiles[pFile->GetID()];
|
const SGAFile &File = this->lpFiles[pFile->GetID()];
|
||||||
|
|
||||||
uiSize = File.uiSizeOnDisk;
|
uiSize = File.uiSizeOnDisk;
|
||||||
|
|
||||||
return hlTrue;
|
return hlTrue;
|
||||||
}
|
}
|
||||||
|
|
||||||
template<typename TSGADirectoryHeader, typename TSGASection, typename TSGAFolder, typename TSGAFile, typename TSGAFileHeader>
|
template<typename TSGAHeader, typename TSGADirectoryHeader, typename TSGASection, typename TSGAFolder, typename TSGAFile>
|
||||||
hlBool CSGAFile::CSGADirectory<TSGADirectoryHeader, TSGASection, TSGAFolder, TSGAFile, TSGAFileHeader>::CreateStreamInternal(const CDirectoryFile *pFile, Streams::IStream *&pStream) const
|
hlBool CSGAFile::CSGADirectory<TSGAHeader, TSGADirectoryHeader, TSGASection, TSGAFolder, TSGAFile>::CreateStreamInternal(const CDirectoryFile *pFile, Streams::IStream *&pStream) const
|
||||||
{
|
{
|
||||||
const TSGAFile &File = this->lpFiles[pFile->GetID()];
|
const SGAFile &File = this->lpFiles[pFile->GetID()];
|
||||||
|
|
||||||
if(File.uiType == 0)
|
if(File.uiType == 0)
|
||||||
{
|
{
|
||||||
pStream = new Streams::CMappingStream(*this->File.pMapping, this->File.pHeader->uiFileDataOffset + File.uiOffset, File.uiSizeOnDisk);
|
pStream = new Streams::CMappingStream(*this->File.pMapping, static_cast<const SGAHeader *>(this->File.pHeader)->uiFileDataOffset + File.uiOffset, File.uiSizeOnDisk);
|
||||||
return hlTrue;
|
return hlTrue;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
#if USE_ZLIB
|
#if USE_ZLIB
|
||||||
Mapping::CView *pFileDataView = 0;
|
Mapping::CView *pFileDataView = 0;
|
||||||
if(this->File.pMapping->Map(pFileDataView, this->File.pHeader->uiFileDataOffset + File.uiOffset, File.uiSizeOnDisk))
|
if(this->File.pMapping->Map(pFileDataView, static_cast<const SGAHeader *>(this->File.pHeader)->uiFileDataOffset + File.uiOffset, File.uiSizeOnDisk))
|
||||||
{
|
{
|
||||||
hlBool bResult = hlFalse;
|
hlBool bResult = hlFalse;
|
||||||
hlByte *lpInflateBuffer = new hlByte[File.uiSize];
|
hlByte *lpInflateBuffer = new hlByte[File.uiSize];
|
||||||
|
@ -617,8 +898,8 @@ hlBool CSGAFile::CSGADirectory<TSGADirectoryHeader, TSGASection, TSGAFolder, TSG
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
template<typename TSGADirectoryHeader, typename TSGASection, typename TSGAFolder, typename TSGAFile, typename TSGAFileHeader>
|
template<typename TSGAHeader, typename TSGADirectoryHeader, typename TSGASection, typename TSGAFolder, typename TSGAFile>
|
||||||
hlVoid CSGAFile::CSGADirectory<TSGADirectoryHeader, TSGASection, TSGAFolder, TSGAFile, TSGAFileHeader>::ReleaseStreamInternal(Streams::IStream &Stream) const
|
hlVoid CSGAFile::CSGADirectory<TSGAHeader, TSGADirectoryHeader, TSGASection, TSGAFolder, TSGAFile>::ReleaseStreamInternal(Streams::IStream &Stream) const
|
||||||
{
|
{
|
||||||
if(Stream.GetType() == HL_STREAM_MEMORY)
|
if(Stream.GetType() == HL_STREAM_MEMORY)
|
||||||
{
|
{
|
||||||
|
|
155
HLLib/SGAFile.h
155
HLLib/SGAFile.h
|
@ -22,11 +22,15 @@ namespace HLLib
|
||||||
private:
|
private:
|
||||||
#pragma pack(1)
|
#pragma pack(1)
|
||||||
|
|
||||||
struct SGAHeader
|
struct SGAHeaderBase
|
||||||
{
|
{
|
||||||
hlChar lpSignature[8];
|
hlChar lpSignature[8];
|
||||||
hlUShort uiMajorVersion;
|
hlUShort uiMajorVersion;
|
||||||
hlUShort uiMinorVersion;
|
hlUShort uiMinorVersion;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct SGAHeader4 : public SGAHeaderBase
|
||||||
|
{
|
||||||
hlByte lpFileMD5[16];
|
hlByte lpFileMD5[16];
|
||||||
hlWChar lpName[64];
|
hlWChar lpName[64];
|
||||||
hlByte lpHeaderMD5[16];
|
hlByte lpHeaderMD5[16];
|
||||||
|
@ -35,6 +39,14 @@ namespace HLLib
|
||||||
hlUInt uiDummy0;
|
hlUInt uiDummy0;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
struct SGAHeader6 : public SGAHeaderBase
|
||||||
|
{
|
||||||
|
hlWChar lpName[64];
|
||||||
|
hlUInt uiHeaderLength;
|
||||||
|
hlUInt uiFileDataOffset;
|
||||||
|
hlUInt uiDummy0;
|
||||||
|
};
|
||||||
|
|
||||||
template<typename T>
|
template<typename T>
|
||||||
struct SGADirectoryHeader
|
struct SGADirectoryHeader
|
||||||
{
|
{
|
||||||
|
@ -51,6 +63,12 @@ namespace HLLib
|
||||||
typedef SGADirectoryHeader<hlUShort> SGADirectoryHeader4;
|
typedef SGADirectoryHeader<hlUShort> SGADirectoryHeader4;
|
||||||
typedef SGADirectoryHeader<hlUInt> SGADirectoryHeader5;
|
typedef SGADirectoryHeader<hlUInt> SGADirectoryHeader5;
|
||||||
|
|
||||||
|
struct SGADirectoryHeader7 : public SGADirectoryHeader5
|
||||||
|
{
|
||||||
|
hlUInt uiHashTableOffset;
|
||||||
|
hlUInt uiBlockSize;
|
||||||
|
};
|
||||||
|
|
||||||
template<typename T>
|
template<typename T>
|
||||||
struct SGASection
|
struct SGASection
|
||||||
{
|
{
|
||||||
|
@ -79,7 +97,7 @@ namespace HLLib
|
||||||
typedef SGAFolder<hlUShort> SGAFolder4;
|
typedef SGAFolder<hlUShort> SGAFolder4;
|
||||||
typedef SGAFolder<hlUInt> SGAFolder5;
|
typedef SGAFolder<hlUInt> SGAFolder5;
|
||||||
|
|
||||||
struct SGAFile
|
struct SGAFile4
|
||||||
{
|
{
|
||||||
hlUInt uiNameOffset;
|
hlUInt uiNameOffset;
|
||||||
hlUInt uiOffset;
|
hlUInt uiOffset;
|
||||||
|
@ -90,12 +108,32 @@ namespace HLLib
|
||||||
hlByte uiType;
|
hlByte uiType;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
struct SGAFile6 : public SGAFile4
|
||||||
|
{
|
||||||
|
hlUInt uiCRC32;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct SGAFile7 : public SGAFile6
|
||||||
|
{
|
||||||
|
hlUInt uiHashOffset;
|
||||||
|
};
|
||||||
|
|
||||||
struct SGAFileHeader
|
struct SGAFileHeader
|
||||||
{
|
{
|
||||||
hlChar lpName[256];
|
hlChar lpName[256];
|
||||||
hlUInt uiCRC32;
|
hlUInt uiCRC32;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
enum SGAFileVerification
|
||||||
|
{
|
||||||
|
VERIFICATION_NONE,
|
||||||
|
VERIFICATION_CRC,
|
||||||
|
VERIFICATION_CRC_BLOCKS,
|
||||||
|
VERIFICATION_MD5_BLOCKS,
|
||||||
|
VERIFICATION_SHA1_BLOCKS,
|
||||||
|
VERIFICATION_COUNT,
|
||||||
|
};
|
||||||
|
|
||||||
#pragma pack()
|
#pragma pack()
|
||||||
|
|
||||||
class ISGADirectory
|
class ISGADirectory
|
||||||
|
@ -120,23 +158,100 @@ namespace HLLib
|
||||||
virtual hlVoid ReleaseStreamInternal(Streams::IStream &Stream) const = 0;
|
virtual hlVoid ReleaseStreamInternal(Streams::IStream &Stream) const = 0;
|
||||||
};
|
};
|
||||||
|
|
||||||
template<typename TSGADirectoryHeader, typename TSGASection, typename TSGAFolder, typename TSGAFile, typename TSGAFileHeader>
|
// Specialization SGAFile7 and up where the CRC moved to the header and the CRC is of the compressed data and there are stronger hashes.
|
||||||
class CSGADirectory : public ISGADirectory
|
template<typename TSGAHeader, typename TSGADirectoryHeader, typename TSGASection, typename TSGAFolder, typename TSGAFile>
|
||||||
|
class CSGASpecializedDirectory : public ISGADirectory
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
typedef TSGAHeader SGAHeader;
|
||||||
|
typedef TSGADirectoryHeader SGADirectoryHeader;
|
||||||
|
typedef TSGASection SGASection;
|
||||||
|
typedef TSGAFolder SGAFolder;
|
||||||
|
typedef TSGAFile SGAFile;
|
||||||
|
|
||||||
|
CSGASpecializedDirectory(CSGAFile& File);
|
||||||
|
|
||||||
|
protected:
|
||||||
|
CSGAFile& File;
|
||||||
|
|
||||||
|
Mapping::CView *pHeaderDirectoryView;
|
||||||
|
const SGADirectoryHeader *pDirectoryHeader;
|
||||||
|
const SGASection *lpSections;
|
||||||
|
const SGAFolder *lpFolders;
|
||||||
|
const SGAFile *lpFiles;
|
||||||
|
const hlChar *lpStringTable;
|
||||||
|
|
||||||
|
public:
|
||||||
|
virtual hlBool GetItemAttributeInternal(const CDirectoryItem *pItem, HLPackageAttribute eAttribute, HLAttribute &Attribute) const;
|
||||||
|
|
||||||
|
virtual hlBool GetFileValidationInternal(const CDirectoryFile *pFile, HLValidation &eValidation) const;
|
||||||
|
};
|
||||||
|
|
||||||
|
// Specialization SGAFile4 where the CRC was stored in a SGAFileHeader located before the file data.
|
||||||
|
template<typename TSGAHeader, typename TSGADirectoryHeader, typename TSGASection, typename TSGAFolder>
|
||||||
|
class CSGASpecializedDirectory<TSGAHeader, TSGADirectoryHeader, TSGASection, TSGAFolder, SGAFile4> : public ISGADirectory
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
typedef TSGAHeader SGAHeader;
|
||||||
|
typedef TSGADirectoryHeader SGADirectoryHeader;
|
||||||
|
typedef TSGASection SGASection;
|
||||||
|
typedef TSGAFolder SGAFolder;
|
||||||
|
typedef CSGAFile::SGAFile4 SGAFile;
|
||||||
|
|
||||||
|
CSGASpecializedDirectory(CSGAFile& File);
|
||||||
|
|
||||||
|
protected:
|
||||||
|
CSGAFile& File;
|
||||||
|
|
||||||
|
Mapping::CView *pHeaderDirectoryView;
|
||||||
|
const SGADirectoryHeader *pDirectoryHeader;
|
||||||
|
const SGASection *lpSections;
|
||||||
|
const SGAFolder *lpFolders;
|
||||||
|
const SGAFile *lpFiles;
|
||||||
|
const hlChar *lpStringTable;
|
||||||
|
|
||||||
|
public:
|
||||||
|
virtual hlBool GetItemAttributeInternal(const CDirectoryItem *pItem, HLPackageAttribute eAttribute, HLAttribute &Attribute) const;
|
||||||
|
|
||||||
|
virtual hlBool GetFileValidationInternal(const CDirectoryFile *pFile, HLValidation &eValidation) const;
|
||||||
|
};
|
||||||
|
|
||||||
|
// Specialization SGAFile6 where the CRC moved to the header and the CRC is of the compressed data.
|
||||||
|
template<typename TSGAHeader, typename TSGADirectoryHeader, typename TSGASection, typename TSGAFolder>
|
||||||
|
class CSGASpecializedDirectory<TSGAHeader, TSGADirectoryHeader, TSGASection, TSGAFolder, SGAFile6> : public ISGADirectory
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
typedef TSGAHeader SGAHeader;
|
||||||
|
typedef TSGADirectoryHeader SGADirectoryHeader;
|
||||||
|
typedef TSGASection SGASection;
|
||||||
|
typedef TSGAFolder SGAFolder;
|
||||||
|
typedef CSGAFile::SGAFile6 SGAFile;
|
||||||
|
|
||||||
|
CSGASpecializedDirectory(CSGAFile& File);
|
||||||
|
|
||||||
|
protected:
|
||||||
|
CSGAFile& File;
|
||||||
|
|
||||||
|
Mapping::CView *pHeaderDirectoryView;
|
||||||
|
const SGADirectoryHeader *pDirectoryHeader;
|
||||||
|
const SGASection *lpSections;
|
||||||
|
const SGAFolder *lpFolders;
|
||||||
|
const SGAFile *lpFiles;
|
||||||
|
const hlChar *lpStringTable;
|
||||||
|
|
||||||
|
public:
|
||||||
|
virtual hlBool GetItemAttributeInternal(const CDirectoryItem *pItem, HLPackageAttribute eAttribute, HLAttribute &Attribute) const;
|
||||||
|
|
||||||
|
virtual hlBool GetFileValidationInternal(const CDirectoryFile *pFile, HLValidation &eValidation) const;
|
||||||
|
};
|
||||||
|
|
||||||
|
template<typename TSGAHeader, typename TSGADirectoryHeader, typename TSGASection, typename TSGAFolder, typename TSGAFile>
|
||||||
|
class CSGADirectory : public CSGASpecializedDirectory<TSGAHeader, TSGADirectoryHeader, TSGASection, TSGAFolder, TSGAFile>
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
CSGADirectory(CSGAFile& File);
|
CSGADirectory(CSGAFile& File);
|
||||||
virtual ~CSGADirectory();
|
virtual ~CSGADirectory();
|
||||||
|
|
||||||
private:
|
|
||||||
CSGAFile& File;
|
|
||||||
|
|
||||||
Mapping::CView *pHeaderDirectoryView;
|
|
||||||
const TSGADirectoryHeader *pDirectoryHeader;
|
|
||||||
const TSGASection *lpSections;
|
|
||||||
const TSGAFolder *lpFolders;
|
|
||||||
const TSGAFile *lpFiles;
|
|
||||||
const hlChar *lpStringTable;
|
|
||||||
|
|
||||||
public:
|
public:
|
||||||
virtual hlBool MapDataStructures();
|
virtual hlBool MapDataStructures();
|
||||||
virtual hlVoid UnmapDataStructures();
|
virtual hlVoid UnmapDataStructures();
|
||||||
|
@ -146,7 +261,6 @@ namespace HLLib
|
||||||
virtual hlBool GetItemAttributeInternal(const CDirectoryItem *pItem, HLPackageAttribute eAttribute, HLAttribute &Attribute) const;
|
virtual hlBool GetItemAttributeInternal(const CDirectoryItem *pItem, HLPackageAttribute eAttribute, HLAttribute &Attribute) const;
|
||||||
|
|
||||||
virtual hlBool GetFileExtractableInternal(const CDirectoryFile *pFile, hlBool &bExtractable) const;
|
virtual hlBool GetFileExtractableInternal(const CDirectoryFile *pFile, hlBool &bExtractable) const;
|
||||||
virtual hlBool GetFileValidationInternal(const CDirectoryFile *pFile, HLValidation &eValidation) const;
|
|
||||||
virtual hlBool GetFileSizeInternal(const CDirectoryFile *pFile, hlUInt &uiSize) const;
|
virtual hlBool GetFileSizeInternal(const CDirectoryFile *pFile, hlUInt &uiSize) const;
|
||||||
virtual hlBool GetFileSizeOnDiskInternal(const CDirectoryFile *pFile, hlUInt &uiSize) const;
|
virtual hlBool GetFileSizeOnDiskInternal(const CDirectoryFile *pFile, hlUInt &uiSize) const;
|
||||||
|
|
||||||
|
@ -157,18 +271,23 @@ namespace HLLib
|
||||||
hlVoid CreateFolder(CDirectoryFolder *pParent, hlUInt uiFolderIndex);
|
hlVoid CreateFolder(CDirectoryFolder *pParent, hlUInt uiFolderIndex);
|
||||||
};
|
};
|
||||||
|
|
||||||
typedef CSGADirectory<SGADirectoryHeader4, SGASection4, SGAFolder4, SGAFile, SGAFileHeader> CSGADirectory4;
|
typedef CSGADirectory<SGAHeader4, SGADirectoryHeader4, SGASection4, SGAFolder4, SGAFile4> CSGADirectory4;
|
||||||
typedef CSGADirectory<SGADirectoryHeader5, SGASection5, SGAFolder5, SGAFile, SGAFileHeader> CSGADirectory5;
|
typedef CSGADirectory<SGAHeader4, SGADirectoryHeader5, SGASection5, SGAFolder5, SGAFile4> CSGADirectory5;
|
||||||
|
typedef CSGADirectory<SGAHeader6, SGADirectoryHeader5, SGASection5, SGAFolder5, SGAFile6> CSGADirectory6;
|
||||||
|
typedef CSGADirectory<SGAHeader6, SGADirectoryHeader7, SGASection5, SGAFolder5, SGAFile7> CSGADirectory7;
|
||||||
|
|
||||||
friend CSGADirectory4;
|
friend CSGADirectory4;
|
||||||
friend CSGADirectory5;
|
friend CSGADirectory5;
|
||||||
|
friend CSGADirectory6;
|
||||||
|
friend CSGADirectory7;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
static const char *lpAttributeNames[];
|
static const char *lpAttributeNames[];
|
||||||
static const char *lpItemAttributeNames[];
|
static const char *lpItemAttributeNames[];
|
||||||
|
static const char *lpVerificationNames[];
|
||||||
|
|
||||||
Mapping::CView *pHeaderView;
|
Mapping::CView *pHeaderView;
|
||||||
const SGAHeader *pHeader;
|
const SGAHeaderBase *pHeader;
|
||||||
|
|
||||||
ISGADirectory* pDirectory;
|
ISGADirectory* pDirectory;
|
||||||
|
|
||||||
|
|
|
@ -547,7 +547,10 @@ hlBool CVBSPFile::GetFileValidationInternal(const CDirectoryFile *pFile, HLValid
|
||||||
delete pStream;
|
delete pStream;
|
||||||
}
|
}
|
||||||
|
|
||||||
eValidation = (hlULong)pDirectoryItem->uiCRC32 == uiChecksum ? HL_VALIDATES_OK : HL_VALIDATES_CORRUPT;
|
if(eValidation == HL_VALIDATES_ASSUMED_OK)
|
||||||
|
{
|
||||||
|
eValidation = (hlULong)pDirectoryItem->uiCRC32 == uiChecksum ? HL_VALIDATES_OK : HL_VALIDATES_CORRUPT;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
|
|
@ -471,7 +471,10 @@ hlBool CZIPFile::GetFileValidationInternal(const CDirectoryFile *pFile, HLValida
|
||||||
delete pStream;
|
delete pStream;
|
||||||
}
|
}
|
||||||
|
|
||||||
eValidation = (hlULong)pDirectoryItem->uiCRC32 == uiChecksum ? HL_VALIDATES_OK : HL_VALIDATES_CORRUPT;
|
if(eValidation == HL_VALIDATES_ASSUMED_OK)
|
||||||
|
{
|
||||||
|
eValidation = (hlULong)pDirectoryItem->uiCRC32 == uiChecksum ? HL_VALIDATES_OK : HL_VALIDATES_CORRUPT;
|
||||||
|
}
|
||||||
|
|
||||||
return hlTrue;
|
return hlTrue;
|
||||||
}
|
}
|
||||||
|
|
|
@ -65,8 +65,8 @@ typedef hlSingle hlFloat;
|
||||||
#define hlFalse 0
|
#define hlFalse 0
|
||||||
#define hlTrue 1
|
#define hlTrue 1
|
||||||
|
|
||||||
#define HL_VERSION_NUMBER ((2 << 24) | (4 << 16) | (4 << 8) | 0)
|
#define HL_VERSION_NUMBER ((2 << 24) | (4 << 16) | (5 << 8) | 0)
|
||||||
#define HL_VERSION_STRING "2.4.4"
|
#define HL_VERSION_STRING "2.4.5"
|
||||||
|
|
||||||
#define HL_ID_INVALID 0xffffffff
|
#define HL_ID_INVALID 0xffffffff
|
||||||
|
|
||||||
|
@ -254,6 +254,7 @@ typedef enum
|
||||||
HL_SGA_ITEM_MODIFIED,
|
HL_SGA_ITEM_MODIFIED,
|
||||||
HL_SGA_ITEM_TYPE,
|
HL_SGA_ITEM_TYPE,
|
||||||
HL_SGA_ITEM_CRC,
|
HL_SGA_ITEM_CRC,
|
||||||
|
HL_SGA_ITEM_VERIFICATION,
|
||||||
HL_SGA_ITEM_COUNT,
|
HL_SGA_ITEM_COUNT,
|
||||||
|
|
||||||
HL_VBSP_PACKAGE_VERSION = 0,
|
HL_VBSP_PACKAGE_VERSION = 0,
|
||||||
|
|
|
@ -9,11 +9,11 @@ Library/Author Information:
|
||||||
===========================
|
===========================
|
||||||
|
|
||||||
---- General Library Information ----
|
---- General Library Information ----
|
||||||
Date : January 27th, 2013
|
Date : October 17th, 2013
|
||||||
Author : Ryan Gregg
|
Author : Ryan Gregg
|
||||||
Michael Mohr (Linux Port)
|
Michael Mohr (Linux Port)
|
||||||
Title : HLLib
|
Title : HLLib
|
||||||
Build : 2.4.4
|
Build : 2.4.5
|
||||||
Email address : ryansgregg@hotmail.com (Ryan Gregg)
|
Email address : ryansgregg@hotmail.com (Ryan Gregg)
|
||||||
m.mohr@laposte.net (Michael Mohr)
|
m.mohr@laposte.net (Michael Mohr)
|
||||||
Home page / Website : http://nemesis.thewavelength.net/
|
Home page / Website : http://nemesis.thewavelength.net/
|
||||||
|
@ -93,6 +93,10 @@ Console Commands (Interactive console mode):
|
||||||
Library Changelog:
|
Library Changelog:
|
||||||
==================
|
==================
|
||||||
|
|
||||||
|
v2.4.5
|
||||||
|
- Added support for new SGA file format (v6).
|
||||||
|
- Added support for new SGA file format (v7).
|
||||||
|
|
||||||
v2.4.4
|
v2.4.4
|
||||||
- Fixed support for VPK file format (v1).
|
- Fixed support for VPK file format (v1).
|
||||||
|
|
||||||
|
|
162
lib/HLLib.h
162
lib/HLLib.h
|
@ -65,8 +65,8 @@ typedef hlSingle hlFloat;
|
||||||
#define hlFalse 0
|
#define hlFalse 0
|
||||||
#define hlTrue 1
|
#define hlTrue 1
|
||||||
|
|
||||||
#define HL_VERSION_NUMBER ((2 << 24) | (4 << 16) | (4 << 8) | 0)
|
#define HL_VERSION_NUMBER ((2 << 24) | (4 << 16) | (5 << 8) | 0)
|
||||||
#define HL_VERSION_STRING "2.4.4"
|
#define HL_VERSION_STRING "2.4.5"
|
||||||
|
|
||||||
#define HL_ID_INVALID 0xffffffff
|
#define HL_ID_INVALID 0xffffffff
|
||||||
|
|
||||||
|
@ -258,6 +258,7 @@ typedef enum
|
||||||
HL_SGA_ITEM_MODIFIED,
|
HL_SGA_ITEM_MODIFIED,
|
||||||
HL_SGA_ITEM_TYPE,
|
HL_SGA_ITEM_TYPE,
|
||||||
HL_SGA_ITEM_CRC,
|
HL_SGA_ITEM_CRC,
|
||||||
|
HL_SGA_ITEM_VERIFICATION,
|
||||||
HL_SGA_ITEM_COUNT,
|
HL_SGA_ITEM_COUNT,
|
||||||
|
|
||||||
HL_VBSP_PACKAGE_VERSION = 0,
|
HL_VBSP_PACKAGE_VERSION = 0,
|
||||||
|
@ -1884,16 +1885,20 @@ namespace HLLib
|
||||||
// CSGAFile
|
// CSGAFile
|
||||||
//
|
//
|
||||||
|
|
||||||
class HLLIB_API CSGAFile : public CPackage
|
class HLLIB_API CSGAFile : public CPackage
|
||||||
{
|
{
|
||||||
private:
|
private:
|
||||||
#pragma pack(1)
|
#pragma pack(1)
|
||||||
|
|
||||||
struct SGAHeader
|
struct SGAHeaderBase
|
||||||
{
|
{
|
||||||
hlChar lpSignature[8];
|
hlChar lpSignature[8];
|
||||||
hlUShort uiMajorVersion;
|
hlUShort uiMajorVersion;
|
||||||
hlUShort uiMinorVersion;
|
hlUShort uiMinorVersion;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct SGAHeader4 : public SGAHeaderBase
|
||||||
|
{
|
||||||
hlByte lpFileMD5[16];
|
hlByte lpFileMD5[16];
|
||||||
hlWChar lpName[64];
|
hlWChar lpName[64];
|
||||||
hlByte lpHeaderMD5[16];
|
hlByte lpHeaderMD5[16];
|
||||||
|
@ -1902,6 +1907,14 @@ namespace HLLib
|
||||||
hlUInt uiDummy0;
|
hlUInt uiDummy0;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
struct SGAHeader6 : public SGAHeaderBase
|
||||||
|
{
|
||||||
|
hlWChar lpName[64];
|
||||||
|
hlUInt uiHeaderLength;
|
||||||
|
hlUInt uiFileDataOffset;
|
||||||
|
hlUInt uiDummy0;
|
||||||
|
};
|
||||||
|
|
||||||
template<typename T>
|
template<typename T>
|
||||||
struct SGADirectoryHeader
|
struct SGADirectoryHeader
|
||||||
{
|
{
|
||||||
|
@ -1918,6 +1931,12 @@ namespace HLLib
|
||||||
typedef SGADirectoryHeader<hlUShort> SGADirectoryHeader4;
|
typedef SGADirectoryHeader<hlUShort> SGADirectoryHeader4;
|
||||||
typedef SGADirectoryHeader<hlUInt> SGADirectoryHeader5;
|
typedef SGADirectoryHeader<hlUInt> SGADirectoryHeader5;
|
||||||
|
|
||||||
|
struct SGADirectoryHeader7 : public SGADirectoryHeader5
|
||||||
|
{
|
||||||
|
hlUInt uiHashTableOffset;
|
||||||
|
hlUInt uiBlockSize;
|
||||||
|
};
|
||||||
|
|
||||||
template<typename T>
|
template<typename T>
|
||||||
struct SGASection
|
struct SGASection
|
||||||
{
|
{
|
||||||
|
@ -1946,7 +1965,7 @@ namespace HLLib
|
||||||
typedef SGAFolder<hlUShort> SGAFolder4;
|
typedef SGAFolder<hlUShort> SGAFolder4;
|
||||||
typedef SGAFolder<hlUInt> SGAFolder5;
|
typedef SGAFolder<hlUInt> SGAFolder5;
|
||||||
|
|
||||||
struct SGAFile
|
struct SGAFile4
|
||||||
{
|
{
|
||||||
hlUInt uiNameOffset;
|
hlUInt uiNameOffset;
|
||||||
hlUInt uiOffset;
|
hlUInt uiOffset;
|
||||||
|
@ -1957,12 +1976,32 @@ namespace HLLib
|
||||||
hlByte uiType;
|
hlByte uiType;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
struct SGAFile6 : public SGAFile4
|
||||||
|
{
|
||||||
|
hlUInt uiCRC32;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct SGAFile7 : public SGAFile6
|
||||||
|
{
|
||||||
|
hlUInt uiHashOffset;
|
||||||
|
};
|
||||||
|
|
||||||
struct SGAFileHeader
|
struct SGAFileHeader
|
||||||
{
|
{
|
||||||
hlChar lpName[256];
|
hlChar lpName[256];
|
||||||
hlUInt uiCRC32;
|
hlUInt uiCRC32;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
enum SGAFileVerification
|
||||||
|
{
|
||||||
|
VERIFICATION_NONE,
|
||||||
|
VERIFICATION_CRC,
|
||||||
|
VERIFICATION_CRC_BLOCKS,
|
||||||
|
VERIFICATION_MD5_BLOCKS,
|
||||||
|
VERIFICATION_SHA1_BLOCKS,
|
||||||
|
VERIFICATION_COUNT,
|
||||||
|
};
|
||||||
|
|
||||||
#pragma pack()
|
#pragma pack()
|
||||||
|
|
||||||
class ISGADirectory
|
class ISGADirectory
|
||||||
|
@ -1987,23 +2026,100 @@ namespace HLLib
|
||||||
virtual hlVoid ReleaseStreamInternal(Streams::IStream &Stream) const = 0;
|
virtual hlVoid ReleaseStreamInternal(Streams::IStream &Stream) const = 0;
|
||||||
};
|
};
|
||||||
|
|
||||||
template<typename TSGADirectoryHeader, typename TSGASection, typename TSGAFolder, typename TSGAFile, typename TSGAFileHeader>
|
// Specialization SGAFile7 and up where the CRC moved to the header and the CRC is of the compressed data and there are stronger hashes.
|
||||||
class CSGADirectory : public ISGADirectory
|
template<typename TSGAHeader, typename TSGADirectoryHeader, typename TSGASection, typename TSGAFolder, typename TSGAFile>
|
||||||
|
class CSGASpecializedDirectory : public ISGADirectory
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
typedef TSGAHeader SGAHeader;
|
||||||
|
typedef TSGADirectoryHeader SGADirectoryHeader;
|
||||||
|
typedef TSGASection SGASection;
|
||||||
|
typedef TSGAFolder SGAFolder;
|
||||||
|
typedef TSGAFile SGAFile;
|
||||||
|
|
||||||
|
CSGASpecializedDirectory(CSGAFile& File);
|
||||||
|
|
||||||
|
protected:
|
||||||
|
CSGAFile& File;
|
||||||
|
|
||||||
|
Mapping::CView *pHeaderDirectoryView;
|
||||||
|
const SGADirectoryHeader *pDirectoryHeader;
|
||||||
|
const SGASection *lpSections;
|
||||||
|
const SGAFolder *lpFolders;
|
||||||
|
const SGAFile *lpFiles;
|
||||||
|
const hlChar *lpStringTable;
|
||||||
|
|
||||||
|
public:
|
||||||
|
virtual hlBool GetItemAttributeInternal(const CDirectoryItem *pItem, HLPackageAttribute eAttribute, HLAttribute &Attribute) const;
|
||||||
|
|
||||||
|
virtual hlBool GetFileValidationInternal(const CDirectoryFile *pFile, HLValidation &eValidation) const;
|
||||||
|
};
|
||||||
|
|
||||||
|
// Specialization SGAFile4 where the CRC was stored in a SGAFileHeader located before the file data.
|
||||||
|
template<typename TSGAHeader, typename TSGADirectoryHeader, typename TSGASection, typename TSGAFolder>
|
||||||
|
class CSGASpecializedDirectory<TSGAHeader, TSGADirectoryHeader, TSGASection, TSGAFolder, SGAFile4> : public ISGADirectory
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
typedef TSGAHeader SGAHeader;
|
||||||
|
typedef TSGADirectoryHeader SGADirectoryHeader;
|
||||||
|
typedef TSGASection SGASection;
|
||||||
|
typedef TSGAFolder SGAFolder;
|
||||||
|
typedef CSGAFile::SGAFile4 SGAFile;
|
||||||
|
|
||||||
|
CSGASpecializedDirectory(CSGAFile& File);
|
||||||
|
|
||||||
|
protected:
|
||||||
|
CSGAFile& File;
|
||||||
|
|
||||||
|
Mapping::CView *pHeaderDirectoryView;
|
||||||
|
const SGADirectoryHeader *pDirectoryHeader;
|
||||||
|
const SGASection *lpSections;
|
||||||
|
const SGAFolder *lpFolders;
|
||||||
|
const SGAFile *lpFiles;
|
||||||
|
const hlChar *lpStringTable;
|
||||||
|
|
||||||
|
public:
|
||||||
|
virtual hlBool GetItemAttributeInternal(const CDirectoryItem *pItem, HLPackageAttribute eAttribute, HLAttribute &Attribute) const;
|
||||||
|
|
||||||
|
virtual hlBool GetFileValidationInternal(const CDirectoryFile *pFile, HLValidation &eValidation) const;
|
||||||
|
};
|
||||||
|
|
||||||
|
// Specialization SGAFile6 where the CRC moved to the header and the CRC is of the compressed data.
|
||||||
|
template<typename TSGAHeader, typename TSGADirectoryHeader, typename TSGASection, typename TSGAFolder>
|
||||||
|
class CSGASpecializedDirectory<TSGAHeader, TSGADirectoryHeader, TSGASection, TSGAFolder, SGAFile6> : public ISGADirectory
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
typedef TSGAHeader SGAHeader;
|
||||||
|
typedef TSGADirectoryHeader SGADirectoryHeader;
|
||||||
|
typedef TSGASection SGASection;
|
||||||
|
typedef TSGAFolder SGAFolder;
|
||||||
|
typedef CSGAFile::SGAFile6 SGAFile;
|
||||||
|
|
||||||
|
CSGASpecializedDirectory(CSGAFile& File);
|
||||||
|
|
||||||
|
protected:
|
||||||
|
CSGAFile& File;
|
||||||
|
|
||||||
|
Mapping::CView *pHeaderDirectoryView;
|
||||||
|
const SGADirectoryHeader *pDirectoryHeader;
|
||||||
|
const SGASection *lpSections;
|
||||||
|
const SGAFolder *lpFolders;
|
||||||
|
const SGAFile *lpFiles;
|
||||||
|
const hlChar *lpStringTable;
|
||||||
|
|
||||||
|
public:
|
||||||
|
virtual hlBool GetItemAttributeInternal(const CDirectoryItem *pItem, HLPackageAttribute eAttribute, HLAttribute &Attribute) const;
|
||||||
|
|
||||||
|
virtual hlBool GetFileValidationInternal(const CDirectoryFile *pFile, HLValidation &eValidation) const;
|
||||||
|
};
|
||||||
|
|
||||||
|
template<typename TSGAHeader, typename TSGADirectoryHeader, typename TSGASection, typename TSGAFolder, typename TSGAFile>
|
||||||
|
class CSGADirectory : public CSGASpecializedDirectory<TSGAHeader, TSGADirectoryHeader, TSGASection, TSGAFolder, TSGAFile>
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
CSGADirectory(CSGAFile& File);
|
CSGADirectory(CSGAFile& File);
|
||||||
virtual ~CSGADirectory();
|
virtual ~CSGADirectory();
|
||||||
|
|
||||||
private:
|
|
||||||
CSGAFile& File;
|
|
||||||
|
|
||||||
Mapping::CView *pHeaderDirectoryView;
|
|
||||||
const TSGADirectoryHeader *pDirectoryHeader;
|
|
||||||
const TSGASection *lpSections;
|
|
||||||
const TSGAFolder *lpFolders;
|
|
||||||
const TSGAFile *lpFiles;
|
|
||||||
const hlChar *lpStringTable;
|
|
||||||
|
|
||||||
public:
|
public:
|
||||||
virtual hlBool MapDataStructures();
|
virtual hlBool MapDataStructures();
|
||||||
virtual hlVoid UnmapDataStructures();
|
virtual hlVoid UnmapDataStructures();
|
||||||
|
@ -2013,7 +2129,6 @@ namespace HLLib
|
||||||
virtual hlBool GetItemAttributeInternal(const CDirectoryItem *pItem, HLPackageAttribute eAttribute, HLAttribute &Attribute) const;
|
virtual hlBool GetItemAttributeInternal(const CDirectoryItem *pItem, HLPackageAttribute eAttribute, HLAttribute &Attribute) const;
|
||||||
|
|
||||||
virtual hlBool GetFileExtractableInternal(const CDirectoryFile *pFile, hlBool &bExtractable) const;
|
virtual hlBool GetFileExtractableInternal(const CDirectoryFile *pFile, hlBool &bExtractable) const;
|
||||||
virtual hlBool GetFileValidationInternal(const CDirectoryFile *pFile, HLValidation &eValidation) const;
|
|
||||||
virtual hlBool GetFileSizeInternal(const CDirectoryFile *pFile, hlUInt &uiSize) const;
|
virtual hlBool GetFileSizeInternal(const CDirectoryFile *pFile, hlUInt &uiSize) const;
|
||||||
virtual hlBool GetFileSizeOnDiskInternal(const CDirectoryFile *pFile, hlUInt &uiSize) const;
|
virtual hlBool GetFileSizeOnDiskInternal(const CDirectoryFile *pFile, hlUInt &uiSize) const;
|
||||||
|
|
||||||
|
@ -2024,18 +2139,23 @@ namespace HLLib
|
||||||
hlVoid CreateFolder(CDirectoryFolder *pParent, hlUInt uiFolderIndex);
|
hlVoid CreateFolder(CDirectoryFolder *pParent, hlUInt uiFolderIndex);
|
||||||
};
|
};
|
||||||
|
|
||||||
typedef CSGADirectory<SGADirectoryHeader4, SGASection4, SGAFolder4, SGAFile, SGAFileHeader> CSGADirectory4;
|
typedef CSGADirectory<SGAHeader4, SGADirectoryHeader4, SGASection4, SGAFolder4, SGAFile4> CSGADirectory4;
|
||||||
typedef CSGADirectory<SGADirectoryHeader5, SGASection5, SGAFolder5, SGAFile, SGAFileHeader> CSGADirectory5;
|
typedef CSGADirectory<SGAHeader4, SGADirectoryHeader5, SGASection5, SGAFolder5, SGAFile4> CSGADirectory5;
|
||||||
|
typedef CSGADirectory<SGAHeader6, SGADirectoryHeader5, SGASection5, SGAFolder5, SGAFile6> CSGADirectory6;
|
||||||
|
typedef CSGADirectory<SGAHeader6, SGADirectoryHeader7, SGASection5, SGAFolder5, SGAFile7> CSGADirectory7;
|
||||||
|
|
||||||
friend CSGADirectory4;
|
friend CSGADirectory4;
|
||||||
friend CSGADirectory5;
|
friend CSGADirectory5;
|
||||||
|
friend CSGADirectory6;
|
||||||
|
friend CSGADirectory7;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
static const char *lpAttributeNames[];
|
static const char *lpAttributeNames[];
|
||||||
static const char *lpItemAttributeNames[];
|
static const char *lpItemAttributeNames[];
|
||||||
|
static const char *lpVerificationNames[];
|
||||||
|
|
||||||
Mapping::CView *pHeaderView;
|
Mapping::CView *pHeaderView;
|
||||||
const SGAHeader *pHeader;
|
const SGAHeaderBase *pHeader;
|
||||||
|
|
||||||
ISGADirectory* pDirectory;
|
ISGADirectory* pDirectory;
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue