Subversion Repositories filter_foundry

Rev

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(&timestamp, sizeof(time_t), 1, fptr);
226
                (cnt = sizeof(time_t), noErr) ||
-
 
227
                FSWrite(fptr, &cnt, &timestamp);
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