Rev 425 | Rev 445 | Go to most recent revision | Show entire file | Regard whitespace | Details | Blame | Last modification | View Log | RSS feed
Rev 425 | Rev 444 | ||
---|---|---|---|
Line 28... | Line 28... | ||
28 | #include "versioninfo_modify_win.h" |
28 | #include "versioninfo_modify_win.h" |
29 | #include "version.h" |
29 | #include "version.h" |
30 | 30 | ||
31 | extern HINSTANCE hDllInstance; |
31 | extern HINSTANCE hDllInstance; |
32 | 32 | ||
33 | Boolean doresources(char *dstname, int bits); |
33 | Boolean doresources(FSSpec* dst, int bits); |
34 | 34 | ||
35 | void dbglasterror(char *func){ |
35 | void dbglasterror(TCHAR *func){ |
36 | char s[0x100]; |
36 | TCHAR s[0x300]; |
37 | 37 | ||
38 | strcpy(s,func); |
38 | xstrcpy(&s[0],func); |
39 | strcat(s," failed: "); |
39 | xstrcat(&s[0],TEXT(" failed: ")); |
40 | FormatMessage( FORMAT_MESSAGE_FROM_SYSTEM,NULL,GetLastError(),0,s+strlen(s),0x100,NULL ); |
40 | FormatMessage(FORMAT_MESSAGE_FROM_SYSTEM, NULL, GetLastError(), 0, s + xstrlen(s), 0x300 - xstrlen(s), NULL); |
41 | dbg(s); |
41 | dbg(&s[0]); |
42 | } |
42 | } |
43 | 43 | ||
44 | /* |
44 | /* |
45 | BOOL CALLBACK enumfunc(HMODULE hModule,LPCTSTR lpszType,LPCTSTR lpszName,WORD wIDLanguage,LONG lParam){ |
45 | BOOL CALLBACK enumfunc(HMODULE hModule,LPCTSTR lpszType,LPCTSTR lpszName,WORD wIDLanguage,LONG lParam){ |
46 | char s[0x100]; |
46 | char s[0x100]; |
Line 100... | Line 100... | ||
100 | else { |
100 | else { |
101 | return sprintf(newmanifest, manifestp, (char*)name, "x86", VERSION_STR, (char*)description); |
101 | return sprintf(newmanifest, manifestp, (char*)name, "x86", VERSION_STR, (char*)description); |
102 | } |
102 | } |
103 | } |
103 | } |
104 | 104 | ||
105 | ULONG changeVersionInfo(char* dstname, HANDLE hUpdate, PARM_T* pparm, int bits) { |
105 | ULONG changeVersionInfo(FSSpec* dst, HANDLE hUpdate, PARM_T* pparm, int bits) { |
106 | char* soleFilename; |
106 | LPTSTR soleFilename; |
107 | LPWSTR changeRequestStr, tmp; |
107 | LPWSTR changeRequestStrW, tmp; |
108 | ULONG dwError = NOERROR; |
108 | ULONG dwError = NOERROR; |
109 | HRSRC hResInfo; |
109 | HRSRC hResInfo; |
110 | HGLOBAL hg; |
110 | HGLOBAL hg; |
111 | ULONG size; |
111 | ULONG size; |
112 | PVOID pv; |
112 | PVOID pv; |
113 | //BOOL fDiscard = TRUE; |
113 | //BOOL fDiscard = TRUE; |
114 | 114 | ||
115 | if (soleFilename = strrchr(dstname, '\\')) { |
115 | if (soleFilename = xstrrchr(&dst->szName[0], '\\')) { |
116 | ++soleFilename; |
116 | ++soleFilename; |
117 | } |
117 | } |
118 | else { |
118 | else { |
119 | soleFilename = dstname; |
119 | soleFilename = &dst->szName[0]; |
120 | } |
120 | } |
121 | 121 | ||
122 | // Format of argument "PCWSTR changes" is "<name>\0<value>\0<name>\0<value>\0....." |
122 | // Format of argument "PCWSTR changes" is "<name>\0<value>\0<name>\0<value>\0....." |
123 | // You can CHANGE values for any given name |
123 | // You can CHANGE values for any given name |
124 | // You can DELETE entries by setting the value to "\b" (0x08 backspace character) |
124 | // You can DELETE entries by setting the value to "\b" (0x08 backspace character) |
125 | // You cannot (yet) ADD entries. |
125 | // You cannot (yet) ADD entries. |
126 | changeRequestStr = (LPWSTR)malloc(6 * 2 * 100 + 1); |
126 | changeRequestStrW = (LPWSTR)malloc((6 * 2 * 100 + 1) * sizeof(WCHAR)); |
- | 127 | if (changeRequestStrW == 0) return E_OUTOFMEMORY; |
|
- | 128 | memset((char*)changeRequestStrW, 0, sizeof(changeRequestStrW)); |
|
127 | 129 | ||
128 | tmp = changeRequestStr; |
130 | tmp = changeRequestStrW; |
129 | 131 | ||
130 | tmp += mbstowcs(tmp, "Comments", 100); |
132 | tmp += mbstowcs(tmp, "Comments", 100); |
131 | tmp++; |
133 | tmp++; |
132 | tmp += mbstowcs(tmp, "Built using Filter Foundry " VERSION_STR, 100); |
134 | tmp += mbstowcs(tmp, "Built using Filter Foundry " VERSION_STR, 100); |
133 | tmp++; |
135 | tmp++; |
Line 162... | Line 164... | ||
162 | } |
164 | } |
163 | tmp++; |
165 | tmp++; |
164 | 166 | ||
165 | tmp += mbstowcs(tmp, "OriginalFilename", 100); |
167 | tmp += mbstowcs(tmp, "OriginalFilename", 100); |
166 | tmp++; |
168 | tmp++; |
- | 169 | #ifdef UNICODE |
|
- | 170 | xstrcpy(tmp, soleFilename); |
|
- | 171 | tmp += xstrlen(soleFilename); |
|
- | 172 | #else |
|
167 | tmp += mbstowcs(tmp, soleFilename, 100); |
173 | tmp += mbstowcs(tmp, soleFilename, 100); |
- | 174 | #endif |
|
168 | tmp++; |
175 | tmp++; |
169 | 176 | ||
170 | tmp += mbstowcs(tmp, "License", 100); |
177 | tmp += mbstowcs(tmp, "License", 100); |
171 | tmp++; |
178 | tmp++; |
172 | tmp += mbstowcs(tmp, "\b", 100); // \b = remove, since filter is standalone and might have its own license |
179 | tmp += mbstowcs(tmp, "\b", 100); // \b = remove, since filter is standalone and might have its own license |
173 | tmp++; |
180 | tmp++; |
174 | 181 | ||
175 | tmp += mbstowcs(tmp, "", 1); |
182 | tmp += mbstowcs(tmp, "", 1); |
176 | 183 | ||
177 | if (hResInfo = FindResourceEx(hDllInstance, "TPLT", MAKEINTRESOURCE(3000 + bits), MAKELANGID(LANG_ENGLISH, SUBLANG_ENGLISH_US))) |
184 | if (hResInfo = FindResourceEx(hDllInstance, TEXT("TPLT"), MAKEINTRESOURCE(3000 + bits), MAKELANGID(LANG_ENGLISH, SUBLANG_ENGLISH_US))) |
178 | { |
185 | { |
179 | if (hg = LoadResource(hDllInstance, hResInfo)) |
186 | if (hg = LoadResource(hDllInstance, hResInfo)) |
180 | { |
187 | { |
181 | if (size = SizeofResource(hDllInstance, hResInfo)) |
188 | if (size = SizeofResource(hDllInstance, hResInfo)) |
182 | { |
189 | { |
183 | if (pv = LockResource(hg)) |
190 | if (pv = LockResource(hg)) |
184 | { |
191 | { |
185 | if (UpdateVersionRaw(pv, size, &pv, &size, changeRequestStr)) |
192 | if (UpdateVersionRaw(pv, size, &pv, &size, changeRequestStrW)) |
186 | { |
193 | { |
187 | if (_UpdateResource(hUpdate, RT_VERSION, MAKEINTRESOURCE(1), MAKELANGID(LANG_ENGLISH, SUBLANG_ENGLISH_US), pv, size)) |
194 | if (_UpdateResource(hUpdate, RT_VERSION, MAKEINTRESOURCE(1), MAKELANGID(LANG_ENGLISH, SUBLANG_ENGLISH_US), pv, size)) |
188 | { |
195 | { |
189 | //fDiscard = FALSE; |
196 | //fDiscard = FALSE; |
190 | } |
197 | } |
Line 196... | Line 203... | ||
196 | } |
203 | } |
197 | } |
204 | } |
198 | } |
205 | } |
199 | } |
206 | } |
200 | 207 | ||
201 | free(changeRequestStr); |
208 | free(changeRequestStrW); |
202 | 209 | ||
203 | return dwError; |
210 | return dwError; |
204 | } |
211 | } |
205 | 212 | ||
206 | Boolean update_pe_timestamp(const char* filename, time_t timestamp) { |
213 | Boolean update_pe_timestamp(const FSSpec* dst, time_t timestamp) { |
207 | size_t peoffset; |
214 | size_t peoffset; |
208 | FILE* fptr; |
215 | FILEREF fptr; |
209 | - | ||
210 | fptr = fopen(filename, "rb+"); |
216 | Boolean res; |
211 | if (fptr == NULL) return false; |
217 | FILECOUNT cnt; |
212 | 218 | ||
213 | fseek(fptr, 0x3C, SEEK_SET); |
- | |
214 | fread(&peoffset, sizeof(peoffset), 1, fptr); |
219 | if (FSpOpenDF(dst, fsRdWrPerm, &fptr) != noErr) return false; |
215 | 220 | ||
- | 221 | res = |
|
- | 222 | SetFPos(fptr, fsFromStart, 0x3C) || |
|
- | 223 | (cnt = sizeof(peoffset), noErr) || |
|
- | 224 | FSRead(fptr, &cnt, &peoffset) || |
|
216 | fseek(fptr, (long)peoffset + 8, SEEK_SET); |
225 | SetFPos(fptr, fsFromStart, (long)peoffset + 8) || |
217 | fwrite(×tamp, sizeof(time_t), 1, fptr); |
226 | (cnt = sizeof(time_t), noErr) || |
- | 227 | FSWrite(fptr, &cnt, ×tamp); |
|
218 | 228 | ||
219 | fclose(fptr); |
229 | FSClose(fptr); |
220 | 230 | ||
221 | return true; |
231 | return res == noErr; // res=0 means everything was noErr, res=1 means something was !=noErr |
222 | } |
232 | } |
223 | 233 | ||
224 | int binary_replace_file(const char* filename, uint64_t search, uint64_t replace, Boolean align, int maxamount) { |
234 | int binary_replace_file(FSSpec* dst, uint64_t search, uint64_t replace, Boolean align, int maxamount) { |
225 | uint64_t srecord = 0; |
235 | uint64_t srecord = 0; |
226 | int found = 0; |
236 | int found = 0; |
- | 237 | FILEREF fptr; |
|
- | 238 | FILECOUNT cnt; |
|
227 | 239 | ||
228 | FILE* fptr = fopen(filename, "rb+"); |
- | |
229 | if (fptr == NULL) return -1; |
240 | if (FSpOpenDF(dst, fsRdWrPerm, &fptr) != noErr) return -1; |
230 | 241 | ||
- | 242 | cnt = sizeof(srecord); |
|
231 | while ((fread(&srecord, sizeof(srecord), 1, fptr) == 1)) |
243 | while (FSRead(fptr, &cnt, &srecord) == noErr) |
232 | { |
244 | { |
233 | if (srecord == search) { |
245 | if (srecord == search) { |
234 | srecord = replace; |
246 | srecord = replace; |
235 | fseek(fptr, -1*(long)sizeof(srecord), SEEK_CUR); |
247 | SetFPos(fptr, fsFromMark, -1 * (long)sizeof(srecord)); |
236 | fwrite(&srecord, (int)sizeof(srecord), 1, fptr); |
248 | cnt = (int)sizeof(srecord); |
- | 249 | FSWrite(fptr, &cnt, &srecord); |
|
237 | fseek(fptr, 0, SEEK_CUR); // important! |
250 | SetFPos(fptr, fsFromStart, 0); // important for fseek |
238 | found++; |
251 | found++; |
239 | if (found == maxamount) break; |
252 | if (found == maxamount) break; |
240 | } |
253 | } |
241 | else { |
254 | else { |
242 | if (!align) { |
255 | if (!align) { |
243 | fseek(fptr, -1*(long)(sizeof(srecord) - 1), SEEK_CUR); |
256 | SetFPos(fptr, fsFromMark, -1 * (long)(sizeof(srecord) - 1)); |
244 | } |
257 | } |
245 | } |
258 | } |
246 | } |
259 | } |
247 | fclose(fptr); |
260 | FSClose(fptr); |
248 | 261 | ||
249 | return found; |
262 | return found; |
250 | } |
263 | } |
251 | 264 | ||
252 | //DOS .EXE header |
265 | //DOS .EXE header |
Line 282... | Line 295... | ||
282 | uint32_t NumberOfSymbols; |
295 | uint32_t NumberOfSymbols; |
283 | uint16_t SizeOfOptionalHeader; |
296 | uint16_t SizeOfOptionalHeader; |
284 | uint16_t Characteristics; |
297 | uint16_t Characteristics; |
285 | }; |
298 | }; |
286 | 299 | ||
287 | uint32_t calculate_checksum(const char* filename) { |
300 | uint32_t calculate_checksum(FSSpec* dst) { |
288 | //Calculate checksum of image |
301 | //Calculate checksum of image |
289 | // Taken from "PE Bliss" Cross-Platform Portable Executable C++ Library |
302 | // Taken from "PE Bliss" Cross-Platform Portable Executable C++ Library |
290 | // https://github.com/mrexodia/portable-executable-library/blob/master/pe_lib/pe_checksum.cpp |
303 | // https://github.com/mrexodia/portable-executable-library/blob/master/pe_lib/pe_checksum.cpp |
291 | // Converted from C++ to C by Daniel Marschall |
304 | // Converted from C++ to C by Daniel Marschall |
292 | 305 | ||
293 | FILE* fptr; |
306 | FILEREF fptr; |
294 | unsigned long long checksum = 0; |
307 | unsigned long long checksum = 0; |
295 | struct image_dos_header header; |
308 | struct image_dos_header header; |
296 | size_t filesize; |
309 | FILEPOS filesize, i; |
297 | unsigned long long top; |
310 | unsigned long long top; |
298 | unsigned long pe_checksum_pos; |
311 | unsigned long pe_checksum_pos; |
299 | static const unsigned long checksum_pos_in_optional_headers = 64; |
312 | static const unsigned long checksum_pos_in_optional_headers = 64; |
300 | size_t i; |
313 | FILECOUNT cnt; |
301 | 314 | ||
302 | fptr = fopen(filename, "rb"); |
- | |
303 | if (fptr == NULL) return 0x00000000; |
315 | if (FSpOpenDF(dst, fsRdWrPerm, &fptr) != noErr) return 0x00000000; |
304 | 316 | ||
305 | //Read DOS header |
317 | //Read DOS header |
306 | fseek(fptr, 0, SEEK_SET); |
318 | SetFPos(fptr, fsFromStart, 0); |
307 | fread(&header, sizeof(struct image_dos_header), 1, fptr); |
319 | cnt = sizeof(struct image_dos_header); |
- | 320 | FSRead(fptr, &cnt, &header); |
|
308 | 321 | ||
309 | //Calculate PE checksum |
322 | //Calculate PE checksum |
310 | fseek(fptr, 0, SEEK_SET); |
323 | SetFPos(fptr, fsFromStart, 0); |
311 | top = 0xFFFFFFFF; |
324 | top = 0xFFFFFFFF; |
312 | top++; |
325 | top++; |
313 | 326 | ||
314 | //"CheckSum" field position in optional PE headers - it's always 64 for PE and PE+ |
327 | //"CheckSum" field position in optional PE headers - it's always 64 for PE and PE+ |
315 | //Calculate real PE headers "CheckSum" field position |
328 | //Calculate real PE headers "CheckSum" field position |
316 | //Sum is safe here |
329 | //Sum is safe here |
317 | pe_checksum_pos = header.e_lfanew + sizeof(struct image_file_header) + sizeof(uint32_t) + checksum_pos_in_optional_headers; |
330 | pe_checksum_pos = header.e_lfanew + sizeof(struct image_file_header) + sizeof(uint32_t) + checksum_pos_in_optional_headers; |
318 | 331 | ||
319 | //Calculate checksum for each byte of file |
332 | //Calculate checksum for each byte of file |
320 | fseek(fptr, 0L, SEEK_END); |
333 | filesize = 0; |
321 | filesize = ftell(fptr); |
334 | GetEOF(fptr, &filesize); |
322 | fseek(fptr, 0L, SEEK_SET); |
335 | SetFPos(fptr, fsFromStart, 0); |
323 | for (i = 0; i < filesize; i += 4) |
336 | for (i = 0; i < filesize; i += 4) |
324 | { |
337 | { |
325 | unsigned long dw = 0; |
338 | unsigned long dw = 0; |
326 | 339 | ||
327 | //Read DWORD from file |
340 | //Read DWORD from file |
328 | fread(&dw, sizeof(dw), 1, fptr); |
341 | cnt = sizeof(dw); |
- | 342 | FSRead(fptr, &cnt, &dw); |
|
329 | //Skip "CheckSum" DWORD |
343 | //Skip "CheckSum" DWORD |
330 | if (i == pe_checksum_pos) |
344 | if (i == pe_checksum_pos) |
331 | continue; |
345 | continue; |
332 | 346 | ||
333 | //Calculate checksum |
347 | //Calculate checksum |
Line 341... | Line 355... | ||
341 | checksum = (checksum)+(checksum >> 16); |
355 | checksum = (checksum)+(checksum >> 16); |
342 | checksum = checksum & 0xffff; |
356 | checksum = checksum & 0xffff; |
343 | 357 | ||
344 | checksum += (unsigned long)(filesize); |
358 | checksum += (unsigned long)(filesize); |
345 | 359 | ||
346 | fclose(fptr); |
360 | FSClose(fptr); |
347 | 361 | ||
348 | //Return checksum |
362 | //Return checksum |
349 | return (uint32_t)checksum; |
363 | return (uint32_t)checksum; |
350 | } |
364 | } |
351 | 365 | ||
352 | Boolean repair_pe_checksum(const char* filename) { |
366 | Boolean repair_pe_checksum(FSSpec* dst) { |
353 | size_t peoffset; |
367 | size_t peoffset; |
354 | FILE* fptr; |
368 | FILEREF fptr; |
- | 369 | FILECOUNT cnt; |
|
- | 370 | Boolean res; |
|
355 | 371 | ||
356 | uint32_t checksum = calculate_checksum(filename); |
372 | uint32_t checksum = calculate_checksum(dst); |
357 | //if (checksum == 0x00000000) return false; |
373 | //if (checksum == 0x00000000) return false; |
358 | 374 | ||
359 | fptr = fopen(filename, "rb+"); |
- | |
360 | if (fptr == NULL) return false; |
375 | if (FSpOpenDF(dst, fsRdWrPerm, &fptr) != noErr) return false; |
361 | 376 | ||
- | 377 | res = |
|
362 | fseek(fptr, 0x3C, SEEK_SET); |
378 | SetFPos(fptr, fsFromStart, 0x3C) || |
363 | fread(&peoffset, sizeof(peoffset), 1, fptr); |
379 | (cnt = sizeof(peoffset), noErr) || |
- | 380 | FSRead(fptr, &cnt, &peoffset) || |
|
- | 381 | SetFPos(fptr, fsFromStart, (long)peoffset + 88) || |
|
- | 382 | (cnt = sizeof(uint32_t), noErr) || |
|
- | 383 | FSWrite(fptr, &cnt, &checksum); |
|
364 | 384 | ||
365 | fseek(fptr, (long)peoffset + 88, SEEK_SET); |
- | |
366 | fwrite(&checksum, sizeof(uint32_t), 1, fptr); |
385 | FSClose(fptr); |
367 | 386 | ||
368 | fclose(fptr); |
- | |
369 | - | ||
370 | return true; |
387 | return res == noErr; // res=0 means everything was noErr, res=1 means something was !=noErr |
371 | } |
388 | } |
372 | 389 | ||
373 | typedef struct { |
390 | typedef struct { |
374 | char funcname[8]; |
391 | char funcname[8]; |
375 | uint16_t codelen; |
392 | uint16_t codelen; |
Line 383... | Line 400... | ||
383 | typedef struct { |
400 | typedef struct { |
384 | char funcname[8]; |
401 | char funcname[8]; |
385 | char referencename[8]; |
402 | char referencename[8]; |
386 | } symndef_t; |
403 | } symndef_t; |
387 | 404 | ||
388 | Boolean doresources(char *dstname, int bits){ |
405 | Boolean doresources(FSSpec* dst, int bits){ |
389 | HRSRC datarsrc,aetersrc,manifestsrc; |
406 | HRSRC datarsrc,aetersrc,manifestsrc; |
390 | HGLOBAL datah,aeteh,hupdate,manifesth; |
407 | HGLOBAL datah,aeteh,hupdate,manifesth; |
391 | 408 | ||
392 | operdef_t dummy_oper; |
409 | operdef_t dummy_oper; |
393 | funcdef_t dummy_func; |
410 | funcdef_t dummy_func; |
Line 407... | Line 424... | ||
407 | 424 | ||
408 | memset(&dummy_oper, 0, sizeof(operdef_t)); |
425 | memset(&dummy_oper, 0, sizeof(operdef_t)); |
409 | memset(&dummy_func, 0, sizeof(funcdef_t)); |
426 | memset(&dummy_func, 0, sizeof(funcdef_t)); |
410 | memset(&dummy_symn, 0, sizeof(symndef_t)); |
427 | memset(&dummy_symn, 0, sizeof(symndef_t)); |
411 | 428 | ||
412 | if( (hupdate = _BeginUpdateResource(dstname,false)) ){ |
429 | if( (hupdate = _BeginUpdateResource(&dst->szName[0],false)) ){ |
413 | DBG("BeginUpdateResource OK"); |
430 | DBG("BeginUpdateResource OK"); |
414 | if( (datarsrc = FindResource(hDllInstance,MAKEINTRESOURCE(16000 + bits), "TPLT")) |
431 | if( (datarsrc = FindResource(hDllInstance,MAKEINTRESOURCE(16000 + bits), TEXT("TPLT"))) |
415 | && (datah = LoadResource(hDllInstance,datarsrc)) |
432 | && (datah = LoadResource(hDllInstance,datarsrc)) |
416 | && (datap = (Ptr)LockResource(datah)) |
433 | && (datap = (Ptr)LockResource(datah)) |
417 | && (aetersrc = FindResource(hDllInstance, MAKEINTRESOURCE(16000), "AETE")) |
434 | && (aetersrc = FindResource(hDllInstance, MAKEINTRESOURCE(16000), TEXT("AETE"))) |
418 | && (aeteh = LoadResource(hDllInstance, aetersrc)) |
435 | && (aeteh = LoadResource(hDllInstance, aetersrc)) |
419 | && (aetep = (Ptr)LockResource(aeteh)) |
436 | && (aetep = (Ptr)LockResource(aeteh)) |
420 | && (manifestsrc = FindResource(hDllInstance, MAKEINTRESOURCE(1), "TPLT")) |
437 | && (manifestsrc = FindResource(hDllInstance, MAKEINTRESOURCE(1), TEXT("TPLT"))) |
421 | && (manifesth = LoadResource(hDllInstance, manifestsrc)) |
438 | && (manifesth = LoadResource(hDllInstance, manifestsrc)) |
422 | && (manifestp = (Ptr)LockResource(manifesth)) ) |
439 | && (manifestp = (Ptr)LockResource(manifesth)) ) |
423 | { |
440 | { |
424 | char* newmanifest; |
441 | char* newmanifest; |
425 | int manifestsize = SizeofResource(hDllInstance, manifestsrc); |
442 | int manifestsize = SizeofResource(hDllInstance, manifestsrc); |
Line 462... | Line 479... | ||
462 | free(manifestp_copy); |
479 | free(manifestp_copy); |
463 | } |
480 | } |
464 | 481 | ||
465 | // ====== Change version attributes |
482 | // ====== Change version attributes |
466 | 483 | ||
467 | if (changeVersionInfo(dstname, hupdate, pparm, bits) != NOERROR) { |
484 | if (changeVersionInfo(dst, hupdate, pparm, bits) != NOERROR) { |
468 | simplealert(_strdup("changeVersionInfo failed")); |
485 | simplewarning((TCHAR*)TEXT("changeVersionInfo failed")); |
469 | } |
486 | } |
470 | 487 | ||
471 | // ====== Obfuscate pparm! |
488 | // ====== Obfuscate pparm! |
472 | 489 | ||
473 | if (gdata->obfusc) { |
490 | if (gdata->obfusc) { |
Line 489... | Line 506... | ||
489 | set in the Scripting.rc file for the resource AETE and PIPL.rc for the resources PIPL. */ |
506 | set in the Scripting.rc file for the resource AETE and PIPL.rc for the resources PIPL. */ |
490 | 507 | ||
491 | if( |
508 | if( |
492 | _UpdateResource(hupdate, RT_DIALOG, MAKEINTRESOURCE(ID_BUILDDLG), MAKELANGID(LANG_ENGLISH, SUBLANG_ENGLISH_US), NULL, 0) // clean up things we don't need in the standalone plugin |
509 | _UpdateResource(hupdate, RT_DIALOG, MAKEINTRESOURCE(ID_BUILDDLG), MAKELANGID(LANG_ENGLISH, SUBLANG_ENGLISH_US), NULL, 0) // clean up things we don't need in the standalone plugin |
493 | && _UpdateResource(hupdate, RT_DIALOG, MAKEINTRESOURCE(ID_MAINDLG), MAKELANGID(LANG_ENGLISH, SUBLANG_ENGLISH_US), NULL, 0) // clean up things we don't need in the standalone plugin |
510 | && _UpdateResource(hupdate, RT_DIALOG, MAKEINTRESOURCE(ID_MAINDLG), MAKELANGID(LANG_ENGLISH, SUBLANG_ENGLISH_US), NULL, 0) // clean up things we don't need in the standalone plugin |
494 | && _UpdateResource(hupdate, RT_GROUP_ICON, "CAUTION_ICO", MAKELANGID(LANG_NEUTRAL, SUBLANG_NEUTRAL), NULL, 0) // clean up things we don't need in the standalone plugin |
511 | && _UpdateResource(hupdate, RT_GROUP_ICON, TEXT("CAUTION_ICO"), MAKELANGID(LANG_NEUTRAL, SUBLANG_NEUTRAL), NULL, 0) // clean up things we don't need in the standalone plugin |
495 | // && _UpdateResource(hupdate, RT_ICON, MAKEINTRESOURCE(1)/*Caution*/, MAKELANGID(LANG_NEUTRAL, SUBLANG_NEUTRAL), NULL, 0) // clean up things we don't need in the standalone plugin |
512 | // && _UpdateResource(hupdate, RT_ICON, MAKEINTRESOURCE(1)/*Caution*/, MAKELANGID(LANG_NEUTRAL, SUBLANG_NEUTRAL), NULL, 0) // clean up things we don't need in the standalone plugin |
496 | && _UpdateResource(hupdate, RT_GROUP_CURSOR, "HAND_QUESTION", MAKELANGID(LANG_NEUTRAL, SUBLANG_NEUTRAL), NULL, 0) // clean up things we don't need in the standalone plugin |
513 | && _UpdateResource(hupdate, RT_GROUP_CURSOR, TEXT("HAND_QUESTION"), MAKELANGID(LANG_NEUTRAL, SUBLANG_NEUTRAL), NULL, 0) // clean up things we don't need in the standalone plugin |
497 | // TODO: Removing the single resources don't work correctly. Sometimes the cursors are numbered 4,5,6 and sometimes 1,2,3 . Probably conflicts with icons |
514 | // TODO: Removing the single resources don't work correctly. Sometimes the cursors are numbered 4,5,6 and sometimes 1,2,3 . Probably conflicts with icons |
498 | // && _UpdateResource(hupdate, RT_CURSOR, MAKEINTRESOURCE(3)/*QuestionHand*/, MAKELANGID(LANG_NEUTRAL, SUBLANG_NEUTRAL), NULL, 0) // clean up things we don't need in the standalone plugin |
515 | // && _UpdateResource(hupdate, RT_CURSOR, MAKEINTRESOURCE(3)/*QuestionHand*/, MAKELANGID(LANG_NEUTRAL, SUBLANG_NEUTRAL), NULL, 0) // clean up things we don't need in the standalone plugin |
499 | && _UpdateResource(hupdate, "PIPL" /* note: caps!! */,MAKEINTRESOURCE(16000), MAKELANGID(LANG_NEUTRAL,SUBLANG_NEUTRAL),newpipl,(DWORD)piplsize) |
516 | && _UpdateResource(hupdate, TEXT("PIPL") /* note: caps!! */, MAKEINTRESOURCE(16000), MAKELANGID(LANG_NEUTRAL,SUBLANG_NEUTRAL),newpipl,(DWORD)piplsize) |
500 | && _UpdateResource(hupdate, "AETE" /* note: caps!! */, MAKEINTRESOURCE(16000), MAKELANGID(LANG_NEUTRAL, SUBLANG_NEUTRAL), newaete, (DWORD)aetesize) |
517 | && _UpdateResource(hupdate, TEXT("AETE") /* note: caps!! */, MAKEINTRESOURCE(16000), MAKELANGID(LANG_NEUTRAL, SUBLANG_NEUTRAL), newaete, (DWORD)aetesize) |
501 | // OPER and FUNC are written so that "Plugin Manager 2.1" thinks that this plugin is a Filter Factory plugin! SYNM is not important, though. |
518 | // OPER and FUNC are written so that "Plugin Manager 2.1" thinks that this plugin is a Filter Factory plugin! SYNM is not important, though. |
502 | && (gdata->obfusc || _UpdateResource(hupdate, "OPER", MAKEINTRESOURCE(16000), MAKELANGID(LANG_ENGLISH, SUBLANG_ENGLISH_US), &dummy_oper, sizeof(dummy_oper))) |
519 | && (gdata->obfusc || _UpdateResource(hupdate, TEXT("OPER"), MAKEINTRESOURCE(16000), MAKELANGID(LANG_ENGLISH, SUBLANG_ENGLISH_US), &dummy_oper, sizeof(dummy_oper))) |
503 | && (gdata->obfusc || _UpdateResource(hupdate, "FUNC", MAKEINTRESOURCE(16000), MAKELANGID(LANG_ENGLISH, SUBLANG_ENGLISH_US), &dummy_func, sizeof(dummy_func))) |
520 | && (gdata->obfusc || _UpdateResource(hupdate, TEXT("FUNC"), MAKEINTRESOURCE(16000), MAKELANGID(LANG_ENGLISH, SUBLANG_ENGLISH_US), &dummy_func, sizeof(dummy_func))) |
504 | && (gdata->obfusc || _UpdateResource(hupdate, "SYNM", MAKEINTRESOURCE(16000), MAKELANGID(LANG_ENGLISH, SUBLANG_ENGLISH_US), &dummy_symn, sizeof(dummy_symn))) |
521 | && (gdata->obfusc || _UpdateResource(hupdate, TEXT("SYNM"), MAKEINTRESOURCE(16000), MAKELANGID(LANG_ENGLISH, SUBLANG_ENGLISH_US), &dummy_symn, sizeof(dummy_symn))) |
505 | && _UpdateResource(hupdate, RT_MANIFEST, MAKEINTRESOURCE(1), MAKELANGID(LANG_NEUTRAL, SUBLANG_NEUTRAL), newmanifest, (DWORD)manifestsize) |
522 | && _UpdateResource(hupdate, RT_MANIFEST, MAKEINTRESOURCE(1), MAKELANGID(LANG_NEUTRAL, SUBLANG_NEUTRAL), newmanifest, (DWORD)manifestsize) |
506 | && _UpdateResource(hupdate, parm_type,parm_id, MAKELANGID(LANG_NEUTRAL,SUBLANG_NEUTRAL),pparm,sizeof(PARM_T)) ) |
523 | && _UpdateResource(hupdate, parm_type,parm_id, MAKELANGID(LANG_NEUTRAL,SUBLANG_NEUTRAL),pparm,sizeof(PARM_T)) ) |
507 | { |
524 | { |
508 | discard = false; |
525 | discard = false; |
509 | } else { |
526 | } else { |
510 | dbglasterror(_strdup("UpdateResource")); |
527 | dbglasterror((TCHAR*)TEXT("UpdateResource")); |
511 | } |
528 | } |
512 | } |
529 | } |
513 | 530 | ||
514 | free(newmanifest); |
531 | free(newmanifest); |
515 | 532 | ||
Line 520... | Line 537... | ||
520 | 537 | ||
521 | // First try with alignment "4" (this should be the usual case), |
538 | // First try with alignment "4" (this should be the usual case), |
522 | // and if that failed, try without alignment ("1"). |
539 | // and if that failed, try without alignment ("1"). |
523 | // We only need to set maxamount to "1", because "const volatile" makes sure that |
540 | // We only need to set maxamount to "1", because "const volatile" makes sure that |
524 | // the compiler won't place (inline) it at several locations in the code. |
541 | // the compiler won't place (inline) it at several locations in the code. |
525 | if ((binary_replace_file(dstname, cObfuscSeed, obfuscseed, /*align to 4*/1, /*maxamount=*/1) == 0) && |
542 | if ((binary_replace_file(dst, cObfuscSeed, obfuscseed, /*align to 4*/1, /*maxamount=*/1) == 0) && |
526 | (binary_replace_file(dstname, cObfuscSeed, obfuscseed, /*align to 1*/0, /*maxamount=*/1) == 0)) |
543 | (binary_replace_file(dst, cObfuscSeed, obfuscseed, /*align to 1*/0, /*maxamount=*/1) == 0)) |
527 | { |
544 | { |
528 | dbg("binary_replace_file failed"); |
545 | dbg((TCHAR*)TEXT("binary_replace_file failed")); |
529 | discard = true; |
546 | discard = true; |
530 | } |
547 | } |
531 | } |
548 | } |
532 | 549 | ||
533 | update_pe_timestamp(dstname, time(0)); |
550 | if (!update_pe_timestamp(dst, time(0))) { |
- | 551 | simplewarning((TCHAR*)TEXT("update_pe_timestamp failed")); |
|
- | 552 | } |
|
534 | 553 | ||
535 | repair_pe_checksum(dstname); |
554 | if (!repair_pe_checksum(dst)) { |
- | 555 | simplewarning((TCHAR*)TEXT("repair_pe_checksum failed")); |
|
- | 556 | } |
|
536 | }else dbglasterror(_strdup("EndUpdateResource")); |
557 | }else dbglasterror((TCHAR*)TEXT("EndUpdateResource")); |
537 | 558 | ||
538 | }else dbglasterror(_strdup("Find-, Load- or LockResource")); |
559 | }else dbglasterror((TCHAR*)TEXT("Find-, Load- or LockResource")); |
539 | 560 | ||
540 | if(pparm) free(pparm); |
561 | if(pparm) free(pparm); |
541 | if(newpipl) free(newpipl); |
562 | if(newpipl) free(newpipl); |
542 | if(newaete) free(newaete); |
563 | if(newaete) free(newaete); |
543 | }else |
564 | }else |
544 | dbglasterror(_strdup("BeginUpdateResource")); |
565 | dbglasterror((TCHAR*)TEXT("BeginUpdateResource")); |
545 | return !discard; |
566 | return !discard; |
546 | } |
567 | } |
547 | 568 | ||
548 | Boolean remove_64_filename_prefix(char* dstname) { |
569 | Boolean remove_64_filename_prefix(LPTSTR dstname) { |
549 | // foobar.8bf => foobar.8bf |
570 | // foobar.8bf => foobar.8bf |
550 | // foobar64.8bf => foobar.8bf |
571 | // foobar64.8bf => foobar.8bf |
551 | size_t i; |
572 | size_t i; |
552 | for (i = strlen(dstname); i > 2; i--) { |
573 | for (i = xstrlen(dstname); i > 2; i--) { |
553 | if (dstname[i] == '.') { |
574 | if (dstname[i] == '.') { |
554 | if ((dstname[i - 2] == '6') && (dstname[i - 1] == '4')) { |
575 | if ((dstname[i - 2] == '6') && (dstname[i - 1] == '4')) { |
555 | size_t tmp = strlen(dstname); |
576 | size_t tmp = xstrlen(dstname); |
556 | memcpy(&dstname[i - 2], &dstname[i], strlen(dstname) - i + 1); |
577 | memcpy(&dstname[i - 2], &dstname[i], (xstrlen(dstname) - i + 1) * sizeof(TCHAR)); |
557 | dstname[tmp - 2] = 0; |
578 | dstname[tmp - 2] = 0; |
558 | return true; |
579 | return true; |
559 | } |
580 | } |
560 | } |
581 | } |
561 | } |
582 | } |
562 | return false; |
583 | return false; |
563 | } |
584 | } |
564 | 585 | ||
565 | Boolean add_64_filename_prefix(char* dstname) { |
586 | Boolean add_64_filename_prefix(LPTSTR dstname) { |
566 | // foobar.8bf => foobar64.8bf |
587 | // foobar.8bf => foobar64.8bf |
567 | size_t i; |
588 | size_t i; |
568 | for (i = strlen(dstname); i > 2; i--) { |
589 | for (i = xstrlen(dstname); i > 2; i--) { |
569 | if (dstname[i] == '.') { |
590 | if (dstname[i] == '.') { |
570 | size_t tmp = strlen(dstname); |
591 | size_t tmp = xstrlen(dstname); |
571 | memcpy(&dstname[i + 2], &dstname[i], strlen(dstname) - i + 1); |
592 | memcpy(&dstname[i + 2], &dstname[i], (xstrlen(dstname) - i + 1) * sizeof(TCHAR)); |
572 | dstname[i] = '6'; |
593 | dstname[i] = '6'; |
573 | dstname[i + 1] = '4'; |
594 | dstname[i + 1] = '4'; |
574 | dstname[tmp + 2] = 0; |
595 | dstname[tmp + 2] = 0; |
575 | return true; |
596 | return true; |
576 | } |
597 | } |
Line 582... | Line 603... | ||
582 | DWORD dwAttrib = GetFileAttributes(szPath); |
603 | DWORD dwAttrib = GetFileAttributes(szPath); |
583 | return (dwAttrib != INVALID_FILE_ATTRIBUTES && |
604 | return (dwAttrib != INVALID_FILE_ATTRIBUTES && |
584 | !(dwAttrib & FILE_ATTRIBUTE_DIRECTORY)); |
605 | !(dwAttrib & FILE_ATTRIBUTE_DIRECTORY)); |
585 | } |
606 | } |
586 | 607 | ||
587 | Boolean extract_file(LPCTSTR lpType, LPCTSTR lpName, const char* outName) { |
608 | Boolean extract_file(LPCTSTR lpType, LPCTSTR lpName, FSSpec* dst) { |
588 | HGLOBAL datah; |
609 | HGLOBAL datah; |
589 | LPVOID datap; |
610 | LPVOID datap; |
590 | HRSRC datarsrc; |
611 | HRSRC datarsrc; |
591 | size_t datalen; |
612 | FILECOUNT datalen; |
- | 613 | FILEREF fptr; |
|
- | 614 | OSErr res; |
|
592 | 615 | ||
593 | if ((datarsrc = FindResource((HMODULE)hDllInstance, lpName, lpType)) |
616 | if ((datarsrc = FindResource((HMODULE)hDllInstance, lpName, lpType)) |
594 | && (datah = LoadResource((HMODULE)hDllInstance, datarsrc)) |
617 | && (datah = LoadResource((HMODULE)hDllInstance, datarsrc)) |
595 | && (datalen = SizeofResource((HMODULE)hDllInstance, datarsrc)) |
618 | && (datalen = (FILECOUNT)SizeofResource((HMODULE)hDllInstance, datarsrc)) |
596 | && (datap = (Ptr)LockResource(datah))) { |
619 | && (datap = (Ptr)LockResource(datah))) { |
597 | 620 | ||
598 | FILE* fp = fopen(outName, "wb+"); |
621 | FSpDelete(dst); |
599 | if (fp == NULL) return false; |
- | |
600 | if (fwrite(datap, 1, datalen, fp) != datalen) return false; |
622 | if (FSpCreate(dst, kPhotoshopSignature, PS_FILTER_FILETYPE, 0/*sfr->sfScript*/) != noErr) return false; |
601 | if (fclose(fp)) return false; |
- | |
602 | 623 | ||
- | 624 | if (FSpOpenDF(dst, fsRdWrPerm, &fptr) != noErr) return false; |
|
- | 625 | ||
- | 626 | res = FSWrite(fptr, &datalen, datap); |
|
- | 627 | ||
- | 628 | FSClose(fptr); |
|
- | 629 | ||
603 | return true; |
630 | return res == noErr; |
604 | } |
631 | } |
605 | else { |
632 | else { |
606 | return false; |
633 | return false; |
607 | } |
634 | } |
608 | } |
635 | } |
609 | 636 | ||
610 | BOOL StripAuthenticode(const char* pszFileName) { |
637 | BOOL StripAuthenticode(FSSpec* dst) { |
611 | HANDLE hFile = CreateFile(pszFileName, GENERIC_READ | GENERIC_WRITE, FILE_SHARE_READ | FILE_SHARE_DELETE, NULL, OPEN_EXISTING, 0, NULL); |
638 | HANDLE hFile = CreateFile(&dst->szName[0], GENERIC_READ | GENERIC_WRITE, FILE_SHARE_READ | FILE_SHARE_DELETE, NULL, OPEN_EXISTING, 0, NULL); |
612 | if (hFile == INVALID_HANDLE_VALUE) { |
639 | if (hFile == INVALID_HANDLE_VALUE) { |
613 | CloseHandle(hFile); |
640 | CloseHandle(hFile); |
614 | return FALSE; |
641 | return FALSE; |
615 | } |
642 | } |
616 | if (!_ImageRemoveCertificate(hFile, 0)) { |
643 | if (!_ImageRemoveCertificate(hFile, 0)) { |
Line 619... | Line 646... | ||
619 | } |
646 | } |
620 | CloseHandle(hFile); |
647 | CloseHandle(hFile); |
621 | return TRUE; |
648 | return TRUE; |
622 | } |
649 | } |
623 | 650 | ||
624 | OSErr do_make_standalone(char* dstname, int bits) { |
651 | OSErr do_make_standalone(FSSpec* dst, int bits) { |
- | 652 | char errA[MAX_PATH + 200]; |
|
- | 653 | #ifdef UNICODE |
|
- | 654 | TCHAR errW[MAX_PATH + 200]; |
|
- | 655 | #endif |
|
625 | Boolean res; |
656 | Boolean res; |
626 | char err[MAX_PATH + 200]; |
- | |
627 | 657 | ||
628 | //DeleteFile(dstname); |
658 | //DeleteFile(dstname); |
629 | if (extract_file("TPLT", MAKEINTRESOURCE(1000 + bits), dstname)) { |
659 | if (extract_file(TEXT("TPLT"), MAKEINTRESOURCE(1000 + bits), dst)) { |
630 | // In case we did digitally sign the FilterFoundry plugin (which is currently not the case though), |
660 | // In case we did digitally sign the FilterFoundry plugin (which is currently not the case though), |
631 | // we must now remove the signature, because the embedding of parameter data has invalidated it. |
661 | // we must now remove the signature, because the embedding of parameter data has invalidated it. |
632 | // Do it before we manipulate anything, in order to avoid that there is an invalid binary (which might annoy AntiVirus software) |
662 | // Do it before we manipulate anything, in order to avoid that there is an invalid binary (which might annoy AntiVirus software) |
633 | StripAuthenticode(dstname); |
663 | StripAuthenticode(dst); |
634 | 664 | ||
635 | // Now do the resources |
665 | // Now do the resources |
636 | res = doresources(dstname, bits); |
666 | res = doresources(dst, bits); |
637 | if (!res) { |
667 | if (!res) { |
638 | DeleteFile(dstname); |
668 | DeleteFile(&dst->szName[0]); |
- | 669 | ||
639 | sprintf(err, "Could not create %d bit standalone plugin (doresources failed).", bits); |
670 | sprintf(errA, "Could not create %d bit standalone plugin (doresources failed).", bits); |
- | 671 | #ifdef UNICODE |
|
- | 672 | mbstowcs(errW, errA, MAX_PATH + 200); |
|
- | 673 | alertuser(&errW[0], (TCHAR*)TEXT("")); |
|
- | 674 | #else |
|
640 | alertuser(_strdup(&err[0]), _strdup("")); |
675 | alertuser(&errA[0], (TCHAR*)TEXT("")); |
- | 676 | #endif |
|
641 | } |
677 | } |
642 | } |
678 | } |
643 | else { |
679 | else { |
644 | // If you see this error, please make sure that you have called foundry_3264_mixer to include the 32/64 plugins as resource! |
680 | // If you see this error, please make sure that you have called foundry_3264_mixer to include the 32/64 plugins as resource! |
645 | res = false; |
681 | res = false; |
646 | //DeleteFile(dstname); |
682 | //DeleteFile(dstname); |
- | 683 | ||
647 | sprintf(err, "Could not create %d bit standalone plugin (File extraction failed).", bits); |
684 | sprintf(errA, "Could not create %d bit standalone plugin (File extraction failed).", bits); |
- | 685 | #ifdef UNICODE |
|
- | 686 | mbstowcs(errW, errA, MAX_PATH + 200); |
|
- | 687 | alertuser(&errW[0], (TCHAR*)TEXT("")); |
|
- | 688 | #else |
|
648 | alertuser(_strdup(&err[0]), _strdup("")); |
689 | alertuser(&errA[0], (TCHAR*)TEXT("")); |
- | 690 | #endif |
|
649 | } |
691 | } |
650 | 692 | ||
651 | return res ? noErr : ioErr; |
693 | return res ? noErr : ioErr; |
652 | } |
694 | } |
653 | 695 | ||
654 | OSErr make_standalone(StandardFileReply *sfr){ |
696 | OSErr make_standalone(StandardFileReply *sfr){ |
655 | OSErr tmpErr, outErr; |
697 | OSErr tmpErr, outErr; |
656 | char dstname[MAX_PATH+1]; |
698 | FSSpec dst; |
657 | 699 | ||
658 | outErr = noErr; |
700 | outErr = noErr; |
659 | 701 | ||
660 | // Make 32 bit: |
702 | // Make 32 bit: |
661 | // Destfile = no64_or_32(chosenname) |
703 | // Destfile = no64_or_32(chosenname) |
662 | myp2cstrcpy(dstname, sfr->sfFile.name); |
704 | xstrcpy(dst.szName, sfr->sfFile.szName); |
663 | remove_64_filename_prefix(dstname); |
705 | remove_64_filename_prefix(&dst.szName[0]); |
664 | tmpErr = do_make_standalone(&dstname[0], 32); |
706 | tmpErr = do_make_standalone(&dst, 32); |
665 | if (tmpErr != noErr) |
707 | if (tmpErr != noErr) |
666 | outErr = tmpErr; |
708 | outErr = tmpErr; |
667 | else |
709 | else |
668 | showmessage(_strdup("32 bit standalone filter was successfully created")); |
710 | showmessage((TCHAR*)TEXT("32 bit standalone filter was successfully created")); |
669 | 711 | ||
670 | // Make 64 bit: |
712 | // Make 64 bit: |
671 | // Destfile = no64_or_32(chosenname) + 64 |
713 | // Destfile = no64_or_32(chosenname) + 64 |
672 | myp2cstrcpy(dstname, sfr->sfFile.name); |
714 | xstrcpy(dst.szName, sfr->sfFile.szName); |
673 | remove_64_filename_prefix(dstname); |
715 | remove_64_filename_prefix(&dst.szName[0]); |
674 | add_64_filename_prefix(dstname); |
716 | add_64_filename_prefix(&dst.szName[0]); |
675 | tmpErr = do_make_standalone(&dstname[0], 64); |
717 | tmpErr = do_make_standalone(&dst, 64); |
676 | if (tmpErr != noErr) |
718 | if (tmpErr != noErr) |
677 | outErr = tmpErr; |
719 | outErr = tmpErr; |
678 | else |
720 | else |
679 | showmessage(_strdup("64 bit standalone filter was successfully created")); |
721 | showmessage((TCHAR*)TEXT("64 bit standalone filter was successfully created")); |
680 | 722 | ||
681 | return outErr; |
723 | return outErr; |
682 | } |
724 | } |
683 | 725 |