diff --git a/H2OExtractor.dsp b/H2OExtractor.dsp index e631589..3cd8b80 100644 --- a/H2OExtractor.dsp +++ b/H2OExtractor.dsp @@ -104,6 +104,10 @@ SOURCE=.\Source\ArchiveComment.h # End Source File # Begin Source File +SOURCE=.\Source\ArchiveDirectoryNameDesc.h +# End Source File +# Begin Source File + SOURCE=.\Source\ArchiveFile.h # End Source File # Begin Source File diff --git a/Source/Archive.cpp b/Source/Archive.cpp index f888999..8fee942 100644 --- a/Source/Archive.cpp +++ b/Source/Archive.cpp @@ -15,6 +15,10 @@ Archive::Archive(char* szFilePath) Archive::~Archive() { close(); + delete[] m_aDirectoryParents; + delete[] m_pFileNameChunk; + delete[] m_pDirectoryNameChunk; + delete[] m_Comment.szComments; } uint64_t Archive::readComment(uint64_t streamPos) @@ -39,11 +43,11 @@ uint64_t Archive::readComment(uint64_t streamPos) memset(m_Comment.szComments, 0, length); m_hH2O.read(m_Comment.szComments, length-1); -//#if _DEBUG +#if _DEBUG DB::debugLog("- ArchiveHeader: ", m_Comment.szHeader, NULL); DB::debugLog("- VersionInfo: ", m_Comment.VersionInfo, NULL); DB::debugLog("- Comments: ", m_Comment.szComments, NULL); -//#endif +#endif return end; } @@ -52,12 +56,12 @@ uint64_t Archive::readHeader(uint64_t streamPos) m_hH2O.seekg(streamPos, std::ios::beg); m_hH2O.read((char*)&m_Header, sizeof(ArchiveHeader)); -//#if _DEBUG +#if _DEBUG DB::debugLog("- Version: ", m_Header.Version, NULL); DB::debugLog("- FileCount: ", m_Header.FileCount, NULL); DB::debugLog("- CompressedSize: ", m_Header.CompressedSize, NULL); DB::debugLog("- RawSize: ", m_Header.RawSize, NULL); -//#endif +#endif return m_hH2O.tellg(); } @@ -72,8 +76,8 @@ uint64_t Archive::readFileList(uint64_t streamPos) #if _DEBUG DB::debugLog("- CompressionTag: ", curFile.CompressionTag, NULL); - DB::debugLog("- FolderNameIndex: ", (uint32_t)curFile.FolderNameIndex, NULL); - DB::debugLog("- FileNameIndex: ", (uint32_t)curFile.FileNameIndex, NULL); + DB::debugLog("- FolderNameIndex: ", curFile.FolderNameIndex, NULL); + DB::debugLog("- FileNameIndex: ", curFile.FileNameIndex, NULL); DB::debugLog("- FileId: ", curFile.FileId, NULL); DB::debugLog("- RawSize: ", curFile.RawSize, NULL); DB::debugLog("- CompressedSize: ", curFile.CompressedSize, NULL); @@ -86,6 +90,67 @@ uint64_t Archive::readFileList(uint64_t streamPos) return m_hH2O.tellg(); } +uint64_t Archive::readFileNameDesc(uint64_t streamPos) +{ + m_hH2O.seekg(streamPos, std::ios::beg); + m_hH2O.read((char*)&m_FileNameDesc, sizeof(ArchiveFileNameDesc)); + + #if _DEBUG + DB::debugLog("- CompressedSize: ", m_FileNameDesc.CompressedSize, NULL); + DB::debugLog("- RawSize: ", m_FileNameDesc.RawSize, NULL); + DB::debugLog("- CRC32[hex]: ", m_FileNameDesc.CRC32, NULL, true); + #endif + return m_hH2O.tellg(); +} + +uint64_t Archive::readFileNameChunk(uint64_t streamPos) +{ + m_hH2O.seekg(streamPos, std::ios::beg); + m_pFileNameChunk = new char[m_FileNameDesc.CompressedSize]; + m_hH2O.read(m_pFileNameChunk, m_FileNameDesc.CompressedSize); + // TODO: Decompress the file name chunk + return m_hH2O.tellg(); +} + +uint64_t Archive::readDirectoryNameDesc(uint64_t streamPos) +{ + m_hH2O.seekg(streamPos, std::ios::beg); + m_hH2O.read((char*)&m_DirectoryNameDesc, sizeof(ArchiveDirectoryNameDesc)); + + #if _DEBUG + DB::debugLog("- CompressedSize: ", m_DirectoryNameDesc.CompressedSize, NULL); + DB::debugLog("- RawSize: ", m_DirectoryNameDesc.RawSize, NULL); + DB::debugLog("- CRC32[hex]: ", m_DirectoryNameDesc.CRC32, NULL, true); + #endif + return m_hH2O.tellg(); +} + +uint64_t Archive::readDirectoryNameChunk(uint64_t streamPos) +{ + m_hH2O.seekg(streamPos, std::ios::beg); + m_pDirectoryNameChunk = new char[m_DirectoryNameDesc.CompressedSize]; + m_hH2O.read(m_pDirectoryNameChunk, m_DirectoryNameDesc.CompressedSize); + // TODO: Decompress the file name chunk + return m_hH2O.tellg(); +} + +uint64_t Archive::readDirectoryParents(uint64_t streamPos) +{ + m_hH2O.seekg(streamPos, std::ios::beg); + m_hH2O.read((char*)&m_DirectoryCount, sizeof(m_DirectoryCount)); + m_aDirectoryParents = new int32_t[m_DirectoryCount]; + m_hH2O.read((char*)m_aDirectoryParents, sizeof(*m_aDirectoryParents)*m_DirectoryCount); + + #if _DEBUG + DB::debugLog("Directory Count: ", m_DirectoryCount, NULL); + for (int i=0; i ", *(m_aDirectoryParents), ""); + } + #endif + return m_hH2O.tellg(); +} + void Archive::open(char* szFilePath) { m_hH2O.open(szFilePath, std::ifstream::binary); @@ -95,9 +160,19 @@ void Archive::open(char* szFilePath) curPos = readComment(curPos); DB::debugLog("Header Section: ", "", NULL); curPos = readHeader(curPos); - DB::debugLog("\n", "", NULL); - DB::debugLog("File Section: ", "", NULL); + DB::debugLog("\nFile Section: ", "", NULL); curPos = readFileList(curPos); + + DB::debugLog("\nFileNameDesc Section: ", "", NULL); + curPos = readFileNameDesc(curPos); + curPos = readFileNameChunk(curPos); + + DB::debugLog("\nDirectoryNameDesc Section: ", "", NULL); + curPos = readDirectoryNameDesc(curPos); + curPos = readDirectoryNameChunk(curPos); + + DB::debugLog("\nDirectoryParents Section: ", "", NULL); + curPos = readDirectoryParents(curPos); } void Archive::extractByIndex(uint32_t index) @@ -146,4 +221,6 @@ void Archive::init() { memset(&m_Comment, 0, sizeof(m_Comment)); memset(&m_Header, 0, sizeof(m_Header)); + memset(&m_Header, 0, sizeof(m_FileNameDesc)); + memset(&m_Header, 0, sizeof(m_DirectoryNameDesc)); } \ No newline at end of file diff --git a/Source/Archive.h b/Source/Archive.h index 130a331..9c104b9 100644 --- a/Source/Archive.h +++ b/Source/Archive.h @@ -17,6 +17,7 @@ #include "ArchiveFileNameDesc.h" #include "ArchiveFileNameChunk.h" #include "ArchiveFileName.h" +#include "ArchiveDirectoryNameDesc.h" class Archive { @@ -28,6 +29,11 @@ class Archive uint64_t readComment(uint64_t streamPos); uint64_t readHeader(uint64_t streamPos); uint64_t readFileList(uint64_t streamPos); + uint64_t readFileNameDesc(uint64_t streamPos); + uint64_t readFileNameChunk(uint64_t streamPos); + uint64_t readDirectoryNameDesc(uint64_t streamPos); + uint64_t readDirectoryNameChunk(uint64_t streamPos); + uint64_t readDirectoryParents(uint64_t streamPos); void open(char* szFilePath); void extractByIndex(uint32_t index); @@ -36,6 +42,13 @@ class Archive ArchiveComment m_Comment; ArchiveHeader m_Header; + ArchiveFileNameDesc m_FileNameDesc; + ArchiveDirectoryNameDesc m_DirectoryNameDesc; + uint32_t m_DirectoryCount; + int32_t* m_aDirectoryParents; + + char* m_pFileNameChunk; // pointer the raw(compressed) data from the h2o package + char* m_pDirectoryNameChunk; // pointer the raw(compressed) data from the h2o package std::vector m_FileList; diff --git a/Source/ArchiveDirectoryNameDesc.h b/Source/ArchiveDirectoryNameDesc.h new file mode 100644 index 0000000..aaf3ea7 --- /dev/null +++ b/Source/ArchiveDirectoryNameDesc.h @@ -0,0 +1,13 @@ +/* ArchiveDirectoryNameDesc.h */ +#pragma once + +#include "Types.h" + +#pragma pack(push, 1) +struct ArchiveDirectoryNameDesc +{ + uint32_t CompressedSize; + uint32_t RawSize; + char CRC32[4]; +}; +#pragma pack(pop) \ No newline at end of file diff --git a/Source/ArchiveFileNameDesc.h b/Source/ArchiveFileNameDesc.h index a4e05b3..c6b4cbf 100644 --- a/Source/ArchiveFileNameDesc.h +++ b/Source/ArchiveFileNameDesc.h @@ -9,6 +9,5 @@ struct ArchiveFileNameDesc uint32_t CompressedSize; uint32_t RawSize; char CRC32[4]; - char* CompressedChunk; }; #pragma pack(pop) \ No newline at end of file diff --git a/Source/DebugUtils.cpp b/Source/DebugUtils.cpp index 75dafd2..1f50b8c 100644 --- a/Source/DebugUtils.cpp +++ b/Source/DebugUtils.cpp @@ -32,22 +32,28 @@ namespace DB { szComment = (szComment==NULL) ? "" : szComment; std::cout << szDesc << std::fixed << std::setprecision(2) << szFloat << szComment << std::endl; } - void debugLog(char* szDesc, uint32_t szUint, char* szComment) + void debugLog(char* szDesc, int32_t Int32, char* szComment) { szDesc = (szDesc==NULL) ? "" : szDesc; szComment = (szComment==NULL) ? "" : szComment; - std::cout << szDesc << szUint << szComment << std::endl; + std::cout << szDesc << Int32 << szComment << std::endl; } - void debugLog(char* szDesc, uint64_t szUint, char* szComment) + void debugLog(char* szDesc, uint32_t Uint32, char* szComment) + { + szDesc = (szDesc==NULL) ? "" : szDesc; + szComment = (szComment==NULL) ? "" : szComment; + std::cout << szDesc << Uint32 << szComment << std::endl; + } + void debugLog(char* szDesc, uint64_t Uint64, char* szComment) { szDesc = (szDesc==NULL) ? "" : szDesc; szComment = (szComment==NULL) ? "" : szComment; #if (_MSC_VER < 1300) // VC6 doesn't support cout 64bit integer std::cout << szDesc; - printint64(szUint); + printint64(Uint64); std::cout << szComment << std::endl; #else - std::cout << szDesc << szUint << szComment << std::endl; + std::cout << szDesc << Uint64 << szComment << std::endl; #endif } } \ No newline at end of file diff --git a/Source/DebugUtils.h b/Source/DebugUtils.h index 7562d94..0826c8e 100644 --- a/Source/DebugUtils.h +++ b/Source/DebugUtils.h @@ -9,8 +9,9 @@ namespace DB { void printint64(uint64_t i); void debugLog(char* szDesc, char* szString, char* szComment, bool isHex=false); void debugLog(char* szDesc, float szFloat, char* szComment); - void debugLog(char* szDesc, uint32_t szUint32, char* szComment); - void debugLog(char* szDesc, uint64_t szUint64, char* szComment); + void debugLog(char* szDesc, int32_t Int32, char* szComment); + void debugLog(char* szDesc, uint32_t Uint32, char* szComment); + void debugLog(char* szDesc, uint64_t Uint64, char* szComment); } diff --git a/Source/H2OExtractor.cpp b/Source/H2OExtractor.cpp index 98a88db..3ca2b33 100644 --- a/Source/H2OExtractor.cpp +++ b/Source/H2OExtractor.cpp @@ -7,6 +7,6 @@ int main(int argc, char* argv[]) Archive h2o("Input.H2O"); DB::debugLog("\nExtracting files...", "\n", NULL); - h2o.extractAll(); + //h2o.extractAll(); return 0; } \ No newline at end of file