update HLLib to 2.4.5
This commit is contained in:
parent
ae33040994
commit
d2845adff7
|
@ -19,8 +19,8 @@ using System.Runtime.InteropServices;
|
|||
public sealed class HLLib
|
||||
{
|
||||
#region Constants
|
||||
public const int HL_VERSION_NUMBER = ((2 << 24) | (4 << 16) | (4 << 8) | 0);
|
||||
public const string HL_VERSION_STRING = "2.4.4";
|
||||
public const int HL_VERSION_NUMBER = ((2 << 24) | (4 << 16) | (5 << 8) | 0);
|
||||
public const string HL_VERSION_STRING = "2.4.5";
|
||||
|
||||
public const uint HL_ID_INVALID = 0xffffffff;
|
||||
|
||||
|
@ -206,6 +206,7 @@ public sealed class HLLib
|
|||
HL_SGA_ITEM_MODIFIED,
|
||||
HL_SGA_ITEM_TYPE,
|
||||
HL_SGA_ITEM_CRC,
|
||||
HL_SGA_ITEM_VERIFICATION,
|
||||
HL_SGA_ITEM_COUNT,
|
||||
|
||||
HL_VBSP_PACKAGE_VERSION = 0,
|
||||
|
|
|
@ -29,5 +29,5 @@ using System.Runtime.InteropServices;
|
|||
// Build Number
|
||||
// Revision
|
||||
//
|
||||
[assembly: AssemblyVersion("2.4.4.0")]
|
||||
[assembly: AssemblyFileVersion("2.4.4.0")]
|
||||
[assembly: AssemblyVersion("2.4.5.0")]
|
||||
[assembly: AssemblyFileVersion("2.4.5.0")]
|
||||
|
|
|
@ -51,8 +51,8 @@ END
|
|||
//
|
||||
|
||||
VS_VERSION_INFO VERSIONINFO
|
||||
FILEVERSION 2,4,4,0
|
||||
PRODUCTVERSION 2,4,4,0
|
||||
FILEVERSION 2,4,5,0
|
||||
PRODUCTVERSION 2,4,5,0
|
||||
FILEFLAGSMASK 0x17L
|
||||
#ifdef _DEBUG
|
||||
FILEFLAGS 0x1L
|
||||
|
@ -69,12 +69,12 @@ BEGIN
|
|||
BEGIN
|
||||
VALUE "Comments", "Half-Life Package Extraction Utility"
|
||||
VALUE "FileDescription", "HLExtract Application"
|
||||
VALUE "FileVersion", "2.4.4"
|
||||
VALUE "FileVersion", "2.4.5"
|
||||
VALUE "InternalName", "HLExtract"
|
||||
VALUE "LegalCopyright", "Copyright (C) 2006-2013 Ryan Gregg"
|
||||
VALUE "OriginalFilename", "HLExtract.exe"
|
||||
VALUE "ProductName", " HLExtract Application"
|
||||
VALUE "ProductVersion", "2.4.4"
|
||||
VALUE "ProductVersion", "2.4.5"
|
||||
END
|
||||
END
|
||||
BLOCK "VarFileInfo"
|
||||
|
|
|
@ -207,6 +207,17 @@ hlULong HLLib::CRC32(const hlByte *lpBuffer, hlUInt uiBufferSize, hlULong uiCRC)
|
|||
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] =
|
||||
{
|
||||
{
|
||||
|
@ -251,11 +262,6 @@ const hlByte lpMD5Padding[64] =
|
|||
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)
|
||||
{
|
||||
context.lpState[0] = 0x67452301UL;
|
||||
|
@ -286,7 +292,7 @@ hlVoid HLLib::MD5_Update(MD5Context& context, const hlByte *lpBuffer, hlUInt uiB
|
|||
// Round 1.
|
||||
for(hlULong i = 0; i < 16; ++i)
|
||||
{
|
||||
hlULong x = (b & c) | ((~b) & d);
|
||||
hlULong x = d ^ (b & (c ^ d));
|
||||
|
||||
hlULong t = d;
|
||||
d = c;
|
||||
|
@ -360,5 +366,144 @@ hlVoid HLLib::MD5_Finalize(MD5Context& context, hlByte (&lpDigest)[16])
|
|||
|
||||
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_Update(MD5Context& context, const hlByte *lpBuffer, hlUInt uiBufferSize);
|
||||
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
|
||||
|
|
|
@ -51,8 +51,8 @@ END
|
|||
//
|
||||
|
||||
VS_VERSION_INFO VERSIONINFO
|
||||
FILEVERSION 2,4,4,0
|
||||
PRODUCTVERSION 2,4,4,0
|
||||
FILEVERSION 2,4,5,0
|
||||
PRODUCTVERSION 2,4,5,0
|
||||
FILEFLAGSMASK 0x17L
|
||||
#ifdef _DEBUG
|
||||
FILEFLAGS 0x1L
|
||||
|
@ -69,12 +69,12 @@ BEGIN
|
|||
BEGIN
|
||||
VALUE "Comments", "Half-Life Package Library"
|
||||
VALUE "FileDescription", "HLLib Dynamic Link Library"
|
||||
VALUE "FileVersion", "2.4.4"
|
||||
VALUE "FileVersion", "2.4.5"
|
||||
VALUE "InternalName", "HLLib"
|
||||
VALUE "LegalCopyright", "Copyright (C) 2006-2013 Ryan Gregg"
|
||||
VALUE "OriginalFilename", "HLLib.dll"
|
||||
VALUE "ProductName", " HLLib Dynamic Link Library"
|
||||
VALUE "ProductVersion", "2.4.4"
|
||||
VALUE "ProductVersion", "2.4.5"
|
||||
END
|
||||
END
|
||||
BLOCK "VarFileInfo"
|
||||
|
|
|
@ -27,7 +27,8 @@ using namespace HLLib;
|
|||
#define HL_SGA_CHECKSUM_LENGTH 0x00008000
|
||||
|
||||
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)
|
||||
{
|
||||
|
@ -56,17 +57,18 @@ const hlChar *CSGAFile::GetDescription() const
|
|||
|
||||
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.");
|
||||
return hlFalse;
|
||||
}
|
||||
|
||||
if(!this->pMapping->Map(this->pHeaderView, 0, sizeof(SGAHeader)))
|
||||
if(!this->pMapping->Map(this->pHeaderView, 0, uiMaxHeaderSize))
|
||||
{
|
||||
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)
|
||||
{
|
||||
|
@ -74,26 +76,53 @@ hlBool CSGAFile::MapDataStructures()
|
|||
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);
|
||||
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)
|
||||
{
|
||||
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);
|
||||
break;
|
||||
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);
|
||||
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:
|
||||
assert(false);
|
||||
return hlFalse;
|
||||
|
@ -185,17 +214,35 @@ hlBool CSGAFile::GetAttributeInternal(HLPackageAttribute eAttribute, HLAttribute
|
|||
hlAttributeSetUnsignedInteger(&Attribute, this->lpAttributeNames[eAttribute], this->pHeader->uiMinorVersion, hlFalse);
|
||||
return hlTrue;
|
||||
case HL_SGA_PACKAGE_MD5_FILE:
|
||||
BufferToHexString(this->pHeader->lpFileMD5, 16, lpBuffer, sizeof(lpBuffer));
|
||||
if(this->pHeader->uiMajorVersion >= 4 && this->pHeader->uiMajorVersion <= 5)
|
||||
{
|
||||
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:
|
||||
WStringToString(this->pHeader->lpName, lpBuffer, sizeof(lpBuffer));
|
||||
if(this->pHeader->uiMajorVersion >= 4 && this->pHeader->uiMajorVersion <= 5)
|
||||
{
|
||||
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:
|
||||
BufferToHexString(this->pHeader->lpHeaderMD5, 16, lpBuffer, sizeof(lpBuffer));
|
||||
if(this->pHeader->uiMajorVersion >= 4 && this->pHeader->uiMajorVersion <= 5)
|
||||
{
|
||||
BufferToHexString(static_cast<const SGAHeader4 *>(this->pHeader)->lpHeaderMD5, 16, lpBuffer, sizeof(lpBuffer));
|
||||
hlAttributeSetString(&Attribute, this->lpAttributeNames[eAttribute], lpBuffer);
|
||||
return hlTrue;
|
||||
}
|
||||
return hlFalse;
|
||||
default:
|
||||
return hlFalse;
|
||||
}
|
||||
|
@ -221,59 +268,77 @@ CSGAFile::ISGADirectory::~ISGADirectory()
|
|||
|
||||
}
|
||||
|
||||
template<typename TSGADirectoryHeader, typename TSGASection, typename TSGAFolder, typename TSGAFile, typename TSGAFileHeader>
|
||||
CSGAFile::CSGADirectory<TSGADirectoryHeader, TSGASection, TSGAFolder, TSGAFile, TSGAFileHeader>::CSGADirectory(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::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>
|
||||
CSGAFile::CSGADirectory<TSGADirectoryHeader, TSGASection, TSGAFolder, TSGAFile, TSGAFileHeader>::~CSGADirectory()
|
||||
template<typename TSGAHeader, typename TSGADirectoryHeader, typename TSGASection, typename TSGAFolder>
|
||||
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();
|
||||
}
|
||||
|
||||
template<typename TSGADirectoryHeader, typename TSGASection, typename TSGAFolder, typename TSGAFile, typename TSGAFileHeader>
|
||||
hlBool CSGAFile::CSGADirectory<TSGADirectoryHeader, TSGASection, TSGAFolder, TSGAFile, TSGAFileHeader>::MapDataStructures()
|
||||
template<typename TSGAHeader, typename TSGADirectoryHeader, typename TSGASection, typename TSGAFolder, typename TSGAFile>
|
||||
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;
|
||||
}
|
||||
|
||||
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.");
|
||||
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.");
|
||||
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.");
|
||||
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.");
|
||||
return hlFalse;
|
||||
}
|
||||
|
||||
this->lpSections = reinterpret_cast<const TSGASection *>(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->lpFiles = reinterpret_cast<const TSGAFile *>(reinterpret_cast<const hlByte *>(this->pDirectoryHeader) + this->pDirectoryHeader->uiFileOffset);
|
||||
this->lpSections = reinterpret_cast<const SGASection *>(reinterpret_cast<const hlByte *>(this->pDirectoryHeader) + this->pDirectoryHeader->uiSectionOffset);
|
||||
this->lpFolders = reinterpret_cast<const SGAFolder *>(reinterpret_cast<const hlByte *>(this->pDirectoryHeader) + this->pDirectoryHeader->uiFolderOffset);
|
||||
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);
|
||||
|
||||
return hlTrue;
|
||||
}
|
||||
|
||||
template<typename TSGADirectoryHeader, typename TSGASection, typename TSGAFolder, typename TSGAFile, typename TSGAFileHeader>
|
||||
hlVoid CSGAFile::CSGADirectory<TSGADirectoryHeader, TSGASection, TSGAFolder, TSGAFile, TSGAFileHeader>::UnmapDataStructures()
|
||||
template<typename TSGAHeader, typename TSGADirectoryHeader, typename TSGASection, typename TSGAFolder, typename TSGAFile>
|
||||
hlVoid CSGAFile::CSGADirectory<TSGAHeader, TSGADirectoryHeader, TSGASection, TSGAFolder, TSGAFile>::UnmapDataStructures()
|
||||
{
|
||||
this->pDirectoryHeader = 0;
|
||||
this->lpSections = 0;
|
||||
|
@ -284,8 +349,8 @@ hlVoid CSGAFile::CSGADirectory<TSGADirectoryHeader, TSGASection, TSGAFolder, TSG
|
|||
this->File.pMapping->Unmap(this->pHeaderDirectoryView);
|
||||
}
|
||||
|
||||
template<typename TSGADirectoryHeader, typename TSGASection, typename TSGAFolder, typename TSGAFile, typename TSGAFileHeader>
|
||||
CDirectoryFolder *CSGAFile::CSGADirectory<TSGADirectoryHeader, TSGASection, TSGAFolder, TSGAFile, TSGAFileHeader>::CreateRoot()
|
||||
template<typename TSGAHeader, typename TSGADirectoryHeader, typename TSGASection, typename TSGAFolder, typename TSGAFile>
|
||||
CDirectoryFolder *CSGAFile::CSGADirectory<TSGAHeader, TSGADirectoryHeader, TSGASection, TSGAFolder, TSGAFile>::CreateRoot()
|
||||
{
|
||||
CDirectoryFolder *pRoot = new CDirectoryFolder(&File);
|
||||
|
||||
|
@ -310,8 +375,8 @@ CDirectoryFolder *CSGAFile::CSGADirectory<TSGADirectoryHeader, TSGASection, TSGA
|
|||
return pRoot;
|
||||
}
|
||||
|
||||
template<typename TSGADirectoryHeader, typename TSGASection, typename TSGAFolder, typename TSGAFile, typename TSGAFileHeader>
|
||||
hlVoid CSGAFile::CSGADirectory<TSGADirectoryHeader, TSGASection, TSGAFolder, TSGAFile, TSGAFileHeader>::CreateFolder(CDirectoryFolder *pParent, hlUInt uiFolderIndex)
|
||||
template<typename TSGAHeader, typename TSGADirectoryHeader, typename TSGASection, typename TSGAFolder, typename TSGAFile>
|
||||
hlVoid CSGAFile::CSGADirectory<TSGAHeader, TSGADirectoryHeader, TSGASection, TSGAFolder, TSGAFile>::CreateFolder(CDirectoryFolder *pParent, hlUInt uiFolderIndex)
|
||||
{
|
||||
const hlChar* lpName = this->lpStringTable + this->lpFolders[uiFolderIndex].uiNameOffset;
|
||||
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>
|
||||
hlBool CSGAFile::CSGADirectory<TSGADirectoryHeader, TSGASection, TSGAFolder, TSGAFile, TSGAFileHeader>::GetItemAttributeInternal(const CDirectoryItem *pItem, HLPackageAttribute eAttribute, HLAttribute &Attribute) const
|
||||
template<typename TSGAHeader, typename TSGADirectoryHeader, typename TSGASection, typename TSGAFolder>
|
||||
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)
|
||||
{
|
||||
|
@ -393,7 +558,7 @@ hlBool CSGAFile::CSGADirectory<TSGADirectoryHeader, TSGASection, TSGAFolder, TSG
|
|||
case HL_ITEM_FILE:
|
||||
{
|
||||
const CDirectoryFile *pFile = static_cast<const CDirectoryFile *>(pItem);
|
||||
const TSGAFile &File = this->lpFiles[pFile->GetID()];
|
||||
const SGAFile &File = this->lpFiles[pFile->GetID()];
|
||||
switch(eAttribute)
|
||||
{
|
||||
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);
|
||||
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;
|
||||
}
|
||||
}
|
||||
}
|
||||
return hlFalse;
|
||||
return CSGASpecializedDirectory<TSGAHeader, TSGADirectoryHeader, TSGASection, TSGAFolder, TSGAFile>::GetItemAttributeInternal(pItem, eAttribute, Attribute);
|
||||
}
|
||||
|
||||
template<typename TSGADirectoryHeader, typename TSGASection, typename TSGAFolder, typename TSGAFile, typename TSGAFileHeader>
|
||||
hlBool CSGAFile::CSGADirectory<TSGADirectoryHeader, TSGASection, TSGAFolder, TSGAFile, TSGAFileHeader>::GetFileExtractableInternal(const CDirectoryFile *pFile, hlBool &bExtractable) const
|
||||
template<typename TSGAHeader, typename TSGADirectoryHeader, typename TSGASection, typename TSGAFolder, typename TSGAFile>
|
||||
hlBool CSGAFile::CSGADirectory<TSGAHeader, TSGADirectoryHeader, TSGASection, TSGAFolder, TSGAFile>::GetFileExtractableInternal(const CDirectoryFile *pFile, hlBool &bExtractable) const
|
||||
{
|
||||
#if !USE_ZLIB
|
||||
const TSGAFile &File = this->lpFiles[pFile->GetID()];
|
||||
const SGAFile &File = this->lpFiles[pFile->GetID()];
|
||||
|
||||
bExtractable = File.uiType == 0;
|
||||
#else
|
||||
|
@ -470,10 +623,10 @@ hlBool CSGAFile::CSGADirectory<TSGADirectoryHeader, TSGASection, TSGAFolder, TSG
|
|||
return hlTrue;
|
||||
}
|
||||
|
||||
template<typename TSGADirectoryHeader, typename TSGASection, typename TSGAFolder, typename TSGAFile, typename TSGAFileHeader>
|
||||
hlBool CSGAFile::CSGADirectory<TSGADirectoryHeader, TSGASection, TSGAFolder, TSGAFile, TSGAFileHeader>::GetFileValidationInternal(const CDirectoryFile *pFile, HLValidation &eValidation) const
|
||||
template<typename TSGAHeader, typename TSGADirectoryHeader, typename TSGASection, typename TSGAFolder>
|
||||
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(File.uiType != 0)
|
||||
|
@ -484,11 +637,11 @@ hlBool CSGAFile::CSGADirectory<TSGADirectoryHeader, TSGASection, TSGAFolder, TSG
|
|||
#endif
|
||||
|
||||
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;
|
||||
const TSGAFileHeader* pFileHeader = static_cast<const TSGAFileHeader*>(pFileHeaderDataView->GetView());
|
||||
const hlByte* lpBuffer = reinterpret_cast<const hlByte *>(pFileHeader) + sizeof(TSGAFileHeader);
|
||||
const SGAFileHeader* pFileHeader = static_cast<const SGAFileHeader*>(pFileHeaderDataView->GetView());
|
||||
const hlByte* lpBuffer = reinterpret_cast<const hlByte *>(pFileHeader) + sizeof(SGAFileHeader);
|
||||
#if USE_ZLIB
|
||||
hlByte *lpInflateBuffer = 0;
|
||||
if(File.uiType != 0)
|
||||
|
@ -535,7 +688,10 @@ hlBool CSGAFile::CSGADirectory<TSGADirectoryHeader, TSGASection, TSGAFolder, TSG
|
|||
#if USE_ZLIB
|
||||
delete []lpInflateBuffer;
|
||||
#endif
|
||||
if(eValidation == HL_VALIDATES_ASSUMED_OK)
|
||||
{
|
||||
eValidation = static_cast<hlULong>(pFileHeader->uiCRC32) == uiChecksum ? HL_VALIDATES_OK : HL_VALIDATES_CORRUPT;
|
||||
}
|
||||
|
||||
this->File.pMapping->Unmap(pFileHeaderDataView);
|
||||
}
|
||||
|
@ -547,41 +703,166 @@ hlBool CSGAFile::CSGADirectory<TSGADirectoryHeader, TSGASection, TSGAFolder, TSG
|
|||
return hlTrue;
|
||||
}
|
||||
|
||||
template<typename TSGADirectoryHeader, typename TSGASection, typename TSGAFolder, typename TSGAFile, typename TSGAFileHeader>
|
||||
hlBool CSGAFile::CSGADirectory<TSGADirectoryHeader, TSGASection, TSGAFolder, TSGAFile, TSGAFileHeader>::GetFileSizeInternal(const CDirectoryFile *pFile, hlUInt &uiSize) const
|
||||
template<typename TSGAHeader, typename TSGADirectoryHeader, typename TSGASection, typename TSGAFolder>
|
||||
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;
|
||||
|
||||
return hlTrue;
|
||||
}
|
||||
|
||||
template<typename TSGADirectoryHeader, typename TSGASection, typename TSGAFolder, typename TSGAFile, typename TSGAFileHeader>
|
||||
hlBool CSGAFile::CSGADirectory<TSGADirectoryHeader, TSGASection, TSGAFolder, TSGAFile, TSGAFileHeader>::GetFileSizeOnDiskInternal(const CDirectoryFile *pFile, hlUInt &uiSize) const
|
||||
template<typename TSGAHeader, typename TSGADirectoryHeader, typename TSGASection, typename TSGAFolder, typename TSGAFile>
|
||||
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;
|
||||
|
||||
return hlTrue;
|
||||
}
|
||||
|
||||
template<typename TSGADirectoryHeader, typename TSGASection, typename TSGAFolder, typename TSGAFile, typename TSGAFileHeader>
|
||||
hlBool CSGAFile::CSGADirectory<TSGADirectoryHeader, TSGASection, TSGAFolder, TSGAFile, TSGAFileHeader>::CreateStreamInternal(const CDirectoryFile *pFile, Streams::IStream *&pStream) const
|
||||
template<typename TSGAHeader, typename TSGADirectoryHeader, typename TSGASection, typename TSGAFolder, typename TSGAFile>
|
||||
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)
|
||||
{
|
||||
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;
|
||||
}
|
||||
else
|
||||
{
|
||||
#if USE_ZLIB
|
||||
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;
|
||||
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>
|
||||
hlVoid CSGAFile::CSGADirectory<TSGADirectoryHeader, TSGASection, TSGAFolder, TSGAFile, TSGAFileHeader>::ReleaseStreamInternal(Streams::IStream &Stream) const
|
||||
template<typename TSGAHeader, typename TSGADirectoryHeader, typename TSGASection, typename TSGAFolder, typename TSGAFile>
|
||||
hlVoid CSGAFile::CSGADirectory<TSGAHeader, TSGADirectoryHeader, TSGASection, TSGAFolder, TSGAFile>::ReleaseStreamInternal(Streams::IStream &Stream) const
|
||||
{
|
||||
if(Stream.GetType() == HL_STREAM_MEMORY)
|
||||
{
|
||||
|
|
155
HLLib/SGAFile.h
155
HLLib/SGAFile.h
|
@ -22,11 +22,15 @@ namespace HLLib
|
|||
private:
|
||||
#pragma pack(1)
|
||||
|
||||
struct SGAHeader
|
||||
struct SGAHeaderBase
|
||||
{
|
||||
hlChar lpSignature[8];
|
||||
hlUShort uiMajorVersion;
|
||||
hlUShort uiMinorVersion;
|
||||
};
|
||||
|
||||
struct SGAHeader4 : public SGAHeaderBase
|
||||
{
|
||||
hlByte lpFileMD5[16];
|
||||
hlWChar lpName[64];
|
||||
hlByte lpHeaderMD5[16];
|
||||
|
@ -35,6 +39,14 @@ namespace HLLib
|
|||
hlUInt uiDummy0;
|
||||
};
|
||||
|
||||
struct SGAHeader6 : public SGAHeaderBase
|
||||
{
|
||||
hlWChar lpName[64];
|
||||
hlUInt uiHeaderLength;
|
||||
hlUInt uiFileDataOffset;
|
||||
hlUInt uiDummy0;
|
||||
};
|
||||
|
||||
template<typename T>
|
||||
struct SGADirectoryHeader
|
||||
{
|
||||
|
@ -51,6 +63,12 @@ namespace HLLib
|
|||
typedef SGADirectoryHeader<hlUShort> SGADirectoryHeader4;
|
||||
typedef SGADirectoryHeader<hlUInt> SGADirectoryHeader5;
|
||||
|
||||
struct SGADirectoryHeader7 : public SGADirectoryHeader5
|
||||
{
|
||||
hlUInt uiHashTableOffset;
|
||||
hlUInt uiBlockSize;
|
||||
};
|
||||
|
||||
template<typename T>
|
||||
struct SGASection
|
||||
{
|
||||
|
@ -79,7 +97,7 @@ namespace HLLib
|
|||
typedef SGAFolder<hlUShort> SGAFolder4;
|
||||
typedef SGAFolder<hlUInt> SGAFolder5;
|
||||
|
||||
struct SGAFile
|
||||
struct SGAFile4
|
||||
{
|
||||
hlUInt uiNameOffset;
|
||||
hlUInt uiOffset;
|
||||
|
@ -90,12 +108,32 @@ namespace HLLib
|
|||
hlByte uiType;
|
||||
};
|
||||
|
||||
struct SGAFile6 : public SGAFile4
|
||||
{
|
||||
hlUInt uiCRC32;
|
||||
};
|
||||
|
||||
struct SGAFile7 : public SGAFile6
|
||||
{
|
||||
hlUInt uiHashOffset;
|
||||
};
|
||||
|
||||
struct SGAFileHeader
|
||||
{
|
||||
hlChar lpName[256];
|
||||
hlUInt uiCRC32;
|
||||
};
|
||||
|
||||
enum SGAFileVerification
|
||||
{
|
||||
VERIFICATION_NONE,
|
||||
VERIFICATION_CRC,
|
||||
VERIFICATION_CRC_BLOCKS,
|
||||
VERIFICATION_MD5_BLOCKS,
|
||||
VERIFICATION_SHA1_BLOCKS,
|
||||
VERIFICATION_COUNT,
|
||||
};
|
||||
|
||||
#pragma pack()
|
||||
|
||||
class ISGADirectory
|
||||
|
@ -120,23 +158,100 @@ namespace HLLib
|
|||
virtual hlVoid ReleaseStreamInternal(Streams::IStream &Stream) const = 0;
|
||||
};
|
||||
|
||||
template<typename TSGADirectoryHeader, typename TSGASection, typename TSGAFolder, typename TSGAFile, typename TSGAFileHeader>
|
||||
class CSGADirectory : public ISGADirectory
|
||||
// Specialization SGAFile7 and up where the CRC moved to the header and the CRC is of the compressed data and there are stronger hashes.
|
||||
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:
|
||||
CSGADirectory(CSGAFile& File);
|
||||
virtual ~CSGADirectory();
|
||||
|
||||
private:
|
||||
CSGAFile& File;
|
||||
|
||||
Mapping::CView *pHeaderDirectoryView;
|
||||
const TSGADirectoryHeader *pDirectoryHeader;
|
||||
const TSGASection *lpSections;
|
||||
const TSGAFolder *lpFolders;
|
||||
const TSGAFile *lpFiles;
|
||||
const hlChar *lpStringTable;
|
||||
|
||||
public:
|
||||
virtual hlBool MapDataStructures();
|
||||
virtual hlVoid UnmapDataStructures();
|
||||
|
@ -146,7 +261,6 @@ namespace HLLib
|
|||
virtual hlBool GetItemAttributeInternal(const CDirectoryItem *pItem, HLPackageAttribute eAttribute, HLAttribute &Attribute) 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 GetFileSizeOnDiskInternal(const CDirectoryFile *pFile, hlUInt &uiSize) const;
|
||||
|
||||
|
@ -157,18 +271,23 @@ namespace HLLib
|
|||
hlVoid CreateFolder(CDirectoryFolder *pParent, hlUInt uiFolderIndex);
|
||||
};
|
||||
|
||||
typedef CSGADirectory<SGADirectoryHeader4, SGASection4, SGAFolder4, SGAFile, SGAFileHeader> CSGADirectory4;
|
||||
typedef CSGADirectory<SGADirectoryHeader5, SGASection5, SGAFolder5, SGAFile, SGAFileHeader> CSGADirectory5;
|
||||
typedef CSGADirectory<SGAHeader4, SGADirectoryHeader4, SGASection4, SGAFolder4, SGAFile4> CSGADirectory4;
|
||||
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 CSGADirectory5;
|
||||
friend CSGADirectory6;
|
||||
friend CSGADirectory7;
|
||||
|
||||
private:
|
||||
static const char *lpAttributeNames[];
|
||||
static const char *lpItemAttributeNames[];
|
||||
static const char *lpVerificationNames[];
|
||||
|
||||
Mapping::CView *pHeaderView;
|
||||
const SGAHeader *pHeader;
|
||||
const SGAHeaderBase *pHeader;
|
||||
|
||||
ISGADirectory* pDirectory;
|
||||
|
||||
|
|
|
@ -539,8 +539,11 @@ hlBool CVBSPFile::GetFileValidationInternal(const CDirectoryFile *pFile, HLValid
|
|||
delete pStream;
|
||||
}
|
||||
|
||||
if(eValidation == HL_VALIDATES_ASSUMED_OK)
|
||||
{
|
||||
eValidation = (hlULong)pDirectoryItem->uiCRC32 == uiChecksum ? HL_VALIDATES_OK : HL_VALIDATES_CORRUPT;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
eValidation = HL_VALIDATES_ASSUMED_OK;
|
||||
|
|
|
@ -467,7 +467,10 @@ hlBool CZIPFile::GetFileValidationInternal(const CDirectoryFile *pFile, HLValida
|
|||
delete pStream;
|
||||
}
|
||||
|
||||
if(eValidation == HL_VALIDATES_ASSUMED_OK)
|
||||
{
|
||||
eValidation = (hlULong)pDirectoryItem->uiCRC32 == uiChecksum ? HL_VALIDATES_OK : HL_VALIDATES_CORRUPT;
|
||||
}
|
||||
|
||||
return hlTrue;
|
||||
}
|
||||
|
|
|
@ -65,8 +65,8 @@ typedef hlSingle hlFloat;
|
|||
#define hlFalse 0
|
||||
#define hlTrue 1
|
||||
|
||||
#define HL_VERSION_NUMBER ((2 << 24) | (4 << 16) | (4 << 8) | 0)
|
||||
#define HL_VERSION_STRING "2.4.4"
|
||||
#define HL_VERSION_NUMBER ((2 << 24) | (4 << 16) | (5 << 8) | 0)
|
||||
#define HL_VERSION_STRING "2.4.5"
|
||||
|
||||
#define HL_ID_INVALID 0xffffffff
|
||||
|
||||
|
@ -254,6 +254,7 @@ typedef enum
|
|||
HL_SGA_ITEM_MODIFIED,
|
||||
HL_SGA_ITEM_TYPE,
|
||||
HL_SGA_ITEM_CRC,
|
||||
HL_SGA_ITEM_VERIFICATION,
|
||||
HL_SGA_ITEM_COUNT,
|
||||
|
||||
HL_VBSP_PACKAGE_VERSION = 0,
|
||||
|
|
|
@ -9,11 +9,11 @@ Library/Author Information:
|
|||
===========================
|
||||
|
||||
---- General Library Information ----
|
||||
Date : January 27th, 2013
|
||||
Date : October 17th, 2013
|
||||
Author : Ryan Gregg
|
||||
Michael Mohr (Linux Port)
|
||||
Title : HLLib
|
||||
Build : 2.4.4
|
||||
Build : 2.4.5
|
||||
Email address : ryansgregg@hotmail.com (Ryan Gregg)
|
||||
m.mohr@laposte.net (Michael Mohr)
|
||||
Home page / Website : http://nemesis.thewavelength.net/
|
||||
|
@ -93,6 +93,10 @@ Console Commands (Interactive console mode):
|
|||
Library Changelog:
|
||||
==================
|
||||
|
||||
v2.4.5
|
||||
- Added support for new SGA file format (v6).
|
||||
- Added support for new SGA file format (v7).
|
||||
|
||||
v2.4.4
|
||||
- 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 hlTrue 1
|
||||
|
||||
#define HL_VERSION_NUMBER ((2 << 24) | (4 << 16) | (4 << 8) | 0)
|
||||
#define HL_VERSION_STRING "2.4.4"
|
||||
#define HL_VERSION_NUMBER ((2 << 24) | (4 << 16) | (5 << 8) | 0)
|
||||
#define HL_VERSION_STRING "2.4.5"
|
||||
|
||||
#define HL_ID_INVALID 0xffffffff
|
||||
|
||||
|
@ -258,6 +258,7 @@ typedef enum
|
|||
HL_SGA_ITEM_MODIFIED,
|
||||
HL_SGA_ITEM_TYPE,
|
||||
HL_SGA_ITEM_CRC,
|
||||
HL_SGA_ITEM_VERIFICATION,
|
||||
HL_SGA_ITEM_COUNT,
|
||||
|
||||
HL_VBSP_PACKAGE_VERSION = 0,
|
||||
|
@ -1884,16 +1885,20 @@ namespace HLLib
|
|||
// CSGAFile
|
||||
//
|
||||
|
||||
class HLLIB_API CSGAFile : public CPackage
|
||||
class HLLIB_API CSGAFile : public CPackage
|
||||
{
|
||||
private:
|
||||
#pragma pack(1)
|
||||
|
||||
struct SGAHeader
|
||||
struct SGAHeaderBase
|
||||
{
|
||||
hlChar lpSignature[8];
|
||||
hlUShort uiMajorVersion;
|
||||
hlUShort uiMinorVersion;
|
||||
};
|
||||
|
||||
struct SGAHeader4 : public SGAHeaderBase
|
||||
{
|
||||
hlByte lpFileMD5[16];
|
||||
hlWChar lpName[64];
|
||||
hlByte lpHeaderMD5[16];
|
||||
|
@ -1902,6 +1907,14 @@ namespace HLLib
|
|||
hlUInt uiDummy0;
|
||||
};
|
||||
|
||||
struct SGAHeader6 : public SGAHeaderBase
|
||||
{
|
||||
hlWChar lpName[64];
|
||||
hlUInt uiHeaderLength;
|
||||
hlUInt uiFileDataOffset;
|
||||
hlUInt uiDummy0;
|
||||
};
|
||||
|
||||
template<typename T>
|
||||
struct SGADirectoryHeader
|
||||
{
|
||||
|
@ -1918,6 +1931,12 @@ namespace HLLib
|
|||
typedef SGADirectoryHeader<hlUShort> SGADirectoryHeader4;
|
||||
typedef SGADirectoryHeader<hlUInt> SGADirectoryHeader5;
|
||||
|
||||
struct SGADirectoryHeader7 : public SGADirectoryHeader5
|
||||
{
|
||||
hlUInt uiHashTableOffset;
|
||||
hlUInt uiBlockSize;
|
||||
};
|
||||
|
||||
template<typename T>
|
||||
struct SGASection
|
||||
{
|
||||
|
@ -1946,7 +1965,7 @@ namespace HLLib
|
|||
typedef SGAFolder<hlUShort> SGAFolder4;
|
||||
typedef SGAFolder<hlUInt> SGAFolder5;
|
||||
|
||||
struct SGAFile
|
||||
struct SGAFile4
|
||||
{
|
||||
hlUInt uiNameOffset;
|
||||
hlUInt uiOffset;
|
||||
|
@ -1957,12 +1976,32 @@ namespace HLLib
|
|||
hlByte uiType;
|
||||
};
|
||||
|
||||
struct SGAFile6 : public SGAFile4
|
||||
{
|
||||
hlUInt uiCRC32;
|
||||
};
|
||||
|
||||
struct SGAFile7 : public SGAFile6
|
||||
{
|
||||
hlUInt uiHashOffset;
|
||||
};
|
||||
|
||||
struct SGAFileHeader
|
||||
{
|
||||
hlChar lpName[256];
|
||||
hlUInt uiCRC32;
|
||||
};
|
||||
|
||||
enum SGAFileVerification
|
||||
{
|
||||
VERIFICATION_NONE,
|
||||
VERIFICATION_CRC,
|
||||
VERIFICATION_CRC_BLOCKS,
|
||||
VERIFICATION_MD5_BLOCKS,
|
||||
VERIFICATION_SHA1_BLOCKS,
|
||||
VERIFICATION_COUNT,
|
||||
};
|
||||
|
||||
#pragma pack()
|
||||
|
||||
class ISGADirectory
|
||||
|
@ -1987,23 +2026,100 @@ namespace HLLib
|
|||
virtual hlVoid ReleaseStreamInternal(Streams::IStream &Stream) const = 0;
|
||||
};
|
||||
|
||||
template<typename TSGADirectoryHeader, typename TSGASection, typename TSGAFolder, typename TSGAFile, typename TSGAFileHeader>
|
||||
class CSGADirectory : public ISGADirectory
|
||||
// Specialization SGAFile7 and up where the CRC moved to the header and the CRC is of the compressed data and there are stronger hashes.
|
||||
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:
|
||||
CSGADirectory(CSGAFile& File);
|
||||
virtual ~CSGADirectory();
|
||||
|
||||
private:
|
||||
CSGAFile& File;
|
||||
|
||||
Mapping::CView *pHeaderDirectoryView;
|
||||
const TSGADirectoryHeader *pDirectoryHeader;
|
||||
const TSGASection *lpSections;
|
||||
const TSGAFolder *lpFolders;
|
||||
const TSGAFile *lpFiles;
|
||||
const hlChar *lpStringTable;
|
||||
|
||||
public:
|
||||
virtual hlBool MapDataStructures();
|
||||
virtual hlVoid UnmapDataStructures();
|
||||
|
@ -2013,7 +2129,6 @@ namespace HLLib
|
|||
virtual hlBool GetItemAttributeInternal(const CDirectoryItem *pItem, HLPackageAttribute eAttribute, HLAttribute &Attribute) 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 GetFileSizeOnDiskInternal(const CDirectoryFile *pFile, hlUInt &uiSize) const;
|
||||
|
||||
|
@ -2024,18 +2139,23 @@ namespace HLLib
|
|||
hlVoid CreateFolder(CDirectoryFolder *pParent, hlUInt uiFolderIndex);
|
||||
};
|
||||
|
||||
typedef CSGADirectory<SGADirectoryHeader4, SGASection4, SGAFolder4, SGAFile, SGAFileHeader> CSGADirectory4;
|
||||
typedef CSGADirectory<SGADirectoryHeader5, SGASection5, SGAFolder5, SGAFile, SGAFileHeader> CSGADirectory5;
|
||||
typedef CSGADirectory<SGAHeader4, SGADirectoryHeader4, SGASection4, SGAFolder4, SGAFile4> CSGADirectory4;
|
||||
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 CSGADirectory5;
|
||||
friend CSGADirectory6;
|
||||
friend CSGADirectory7;
|
||||
|
||||
private:
|
||||
static const char *lpAttributeNames[];
|
||||
static const char *lpItemAttributeNames[];
|
||||
static const char *lpVerificationNames[];
|
||||
|
||||
Mapping::CView *pHeaderView;
|
||||
const SGAHeader *pHeader;
|
||||
const SGAHeaderBase *pHeader;
|
||||
|
||||
ISGADirectory* pDirectory;
|
||||
|
||||
|
|
Loading…
Reference in New Issue