MCPcopy Create free account
hub / github.com/deathkiller/jazz2-native / FindRelocatedFooter

Function FindRelocatedFooter

Sources/Shared/IO/PakFile.cpp:67–242  ·  view source on GitHub ↗

Source from the content-addressed store, hash-verified

65 }
66
67 static std::int64_t FindRelocatedFooter(std::unique_ptr<Death::IO::Stream>& s)
68 {
69 s->Seek(0, SeekOrigin::Begin);
70
71 std::uint32_t magic = s->ReadValueAsLE<std::uint32_t>();
72
73 // Check for PE signature (MZ header)
74 if ((magic & 0xFFFF) == 0x5A4D) { // "MZ"
75 s->Seek(0x3C, SeekOrigin::Begin);
76 std::uint32_t peHeaderOffset = s->ReadValueAsLE<std::uint32_t>();
77
78 s->Seek(peHeaderOffset, SeekOrigin::Begin);
79 std::uint32_t peSignature = s->ReadValueAsLE<std::uint32_t>();
80 if (peSignature != 0x00004550) { // "PE\0\0"
81 return -1;
82 }
83
84 // Read COFF header
85 s->Seek(peHeaderOffset + 6, SeekOrigin::Begin);
86 std::uint16_t numberOfSections = s->ReadValueAsLE<std::uint16_t>();
87 s->Seek(12, SeekOrigin::Current); // Skip timestamp, symbol table pointer, number of symbols
88 std::uint16_t sizeOfOptionalHeader = s->ReadValueAsLE<std::uint16_t>();
89 s->Seek(2, SeekOrigin::Current); // Skip characteristics
90
91 // Skip optional header to get to section table
92 std::int64_t sectionTablePos = s->GetPosition() + sizeOfOptionalHeader;
93
94 // Search for "pak" section
95 for (std::uint16_t i = 0; i < numberOfSections; i++) {
96 s->Seek(sectionTablePos + i * 40, SeekOrigin::Begin);
97
98 char sectionName[9];
99 s->Read(sectionName, 8);
100 sectionName[8] = '\0';
101
102 if (std::memcmp(sectionName, "pak", 4) == 0) {
103 // Found pak section, read its file offset and size
104 s->Seek(8, SeekOrigin::Current); // Skip VirtualSize and VirtualAddress
105 std::uint32_t sizeOfRawData = s->ReadValueAsLE<std::uint32_t>();
106 std::uint32_t pointerToRawData = s->ReadValueAsLE<std::uint32_t>();
107
108 if (sizeOfRawData >= FooterSize && pointerToRawData > 0) {
109 // Calculate footer position (at the end of pak section)
110 std::int64_t footerPosition = std::int64_t(pointerToRawData) + std::int64_t(sizeOfRawData) - FooterSize;
111
112 s->Seek(footerPosition, SeekOrigin::Begin);
113 std::uint8_t signature[sizeof(Signature)];
114 s->Read(signature, sizeof(signature));
115
116 if (std::memcmp(signature, Signature, sizeof(Signature)) == 0) {
117 return footerPosition;
118 }
119 }
120 break;
121 }
122 }
123
124 return -1;

Callers 1

PakFileMethod · 0.85

Calls 4

SeekMethod · 0.45
GetPositionMethod · 0.45
ReadMethod · 0.45
dataMethod · 0.45

Tested by

no test coverage detected