Merge branch 'upstream'

merging in 2.4.5
This commit is contained in:
Ondřej Hošek 2013-11-22 01:03:39 +01:00
commit f93bccd42c
13 changed files with 945 additions and 144 deletions

View File

@ -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,

View File

@ -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")]

View File

@ -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"

View File

@ -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]);
}
}

View File

@ -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

View File

@ -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"

View File

@ -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));
hlAttributeSetString(&Attribute, this->lpAttributeNames[eAttribute], lpBuffer);
return hlTrue;
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));
hlAttributeSetString(&Attribute, this->lpAttributeNames[eAttribute], lpBuffer);
return hlTrue;
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));
hlAttributeSetString(&Attribute, this->lpAttributeNames[eAttribute], lpBuffer);
return hlTrue;
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
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);
}
@ -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)
{

View File

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

View File

@ -547,7 +547,10 @@ hlBool CVBSPFile::GetFileValidationInternal(const CDirectoryFile *pFile, HLValid
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
{

View File

@ -471,7 +471,10 @@ hlBool CZIPFile::GetFileValidationInternal(const CDirectoryFile *pFile, HLValida
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;
}

View File

@ -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,

View File

@ -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).

View File

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