Rev 456 | Go to most recent revision | Only display areas with differences | Regard whitespace | Details | Blame | Last modification | View Log | RSS feed
Rev 456 | Rev 529 | ||
---|---|---|---|
1 | /* |
1 | /* |
2 | This file is part of "Filter Foundry", a filter plugin for Adobe Photoshop |
2 | This file is part of "Filter Foundry", a filter plugin for Adobe Photoshop |
3 | Copyright (C) 2003-2009 Toby Thain, toby@telegraphics.com.au |
3 | Copyright (C) 2003-2009 Toby Thain, toby@telegraphics.com.au |
4 | Copyright (C) 2018-2021 Daniel Marschall, ViaThinkSoft |
4 | Copyright (C) 2018-2022 Daniel Marschall, ViaThinkSoft |
5 | 5 | ||
6 | This program is free software; you can redistribute it and/or modify |
6 | This program is free software; you can redistribute it and/or modify |
7 | it under the terms of the GNU General Public License as published by |
7 | it under the terms of the GNU General Public License as published by |
8 | the Free Software Foundation; either version 2 of the License, or |
8 | the Free Software Foundation; either version 2 of the License, or |
9 | (at your option) any later version. |
9 | (at your option) any later version. |
10 | 10 | ||
11 | This program is distributed in the hope that it will be useful, |
11 | This program is distributed in the hope that it will be useful, |
12 | but WITHOUT ANY WARRANTY; without even the implied warranty of |
12 | but WITHOUT ANY WARRANTY; without even the implied warranty of |
13 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
13 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
14 | GNU General Public License for more details. |
14 | GNU General Public License for more details. |
15 | 15 | ||
16 | You should have received a copy of the GNU General Public License |
16 | You should have received a copy of the GNU General Public License |
17 | along with this program; if not, write to the Free Software |
17 | along with this program; if not, write to the Free Software |
18 | Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA |
18 | Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA |
19 | */ |
19 | */ |
20 | 20 | ||
21 | #ifndef _CRT_SECURE_NO_WARNINGS |
21 | #ifndef _CRT_SECURE_NO_WARNINGS |
22 | #define _CRT_SECURE_NO_WARNINGS |
22 | #define _CRT_SECURE_NO_WARNINGS |
23 | #endif |
23 | #endif |
24 | 24 | ||
25 | #include <iostream> |
25 | #include <iostream> |
26 | #include <windows.h> |
26 | #include <windows.h> |
27 | #include <string> |
27 | #include <string> |
28 | #include <fstream> |
28 | #include <fstream> |
29 | #include <vector> |
29 | #include <vector> |
30 | 30 | ||
31 | typedef struct _PE32 { |
31 | typedef struct _PE32 { |
32 | uint32_t magic; // 0x50450000 |
32 | uint32_t magic; // 0x50450000 |
33 | IMAGE_FILE_HEADER fileHeader; // COFF Header without Signature |
33 | IMAGE_FILE_HEADER fileHeader; // COFF Header without Signature |
34 | IMAGE_OPTIONAL_HEADER32 optHeader; // Standard COFF fields, Windows Specific Fields, Data Directories |
34 | IMAGE_OPTIONAL_HEADER32 optHeader; // Standard COFF fields, Windows Specific Fields, Data Directories |
35 | } PE32; |
35 | } PE32; |
36 | 36 | ||
37 | #ifdef UNICODE |
37 | #ifdef UNICODE |
38 | typedef std::wstring tstring; |
38 | typedef std::wstring tstring; |
39 | #else |
39 | #else |
40 | typedef std::string tstring; |
40 | typedef std::string tstring; |
41 | #endif |
41 | #endif |
42 | 42 | ||
43 | int binary_file_string_replace(tstring file_name, const char* asearch, const char* areplace) { |
43 | int binary_file_string_replace(tstring file_name, const char* asearch, const char* areplace) { |
44 | std::ifstream input(file_name, std::ios::binary); |
44 | std::ifstream input(file_name, std::ios::binary); |
45 | 45 | ||
46 | std::vector<char> buffer((std::istreambuf_iterator<char>(input)), (std::istreambuf_iterator<char>())); |
46 | std::vector<char> buffer((std::istreambuf_iterator<char>(input)), (std::istreambuf_iterator<char>())); |
47 | std::vector<char>::iterator itbegin = buffer.begin(); |
47 | std::vector<char>::iterator itbegin = buffer.begin(); |
48 | std::vector<char>::iterator itend = buffer.end(); |
48 | std::vector<char>::iterator itend = buffer.end(); |
49 | 49 | ||
50 | if (strlen(asearch) != strlen(areplace)) { |
50 | if (strlen(asearch) != strlen(areplace)) { |
51 | printf("Replace value length greater than original!\n"); |
51 | printf("Replace value length greater than original!\n"); |
52 | return -1; |
52 | return -1; |
53 | } |
53 | } |
54 | int MAX_BUFFER = strlen(asearch); |
54 | int MAX_BUFFER = strlen(asearch); |
55 | 55 | ||
56 | char* needed_str = (char*)malloc(MAX_BUFFER); |
56 | char* needed_str = (char*)malloc(MAX_BUFFER); |
57 | if (needed_str == 0) return -1; |
57 | if (needed_str == 0) return -1; |
58 | char* replace_str = (char*)malloc(MAX_BUFFER); |
58 | char* replace_str = (char*)malloc(MAX_BUFFER); |
59 | if (replace_str == 0) return -1; |
59 | if (replace_str == 0) return -1; |
60 | 60 | ||
61 | memcpy(needed_str, asearch, MAX_BUFFER); |
61 | memcpy(needed_str, asearch, MAX_BUFFER); |
62 | memcpy(replace_str, areplace, MAX_BUFFER); |
62 | memcpy(replace_str, areplace, MAX_BUFFER); |
63 | 63 | ||
64 | int ifound = 0; |
64 | int ifound = 0; |
65 | 65 | ||
66 | for (auto it = itbegin; it < itend; it++) { |
66 | for (auto it = itbegin; it < itend; it++) { |
67 | if (memcmp(it._Ptr, needed_str, MAX_BUFFER) == 0) { |
67 | if (memcmp(it._Ptr, needed_str, MAX_BUFFER) == 0) { |
68 | strncpy(it._Ptr, replace_str, MAX_BUFFER); |
68 | strncpy(it._Ptr, replace_str, MAX_BUFFER); |
69 | it += MAX_BUFFER - 1; // -1 because it++ will be set on the next loop |
69 | it += MAX_BUFFER - 1; // -1 because it++ will be set on the next loop |
70 | ifound++; |
70 | ifound++; |
71 | } |
71 | } |
72 | } |
72 | } |
73 | 73 | ||
74 | if (ifound > 0) { |
74 | if (ifound > 0) { |
75 | std::ofstream ofile(file_name, std::ios::out | std::ios::binary); |
75 | std::ofstream ofile(file_name, std::ios::out | std::ios::binary); |
76 | ofile.write((char*)&buffer[0], buffer.size() * sizeof(char)); |
76 | ofile.write((char*)&buffer[0], buffer.size() * sizeof(char)); |
77 | ofile.close(); |
77 | ofile.close(); |
78 | } |
78 | } |
79 | 79 | ||
80 | return ifound; |
80 | return ifound; |
81 | } |
81 | } |
82 | 82 | ||
83 | int binary_file_string_find(tstring file_name, const char* asearch) { |
83 | int binary_file_string_find(tstring file_name, const char* asearch) { |
84 | std::ifstream input(file_name, std::ios::binary); |
84 | std::ifstream input(file_name, std::ios::binary); |
85 | 85 | ||
86 | std::vector<char> buffer((std::istreambuf_iterator<char>(input)), (std::istreambuf_iterator<char>())); |
86 | std::vector<char> buffer((std::istreambuf_iterator<char>(input)), (std::istreambuf_iterator<char>())); |
87 | std::vector<char>::iterator itbegin = buffer.begin(); |
87 | std::vector<char>::iterator itbegin = buffer.begin(); |
88 | std::vector<char>::iterator itend = buffer.end(); |
88 | std::vector<char>::iterator itend = buffer.end(); |
89 | 89 | ||
90 | int MAX_BUFFER = strlen(asearch); |
90 | int MAX_BUFFER = strlen(asearch); |
91 | 91 | ||
92 | char* needed_str = (char*)malloc(MAX_BUFFER); |
92 | char* needed_str = (char*)malloc(MAX_BUFFER); |
93 | if (needed_str == 0) return -1; |
93 | if (needed_str == 0) return -1; |
94 | 94 | ||
95 | memcpy(needed_str, asearch, MAX_BUFFER); |
95 | memcpy(needed_str, asearch, MAX_BUFFER); |
96 | 96 | ||
97 | int ifound = 0; |
97 | int ifound = 0; |
98 | 98 | ||
99 | for (auto it = itbegin; it < itend; it++) { |
99 | for (auto it = itbegin; it < itend; it++) { |
100 | if (memcmp(it._Ptr, needed_str, MAX_BUFFER) == 0) { |
100 | if (memcmp(it._Ptr, needed_str, MAX_BUFFER) == 0) { |
101 | it += MAX_BUFFER - 1; // -1 because it++ will be set on the next loop |
101 | it += MAX_BUFFER - 1; // -1 because it++ will be set on the next loop |
102 | ifound++; |
102 | ifound++; |
103 | } |
103 | } |
104 | } |
104 | } |
105 | 105 | ||
106 | return ifound; |
106 | return ifound; |
107 | } |
107 | } |
108 | 108 | ||
109 | void _set_pe_int32(FILE* fptr, size_t fieldoffset, int32_t val) { |
109 | void _set_pe_int32(FILE* fptr, size_t fieldoffset, int32_t val) { |
110 | size_t peoffset; |
110 | size_t peoffset; |
111 | 111 | ||
112 | fseek(fptr, 0x3C, SEEK_SET); |
112 | fseek(fptr, 0x3C, SEEK_SET); |
113 | fread(&peoffset, sizeof(peoffset), 1, fptr); |
113 | fread(&peoffset, sizeof(peoffset), 1, fptr); |
114 | 114 | ||
115 | fseek(fptr, (long)peoffset + fieldoffset, SEEK_SET); |
115 | fseek(fptr, (long)peoffset + fieldoffset, SEEK_SET); |
116 | fwrite(&val, sizeof(int32_t), 1, fptr); |
116 | fwrite(&val, sizeof(int32_t), 1, fptr); |
117 | } |
117 | } |
118 | 118 | ||
119 | int32_t _get_pe_int32(FILE* fptr, size_t fieldoffset) { |
119 | int32_t _get_pe_int32(FILE* fptr, size_t fieldoffset) { |
120 | size_t peoffset; |
120 | size_t peoffset; |
121 | int32_t res; |
121 | int32_t res; |
122 | 122 | ||
123 | fseek(fptr, 0x3C, SEEK_SET); |
123 | fseek(fptr, 0x3C, SEEK_SET); |
124 | fread(&peoffset, sizeof(peoffset), 1, fptr); |
124 | fread(&peoffset, sizeof(peoffset), 1, fptr); |
125 | 125 | ||
126 | fseek(fptr, (long)peoffset + fieldoffset, SEEK_SET); |
126 | fseek(fptr, (long)peoffset + fieldoffset, SEEK_SET); |
127 | fread(&res, sizeof(int32_t), 1, fptr); |
127 | fread(&res, sizeof(int32_t), 1, fptr); |
128 | 128 | ||
129 | return res; |
129 | return res; |
130 | } |
130 | } |
131 | 131 | ||
132 | bool update_pe_timestamp(LPCTSTR filename, __time32_t timestamp) { |
132 | bool update_pe_timestamp(LPCTSTR filename, __time32_t timestamp) { |
133 | FILE* fptr = _wfopen(filename, L"rb+"); |
133 | FILE* fptr = _wfopen(filename, L"rb+"); |
134 | if (fptr == NULL) return false; |
134 | if (fptr == NULL) return false; |
135 | 135 | ||
136 | _set_pe_int32(fptr, /*0x0008*/offsetof(PE32, fileHeader.TimeDateStamp), timestamp); |
136 | _set_pe_int32(fptr, /*0x0008*/offsetof(PE32, fileHeader.TimeDateStamp), timestamp); |
137 | 137 | ||
138 | fclose(fptr); |
138 | fclose(fptr); |
139 | 139 | ||
140 | return true; |
140 | return true; |
141 | } |
141 | } |
142 | 142 | ||
143 | bool openWatcomCosmetics(LPCTSTR filename) { |
143 | bool openWatcomCosmetics(LPCTSTR filename) { |
144 | if (binary_file_string_find(filename, "Open Watcom") > 0) { |
144 | if (binary_file_string_find(filename, "Open Watcom") > 0) { |
145 | FILE* fptr = _wfopen(filename, L"rb+"); |
145 | FILE* fptr = _wfopen(filename, L"rb+"); |
146 | if (fptr == NULL) return false; |
146 | if (fptr == NULL) return false; |
147 | 147 | ||
148 | // Min OS Version 1.11 ... But the actual minimal Windows version is Windows NT 3.11 |
148 | // Min OS Version 1.11 ... But the actual minimal Windows version is Windows NT 3.11 |
149 | int32_t minOsVersion = _get_pe_int32(fptr, /*0x0040*/offsetof(PE32, optHeader.MajorOperatingSystemVersion)); |
149 | int32_t minOsVersion = _get_pe_int32(fptr, /*0x0040*/offsetof(PE32, optHeader.MajorOperatingSystemVersion)); |
150 | if (minOsVersion == 0x000B0001) { |
150 | if (minOsVersion == 0x000B0001) { |
151 | _set_pe_int32(fptr, /*0x0040*/offsetof(PE32, optHeader.MajorOperatingSystemVersion), 0x00000003); // Windows 3.0 |
151 | _set_pe_int32(fptr, /*0x0040*/offsetof(PE32, optHeader.MajorOperatingSystemVersion), 0x00000003); // Windows 3.0 |
152 | } |
152 | } |
153 | 153 | ||
154 | // Stack reserved cannot be changed with linker option "OPTION STACK=1m" (Rejected https://github.com/open-watcom/open-watcom-v2/issues/780) |
154 | // Stack reserved cannot be changed with linker option "OPTION STACK=1m" (Rejected https://github.com/open-watcom/open-watcom-v2/issues/780) |
155 | // It is not required for DLLs, but everybody does it, and I think it is cosmetics to fill these fields, even if not required. |
155 | // It is not required for DLLs, but everybody does it, and I think it is cosmetics to fill these fields, even if not required. |
156 | _set_pe_int32(fptr, /*0x0060*/offsetof(PE32, optHeader.SizeOfStackReserve), 0x00100000); |
156 | _set_pe_int32(fptr, /*0x0060*/offsetof(PE32, optHeader.SizeOfStackReserve), 0x00100000); |
157 | _set_pe_int32(fptr, /*0x0064*/offsetof(PE32, optHeader.SizeOfStackCommit), 0x00001000); |
157 | _set_pe_int32(fptr, /*0x0064*/offsetof(PE32, optHeader.SizeOfStackCommit), 0x00001000); |
158 | // Heap reserved can be changed with linker option "OPTION HEAP=1m" |
158 | // Heap reserved can be changed with linker option "OPTION HEAP=1m" before beta 21 Dec 2021 |
159 | _set_pe_int32(fptr, /*0x0068*/offsetof(PE32, optHeader.SizeOfHeapReserve), 0x00100000); |
159 | _set_pe_int32(fptr, /*0x0068*/offsetof(PE32, optHeader.SizeOfHeapReserve), 0x00100000); |
160 | _set_pe_int32(fptr, /*0x006C*/offsetof(PE32, optHeader.SizeOfHeapCommit), 0x00001000); |
160 | _set_pe_int32(fptr, /*0x006C*/offsetof(PE32, optHeader.SizeOfHeapCommit), 0x00001000); |
161 | 161 | ||
162 | fclose(fptr); |
162 | fclose(fptr); |
163 | 163 | ||
164 | // 32 bit (OpenWatcom cosmetics): Export table name "FilterFoundry.dll" => "FilterFoundry.8bf" |
164 | // 32 bit (OpenWatcom cosmetics): Export table name "FilterFoundry.dll" => "FilterFoundry.8bf" |
165 | // since OpenWatcom cannot link a 8BF file natively. |
165 | // since OpenWatcom cannot link a 8BF file natively. |
166 | binary_file_string_replace(filename, "FilterFoundry.dll", "FilterFoundry.8bf"); |
166 | binary_file_string_replace(filename, "FilterFoundry.dll", "FilterFoundry.8bf"); |
167 | } |
167 | } |
168 | 168 | ||
169 | return true; |
169 | return true; |
170 | } |
170 | } |
171 | 171 | ||
172 | uint32_t calculate_checksum(LPCTSTR filename) { |
172 | uint32_t calculate_checksum(LPCTSTR filename) { |
173 | //Calculate checksum of image |
173 | //Calculate checksum of image |
174 | // Taken from "PE Bliss" Cross-Platform Portable Executable C++ Library |
174 | // Taken from "PE Bliss" Cross-Platform Portable Executable C++ Library |
175 | // https://github.com/mrexodia/portable-executable-library/blob/master/pe_lib/pe_checksum.cpp |
175 | // https://github.com/mrexodia/portable-executable-library/blob/master/pe_lib/pe_checksum.cpp |
176 | // Converted from C++ to C by Daniel Marschall |
176 | // Converted from C++ to C by Daniel Marschall |
177 | 177 | ||
178 | FILE* fptr; |
178 | FILE* fptr; |
179 | unsigned long long checksum = 0; |
179 | unsigned long long checksum = 0; |
180 | IMAGE_DOS_HEADER header; |
180 | IMAGE_DOS_HEADER header; |
181 | size_t filesize; |
181 | size_t filesize; |
182 | unsigned long long top; |
182 | unsigned long long top; |
183 | unsigned long pe_checksum_pos; |
183 | unsigned long pe_checksum_pos; |
184 | static const unsigned long checksum_pos_in_optional_headers = 64; |
184 | static const unsigned long checksum_pos_in_optional_headers = 64; |
185 | size_t i; |
185 | size_t i; |
186 | 186 | ||
187 | fptr = _wfopen(filename, L"rb"); |
187 | fptr = _wfopen(filename, L"rb"); |
188 | if (fptr == NULL) return 0x00000000; |
188 | if (fptr == NULL) return 0x00000000; |
189 | 189 | ||
190 | //Read DOS header |
190 | //Read DOS header |
191 | fseek(fptr, 0, SEEK_SET); |
191 | fseek(fptr, 0, SEEK_SET); |
192 | fread(&header, sizeof(IMAGE_DOS_HEADER), 1, fptr); |
192 | fread(&header, sizeof(IMAGE_DOS_HEADER), 1, fptr); |
193 | 193 | ||
194 | //Calculate PE checksum |
194 | //Calculate PE checksum |
195 | fseek(fptr, 0, SEEK_SET); |
195 | fseek(fptr, 0, SEEK_SET); |
196 | top = 0xFFFFFFFF; |
196 | top = 0xFFFFFFFF; |
197 | top++; |
197 | top++; |
198 | 198 | ||
199 | //"CheckSum" field position in optional PE headers - it's always 64 for PE and PE+ |
199 | //"CheckSum" field position in optional PE headers - it's always 64 for PE and PE+ |
200 | //Calculate real PE headers "CheckSum" field position |
200 | //Calculate real PE headers "CheckSum" field position |
201 | //Sum is safe here |
201 | //Sum is safe here |
202 | pe_checksum_pos = header.e_lfanew + sizeof(IMAGE_FILE_HEADER) + sizeof(uint32_t) + checksum_pos_in_optional_headers; |
202 | pe_checksum_pos = header.e_lfanew + sizeof(IMAGE_FILE_HEADER) + sizeof(uint32_t) + checksum_pos_in_optional_headers; |
203 | 203 | ||
204 | //Calculate checksum for each byte of file |
204 | //Calculate checksum for each byte of file |
205 | fseek(fptr, 0L, SEEK_END); |
205 | fseek(fptr, 0L, SEEK_END); |
206 | filesize = ftell(fptr); |
206 | filesize = ftell(fptr); |
207 | fseek(fptr, 0L, SEEK_SET); |
207 | fseek(fptr, 0L, SEEK_SET); |
208 | for (i = 0; i < filesize; i += 4) |
208 | for (i = 0; i < filesize; i += 4) |
209 | { |
209 | { |
210 | unsigned long dw = 0; |
210 | unsigned long dw = 0; |
211 | 211 | ||
212 | //Read DWORD from file |
212 | //Read DWORD from file |
213 | fread(&dw, sizeof(dw), 1, fptr); |
213 | fread(&dw, sizeof(dw), 1, fptr); |
214 | //Skip "CheckSum" DWORD |
214 | //Skip "CheckSum" DWORD |
215 | if (i == pe_checksum_pos) |
215 | if (i == pe_checksum_pos) |
216 | continue; |
216 | continue; |
217 | 217 | ||
218 | //Calculate checksum |
218 | //Calculate checksum |
219 | checksum = (checksum & 0xffffffff) + dw + (checksum >> 32); |
219 | checksum = (checksum & 0xffffffff) + dw + (checksum >> 32); |
220 | if (checksum > top) |
220 | if (checksum > top) |
221 | checksum = (checksum & 0xffffffff) + (checksum >> 32); |
221 | checksum = (checksum & 0xffffffff) + (checksum >> 32); |
222 | } |
222 | } |
223 | 223 | ||
224 | //Finish checksum |
224 | //Finish checksum |
225 | checksum = (checksum & 0xffff) + (checksum >> 16); |
225 | checksum = (checksum & 0xffff) + (checksum >> 16); |
226 | checksum = (checksum)+(checksum >> 16); |
226 | checksum = (checksum)+(checksum >> 16); |
227 | checksum = checksum & 0xffff; |
227 | checksum = checksum & 0xffff; |
228 | 228 | ||
229 | checksum += (unsigned long)(filesize); |
229 | checksum += (unsigned long)(filesize); |
230 | 230 | ||
231 | fclose(fptr); |
231 | fclose(fptr); |
232 | 232 | ||
233 | //Return checksum |
233 | //Return checksum |
234 | return (uint32_t)checksum; |
234 | return (uint32_t)checksum; |
235 | } |
235 | } |
236 | 236 | ||
237 | bool repair_pe_checksum(LPCTSTR filename) { |
237 | bool repair_pe_checksum(LPCTSTR filename) { |
238 | FILE* fptr; |
238 | FILE* fptr; |
239 | 239 | ||
240 | uint32_t checksum = calculate_checksum(filename); |
240 | uint32_t checksum = calculate_checksum(filename); |
241 | //if (checksum == 0x00000000) return false; |
241 | //if (checksum == 0x00000000) return false; |
242 | 242 | ||
243 | fptr = _wfopen(filename, L"rb+"); |
243 | fptr = _wfopen(filename, L"rb+"); |
244 | if (fptr == NULL) return false; |
244 | if (fptr == NULL) return false; |
245 | 245 | ||
246 | _set_pe_int32(fptr, /*0x0058*/offsetof(PE32, optHeader.CheckSum), (int32_t)checksum); |
246 | _set_pe_int32(fptr, /*0x0058*/offsetof(PE32, optHeader.CheckSum), (int32_t)checksum); |
247 | 247 | ||
248 | fclose(fptr); |
248 | fclose(fptr); |
249 | 249 | ||
250 | return true; |
250 | return true; |
251 | } |
251 | } |
252 | 252 | ||
253 | bool removeFromFile(LPCTSTR pluginfile, LPCTSTR lpType, LPCTSTR lpName, WORD wLanguage) { |
253 | bool removeFromFile(LPCTSTR pluginfile, LPCTSTR lpType, LPCTSTR lpName, WORD wLanguage) { |
254 | bool bSuccessful = false; |
254 | bool bSuccessful = false; |
255 | 255 | ||
256 | HANDLE hRes = BeginUpdateResource(pluginfile, false); |
256 | HANDLE hRes = BeginUpdateResource(pluginfile, false); |
257 | if (hRes != NULL) { |
257 | if (hRes != NULL) { |
258 | if (UpdateResource(hRes, lpType, lpName, wLanguage, NULL, 0)) { |
258 | if (UpdateResource(hRes, lpType, lpName, wLanguage, NULL, 0)) { |
259 | if (EndUpdateResource(hRes, false)) { |
259 | if (EndUpdateResource(hRes, false)) { |
260 | bSuccessful = true; |
260 | bSuccessful = true; |
261 | } |
261 | } |
262 | } |
262 | } |
263 | else { |
263 | else { |
264 | EndUpdateResource(hRes, true); |
264 | EndUpdateResource(hRes, true); |
265 | } |
265 | } |
266 | } |
266 | } |
267 | 267 | ||
268 | return bSuccessful; |
268 | return bSuccessful; |
269 | } |
269 | } |
270 | 270 | ||
271 | bool addToFile(LPCTSTR pluginfile, LPCTSTR otherfile, LPCTSTR lpType, LPCTSTR lpName, WORD wLanguage) { |
271 | bool addToFile(LPCTSTR pluginfile, LPCTSTR otherfile, LPCTSTR lpType, LPCTSTR lpName, WORD wLanguage) { |
272 | HANDLE hFile; |
272 | HANDLE hFile; |
273 | DWORD dwFileSize, dwBytesRead; |
273 | DWORD dwFileSize, dwBytesRead; |
274 | LPBYTE lpBuffer; |
274 | LPBYTE lpBuffer; |
275 | bool bSuccessful = false; |
275 | bool bSuccessful = false; |
276 | 276 | ||
277 | hFile = CreateFile(otherfile, GENERIC_READ, |
277 | hFile = CreateFile(otherfile, GENERIC_READ, |
278 | 0, |
278 | 0, |
279 | NULL, |
279 | NULL, |
280 | OPEN_EXISTING, |
280 | OPEN_EXISTING, |
281 | FILE_ATTRIBUTE_NORMAL, |
281 | FILE_ATTRIBUTE_NORMAL, |
282 | NULL); |
282 | NULL); |
283 | 283 | ||
284 | if (INVALID_HANDLE_VALUE != hFile) |
284 | if (INVALID_HANDLE_VALUE != hFile) |
285 | { |
285 | { |
286 | dwFileSize = GetFileSize(hFile, NULL); |
286 | dwFileSize = GetFileSize(hFile, NULL); |
287 | 287 | ||
288 | //lpBuffer = new BYTE[dwFileSize]; |
288 | //lpBuffer = new BYTE[dwFileSize]; |
289 | lpBuffer = (LPBYTE)malloc(dwFileSize); |
289 | lpBuffer = (LPBYTE)malloc(dwFileSize); |
290 | 290 | ||
291 | if (ReadFile(hFile, lpBuffer, dwFileSize, &dwBytesRead, NULL) != FALSE) |
291 | if (ReadFile(hFile, lpBuffer, dwFileSize, &dwBytesRead, NULL) != FALSE) |
292 | { |
292 | { |
293 | HANDLE hRes = BeginUpdateResource(pluginfile, false); |
293 | HANDLE hRes = BeginUpdateResource(pluginfile, false); |
294 | if (hRes != NULL) { |
294 | if (hRes != NULL) { |
295 | if (UpdateResource(hRes, lpType, lpName, wLanguage, lpBuffer, dwFileSize)) { |
295 | if (UpdateResource(hRes, lpType, lpName, wLanguage, lpBuffer, dwFileSize)) { |
296 | if (EndUpdateResource(hRes, false)) { |
296 | if (EndUpdateResource(hRes, false)) { |
297 | bSuccessful = true; |
297 | bSuccessful = true; |
298 | } |
298 | } |
299 | } |
299 | } |
300 | else { |
300 | else { |
301 | EndUpdateResource(hRes, true); |
301 | EndUpdateResource(hRes, true); |
302 | } |
302 | } |
303 | } |
303 | } |
304 | } |
304 | } |
305 | 305 | ||
306 | //delete[] lpBuffer; |
306 | //delete[] lpBuffer; |
307 | free(lpBuffer); |
307 | free(lpBuffer); |
308 | 308 | ||
309 | CloseHandle(hFile); |
309 | CloseHandle(hFile); |
310 | } |
310 | } |
311 | 311 | ||
312 | return bSuccessful; |
312 | return bSuccessful; |
313 | } |
313 | } |
314 | 314 | ||
315 | 315 | ||
316 | int main() |
316 | int main() |
317 | { |
317 | { |
318 | LPCTSTR lpTemplateType = L"TPLT"; |
318 | LPCTSTR lpTemplateType = L"TPLT"; |
319 | LPCTSTR lpName32Plugin = (LPCTSTR)1032; |
319 | LPCTSTR lpName32Plugin = (LPCTSTR)1032; |
320 | LPCTSTR lpName64Plugin = (LPCTSTR)1064; |
320 | LPCTSTR lpName64Plugin = (LPCTSTR)1064; |
321 | LPCTSTR lpName32Version = (LPCTSTR)3032; |
321 | LPCTSTR lpName32Version = (LPCTSTR)3032; |
322 | LPCTSTR lpName64Version = (LPCTSTR)3064; |
322 | LPCTSTR lpName64Version = (LPCTSTR)3064; |
323 | LPCTSTR lpName32Pipl = (LPCTSTR)16032; |
323 | LPCTSTR lpName32Pipl = (LPCTSTR)16032; |
324 | LPCTSTR lpName64Pipl = (LPCTSTR)16064; |
324 | LPCTSTR lpName64Pipl = (LPCTSTR)16064; |
325 | WORD wLanguageEnUs = MAKELANGID(LANG_ENGLISH, SUBLANG_ENGLISH_US); // 1033 en-US |
325 | WORD wLanguageEnUs = MAKELANGID(LANG_ENGLISH, SUBLANG_ENGLISH_US); // 1033 en-US |
326 | WORD wLanguageNeutral = MAKELANGID(LANG_NEUTRAL, SUBLANG_NEUTRAL); // 0 Neutral |
326 | WORD wLanguageNeutral = MAKELANGID(LANG_NEUTRAL, SUBLANG_NEUTRAL); // 0 Neutral |
327 | 327 | ||
328 | LPCTSTR file32in = L"in\\FilterFoundry.8bf"; |
328 | LPCTSTR file32in = L"in\\FilterFoundry.8bf"; |
329 | LPCTSTR file64in = L"in\\FilterFoundry64.8bf"; |
329 | LPCTSTR file64in = L"in\\FilterFoundry64.8bf"; |
330 | LPCTSTR file32out = L"out\\FilterFoundry.8bf"; |
330 | LPCTSTR file32out = L"out\\FilterFoundry.8bf"; |
331 | LPCTSTR file64out = L"out\\FilterFoundry64.8bf"; |
331 | LPCTSTR file64out = L"out\\FilterFoundry64.8bf"; |
332 | LPCTSTR file32tmp = L"FilterFoundry.tmp"; |
332 | LPCTSTR file32tmp = L"FilterFoundry.tmp"; |
333 | LPCTSTR file64tmp = L"FilterFoundry64.tmp"; |
333 | LPCTSTR file64tmp = L"FilterFoundry64.tmp"; |
334 | 334 | ||
335 | // 1a. Copy 32 "IN" to 32 "TMP", and 64 "IN" to 64 "TMP" |
335 | // 1a. Copy 32 "IN" to 32 "TMP", and 64 "IN" to 64 "TMP" |
336 | { |
336 | { |
337 | if (!CopyFile(file32in, file32tmp, false)) { |
337 | if (!CopyFile(file32in, file32tmp, false)) { |
338 | DeleteFile(file32out); |
338 | DeleteFile(file32out); |
339 | DeleteFile(file64out); |
339 | DeleteFile(file64out); |
340 | printf("Error: Copyfile 32in > 32tmp\n"); |
340 | printf("Error: Copyfile 32in > 32tmp\n"); |
341 | return 1; |
341 | return 1; |
342 | } |
342 | } |
343 | 343 | ||
344 | if (!CopyFile(file64in, file64tmp, false)) { |
344 | if (!CopyFile(file64in, file64tmp, false)) { |
345 | DeleteFile(file32out); |
345 | DeleteFile(file32out); |
346 | DeleteFile(file64out); |
346 | DeleteFile(file64out); |
347 | printf("Error: Copyfile 64in > 64tmp\n"); |
347 | printf("Error: Copyfile 64in > 64tmp\n"); |
348 | return 1; |
348 | return 1; |
349 | } |
349 | } |
350 | } |
350 | } |
351 | 351 | ||
352 | // 1b. Copy 32 "IN" to 32 "OUT", and 64 "IN" to 64 "OUT" (will be edited later) |
352 | // 1b. Copy 32 "IN" to 32 "OUT", and 64 "IN" to 64 "OUT" (will be edited later) |
353 | { |
353 | { |
354 | if (!CopyFile(file32in, file32out, false)) { |
354 | if (!CopyFile(file32in, file32out, false)) { |
355 | DeleteFile(file32out); |
355 | DeleteFile(file32out); |
356 | DeleteFile(file64out); |
356 | DeleteFile(file64out); |
357 | printf("Error: Copyfile 32in > 32out\n"); |
357 | printf("Error: Copyfile 32in > 32out\n"); |
358 | return 1; |
358 | return 1; |
359 | } |
359 | } |
360 | 360 | ||
361 | if (!CopyFile(file64in, file64out, false)) { |
361 | if (!CopyFile(file64in, file64out, false)) { |
362 | DeleteFile(file32out); |
362 | DeleteFile(file32out); |
363 | DeleteFile(file64out); |
363 | DeleteFile(file64out); |
364 | printf("Error: Copyfile 64in > 64out\n"); |
364 | printf("Error: Copyfile 64in > 64out\n"); |
365 | return 1; |
365 | return 1; |
366 | } |
366 | } |
367 | } |
367 | } |
368 | 368 | ||
369 | // 2. Remove any template residues at 32/64 "TMP", since they are only used for building |
369 | // 2. Remove any template residues at 32/64 "TMP", since they are only used for building |
370 | // "TMP" is our "standalone plugin skelleton" |
370 | // "TMP" is our "standalone plugin skelleton" |
371 | // TODO: Also remove build dialogs, cursors and icons (like done in make_win.c)? |
371 | // TODO: Also remove build dialogs, cursors and icons (like done in make_win.c)? |
372 | { |
372 | { |
373 | // Remove TPLT 1 (Manifest template) |
373 | // Remove TPLT 1 (Manifest template) |
374 | removeFromFile(file32tmp, lpTemplateType, MAKEINTRESOURCE(1), wLanguageNeutral); |
374 | removeFromFile(file32tmp, lpTemplateType, MAKEINTRESOURCE(1), wLanguageNeutral); |
375 | removeFromFile(file64tmp, lpTemplateType, MAKEINTRESOURCE(1), wLanguageNeutral); |
375 | removeFromFile(file64tmp, lpTemplateType, MAKEINTRESOURCE(1), wLanguageNeutral); |
376 | 376 | ||
377 | // Remove TPLT 1032/1064 (8BF included) |
377 | // Remove TPLT 1032/1064 (8BF included) |
378 | removeFromFile(file32tmp, lpTemplateType, lpName32Plugin, wLanguageEnUs); |
378 | removeFromFile(file32tmp, lpTemplateType, lpName32Plugin, wLanguageEnUs); |
379 | removeFromFile(file32tmp, lpTemplateType, lpName64Plugin, wLanguageEnUs); |
379 | removeFromFile(file32tmp, lpTemplateType, lpName64Plugin, wLanguageEnUs); |
380 | removeFromFile(file64tmp, lpTemplateType, lpName32Plugin, wLanguageEnUs); |
380 | removeFromFile(file64tmp, lpTemplateType, lpName32Plugin, wLanguageEnUs); |
381 | removeFromFile(file64tmp, lpTemplateType, lpName64Plugin, wLanguageEnUs); |
381 | removeFromFile(file64tmp, lpTemplateType, lpName64Plugin, wLanguageEnUs); |
382 | 382 | ||
383 | // Remove TPLT 3032/3064 (Versioninfo included) |
383 | // Remove TPLT 3032/3064 (Versioninfo included) |
384 | removeFromFile(file32tmp, lpTemplateType, lpName32Version, wLanguageEnUs); |
384 | removeFromFile(file32tmp, lpTemplateType, lpName32Version, wLanguageEnUs); |
385 | removeFromFile(file32tmp, lpTemplateType, lpName64Version, wLanguageEnUs); |
385 | removeFromFile(file32tmp, lpTemplateType, lpName64Version, wLanguageEnUs); |
386 | removeFromFile(file64tmp, lpTemplateType, lpName32Version, wLanguageEnUs); |
386 | removeFromFile(file64tmp, lpTemplateType, lpName32Version, wLanguageEnUs); |
387 | removeFromFile(file64tmp, lpTemplateType, lpName64Version, wLanguageEnUs); |
387 | removeFromFile(file64tmp, lpTemplateType, lpName64Version, wLanguageEnUs); |
388 | 388 | ||
389 | // Remove TPLT 16032/16064 (PIPL template) |
389 | // Remove TPLT 16032/16064 (PIPL template) |
390 | removeFromFile(file32tmp, lpTemplateType, lpName32Pipl, wLanguageNeutral); |
390 | removeFromFile(file32tmp, lpTemplateType, lpName32Pipl, wLanguageNeutral); |
391 | removeFromFile(file32tmp, lpTemplateType, lpName64Pipl, wLanguageNeutral); |
391 | removeFromFile(file32tmp, lpTemplateType, lpName64Pipl, wLanguageNeutral); |
392 | removeFromFile(file64tmp, lpTemplateType, lpName32Pipl, wLanguageNeutral); |
392 | removeFromFile(file64tmp, lpTemplateType, lpName32Pipl, wLanguageNeutral); |
393 | removeFromFile(file64tmp, lpTemplateType, lpName64Pipl, wLanguageNeutral); |
393 | removeFromFile(file64tmp, lpTemplateType, lpName64Pipl, wLanguageNeutral); |
394 | } |
394 | } |
395 | 395 | ||
396 | // Do some cosmetics to OpenWatcom binaries |
396 | // Do some cosmetics to OpenWatcom binaries |
397 | openWatcomCosmetics(file32tmp); |
397 | openWatcomCosmetics(file32tmp); |
398 | openWatcomCosmetics(file32out); |
398 | openWatcomCosmetics(file32out); |
399 | 399 | ||
400 | // 3. Update timestamp of 32/64 "TMP" |
400 | // 3. Update timestamp of 32/64 "TMP" |
401 | { |
401 | { |
402 | if (!update_pe_timestamp(file32tmp, (__time32_t)time(0))) { |
402 | if (!update_pe_timestamp(file32tmp, (__time32_t)time(0))) { |
403 | DeleteFile(file32out); |
403 | DeleteFile(file32out); |
404 | DeleteFile(file64out); |
404 | DeleteFile(file64out); |
405 | printf("Error: Update TMP timestamp 32\n"); |
405 | printf("Error: Update TMP timestamp 32\n"); |
406 | return 1; |
406 | return 1; |
407 | } |
407 | } |
408 | 408 | ||
409 | if (!update_pe_timestamp(file64tmp, (__time32_t)time(0))) { |
409 | if (!update_pe_timestamp(file64tmp, (__time32_t)time(0))) { |
410 | DeleteFile(file32out); |
410 | DeleteFile(file32out); |
411 | DeleteFile(file64out); |
411 | DeleteFile(file64out); |
412 | printf("Error: Update TMP timestamp 64\n"); |
412 | printf("Error: Update TMP timestamp 64\n"); |
413 | return 1; |
413 | return 1; |
414 | } |
414 | } |
415 | } |
415 | } |
416 | 416 | ||
417 | // 4. Repair checksums of 32/64 "TMP" |
417 | // 4. Repair checksums of 32/64 "TMP" |
418 | { |
418 | { |
419 | if (!repair_pe_checksum(file32tmp)) { |
419 | if (!repair_pe_checksum(file32tmp)) { |
420 | DeleteFile(file32out); |
420 | DeleteFile(file32out); |
421 | DeleteFile(file64out); |
421 | DeleteFile(file64out); |
422 | printf("Error: Repair TMP checksum 32\n"); |
422 | printf("Error: Repair TMP checksum 32\n"); |
423 | return 1; |
423 | return 1; |
424 | } |
424 | } |
425 | if (!repair_pe_checksum(file64tmp)) { |
425 | if (!repair_pe_checksum(file64tmp)) { |
426 | DeleteFile(file32out); |
426 | DeleteFile(file32out); |
427 | DeleteFile(file64out); |
427 | DeleteFile(file64out); |
428 | printf("Error: Repair TMP checksum 64\n"); |
428 | printf("Error: Repair TMP checksum 64\n"); |
429 | return 1; |
429 | return 1; |
430 | } |
430 | } |
431 | } |
431 | } |
432 | 432 | ||
433 | // 6. Add 32/64 "TMP" to 64/32 "OUT" ("criss-cross") |
433 | // 6. Add 32/64 "TMP" to 64/32 "OUT" ("criss-cross") |
434 | { |
434 | { |
435 | if (!addToFile(file32out, file32tmp, lpTemplateType, lpName32Plugin, wLanguageEnUs)) { |
435 | if (!addToFile(file32out, file32tmp, lpTemplateType, lpName32Plugin, wLanguageEnUs)) { |
436 | DeleteFile(file32out); |
436 | DeleteFile(file32out); |
437 | DeleteFile(file64out); |
437 | DeleteFile(file64out); |
438 | printf("Error: Add 32 to 32\n"); |
438 | printf("Error: Add 32 to 32\n"); |
439 | return 1; |
439 | return 1; |
440 | } |
440 | } |
441 | if (!addToFile(file32out, file64tmp, lpTemplateType, lpName64Plugin, wLanguageEnUs)) { |
441 | if (!addToFile(file32out, file64tmp, lpTemplateType, lpName64Plugin, wLanguageEnUs)) { |
442 | DeleteFile(file32out); |
442 | DeleteFile(file32out); |
443 | DeleteFile(file64out); |
443 | DeleteFile(file64out); |
444 | printf("Error: Add 64 to 32\n"); |
444 | printf("Error: Add 64 to 32\n"); |
445 | return 1; |
445 | return 1; |
446 | } |
446 | } |
447 | 447 | ||
448 | if (!addToFile(file64out, file32tmp, lpTemplateType, lpName32Plugin, wLanguageEnUs)) { |
448 | if (!addToFile(file64out, file32tmp, lpTemplateType, lpName32Plugin, wLanguageEnUs)) { |
449 | DeleteFile(file32out); |
449 | DeleteFile(file32out); |
450 | DeleteFile(file64out); |
450 | DeleteFile(file64out); |
451 | printf("Error: Add 32 to 64\n"); |
451 | printf("Error: Add 32 to 64\n"); |
452 | return 1; |
452 | return 1; |
453 | } |
453 | } |
454 | 454 | ||
455 | if (!addToFile(file64out, file64tmp, lpTemplateType, lpName64Plugin, wLanguageEnUs)) { |
455 | if (!addToFile(file64out, file64tmp, lpTemplateType, lpName64Plugin, wLanguageEnUs)) { |
456 | DeleteFile(file32out); |
456 | DeleteFile(file32out); |
457 | DeleteFile(file64out); |
457 | DeleteFile(file64out); |
458 | printf("Error: Add 64 to 64\n"); |
458 | printf("Error: Add 64 to 64\n"); |
459 | return 1; |
459 | return 1; |
460 | } |
460 | } |
461 | } |
461 | } |
462 | 462 | ||
463 | // 7a. Read Version Info from 32 bit "TMP", and copy it to 32/64 "OUT" template |
463 | // 7a. Read Version Info from 32 bit "TMP", and copy it to 32/64 "OUT" template |
464 | { |
464 | { |
465 | HMODULE lib = LoadLibraryEx(file32tmp, NULL, LOAD_LIBRARY_AS_DATAFILE); |
465 | HMODULE lib = LoadLibraryEx(file32tmp, NULL, LOAD_LIBRARY_AS_DATAFILE); |
466 | if (!lib) { |
466 | if (!lib) { |
467 | printf("Loadlib failed at versioninfo TPLT 32"); |
467 | printf("Loadlib failed at versioninfo TPLT 32"); |
468 | return 1; |
468 | return 1; |
469 | } |
469 | } |
470 | HRSRC resinfo = FindResource(lib, MAKEINTRESOURCE(1), RT_VERSION); |
470 | HRSRC resinfo = FindResource(lib, MAKEINTRESOURCE(1), RT_VERSION); |
471 | if (!resinfo) { |
471 | if (!resinfo) { |
472 | printf("FindResource failed at versioninfo TPLT 32"); |
472 | printf("FindResource failed at versioninfo TPLT 32"); |
473 | return 1; |
473 | return 1; |
474 | } |
474 | } |
475 | size_t cbVersionInfo = SizeofResource(lib, resinfo); |
475 | size_t cbVersionInfo = SizeofResource(lib, resinfo); |
476 | HGLOBAL hvinfo = LoadResource(lib, resinfo); |
476 | HGLOBAL hvinfo = LoadResource(lib, resinfo); |
477 | if (!hvinfo) { |
477 | if (!hvinfo) { |
478 | printf("LoadResource failed at versioninfo TPLT 32"); |
478 | printf("LoadResource failed at versioninfo TPLT 32"); |
479 | return 1; |
479 | return 1; |
480 | } |
480 | } |
481 | char* vinfo = (char*)LockResource(hvinfo); |
481 | char* vinfo = (char*)LockResource(hvinfo); |
482 | char* vinfocpy = (char*)malloc(cbVersionInfo); |
482 | char* vinfocpy = (char*)malloc(cbVersionInfo); |
483 | if (vinfocpy == NULL) return 1; |
483 | if (vinfocpy == NULL) return 1; |
484 | memcpy(vinfocpy, vinfo, cbVersionInfo); |
484 | memcpy(vinfocpy, vinfo, cbVersionInfo); |
485 | UnlockResource(hvinfo); |
485 | UnlockResource(hvinfo); |
486 | FreeLibrary(lib); |
486 | FreeLibrary(lib); |
487 | 487 | ||
488 | // Write Version info to TPLT Resource of 32 bit "OUT" |
488 | // Write Version info to TPLT Resource of 32 bit "OUT" |
489 | 489 | ||
490 | HANDLE hupd = BeginUpdateResource(file32out, false); |
490 | HANDLE hupd = BeginUpdateResource(file32out, false); |
491 | UpdateResource(hupd, TEXT("TPLT"), lpName32Version, MAKELANGID(LANG_ENGLISH, SUBLANG_ENGLISH_US), vinfocpy, cbVersionInfo); |
491 | UpdateResource(hupd, TEXT("TPLT"), lpName32Version, MAKELANGID(LANG_ENGLISH, SUBLANG_ENGLISH_US), vinfocpy, cbVersionInfo); |
492 | EndUpdateResource(hupd, false); |
492 | EndUpdateResource(hupd, false); |
493 | 493 | ||
494 | // Write Version info to TPLT Resource of 64 bit "OUT" |
494 | // Write Version info to TPLT Resource of 64 bit "OUT" |
495 | 495 | ||
496 | hupd = BeginUpdateResource(file64out, false); |
496 | hupd = BeginUpdateResource(file64out, false); |
497 | UpdateResource(hupd, TEXT("TPLT"), lpName32Version, MAKELANGID(LANG_ENGLISH, SUBLANG_ENGLISH_US), vinfocpy, cbVersionInfo); |
497 | UpdateResource(hupd, TEXT("TPLT"), lpName32Version, MAKELANGID(LANG_ENGLISH, SUBLANG_ENGLISH_US), vinfocpy, cbVersionInfo); |
498 | EndUpdateResource(hupd, false); |
498 | EndUpdateResource(hupd, false); |
499 | 499 | ||
500 | // Free memory |
500 | // Free memory |
501 | 501 | ||
502 | free(vinfocpy); |
502 | free(vinfocpy); |
503 | } |
503 | } |
504 | 504 | ||
505 | // 7b. Read Version Info from 64 bit "TMP", and copy it to 32/64 "OUT" template |
505 | // 7b. Read Version Info from 64 bit "TMP", and copy it to 32/64 "OUT" template |
506 | { |
506 | { |
507 | HMODULE lib = LoadLibraryEx(file64tmp, NULL, LOAD_LIBRARY_AS_DATAFILE); |
507 | HMODULE lib = LoadLibraryEx(file64tmp, NULL, LOAD_LIBRARY_AS_DATAFILE); |
508 | if (!lib) { |
508 | if (!lib) { |
509 | printf("Loadlib failed at versioninfo TPLT 64"); |
509 | printf("Loadlib failed at versioninfo TPLT 64"); |
510 | return 1; |
510 | return 1; |
511 | } |
511 | } |
512 | HRSRC resinfo = FindResource(lib, MAKEINTRESOURCE(1), RT_VERSION); |
512 | HRSRC resinfo = FindResource(lib, MAKEINTRESOURCE(1), RT_VERSION); |
513 | if (!resinfo) { |
513 | if (!resinfo) { |
514 | printf("FindResource failed at versioninfo TPLT 64"); |
514 | printf("FindResource failed at versioninfo TPLT 64"); |
515 | return 1; |
515 | return 1; |
516 | } |
516 | } |
517 | size_t cbVersionInfo = SizeofResource(lib, resinfo); |
517 | size_t cbVersionInfo = SizeofResource(lib, resinfo); |
518 | HGLOBAL hvinfo = LoadResource(lib, resinfo); |
518 | HGLOBAL hvinfo = LoadResource(lib, resinfo); |
519 | if (!hvinfo) { |
519 | if (!hvinfo) { |
520 | printf("LoadResource failed at versioninfo TPLT 64"); |
520 | printf("LoadResource failed at versioninfo TPLT 64"); |
521 | return 1; |
521 | return 1; |
522 | } |
522 | } |
523 | char* vinfo = (char*)LockResource(hvinfo); |
523 | char* vinfo = (char*)LockResource(hvinfo); |
524 | char* vinfocpy = (char*)malloc(cbVersionInfo); |
524 | char* vinfocpy = (char*)malloc(cbVersionInfo); |
525 | if (vinfocpy == NULL) return 1; |
525 | if (vinfocpy == NULL) return 1; |
526 | memcpy(vinfocpy, vinfo, cbVersionInfo); |
526 | memcpy(vinfocpy, vinfo, cbVersionInfo); |
527 | UnlockResource(hvinfo); |
527 | UnlockResource(hvinfo); |
528 | FreeLibrary(lib); |
528 | FreeLibrary(lib); |
529 | 529 | ||
530 | // Write Version info to TPLT Resource of 32 bit "OUT" |
530 | // Write Version info to TPLT Resource of 32 bit "OUT" |
531 | 531 | ||
532 | HANDLE hupd = BeginUpdateResource(file32out, false); |
532 | HANDLE hupd = BeginUpdateResource(file32out, false); |
533 | UpdateResource(hupd, TEXT("TPLT"), lpName64Version, 1033, vinfocpy, cbVersionInfo); |
533 | UpdateResource(hupd, TEXT("TPLT"), lpName64Version, 1033, vinfocpy, cbVersionInfo); |
534 | EndUpdateResource(hupd, false); |
534 | EndUpdateResource(hupd, false); |
535 | 535 | ||
536 | // Write Version info to TPLT Resource of 64 bit "OUT" |
536 | // Write Version info to TPLT Resource of 64 bit "OUT" |
537 | 537 | ||
538 | hupd = BeginUpdateResource(file64out, false); |
538 | hupd = BeginUpdateResource(file64out, false); |
539 | UpdateResource(hupd, TEXT("TPLT"), lpName64Version, 1033, vinfocpy, cbVersionInfo); |
539 | UpdateResource(hupd, TEXT("TPLT"), lpName64Version, 1033, vinfocpy, cbVersionInfo); |
540 | EndUpdateResource(hupd, false); |
540 | EndUpdateResource(hupd, false); |
541 | 541 | ||
542 | // Free memory |
542 | // Free memory |
543 | 543 | ||
544 | free(vinfocpy); |
544 | free(vinfocpy); |
545 | } |
545 | } |
546 | 546 | ||
547 | // 8. Delete 32/64 "TMP" |
547 | // 8. Delete 32/64 "TMP" |
548 | { |
548 | { |
549 | DeleteFile(file32tmp); |
549 | DeleteFile(file32tmp); |
550 | DeleteFile(file64tmp); |
550 | DeleteFile(file64tmp); |
551 | } |
551 | } |
552 | 552 | ||
553 | // 9. Update timestamp of 32/64 "OUT" |
553 | // 9. Update timestamp of 32/64 "OUT" |
554 | { |
554 | { |
555 | if (!update_pe_timestamp(file32out, (__time32_t)time(0))) { |
555 | if (!update_pe_timestamp(file32out, (__time32_t)time(0))) { |
556 | DeleteFile(file32out); |
556 | DeleteFile(file32out); |
557 | DeleteFile(file64out); |
557 | DeleteFile(file64out); |
558 | printf("Error: Update OUT timestamp 32\n"); |
558 | printf("Error: Update OUT timestamp 32\n"); |
559 | return 1; |
559 | return 1; |
560 | } |
560 | } |
561 | 561 | ||
562 | if (!update_pe_timestamp(file64out, (__time32_t)time(0))) { |
562 | if (!update_pe_timestamp(file64out, (__time32_t)time(0))) { |
563 | DeleteFile(file32out); |
563 | DeleteFile(file32out); |
564 | DeleteFile(file64out); |
564 | DeleteFile(file64out); |
565 | printf("Error: Update OUT timestamp 64\n"); |
565 | printf("Error: Update OUT timestamp 64\n"); |
566 | return 1; |
566 | return 1; |
567 | } |
567 | } |
568 | } |
568 | } |
569 | 569 | ||
570 | // 10. Repair checksums of 32/64 "OUT" |
570 | // 10. Repair checksums of 32/64 "OUT" |
571 | { |
571 | { |
572 | if (!repair_pe_checksum(file32out)) { |
572 | if (!repair_pe_checksum(file32out)) { |
573 | DeleteFile(file32out); |
573 | DeleteFile(file32out); |
574 | DeleteFile(file64out); |
574 | DeleteFile(file64out); |
575 | printf("Error: Repair OUT checksum 32\n"); |
575 | printf("Error: Repair OUT checksum 32\n"); |
576 | return 1; |
576 | return 1; |
577 | } |
577 | } |
578 | if (!repair_pe_checksum(file64out)) { |
578 | if (!repair_pe_checksum(file64out)) { |
579 | DeleteFile(file32out); |
579 | DeleteFile(file32out); |
580 | DeleteFile(file64out); |
580 | DeleteFile(file64out); |
581 | printf("Error: Repair OUT checksum 64\n"); |
581 | printf("Error: Repair OUT checksum 64\n"); |
582 | return 1; |
582 | return 1; |
583 | } |
583 | } |
584 | } |
584 | } |
585 | 585 | ||
586 | // 11. All done! |
586 | // 11. All done! |
587 | 587 | ||
588 | printf("All OK!\n"); |
588 | printf("All OK!\n"); |
589 | return 0; |
589 | return 0; |
590 | } |
590 | } |
591 | 591 |