Skip to content
This repository was archived by the owner on Aug 1, 2025. It is now read-only.

Commit 64280ef

Browse files
Ritchie1108Bush2021
authored andcommitted
refactor: use std::function and move implementation to pakfile.cc
1 parent d4d46f0 commit 64280ef

3 files changed

Lines changed: 182 additions & 177 deletions

File tree

src/pakfile.cc

Lines changed: 176 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1 +1,176 @@
1-
// TODO
1+
#include "pakfile.h"
2+
3+
#include <windows.h>
4+
5+
#pragma warning(disable : 4334)
6+
#pragma warning(disable : 4267)
7+
#pragma warning(disable : 4838)
8+
9+
extern "C" {
10+
#include "..\mini_gzip\miniz.c" // Must be included first
11+
12+
#include "..\mini_gzip\mini_gzip.c"
13+
#include "..\mini_gzip\mini_gzip.h"
14+
}
15+
16+
namespace {
17+
#pragma pack(push)
18+
#pragma pack(1)
19+
20+
#define PACK4_FILE_VERSION (4)
21+
#define PACK5_FILE_VERSION (5)
22+
23+
struct PAK4_HEADER {
24+
uint32_t num_entries;
25+
uint8_t encodeing;
26+
};
27+
28+
struct PAK5_HEADER {
29+
uint32_t encodeing;
30+
uint16_t resource_count;
31+
uint16_t alias_count;
32+
};
33+
34+
struct PAK_ENTRY {
35+
uint16_t resource_id;
36+
uint32_t file_offset;
37+
};
38+
39+
struct PAK_ALIAS {
40+
uint16_t resource_id;
41+
uint16_t entry_index;
42+
};
43+
#pragma pack(pop)
44+
45+
bool CheckHeader(uint8_t* buffer,
46+
PAK_ENTRY*& pak_entry,
47+
PAK_ENTRY*& end_entry) {
48+
uint32_t version = *(uint32_t*)buffer;
49+
50+
if (version != PACK4_FILE_VERSION && version != PACK5_FILE_VERSION)
51+
return false;
52+
53+
if (version == PACK4_FILE_VERSION) {
54+
PAK4_HEADER* pak_header = (PAK4_HEADER*)(buffer + sizeof(uint32_t));
55+
if (pak_header->encodeing != 1)
56+
return false;
57+
58+
pak_entry = (PAK_ENTRY*)(buffer + sizeof(uint32_t) + sizeof(PAK4_HEADER));
59+
end_entry = pak_entry + pak_header->num_entries;
60+
}
61+
62+
if (version == PACK5_FILE_VERSION) {
63+
PAK5_HEADER* pak_header = (PAK5_HEADER*)(buffer + sizeof(uint32_t));
64+
if (pak_header->encodeing != 1)
65+
return false;
66+
67+
pak_entry = (PAK_ENTRY*)(buffer + sizeof(uint32_t) + sizeof(PAK5_HEADER));
68+
end_entry = pak_entry + pak_header->resource_count;
69+
}
70+
71+
// In order to save the "next item" of the last item,
72+
// the id of this special item must be 0
73+
if (!end_entry || end_entry->resource_id != 0)
74+
return false;
75+
76+
return true;
77+
}
78+
79+
void PakFind(uint8_t* buffer,
80+
uint8_t* pos,
81+
std::function<void(uint8_t*, uint32_t)> f) {
82+
PAK_ENTRY* pak_entry = nullptr;
83+
PAK_ENTRY* end_entry = nullptr;
84+
85+
if (!CheckHeader(buffer, pak_entry, end_entry))
86+
return;
87+
88+
do {
89+
PAK_ENTRY* next_entry = pak_entry + 1;
90+
if (pos >= buffer + pak_entry->file_offset &&
91+
pos <= buffer + next_entry->file_offset) {
92+
f(buffer + pak_entry->file_offset,
93+
next_entry->file_offset - pak_entry->file_offset);
94+
break;
95+
}
96+
97+
pak_entry = next_entry;
98+
} while (pak_entry->resource_id != 0);
99+
}
100+
} // namespace
101+
102+
void TraversalGZIPFile(uint8_t* buffer,
103+
std::function<bool(uint8_t*, uint32_t, size_t&)>&& f) {
104+
PAK_ENTRY* pak_entry = nullptr;
105+
PAK_ENTRY* end_entry = nullptr;
106+
107+
if (!CheckHeader(buffer, pak_entry, end_entry))
108+
return;
109+
110+
do {
111+
PAK_ENTRY* next_entry = pak_entry + 1;
112+
size_t old_size = next_entry->file_offset - pak_entry->file_offset;
113+
114+
if (old_size < 10 * 1024) {
115+
pak_entry = next_entry;
116+
continue;
117+
}
118+
119+
BYTE gzip[] = {0x1F, 0x8B, 0x08};
120+
size_t gzip_len = sizeof(gzip);
121+
if (memcmp(buffer + pak_entry->file_offset, gzip, gzip_len) != 0) {
122+
// Not a gzip file, skip
123+
pak_entry = next_entry;
124+
continue;
125+
}
126+
127+
uint32_t original_size = *(uint32_t*)(buffer + next_entry->file_offset - 4);
128+
uint8_t* unpack_buffer = (uint8_t*)malloc(original_size);
129+
if (!unpack_buffer)
130+
return;
131+
132+
struct mini_gzip gz;
133+
mini_gz_start(&gz, buffer + pak_entry->file_offset, old_size);
134+
uint32_t unpack_len = mini_gz_unpack(&gz, unpack_buffer, original_size);
135+
136+
if (original_size == unpack_len) {
137+
size_t new_len = old_size;
138+
bool changed = f(unpack_buffer, unpack_len, new_len);
139+
if (changed) {
140+
size_t compress_size = 0;
141+
uint8_t* compress_buffer =
142+
(uint8_t*)gzip_compress(unpack_buffer, new_len, &compress_size);
143+
if (compress_buffer && compress_size < old_size) {
144+
/*FILE *fp = fopen("test.gz", "wb");
145+
fwrite(compress_buffer, compress_size, 1, fp);
146+
fclose(fp);*/
147+
148+
memcpy(buffer + pak_entry->file_offset, compress_buffer, 10);
149+
150+
// extra
151+
buffer[pak_entry->file_offset + 3] = 0x04;
152+
uint16_t extra_length = old_size - compress_size - 2;
153+
memcpy(buffer + pak_entry->file_offset + 10, &extra_length,
154+
sizeof(extra_length));
155+
memset(buffer + pak_entry->file_offset + 12, '\0', extra_length);
156+
157+
// compress
158+
memcpy(buffer + pak_entry->file_offset + 12 + extra_length,
159+
compress_buffer + 10, compress_size - 10);
160+
161+
/*fp = fopen("test2.gz", "wb");
162+
fwrite(buffer + pak_entry->file_offset, old_size, 1, fp);
163+
fclose(fp);*/
164+
} else {
165+
// DebugLog(L"gzip compress error %d %d", compress_size, old_size);
166+
}
167+
168+
if (compress_buffer)
169+
free(compress_buffer);
170+
}
171+
}
172+
173+
free(unpack_buffer);
174+
pak_entry = next_entry;
175+
} while (pak_entry->resource_id != 0);
176+
}

src/pakfile.h

Lines changed: 3 additions & 174 deletions
Original file line numberDiff line numberDiff line change
@@ -1,180 +1,9 @@
11
#ifndef CHROME_PLUS_SRC_PAKFILE_H_
22
#define CHROME_PLUS_SRC_PAKFILE_H_
33

4-
#pragma warning(disable : 4334)
5-
#pragma warning(disable : 4267)
4+
#include <functional>
65

7-
extern "C"
8-
{
9-
#include "..\mini_gzip\miniz.c"
10-
#include "..\mini_gzip\mini_gzip.h"
11-
#include "..\mini_gzip\mini_gzip.c"
12-
}
13-
14-
#pragma pack(push)
15-
#pragma pack(1)
16-
17-
#define PACK4_FILE_VERSION (4)
18-
#define PACK5_FILE_VERSION (5)
19-
20-
#include "utils.h"
21-
22-
struct PAK4_HEADER {
23-
uint32_t num_entries;
24-
uint8_t encodeing;
25-
};
26-
27-
struct PAK5_HEADER {
28-
uint32_t encodeing;
29-
uint16_t resource_count;
30-
uint16_t alias_count;
31-
};
32-
33-
struct PAK_ENTRY {
34-
uint16_t resource_id;
35-
uint32_t file_offset;
36-
};
37-
38-
struct PAK_ALIAS {
39-
uint16_t resource_id;
40-
uint16_t entry_index;
41-
};
42-
#pragma pack(pop)
43-
44-
bool CheckHeader(uint8_t* buffer,
45-
PAK_ENTRY*& pak_entry,
46-
PAK_ENTRY*& end_entry) {
47-
uint32_t version = *(uint32_t*)buffer;
48-
49-
if (version != PACK4_FILE_VERSION && version != PACK5_FILE_VERSION)
50-
return false;
51-
52-
if (version == PACK4_FILE_VERSION) {
53-
PAK4_HEADER* pak_header = (PAK4_HEADER*)(buffer + sizeof(uint32_t));
54-
if (pak_header->encodeing != 1)
55-
return false;
56-
57-
pak_entry = (PAK_ENTRY*)(buffer + sizeof(uint32_t) + sizeof(PAK4_HEADER));
58-
end_entry = pak_entry + pak_header->num_entries;
59-
}
60-
61-
if (version == PACK5_FILE_VERSION) {
62-
PAK5_HEADER* pak_header = (PAK5_HEADER*)(buffer + sizeof(uint32_t));
63-
if (pak_header->encodeing != 1)
64-
return false;
65-
66-
pak_entry = (PAK_ENTRY*)(buffer + sizeof(uint32_t) + sizeof(PAK5_HEADER));
67-
end_entry = pak_entry + pak_header->resource_count;
68-
}
69-
70-
// In order to save the "next item" of the last item,
71-
// the id of this special item must be 0
72-
if (!end_entry || end_entry->resource_id != 0)
73-
return false;
74-
75-
return true;
76-
}
77-
78-
template <typename Function>
79-
void PakFind(uint8_t* buffer, uint8_t* pos, Function f) {
80-
PAK_ENTRY* pak_entry = nullptr;
81-
PAK_ENTRY* end_entry = nullptr;
82-
83-
// Check the file header.
84-
if (!CheckHeader(buffer, pak_entry, end_entry))
85-
return;
86-
87-
do {
88-
PAK_ENTRY* next_entry = pak_entry + 1;
89-
if (pos >= buffer + pak_entry->file_offset &&
90-
pos <= buffer + next_entry->file_offset) {
91-
f(buffer + pak_entry->file_offset,
92-
next_entry->file_offset - pak_entry->file_offset);
93-
break;
94-
}
95-
96-
pak_entry = next_entry;
97-
} while (pak_entry->resource_id != 0);
98-
}
99-
100-
template <typename Function>
101-
void TraversalGZIPFile(uint8_t* buffer, Function f) {
102-
PAK_ENTRY* pak_entry = NULL;
103-
PAK_ENTRY* end_entry = NULL;
104-
105-
// Check the file header.
106-
if (!CheckHeader(buffer, pak_entry, end_entry))
107-
return;
108-
109-
do {
110-
PAK_ENTRY* next_entry = pak_entry + 1;
111-
uint32_t old_size = next_entry->file_offset - pak_entry->file_offset;
112-
113-
if (old_size < 10 * 1024) {
114-
// Files smaller than 10 kb are skipped.
115-
pak_entry = next_entry;
116-
continue;
117-
}
118-
119-
BYTE gzip[] = {0x1F, 0x8B, 0x08};
120-
size_t gzip_len = sizeof(gzip);
121-
if (memcmp(buffer + pak_entry->file_offset, gzip, gzip_len) != 0) {
122-
// Files that are not gzip format are skipped.
123-
pak_entry = next_entry;
124-
continue;
125-
}
126-
127-
uint32_t original_size = *(uint32_t*)(buffer + next_entry->file_offset - 4);
128-
uint8_t* unpack_buffer = (uint8_t*)malloc(original_size);
129-
if (!unpack_buffer)
130-
return;
131-
132-
struct mini_gzip gz;
133-
mini_gz_start(&gz, buffer + pak_entry->file_offset, old_size);
134-
int unpack_len = mini_gz_unpack(&gz, unpack_buffer, original_size);
135-
136-
if (original_size == unpack_len) {
137-
uint32_t new_len = old_size;
138-
bool changed = f(unpack_buffer, unpack_len, new_len);
139-
if (changed) {
140-
// If the file is changed.
141-
size_t compress_size = 0;
142-
uint8_t* compress_buffer =
143-
(uint8_t*)gzip_compress(unpack_buffer, new_len, &compress_size);
144-
if (compress_buffer && compress_size < old_size) {
145-
/*FILE *fp = fopen("test.gz", "wb");
146-
fwrite(compress_buffer, compress_size, 1, fp);
147-
fclose(fp);*/
148-
149-
// gzip header
150-
memcpy(buffer + pak_entry->file_offset, compress_buffer, 10);
151-
152-
// extra
153-
buffer[pak_entry->file_offset + 3] = 0x04;
154-
uint16_t extra_length = old_size - compress_size - 2;
155-
memcpy(buffer + pak_entry->file_offset + 10, &extra_length,
156-
sizeof(extra_length));
157-
memset(buffer + pak_entry->file_offset + 12, '\0', extra_length);
158-
159-
// compress
160-
memcpy(buffer + pak_entry->file_offset + 12 + extra_length,
161-
compress_buffer + 10, compress_size - 10);
162-
163-
/*fp = fopen("test2.gz", "wb");
164-
fwrite(buffer + pak_entry->file_offset, old_size, 1, fp);
165-
fclose(fp);*/
166-
} else {
167-
DebugLog(L"gzip compress error %d %d", compress_size, old_size);
168-
}
169-
170-
if (compress_buffer)
171-
free(compress_buffer);
172-
}
173-
}
174-
175-
free(unpack_buffer);
176-
pak_entry = next_entry;
177-
} while (pak_entry->resource_id != 0);
178-
}
6+
void TraversalGZIPFile(uint8_t* buffer,
7+
std::function<bool(uint8_t*, uint32_t, size_t&)>&& f);
1798

1809
#endif // CHROME_PLUS_SRC_PAKFILE_H_

src/pakpatch.cc

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -40,8 +40,9 @@ HANDLE WINAPI MyMapViewOfFile(_In_ HANDLE hFileMappingObject,
4040

4141
if (buffer) {
4242
// Traverse the gzip file.
43-
TraversalGZIPFile((BYTE*)buffer, [=](uint8_t* begin, uint32_t size,
44-
uint32_t& new_len) {
43+
TraversalGZIPFile(static_cast<BYTE*>(buffer), [=](uint8_t* begin,
44+
uint32_t size,
45+
size_t& new_len) {
4546
bool changed = false;
4647

4748
BYTE search_start[] = R"(</settings-about-page>)";

0 commit comments

Comments
 (0)