Subversion Repositories filter_foundry

Rev

Rev 511 | Rev 536 | Go to most recent revision | Only display areas with differences | Regard whitespace | Details | Blame | Last modification | View Log | RSS feed

Rev 511 Rev 515
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-2022 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
#include "ff.h"
21
#include "ff.h"
22
 
22
 
23
#include <time.h>
23
#include <time.h>
24
 
24
 
25
#include "file_compat.h"
25
#include "file_compat.h"
26
#include "compat_string.h"
26
#include "compat_string.h"
27
#include "compat_win.h"
27
#include "compat_win.h"
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
typedef struct _PE32 {
33
typedef struct _PE32 {
34
        uint32_t magic; // 0x50450000
34
        uint32_t magic; // 0x50450000
35
        IMAGE_FILE_HEADER fileHeader; // COFF Header without Signature
35
        IMAGE_FILE_HEADER fileHeader; // COFF Header without Signature
36
        IMAGE_OPTIONAL_HEADER32 optHeader; // Standard COFF fields, Windows Specific Fields, Data Directories
36
        IMAGE_OPTIONAL_HEADER32 optHeader; // Standard COFF fields, Windows Specific Fields, Data Directories
37
} PE32;
37
} PE32;
38
 
38
 
39
Boolean doresources(FSSpec* dst, int bits);
39
Boolean doresources(FSSpec* dst, int bits);
40
 
40
 
41
void showLastError(TCHAR *func){
41
void showLastError(TCHAR *func){
42
        TCHAR s[0x300] = {0};
42
        TCHAR s[0x300] = {0};
43
 
43
 
44
        xstrcpy(&s[0],func);
44
        xstrcpy(&s[0],func);
45
        xstrcat(&s[0],TEXT(" failed: ")); // TODO (Not so important): TRANSLATE
45
        xstrcat(&s[0],TEXT(" failed: ")); // TODO (Not so important): TRANSLATE
46
        FormatMessage(FORMAT_MESSAGE_FROM_SYSTEM, NULL, GetLastError(), 0, s + xstrlen(s), 0x300 - (DWORD)xstrlen(s), NULL);
46
        FormatMessage(FORMAT_MESSAGE_FROM_SYSTEM, NULL, GetLastError(), 0, s + xstrlen(s), 0x300 - (DWORD)xstrlen(s), NULL);
47
        simplealert(&s[0]);
47
        simplealert(&s[0]);
48
}
48
}
49
 
49
 
50
/*
50
/*
51
BOOL CALLBACK enumfunc(HMODULE hModule,LPCTSTR lpszType,LPCTSTR lpszName,WORD wIDLanguage,LONG lParam){
51
BOOL CALLBACK enumfunc(HMODULE hModule,LPCTSTR lpszType,LPCTSTR lpszName,WORD wIDLanguage,LONG lParam){
52
        #ifdef DEBUG
52
        #ifdef DEBUG
53
        char s[0x100];
53
        char s[0x100];
54
        sprintf(s,"EnumResourceLanguages callback: module=%#x type=%s name=%s lang=%d",
54
        sprintf(s,"EnumResourceLanguages callback: module=%#x type=%s name=%s lang=%d",
55
                hModule,lpszType,lpszName,wIDLanguage);
55
                hModule,lpszType,lpszName,wIDLanguage);
56
        dbg(s);
56
        dbg(s);
57
        #endif
57
        #endif
58
        return TRUE;
58
        return TRUE;
59
}
59
}
60
*/
60
*/
61
 
61
 
62
int WriteXmlEscaped(char* description, char c) {
62
int WriteXmlEscaped(char* description, char c) {
63
        int idescription = 0;
63
        int idescription = 0;
64
        if (c == '&') {
64
        if (c == '&') {
65
                description[idescription++] = '&';
65
                description[idescription++] = '&';
66
                description[idescription++] = 'a';
66
                description[idescription++] = 'a';
67
                description[idescription++] = 'm';
67
                description[idescription++] = 'm';
68
                description[idescription++] = 'p';
68
                description[idescription++] = 'p';
69
                description[idescription++] = ';';
69
                description[idescription++] = ';';
70
        }
70
        }
71
        else if (c == '<') {
71
        else if (c == '<') {
72
                description[idescription++] = '&';
72
                description[idescription++] = '&';
73
                description[idescription++] = 'l';
73
                description[idescription++] = 'l';
74
                description[idescription++] = 't';
74
                description[idescription++] = 't';
75
                description[idescription++] = ';';
75
                description[idescription++] = ';';
76
        }
76
        }
77
        else if (c == '>') {
77
        else if (c == '>') {
78
                description[idescription++] = '&';
78
                description[idescription++] = '&';
79
                description[idescription++] = 'g';
79
                description[idescription++] = 'g';
80
                description[idescription++] = 't';
80
                description[idescription++] = 't';
81
                description[idescription++] = ';';
81
                description[idescription++] = ';';
82
        }
82
        }
83
        else {
83
        else {
84
                description[idescription++] = c;
84
                description[idescription++] = c;
85
        }
85
        }
86
        return idescription;
86
        return idescription;
87
}
87
}
88
 
88
 
89
int domanifest(char *newmanifest, char *manifestp, PARM_T* pparm, int bits) {
89
int domanifest(char *newmanifest, char *manifestp, PARM_T* pparm, int bits) {
90
        char* name;
90
        char* name;
91
        char* description, *tmpDescription;
91
        char* description, *tmpDescription;
92
        int res;
92
        int res;
93
        size_t i;
93
        size_t i;
94
        size_t iname;
94
        size_t iname;
95
 
95
 
96
        name = (char*)malloc(40 + (2 * 256) * 5);
96
        name = (char*)malloc(40 + (2 * 256) * 5);
97
        description = (char*)malloc(10 + (2 * 256)); // x4 because & becomes &amp;
97
        description = (char*)malloc(10 + (2 * 256)); // x4 because & becomes &amp;
98
        if (name == NULL || description == NULL) return 0;
98
        if (name == NULL || description == NULL) return 0;
99
       
99
       
100
        // Description
100
        // Description
101
        tmpDescription = description;
101
        tmpDescription = description;
102
        for (i = 0; i < strlen(pparm->szCategory); i++) {
102
        for (i = 0; i < strlen(pparm->szCategory); i++) {
103
                char c = pparm->szCategory[i];
103
                char c = pparm->szCategory[i];
104
                tmpDescription += WriteXmlEscaped(tmpDescription, c);
104
                tmpDescription += WriteXmlEscaped(tmpDescription, c);
105
        }
105
        }
106
        tmpDescription += WriteXmlEscaped(tmpDescription, ' ');
106
        tmpDescription += WriteXmlEscaped(tmpDescription, ' ');
107
        tmpDescription += WriteXmlEscaped(tmpDescription, '-');
107
        tmpDescription += WriteXmlEscaped(tmpDescription, '-');
108
        tmpDescription += WriteXmlEscaped(tmpDescription, ' ');
108
        tmpDescription += WriteXmlEscaped(tmpDescription, ' ');
109
        for (i = 0; i < strlen(pparm->szTitle); i++) {
109
        for (i = 0; i < strlen(pparm->szTitle); i++) {
110
                char c = pparm->szTitle[i];
110
                char c = pparm->szTitle[i];
111
                tmpDescription += WriteXmlEscaped(tmpDescription, c);
111
                tmpDescription += WriteXmlEscaped(tmpDescription, c);
112
        }
112
        }
113
        tmpDescription[0] = '\0';
113
        tmpDescription[0] = '\0';
114
 
114
 
115
        // Name
115
        // Name
116
        strcpy(name, "Telegraphics.FilterFoundry.");
116
        strcpy(name, "Telegraphics.FilterFoundry.");
117
        iname = strlen("Telegraphics.FilterFoundry.");
117
        iname = strlen("Telegraphics.FilterFoundry.");
118
        for (i = 0; i < strlen(pparm->szCategory); i++) {
118
        for (i = 0; i < strlen(pparm->szCategory); i++) {
119
                char c = pparm->szCategory[i];
119
                char c = pparm->szCategory[i];
120
                if (((c >= 'A') && (c <= 'Z')) || ((c >= 'a') && (c <= 'z')) || ((c >= '0') && (c <= '9'))) {
120
                if (((c >= 'A') && (c <= 'Z')) || ((c >= 'a') && (c <= 'z')) || ((c >= '0') && (c <= '9'))) {
121
                        name[iname++] = c;
121
                        name[iname++] = c;
122
                }
122
                }
123
        }
123
        }
124
        name[iname++] = '.';
124
        name[iname++] = '.';
125
        for (i = 0; i < strlen(pparm->szTitle); i++) {
125
        for (i = 0; i < strlen(pparm->szTitle); i++) {
126
                char c = pparm->szTitle[i];
126
                char c = pparm->szTitle[i];
127
                if (((c >= 'A') && (c <= 'Z')) || ((c >= 'a') && (c <= 'z')) || ((c >= '0') && (c <= '9'))) {
127
                if (((c >= 'A') && (c <= 'Z')) || ((c >= 'a') && (c <= 'z')) || ((c >= '0') && (c <= '9'))) {
128
                        name[iname++] = c;
128
                        name[iname++] = c;
129
                }
129
                }
130
        }
130
        }
131
        name[iname++] = '\0';
131
        name[iname++] = '\0';
132
 
132
 
133
        if (bits == 64) {
133
        if (bits == 64) {
134
                res = sprintf(newmanifest, manifestp, (char*)name, "amd64", VERSION_STR, (char*)description);
134
                res = sprintf(newmanifest, manifestp, (char*)name, "amd64", VERSION_STR, (char*)description);
135
        }
135
        }
136
        else {
136
        else {
137
                res = sprintf(newmanifest, manifestp, (char*)name, "x86", VERSION_STR, (char*)description);
137
                res = sprintf(newmanifest, manifestp, (char*)name, "x86", VERSION_STR, (char*)description);
138
        }
138
        }
139
 
139
 
140
        free(name);
140
        free(name);
141
        free(description);
141
        free(description);
142
 
142
 
143
        return res;
143
        return res;
144
}
144
}
145
 
145
 
146
ULONG changeVersionInfo(FSSpec* dst, HANDLE hUpdate, PARM_T* pparm, int bits) {
146
ULONG changeVersionInfo(FSSpec* dst, HANDLE hUpdate, PARM_T* pparm, int bits) {
147
        LPTSTR soleFilename;
147
        LPTSTR soleFilename;
148
        LPWSTR changeRequestStrW, tmp;
148
        LPWSTR changeRequestStrW, tmp;
149
        ULONG dwError = NOERROR;
149
        ULONG dwError = NOERROR;
150
        HRSRC hResInfo;
150
        HRSRC hResInfo;
151
        HGLOBAL hg;
151
        HGLOBAL hg;
152
        ULONG size;
152
        ULONG size;
153
        PVOID pv;
153
        PVOID pv;
154
        //BOOL fDiscard = TRUE;
154
        //BOOL fDiscard = TRUE;
155
 
155
 
156
        if (soleFilename = xstrrchr(&dst->szName[0], '\\')) {
156
        if (soleFilename = xstrrchr(&dst->szName[0], '\\')) {
157
                ++soleFilename;
157
                ++soleFilename;
158
        }
158
        }
159
        else {
159
        else {
160
                soleFilename = &dst->szName[0];
160
                soleFilename = &dst->szName[0];
161
        }
161
        }
162
 
162
 
163
        // Format of argument "PCWSTR changes" is "<name>\0<value>\0<name>\0<value>\0....."
163
        // Format of argument "PCWSTR changes" is "<name>\0<value>\0<name>\0<value>\0....."
164
        // You can CHANGE values for any given name
164
        // You can CHANGE values for any given name
165
        // You can DELETE entries by setting the value to "\b" (0x08 backspace character)
165
        // You can DELETE entries by setting the value to "\b" (0x08 backspace character)
166
        // You cannot (yet) ADD entries.
166
        // You cannot (yet) ADD entries.
167
        changeRequestStrW = (LPWSTR)malloc((6 * 2 * 100 + 1) * sizeof(WCHAR));
167
        changeRequestStrW = (LPWSTR)malloc((6 * 2 * 100 + 1) * sizeof(WCHAR));
168
        if (changeRequestStrW == 0) return E_OUTOFMEMORY;
168
        if (changeRequestStrW == 0) return E_OUTOFMEMORY;
169
        memset((char*)changeRequestStrW, 0, sizeof(changeRequestStrW));
169
        memset((char*)changeRequestStrW, 0, sizeof(changeRequestStrW));
170
 
170
 
171
        tmp = changeRequestStrW;
171
        tmp = changeRequestStrW;
172
 
172
 
173
        tmp += mbstowcs(tmp, "Comments", 100);
173
        tmp += mbstowcs(tmp, "Comments", 100);
174
        tmp++;
174
        tmp++;
175
        tmp += mbstowcs(tmp, "Built using Filter Foundry " VERSION_STR, 100);
175
        tmp += mbstowcs(tmp, "Built using Filter Foundry " VERSION_STR, 100);
176
        tmp++;
176
        tmp++;
177
 
177
 
178
        tmp += mbstowcs(tmp, "CompanyName", 100);
178
        tmp += mbstowcs(tmp, "CompanyName", 100);
179
        tmp++;
179
        tmp++;
180
        if (strlen(pparm->szAuthor) > 0) {
180
        if (strlen(pparm->szAuthor) > 0) {
181
                tmp += mbstowcs(tmp, pparm->szAuthor, 100);
181
                tmp += mbstowcs(tmp, pparm->szAuthor, 100);
182
        }
182
        }
183
        else {
183
        else {
184
                tmp += mbstowcs(tmp, "\b", 100); // \b = remove
184
                tmp += mbstowcs(tmp, "\b", 100); // \b = remove
185
        }
185
        }
186
        tmp++;
186
        tmp++;
187
 
187
 
188
        tmp += mbstowcs(tmp, "LegalCopyright", 100);
188
        tmp += mbstowcs(tmp, "LegalCopyright", 100);
189
        tmp++;
189
        tmp++;
190
        if (strlen(pparm->szCopyright) > 0) {
190
        if (strlen(pparm->szCopyright) > 0) {
191
                tmp += mbstowcs(tmp, pparm->szCopyright, 100);
191
                tmp += mbstowcs(tmp, pparm->szCopyright, 100);
192
        }
192
        }
193
        else {
193
        else {
194
                tmp += mbstowcs(tmp, "\b", 100); // \b = remove
194
                tmp += mbstowcs(tmp, "\b", 100); // \b = remove
195
        }
195
        }
196
        tmp++;
196
        tmp++;
197
 
197
 
198
        tmp += mbstowcs(tmp, "FileDescription", 100);
198
        tmp += mbstowcs(tmp, "FileDescription", 100);
199
        tmp++;
199
        tmp++;
200
        if (strlen(pparm->szTitle) > 0) {
200
        if (strlen(pparm->szTitle) > 0) {
201
                tmp += mbstowcs(tmp, pparm->szTitle, 100);
201
                tmp += mbstowcs(tmp, pparm->szTitle, 100);
202
        }
202
        }
203
        else {
203
        else {
204
                tmp += mbstowcs(tmp, "Untitled filter", 100);
204
                tmp += mbstowcs(tmp, "Untitled filter", 100);
205
        }
205
        }
206
        tmp++;
206
        tmp++;
207
 
207
 
208
        tmp += mbstowcs(tmp, "OriginalFilename", 100);
208
        tmp += mbstowcs(tmp, "OriginalFilename", 100);
209
        tmp++;
209
        tmp++;
210
        #ifdef UNICODE
210
        #ifdef UNICODE
211
        xstrcpy(tmp, soleFilename);
211
        xstrcpy(tmp, soleFilename);
212
        tmp += xstrlen(soleFilename);
212
        tmp += xstrlen(soleFilename);
213
        #else
213
        #else
214
        tmp += mbstowcs(tmp, soleFilename, 100);
214
        tmp += mbstowcs(tmp, soleFilename, 100);
215
        #endif
215
        #endif
216
        tmp++;
216
        tmp++;
217
 
217
 
218
        tmp += mbstowcs(tmp, "License", 100);
218
        tmp += mbstowcs(tmp, "License", 100);
219
        tmp++;
219
        tmp++;
220
        tmp += mbstowcs(tmp, "\b", 100); // \b = remove, since filter is standalone and might have its own license
220
        tmp += mbstowcs(tmp, "\b", 100); // \b = remove, since filter is standalone and might have its own license
221
        tmp++;
221
        tmp++;
222
 
222
 
223
        tmp += mbstowcs(tmp, "", 1);
223
        tmp += mbstowcs(tmp, "", 1);
224
 
224
 
225
        if (hResInfo = FindResourceEx(hDllInstance, TEXT("TPLT"), MAKEINTRESOURCE(3000 + bits), MAKELANGID(LANG_ENGLISH, SUBLANG_ENGLISH_US)))
225
        if (hResInfo = FindResourceEx(hDllInstance, TEXT("TPLT"), MAKEINTRESOURCE(3000 + bits), MAKELANGID(LANG_ENGLISH, SUBLANG_ENGLISH_US)))
226
        {
226
        {
227
                if (hg = LoadResource(hDllInstance, hResInfo))
227
                if (hg = LoadResource(hDllInstance, hResInfo))
228
                {
228
                {
229
                        if (size = SizeofResource(hDllInstance, hResInfo))
229
                        if (size = SizeofResource(hDllInstance, hResInfo))
230
                        {
230
                        {
231
                                if (pv = LockResource(hg))
231
                                if (pv = LockResource(hg))
232
                                {
232
                                {
233
                                        if (UpdateVersionRaw(pv, size, &pv, &size, changeRequestStrW))
233
                                        if (UpdateVersionRaw(pv, size, &pv, &size, changeRequestStrW))
234
                                        {
234
                                        {
235
                                                if (_UpdateResource(hUpdate, RT_VERSION, MAKEINTRESOURCE(1), MAKELANGID(LANG_ENGLISH, SUBLANG_ENGLISH_US), pv, size))
235
                                                if (_UpdateResource(hUpdate, RT_VERSION, MAKEINTRESOURCE(1), MAKELANGID(LANG_ENGLISH, SUBLANG_ENGLISH_US), pv, size))
236
                                                {
236
                                                {
237
                                                        //fDiscard = FALSE;
237
                                                        //fDiscard = FALSE;
238
                                                }
238
                                                }
239
                                                else {
239
                                                else {
240
                                                        //dwError = GetLastError();
240
                                                        //dwError = GetLastError();
241
                                                }
241
                                                }
242
                                        }
242
                                        }
243
                                        LocalFree(pv);
243
                                        LocalFree(pv);
244
                                }
244
                                }
245
                        }
245
                        }
246
                }
246
                }
247
        }
247
        }
248
 
248
 
249
        free(changeRequestStrW);
249
        free(changeRequestStrW);
250
 
250
 
251
        return dwError;
251
        return dwError;
252
}
252
}
253
 
253
 
254
typedef long __time32_t;
254
typedef long __time32_t;
255
 
255
 
256
Boolean update_pe_timestamp(const FSSpec* dst, __time32_t timestamp) {
256
Boolean update_pe_timestamp(const FSSpec* dst, __time32_t timestamp) {
257
        size_t peoffset;
257
        size_t peoffset;
258
        FILEREF fptr;
258
        FILEREF fptr;
259
        Boolean res;
259
        Boolean res;
260
        FILECOUNT cnt;
260
        FILECOUNT cnt;
261
 
261
 
262
        if (FSpOpenDF(dst, fsRdWrPerm, &fptr) != noErr) return false;
262
        if (FSpOpenDF(dst, fsRdWrPerm, &fptr) != noErr) return false;
263
 
263
 
264
        res =
264
        res =
265
                SetFPos(fptr, fsFromStart, 0x3C) ||
265
                SetFPos(fptr, fsFromStart, 0x3C) ||
266
                (cnt = sizeof(peoffset), noErr) ||
266
                (cnt = sizeof(peoffset), noErr) ||
267
                FSRead(fptr, &cnt, &peoffset) ||
267
                FSRead(fptr, &cnt, &peoffset) ||
268
                SetFPos(fptr, fsFromStart, (long)peoffset + /*0x0008*/offsetof(PE32, fileHeader.TimeDateStamp)) ||
268
                SetFPos(fptr, fsFromStart, (long)peoffset + /*0x0008*/offsetof(PE32, fileHeader.TimeDateStamp)) ||
269
                (cnt = sizeof(__time32_t), noErr) ||
269
                (cnt = sizeof(__time32_t), noErr) ||
270
                FSWrite(fptr, &cnt, &timestamp);
270
                FSWrite(fptr, &cnt, &timestamp);
271
 
271
 
272
        FSClose(fptr);
272
        FSClose(fptr);
273
 
273
 
274
        return res == noErr; // res=0 means everything was noErr, res=1 means something was !=noErr
274
        return res == noErr; // res=0 means everything was noErr, res=1 means something was !=noErr
275
}
275
}
276
 
276
 
277
uint32_t calculate_checksum(FSSpec* dst) {
277
uint32_t calculate_checksum(FSSpec* dst) {
278
        //Calculate checksum of image
278
        //Calculate checksum of image
279
        // Taken from "PE Bliss" Cross-Platform Portable Executable C++ Library
279
        // Taken from "PE Bliss" Cross-Platform Portable Executable C++ Library
280
        // https://github.com/mrexodia/portable-executable-library/blob/master/pe_lib/pe_checksum.cpp
280
        // https://github.com/mrexodia/portable-executable-library/blob/master/pe_lib/pe_checksum.cpp
281
        // Converted from C++ to C by Daniel Marschall
281
        // Converted from C++ to C by Daniel Marschall
282
 
282
 
283
        FILEREF fptr;
283
        FILEREF fptr;
284
        unsigned long long checksum = 0;
284
        unsigned long long checksum = 0;
285
        IMAGE_DOS_HEADER header;
285
        IMAGE_DOS_HEADER header;
286
        FILEPOS filesize, i;
286
        FILEPOS filesize, i;
287
        unsigned long long top;
287
        unsigned long long top;
288
        unsigned long pe_checksum_pos;
288
        unsigned long pe_checksum_pos;
289
        static const unsigned long checksum_pos_in_optional_headers = 64;
289
        static const unsigned long checksum_pos_in_optional_headers = 64;
290
        FILECOUNT cnt;
290
        FILECOUNT cnt;
291
 
291
 
292
        if (FSpOpenDF(dst, fsRdWrPerm, &fptr) != noErr) return 0x00000000;
292
        if (FSpOpenDF(dst, fsRdWrPerm, &fptr) != noErr) return 0x00000000;
293
 
293
 
294
        //Read DOS header
294
        //Read DOS header
295
        SetFPos(fptr, fsFromStart, 0);
295
        SetFPos(fptr, fsFromStart, 0);
296
        cnt = sizeof(IMAGE_DOS_HEADER);
296
        cnt = sizeof(IMAGE_DOS_HEADER);
297
        FSRead(fptr, &cnt, &header);
297
        FSRead(fptr, &cnt, &header);
298
 
298
 
299
        //Calculate PE checksum
299
        //Calculate PE checksum
300
        SetFPos(fptr, fsFromStart, 0);
300
        SetFPos(fptr, fsFromStart, 0);
301
        top = 0xFFFFFFFF;
301
        top = 0xFFFFFFFF;
302
        top++;
302
        top++;
303
 
303
 
304
        //"CheckSum" field position in optional PE headers - it's always 64 for PE and PE+
304
        //"CheckSum" field position in optional PE headers - it's always 64 for PE and PE+
305
        //Calculate real PE headers "CheckSum" field position
305
        //Calculate real PE headers "CheckSum" field position
306
        //Sum is safe here
306
        //Sum is safe here
307
        pe_checksum_pos = header.e_lfanew + sizeof(IMAGE_FILE_HEADER) + sizeof(uint32_t) + checksum_pos_in_optional_headers;
307
        pe_checksum_pos = header.e_lfanew + sizeof(IMAGE_FILE_HEADER) + sizeof(uint32_t) + checksum_pos_in_optional_headers;
308
 
308
 
309
        //Calculate checksum for each byte of file
309
        //Calculate checksum for each byte of file
310
        filesize = 0;
310
        filesize = 0;
311
        GetEOF(fptr, &filesize);
311
        GetEOF(fptr, &filesize);
312
        SetFPos(fptr, fsFromStart, 0);
312
        SetFPos(fptr, fsFromStart, 0);
313
        for (i = 0; i < filesize; i += 4)
313
        for (i = 0; i < filesize; i += 4)
314
        {
314
        {
315
                unsigned long dw = 0;
315
                unsigned long dw = 0;
316
 
316
 
317
                //Read DWORD from file
317
                //Read DWORD from file
318
                cnt = sizeof(dw);
318
                cnt = sizeof(dw);
319
                FSRead(fptr, &cnt, &dw);
319
                FSRead(fptr, &cnt, &dw);
320
                //Skip "CheckSum" DWORD
320
                //Skip "CheckSum" DWORD
321
                if (i == pe_checksum_pos)
321
                if (i == pe_checksum_pos)
322
                        continue;
322
                        continue;
323
 
323
 
324
                //Calculate checksum
324
                //Calculate checksum
325
                checksum = (checksum & 0xffffffff) + dw + (checksum >> 32);
325
                checksum = (checksum & 0xffffffff) + dw + (checksum >> 32);
326
                if (checksum > top)
326
                if (checksum > top)
327
                        checksum = (checksum & 0xffffffff) + (checksum >> 32);
327
                        checksum = (checksum & 0xffffffff) + (checksum >> 32);
328
        }
328
        }
329
 
329
 
330
        //Finish checksum
330
        //Finish checksum
331
        checksum = (checksum & 0xffff) + (checksum >> 16);
331
        checksum = (checksum & 0xffff) + (checksum >> 16);
332
        checksum = (checksum)+(checksum >> 16);
332
        checksum = (checksum)+(checksum >> 16);
333
        checksum = checksum & 0xffff;
333
        checksum = checksum & 0xffff;
334
 
334
 
335
        checksum += (unsigned long)(filesize);
335
        checksum += (unsigned long)(filesize);
336
 
336
 
337
        FSClose(fptr);
337
        FSClose(fptr);
338
 
338
 
339
        //Return checksum
339
        //Return checksum
340
        return (uint32_t)checksum;
340
        return (uint32_t)checksum;
341
}
341
}
342
 
342
 
343
Boolean repair_pe_checksum(FSSpec* dst) {
343
Boolean repair_pe_checksum(FSSpec* dst) {
344
        size_t peoffset;
344
        size_t peoffset;
345
        FILEREF fptr;
345
        FILEREF fptr;
346
        FILECOUNT cnt;
346
        FILECOUNT cnt;
347
        Boolean res;
347
        Boolean res;
348
 
348
 
349
        uint32_t checksum = calculate_checksum(dst);
349
        uint32_t checksum = calculate_checksum(dst);
350
        //if (checksum == 0x00000000) return false;
350
        //if (checksum == 0x00000000) return false;
351
 
351
 
352
        if (FSpOpenDF(dst, fsRdWrPerm, &fptr) != noErr) return false;
352
        if (FSpOpenDF(dst, fsRdWrPerm, &fptr) != noErr) return false;
353
 
353
 
354
        res =
354
        res =
355
                SetFPos(fptr, fsFromStart, 0x3C) ||
355
                SetFPos(fptr, fsFromStart, 0x3C) ||
356
                (cnt = sizeof(peoffset), noErr) ||
356
                (cnt = sizeof(peoffset), noErr) ||
357
                FSRead(fptr, &cnt, &peoffset) ||
357
                FSRead(fptr, &cnt, &peoffset) ||
358
                SetFPos(fptr, fsFromStart, (long)peoffset + /*0x0058*/offsetof(PE32, optHeader.CheckSum)) ||
358
                SetFPos(fptr, fsFromStart, (long)peoffset + /*0x0058*/offsetof(PE32, optHeader.CheckSum)) ||
359
                (cnt = sizeof(uint32_t), noErr) ||
359
                (cnt = sizeof(uint32_t), noErr) ||
360
                FSWrite(fptr, &cnt, &checksum);
360
                FSWrite(fptr, &cnt, &checksum);
361
 
361
 
362
        FSClose(fptr);
362
        FSClose(fptr);
363
 
363
 
364
        return res == noErr; // res=0 means everything was noErr, res=1 means something was !=noErr
364
        return res == noErr; // res=0 means everything was noErr, res=1 means something was !=noErr
365
}
365
}
366
 
366
 
367
typedef struct {
367
typedef struct {
368
        char funcname[8];
368
        char funcname[8];
369
        uint16_t codelen;
369
        uint16_t codelen;
370
} operdef_t;
370
} operdef_t;
371
 
371
 
372
typedef struct {
372
typedef struct {
373
        char funcname[8];
373
        char funcname[8];
374
        uint16_t numparams;
374
        uint16_t numparams;
375
} funcdef_t;
375
} funcdef_t;
376
 
376
 
377
typedef struct {
377
typedef struct {
378
        char funcname[8];
378
        char funcname[8];
379
        char referencename[8];
379
        char referencename[8];
380
} symndef_t;
380
} symndef_t;
381
 
381
 
382
Boolean doresources(FSSpec* dst, int bits){
382
Boolean doresources(FSSpec* dst, int bits){
383
        HRSRC datarsrc,aetersrc,manifestsrc;
383
        HRSRC datarsrc,aetersrc,manifestsrc;
384
        HGLOBAL datah,aeteh,hupdate,manifesth;
384
        HGLOBAL datah,aeteh,hupdate,manifesth;
385
 
385
 
386
        operdef_t dummy_oper;
386
        operdef_t dummy_oper;
387
        funcdef_t dummy_func;
387
        funcdef_t dummy_func;
388
        symndef_t dummy_symn;
388
        symndef_t dummy_symn;
389
 
389
 
390
        Ptr newpipl = NULL, newaete = NULL;
390
        Ptr newpipl = NULL, newaete = NULL;
391
        LPVOID datap, aetep, manifestp;
391
        LPVOID datap, aetep, manifestp;
392
        char* manifestp_copy;
392
        char* manifestp_copy;
393
        PARM_T *pparm = NULL;
393
        PARM_T *pparm = NULL;
394
        size_t piplsize,aetesize,origsize;
394
        size_t piplsize,aetesize,origsize;
395
        char title[256], category[256];
395
        char title[256], category[256];
396
        LPCTSTR parm_type;
396
        LPCTSTR parm_type;
397
        LPCTSTR parm_id;
397
        LPCTSTR parm_id;
398
        Boolean discard = true;
398
        Boolean discard = true;
399
        uint64_t obfuscseed = 0, obfuscseed2 = 0;
399
        uint64_t obfuscseed = 0, obfuscseed2 = 0;
400
        long event_id = 0;
400
        long event_id = 0;
401
 
401
 
402
        memset(&dummy_oper, 0, sizeof(operdef_t));
402
        memset(&dummy_oper, 0, sizeof(operdef_t));
403
        memset(&dummy_func, 0, sizeof(funcdef_t));
403
        memset(&dummy_func, 0, sizeof(funcdef_t));
404
        memset(&dummy_symn, 0, sizeof(symndef_t));
404
        memset(&dummy_symn, 0, sizeof(symndef_t));
405
 
405
 
406
        if( (hupdate = _BeginUpdateResource(&dst->szName[0],false)) ){
406
        if( (hupdate = _BeginUpdateResource(&dst->szName[0],false)) ){
407
                if( (datarsrc = FindResource(hDllInstance,MAKEINTRESOURCE(16000 + bits), TEXT("TPLT")))
407
                if( (datarsrc = FindResource(hDllInstance,MAKEINTRESOURCE(16000 + bits), TEXT("TPLT")))
408
                        && (datah = LoadResource(hDllInstance,datarsrc))
408
                        && (datah = LoadResource(hDllInstance,datarsrc))
409
                        && (datap = (Ptr)LockResource(datah))
409
                        && (datap = (Ptr)LockResource(datah))
410
                        && (aetersrc = FindResource(hDllInstance, MAKEINTRESOURCE(16000), TEXT("AETE")))
410
                        && (aetersrc = FindResource(hDllInstance, MAKEINTRESOURCE(16000), TEXT("AETE")))
411
                        && (aeteh = LoadResource(hDllInstance, aetersrc))
411
                        && (aeteh = LoadResource(hDllInstance, aetersrc))
412
                        && (aetep = (Ptr)LockResource(aeteh))
412
                        && (aetep = (Ptr)LockResource(aeteh))
413
                        && (manifestsrc = FindResource(hDllInstance, MAKEINTRESOURCE(1), TEXT("TPLT")))
413
                        && (manifestsrc = FindResource(hDllInstance, MAKEINTRESOURCE(1), TEXT("TPLT")))
414
                        && (manifesth = LoadResource(hDllInstance, manifestsrc))
414
                        && (manifesth = LoadResource(hDllInstance, manifestsrc))
415
                        && (manifestp = (Ptr)LockResource(manifesth)) )
415
                        && (manifestp = (Ptr)LockResource(manifesth)) )
416
                {
416
                {
417
                        char* newmanifest;
417
                        char* newmanifest;
418
                        int manifestsize = SizeofResource(hDllInstance, manifestsrc);
418
                        int manifestsize = SizeofResource(hDllInstance, manifestsrc);
419
 
419
 
420
                        newmanifest = (char*)malloc((size_t)manifestsize + 4096/*+4KiB for name,description,etc.*/);
420
                        newmanifest = (char*)malloc((size_t)manifestsize + 4096/*+4KiB for name,description,etc.*/);
421
 
421
 
422
                        strcpy_win_replace_ampersand(&title[0], &gdata->parm.szTitle[0]);
422
                        strcpy_win_replace_ampersand(&title[0], &gdata->parm.szTitle[0]);
423
                        if (gdata->parm.popDialog)
423
                        if (gdata->parm.popDialog)
424
                                strcat(title, "...");
424
                                strcat(title, "...");
425
 
425
 
426
                        strcpy_win_replace_ampersand(&category[0], &gdata->parm.szCategory[0]);
426
                        strcpy_win_replace_ampersand(&category[0], &gdata->parm.szCategory[0]);
427
 
427
 
428
                        origsize = SizeofResource(hDllInstance,datarsrc);
428
                        origsize = SizeofResource(hDllInstance,datarsrc);
429
 
429
 
430
                        if( (newpipl = (Ptr)malloc(origsize+0x300))
430
                        if( (newpipl = (Ptr)malloc(origsize+0x300))
431
                         && (newaete = (Ptr)malloc(4096))
431
                         && (newaete = (Ptr)malloc(4096))
432
                         && (pparm = (PARM_T*)malloc(sizeof(PARM_T))) )
432
                         && (pparm = (PARM_T*)malloc(sizeof(PARM_T))) )
433
                        {
433
                        {
434
                                // ====== Generate AETE and PIPL
434
                                // ====== Generate AETE and PIPL
435
 
435
 
436
                                /* add user-specified title and category to new PiPL */
436
                                /* add user-specified title and category to new PiPL */
437
                                memcpy(newpipl,datap,origsize);
437
                                memcpy(newpipl,datap,origsize);
438
                                /* note that Windows PiPLs have 2 byte version datum in front
438
                                /* note that Windows PiPLs have 2 byte version datum in front
439
                                   that isn't reflected in struct definition or Mac resource template: */
439
                                   that isn't reflected in struct definition or Mac resource template: */
440
                                piplsize = fixpipl((PIPropertyList*)(newpipl+2),origsize-2,&title[0],&category[0],&event_id) + 2;
440
                                piplsize = fixpipl((PIPropertyList*)(newpipl+2),origsize-2,&title[0],&gdata->parm.szTitle[0],&category[0],&event_id) + 2;
441
 
441
 
442
                                /* set up the PARM resource with saved parameters */
442
                                /* set up the PARM resource with saved parameters */
443
                                memcpy(pparm,&gdata->parm,sizeof(PARM_T));
443
                                memcpy(pparm,&gdata->parm,sizeof(PARM_T));
444
 
444
 
445
                                /* Generate 'aete' resource (contains names of the parameters for the "Actions" tab in Photoshop) */
445
                                /* Generate 'aete' resource (contains names of the parameters for the "Actions" tab in Photoshop) */
446
                                aetesize = aete_generate(newaete, pparm, event_id);
446
                                aetesize = aete_generate(newaete, pparm, event_id);
447
 
447
 
448
                                // ====== Create fitting manifest for the activation context
448
                                // ====== Create fitting manifest for the activation context
449
 
449
 
450
                                manifestp_copy = (char*)malloc((size_t)manifestsize + 1/*sz*/);
450
                                manifestp_copy = (char*)malloc((size_t)manifestsize + 1/*sz*/);
451
                                if (manifestp_copy != 0) {
451
                                if (manifestp_copy != 0) {
452
                                        memcpy(manifestp_copy, manifestp, manifestsize); // copy manifestp to manifestp_copy, because manifestp is readonly
452
                                        memcpy(manifestp_copy, manifestp, manifestsize); // copy manifestp to manifestp_copy, because manifestp is readonly
453
                                        manifestp_copy[manifestsize] = '\0'; // and add the null-terminating char, because domanifest() uses sprintf() on it
453
                                        manifestp_copy[manifestsize] = '\0'; // and add the null-terminating char, because domanifest() uses sprintf() on it
454
                                        manifestsize = domanifest(newmanifest, manifestp_copy, pparm, bits);
454
                                        manifestsize = domanifest(newmanifest, manifestp_copy, pparm, bits);
455
                                        free(manifestp_copy);
455
                                        free(manifestp_copy);
456
                                }
456
                                }
457
 
457
 
458
                                // ====== Change version attributes
458
                                // ====== Change version attributes
459
 
459
 
460
                                if (changeVersionInfo(dst, hupdate, pparm, bits) != NOERROR) {
460
                                if (changeVersionInfo(dst, hupdate, pparm, bits) != NOERROR) {
461
                                        simplewarning((TCHAR*)TEXT("changeVersionInfo failed")); // TODO (Not so important): TRANSLATE
461
                                        simplewarning((TCHAR*)TEXT("changeVersionInfo failed")); // TODO (Not so important): TRANSLATE
462
                                }
462
                                }
463
 
463
 
464
                                // ====== Obfuscate pparm!
464
                                // ====== Obfuscate pparm!
465
 
465
 
466
                                if (gdata->obfusc) {
466
                                if (gdata->obfusc) {
467
                                        parm_type = OBFUSCDATA_TYPE_NEW;
467
                                        parm_type = OBFUSCDATA_TYPE_NEW;
468
                                        parm_id = OBFUSCDATA_ID_NEW;
468
                                        parm_id = OBFUSCDATA_ID_NEW;
469
 
469
 
470
                                        // Note: After we have finished updating the resources, we will write <obfuscseed> into the binary code of the 8BF file
470
                                        // Note: After we have finished updating the resources, we will write <obfuscseed> into the binary code of the 8BF file
471
                                        obfusc(pparm, &obfuscseed, &obfuscseed2);
471
                                        obfusc(pparm, &obfuscseed, &obfuscseed2);
472
                                }else{
472
                                }else{
473
                                        parm_type = PARM_TYPE;
473
                                        parm_type = PARM_TYPE;
474
                                        parm_id = PARM_ID_NEW;
474
                                        parm_id = PARM_ID_NEW;
475
                                }
475
                                }
476
 
476
 
477
                                // ====== Save AETE, PIPL, Manifest and PARM/RCDATA
477
                                // ====== Save AETE, PIPL, Manifest and PARM/RCDATA
478
 
478
 
479
                                /* Attention: The resource we have found using FindResource() might have a different
479
                                /* Attention: The resource we have found using FindResource() might have a different
480
                                   language than the resource we are saving (Neutral), so we might end up having
480
                                   language than the resource we are saving (Neutral), so we might end up having
481
                                   multiple languages for the same resource. Therefore, the language "Neutral" was
481
                                   multiple languages for the same resource. Therefore, the language "Neutral" was
482
                                   set in the Scripting.rc file for the resource AETE and PIPL.rc for the resources PIPL. */
482
                                   set in the Scripting.rc file for the resource AETE and PIPL.rc for the resources PIPL. */
483
 
483
 
484
                                if(
484
                                if(
485
                                           _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
485
                                           _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
486
                                        && _UpdateResource(hupdate, RT_DIALOG, MAKEINTRESOURCE(ID_BUILDDLG), MAKELANGID(LANG_GERMAN, SUBLANG_GERMAN), NULL, 0) // clean up things we don't need in the standalone plugin
486
                                        && _UpdateResource(hupdate, RT_DIALOG, MAKEINTRESOURCE(ID_BUILDDLG), MAKELANGID(LANG_GERMAN, SUBLANG_GERMAN), NULL, 0) // clean up things we don't need in the standalone plugin
487
                                        && _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
487
                                        && _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
488
                                        && _UpdateResource(hupdate, RT_DIALOG, MAKEINTRESOURCE(ID_MAINDLG), MAKELANGID(LANG_GERMAN, SUBLANG_GERMAN), NULL, 0) // clean up things we don't need in the standalone plugin
488
                                        && _UpdateResource(hupdate, RT_DIALOG, MAKEINTRESOURCE(ID_MAINDLG), MAKELANGID(LANG_GERMAN, SUBLANG_GERMAN), NULL, 0) // clean up things we don't need in the standalone plugin
489
                                        && _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
489
                                        && _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
490
//                                      && _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
490
//                                      && _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
491
                                        && _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
491
                                        && _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
492
                                        // 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
492
                                        // 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
493
//                                      && _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
493
//                                      && _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
494
                                        && _UpdateResource(hupdate, TEXT("PIPL") /* note: caps!! */, MAKEINTRESOURCE(16000), MAKELANGID(LANG_NEUTRAL,SUBLANG_NEUTRAL),newpipl,(DWORD)piplsize)
494
                                        && _UpdateResource(hupdate, TEXT("PIPL") /* note: caps!! */, MAKEINTRESOURCE(16000), MAKELANGID(LANG_NEUTRAL,SUBLANG_NEUTRAL),newpipl,(DWORD)piplsize)
495
                                        && _UpdateResource(hupdate, TEXT("AETE") /* note: caps!! */, MAKEINTRESOURCE(16000), MAKELANGID(LANG_NEUTRAL, SUBLANG_NEUTRAL), newaete, (DWORD)aetesize)
495
                                        && _UpdateResource(hupdate, TEXT("AETE") /* note: caps!! */, MAKEINTRESOURCE(16000), MAKELANGID(LANG_NEUTRAL, SUBLANG_NEUTRAL), newaete, (DWORD)aetesize)
496
                                        // 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.
496
                                        // 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.
497
                                        && (gdata->obfusc || _UpdateResource(hupdate, TEXT("OPER"), MAKEINTRESOURCE(16000), MAKELANGID(LANG_ENGLISH, SUBLANG_ENGLISH_US), &dummy_oper, sizeof(dummy_oper)))
497
                                        && (gdata->obfusc || _UpdateResource(hupdate, TEXT("OPER"), MAKEINTRESOURCE(16000), MAKELANGID(LANG_ENGLISH, SUBLANG_ENGLISH_US), &dummy_oper, sizeof(dummy_oper)))
498
                                        && (gdata->obfusc || _UpdateResource(hupdate, TEXT("FUNC"), MAKEINTRESOURCE(16000), MAKELANGID(LANG_ENGLISH, SUBLANG_ENGLISH_US), &dummy_func, sizeof(dummy_func)))
498
                                        && (gdata->obfusc || _UpdateResource(hupdate, TEXT("FUNC"), MAKEINTRESOURCE(16000), MAKELANGID(LANG_ENGLISH, SUBLANG_ENGLISH_US), &dummy_func, sizeof(dummy_func)))
499
                                        && (gdata->obfusc || _UpdateResource(hupdate, TEXT("SYNM"), MAKEINTRESOURCE(16000), MAKELANGID(LANG_ENGLISH, SUBLANG_ENGLISH_US), &dummy_symn, sizeof(dummy_symn)))
499
                                        && (gdata->obfusc || _UpdateResource(hupdate, TEXT("SYNM"), MAKEINTRESOURCE(16000), MAKELANGID(LANG_ENGLISH, SUBLANG_ENGLISH_US), &dummy_symn, sizeof(dummy_symn)))
500
                                        && _UpdateResource(hupdate, RT_MANIFEST, MAKEINTRESOURCE(1), MAKELANGID(LANG_NEUTRAL, SUBLANG_NEUTRAL), newmanifest, (DWORD)manifestsize)
500
                                        && _UpdateResource(hupdate, RT_MANIFEST, MAKEINTRESOURCE(1), MAKELANGID(LANG_NEUTRAL, SUBLANG_NEUTRAL), newmanifest, (DWORD)manifestsize)
501
                                        && _UpdateResource(hupdate, parm_type,parm_id, MAKELANGID(LANG_NEUTRAL,SUBLANG_NEUTRAL),pparm,sizeof(PARM_T)) )
501
                                        && _UpdateResource(hupdate, parm_type,parm_id, MAKELANGID(LANG_NEUTRAL,SUBLANG_NEUTRAL),pparm,sizeof(PARM_T)) )
502
                                {
502
                                {
503
                                        discard = false;
503
                                        discard = false;
504
                                } else {
504
                                } else {
505
                                        showLastError((TCHAR*)TEXT("UpdateResource"));
505
                                        showLastError((TCHAR*)TEXT("UpdateResource"));
506
                                }
506
                                }
507
                        }
507
                        }
508
 
508
 
509
                        free(newmanifest);
509
                        free(newmanifest);
510
 
510
 
511
                        // Here, the file will be saved
511
                        // Here, the file will be saved
512
                        if (_EndUpdateResource(hupdate, discard)) {
512
                        if (_EndUpdateResource(hupdate, discard)) {
513
                                if (gdata->obfusc) {
513
                                if (gdata->obfusc) {
514
                                        // We modify the binary code to replace the deobfuscate-seed from <cObfuscSeed> to <obfuscseed>
514
                                        // We modify the binary code to replace the deobfuscate-seed from <cObfuscSeed> to <obfuscseed>
515
 
515
 
516
                                        // First try with alignment "4" (this should be the usual case),
516
                                        // First try with alignment "4" (this should be the usual case),
517
                                        // and if that failed, try without alignment ("1").
517
                                        // and if that failed, try without alignment ("1").
518
                                        // We only need to set maxamount to "1", because "const volatile" makes sure that
518
                                        // We only need to set maxamount to "1", because "const volatile" makes sure that
519
                                        // the compiler won't place (inline) it at several locations in the code.
519
                                        // the compiler won't place (inline) it at several locations in the code.
520
                                        if (!obfusc_seed_replace(dst, GetObfuscSeed(), GetObfuscSeed2(), obfuscseed, obfuscseed2, 1, 1))
520
                                        if (!obfusc_seed_replace(dst, GetObfuscSeed(), GetObfuscSeed2(), obfuscseed, obfuscseed2, 1, 1))
521
                                        {
521
                                        {
522
                                                simplewarning((TCHAR*)TEXT("obfusc_seed_replace failed")); // TODO (Not so important): TRANSLATE
522
                                                simplewarning((TCHAR*)TEXT("obfusc_seed_replace failed")); // TODO (Not so important): TRANSLATE
523
                                                discard = true;
523
                                                discard = true;
524
                                        }
524
                                        }
525
                                }
525
                                }
526
 
526
 
527
                                if (!update_pe_timestamp(dst, (__time32_t)time(0))) {
527
                                if (!update_pe_timestamp(dst, (__time32_t)time(0))) {
528
                                        simplewarning((TCHAR*)TEXT("update_pe_timestamp failed")); // TODO (Not so important): TRANSLATE
528
                                        simplewarning((TCHAR*)TEXT("update_pe_timestamp failed")); // TODO (Not so important): TRANSLATE
529
                                }
529
                                }
530
 
530
 
531
                                if (!repair_pe_checksum(dst)) {
531
                                if (!repair_pe_checksum(dst)) {
532
                                        simplewarning((TCHAR*)TEXT("repair_pe_checksum failed")); // TODO (Not so important): TRANSLATE
532
                                        simplewarning((TCHAR*)TEXT("repair_pe_checksum failed")); // TODO (Not so important): TRANSLATE
533
                                }
533
                                }
534
                        }else showLastError((TCHAR*)TEXT("EndUpdateResource"));
534
                        }else showLastError((TCHAR*)TEXT("EndUpdateResource"));
535
 
535
 
536
                }else showLastError((TCHAR*)TEXT("Find-, Load- or LockResource"));
536
                }else showLastError((TCHAR*)TEXT("Find-, Load- or LockResource"));
537
 
537
 
538
                if(pparm) free(pparm);
538
                if(pparm) free(pparm);
539
                if(newpipl) free(newpipl);
539
                if(newpipl) free(newpipl);
540
                if(newaete) free(newaete);
540
                if(newaete) free(newaete);
541
        }else
541
        }else
542
        showLastError((TCHAR*)TEXT("BeginUpdateResource"));
542
        showLastError((TCHAR*)TEXT("BeginUpdateResource"));
543
        return !discard;
543
        return !discard;
544
}
544
}
545
 
545
 
546
Boolean remove_64_filename_prefix(LPTSTR dstname) {
546
Boolean remove_64_filename_prefix(LPTSTR dstname) {
547
        // foobar.8bf => foobar.8bf
547
        // foobar.8bf => foobar.8bf
548
        // foobar64.8bf => foobar.8bf
548
        // foobar64.8bf => foobar.8bf
549
        size_t i;
549
        size_t i;
550
        for (i = xstrlen(dstname); i > 2; i--) {
550
        for (i = xstrlen(dstname); i > 2; i--) {
551
                if (dstname[i] == '.') {
551
                if (dstname[i] == '.') {
552
                        if ((dstname[i - 2] == '6') && (dstname[i - 1] == '4')) {
552
                        if ((dstname[i - 2] == '6') && (dstname[i - 1] == '4')) {
553
                                size_t tmp = xstrlen(dstname);
553
                                size_t tmp = xstrlen(dstname);
554
                                memcpy(&dstname[i - 2], &dstname[i], (xstrlen(dstname) - i + 1) * sizeof(TCHAR));
554
                                memcpy(&dstname[i - 2], &dstname[i], (xstrlen(dstname) - i + 1) * sizeof(TCHAR));
555
                                dstname[tmp - 2] = 0;
555
                                dstname[tmp - 2] = 0;
556
                                return true;
556
                                return true;
557
                        }
557
                        }
558
                }
558
                }
559
        }
559
        }
560
        return false;
560
        return false;
561
}
561
}
562
 
562
 
563
Boolean add_64_filename_prefix(LPTSTR dstname) {
563
Boolean add_64_filename_prefix(LPTSTR dstname) {
564
        // foobar.8bf => foobar64.8bf
564
        // foobar.8bf => foobar64.8bf
565
        size_t i;
565
        size_t i;
566
        for (i = xstrlen(dstname); i > 2; i--) {
566
        for (i = xstrlen(dstname); i > 2; i--) {
567
                if (dstname[i] == '.') {
567
                if (dstname[i] == '.') {
568
                        size_t tmp = xstrlen(dstname);
568
                        size_t tmp = xstrlen(dstname);
569
                        memcpy(&dstname[i + 2], &dstname[i], (xstrlen(dstname) - i + 1) * sizeof(TCHAR));
569
                        memcpy(&dstname[i + 2], &dstname[i], (xstrlen(dstname) - i + 1) * sizeof(TCHAR));
570
                        dstname[i] = '6';
570
                        dstname[i] = '6';
571
                        dstname[i + 1] = '4';
571
                        dstname[i + 1] = '4';
572
                        dstname[tmp + 2] = 0;
572
                        dstname[tmp + 2] = 0;
573
                        return true;
573
                        return true;
574
                }
574
                }
575
        }
575
        }
576
        return false;
576
        return false;
577
}
577
}
578
 
578
 
579
BOOL FileExists(LPCTSTR szPath) {
579
BOOL FileExists(LPCTSTR szPath) {
580
        DWORD dwAttrib = GetFileAttributes(szPath);
580
        DWORD dwAttrib = GetFileAttributes(szPath);
581
        return (dwAttrib != INVALID_FILE_ATTRIBUTES &&
581
        return (dwAttrib != INVALID_FILE_ATTRIBUTES &&
582
                !(dwAttrib & FILE_ATTRIBUTE_DIRECTORY));
582
                !(dwAttrib & FILE_ATTRIBUTE_DIRECTORY));
583
}
583
}
584
 
584
 
585
Boolean extract_file(LPCTSTR lpType, LPCTSTR lpName, FSSpec* dst) {
585
Boolean extract_file(LPCTSTR lpType, LPCTSTR lpName, FSSpec* dst) {
586
        HGLOBAL datah;
586
        HGLOBAL datah;
587
        LPVOID datap;
587
        LPVOID datap;
588
        HRSRC datarsrc;
588
        HRSRC datarsrc;
589
        FILECOUNT datalen;
589
        FILECOUNT datalen;
590
        FILEREF fptr;
590
        FILEREF fptr;
591
        OSErr res;
591
        OSErr res;
592
 
592
 
593
        if ((datarsrc = FindResource((HMODULE)hDllInstance, lpName, lpType))
593
        if ((datarsrc = FindResource((HMODULE)hDllInstance, lpName, lpType))
594
                && (datah = LoadResource((HMODULE)hDllInstance, datarsrc))
594
                && (datah = LoadResource((HMODULE)hDllInstance, datarsrc))
595
                && (datalen = (FILECOUNT)SizeofResource((HMODULE)hDllInstance, datarsrc))
595
                && (datalen = (FILECOUNT)SizeofResource((HMODULE)hDllInstance, datarsrc))
596
                && (datap = (Ptr)LockResource(datah))) {
596
                && (datap = (Ptr)LockResource(datah))) {
597
 
597
 
598
                FSpDelete(dst);
598
                FSpDelete(dst);
599
                if (FSpCreate(dst, kPhotoshopSignature, PS_FILTER_FILETYPE, 0/*sfr->sfScript*/) != noErr) return false;
599
                if (FSpCreate(dst, kPhotoshopSignature, PS_FILTER_FILETYPE, 0/*sfr->sfScript*/) != noErr) return false;
600
 
600
 
601
                if (FSpOpenDF(dst, fsRdWrPerm, &fptr) != noErr) return false;
601
                if (FSpOpenDF(dst, fsRdWrPerm, &fptr) != noErr) return false;
602
 
602
 
603
                res = FSWrite(fptr, &datalen, datap);
603
                res = FSWrite(fptr, &datalen, datap);
604
 
604
 
605
                FSClose(fptr);
605
                FSClose(fptr);
606
 
606
 
607
                return res == noErr;
607
                return res == noErr;
608
        }
608
        }
609
        else {
609
        else {
610
                return false;
610
                return false;
611
        }
611
        }
612
}
612
}
613
 
613
 
614
BOOL StripAuthenticode(FSSpec* dst) {
614
BOOL StripAuthenticode(FSSpec* dst) {
615
        HANDLE hFile = CreateFile(&dst->szName[0], GENERIC_READ | GENERIC_WRITE, FILE_SHARE_READ | FILE_SHARE_DELETE, NULL, OPEN_EXISTING, 0, NULL);
615
        HANDLE hFile = CreateFile(&dst->szName[0], GENERIC_READ | GENERIC_WRITE, FILE_SHARE_READ | FILE_SHARE_DELETE, NULL, OPEN_EXISTING, 0, NULL);
616
        if (hFile == INVALID_HANDLE_VALUE) {
616
        if (hFile == INVALID_HANDLE_VALUE) {
617
                CloseHandle(hFile);
617
                CloseHandle(hFile);
618
                return FALSE;
618
                return FALSE;
619
        }
619
        }
620
        if (!_ImageRemoveCertificate(hFile, 0)) {
620
        if (!_ImageRemoveCertificate(hFile, 0)) {
621
                CloseHandle(hFile);
621
                CloseHandle(hFile);
622
                return FALSE;
622
                return FALSE;
623
        }
623
        }
624
        CloseHandle(hFile);
624
        CloseHandle(hFile);
625
        return TRUE;
625
        return TRUE;
626
}
626
}
627
 
627
 
628
OSErr do_make_standalone(FSSpec* dst, int bits) {
628
OSErr do_make_standalone(FSSpec* dst, int bits) {
629
        Boolean res;
629
        Boolean res;
630
 
630
 
631
        //DeleteFile(dstname);
631
        //DeleteFile(dstname);
632
        if (extract_file(TEXT("TPLT"), MAKEINTRESOURCE(1000 + bits), dst)) {
632
        if (extract_file(TEXT("TPLT"), MAKEINTRESOURCE(1000 + bits), dst)) {
633
                // In case we did digitally sign the FilterFoundry plugin (which is currently not the case though),
633
                // In case we did digitally sign the FilterFoundry plugin (which is currently not the case though),
634
                // we must now remove the signature, because the embedding of parameter data has invalidated it.
634
                // we must now remove the signature, because the embedding of parameter data has invalidated it.
635
                // Do it before we manipulate anything, in order to avoid that there is an invalid binary (which might annoy AntiVirus software)
635
                // Do it before we manipulate anything, in order to avoid that there is an invalid binary (which might annoy AntiVirus software)
636
                StripAuthenticode(dst);
636
                StripAuthenticode(dst);
637
 
637
 
638
                // Now do the resources
638
                // Now do the resources
639
                res = doresources(dst, bits);
639
                res = doresources(dst, bits);
640
                if (!res) {
640
                if (!res) {
641
                        DeleteFile(&dst->szName[0]);
641
                        DeleteFile(&dst->szName[0]);
642
                        alertuser_id(bits == 32 ? MSG_CANNOT_CREATE_32BIT_FILTER_ID : MSG_CANNOT_CREATE_64BIT_FILTER_ID, (TCHAR*)TEXT("doresources failed"));
642
                        alertuser_id(bits == 32 ? MSG_CANNOT_CREATE_32BIT_FILTER_ID : MSG_CANNOT_CREATE_64BIT_FILTER_ID, (TCHAR*)TEXT("doresources failed"));
643
                }
643
                }
644
        }
644
        }
645
        else {
645
        else {
646
                // If you see this error, please make sure that you have called foundry_3264_mixer to include the 32/64 plugins as resource!
646
                // If you see this error, please make sure that you have called foundry_3264_mixer to include the 32/64 plugins as resource!
647
                res = false;
647
                res = false;
648
                //DeleteFile(dstname);
648
                //DeleteFile(dstname);
649
 
649
 
650
                alertuser_id(bits == 32 ? MSG_CANNOT_CREATE_32BIT_FILTER_ID : MSG_CANNOT_CREATE_64BIT_FILTER_ID, (TCHAR*)TEXT("extract_file failed"));
650
                alertuser_id(bits == 32 ? MSG_CANNOT_CREATE_32BIT_FILTER_ID : MSG_CANNOT_CREATE_64BIT_FILTER_ID, (TCHAR*)TEXT("extract_file failed"));
651
        }
651
        }
652
 
652
 
653
        return res ? noErr : ioErr;
653
        return res ? noErr : ioErr;
654
}
654
}
655
 
655
 
656
OSErr make_standalone(StandardFileReply *sfr){
656
OSErr make_standalone(StandardFileReply *sfr){
657
        OSErr tmpErr, outErr;
657
        OSErr tmpErr, outErr;
658
        FSSpec dst = { 0 };
658
        FSSpec dst = { 0 };
659
 
659
 
660
        outErr = noErr;
660
        outErr = noErr;
661
 
661
 
662
        // Make 32 bit:
662
        // Make 32 bit:
663
        // Destfile = no64_or_32(chosenname)
663
        // Destfile = no64_or_32(chosenname)
664
        xstrcpy(dst.szName, sfr->sfFile.szName);
664
        xstrcpy(dst.szName, sfr->sfFile.szName);
665
        remove_64_filename_prefix(&dst.szName[0]);
665
        remove_64_filename_prefix(&dst.szName[0]);
666
        tmpErr = do_make_standalone(&dst, 32);
666
        tmpErr = do_make_standalone(&dst, 32);
667
        if (tmpErr != noErr)
667
        if (tmpErr != noErr)
668
                outErr = tmpErr;
668
                outErr = tmpErr;
669
        else
669
        else
670
                showmessage_id(MSG_BUILT32_ID);
670
                showmessage_id(MSG_BUILT32_ID);
671
 
671
 
672
        // Make 64 bit:
672
        // Make 64 bit:
673
        // Destfile = no64_or_32(chosenname) + 64
673
        // Destfile = no64_or_32(chosenname) + 64
674
        xstrcpy(dst.szName, sfr->sfFile.szName);
674
        xstrcpy(dst.szName, sfr->sfFile.szName);
675
        remove_64_filename_prefix(&dst.szName[0]);
675
        remove_64_filename_prefix(&dst.szName[0]);
676
        add_64_filename_prefix(&dst.szName[0]);
676
        add_64_filename_prefix(&dst.szName[0]);
677
        tmpErr = do_make_standalone(&dst, 64);
677
        tmpErr = do_make_standalone(&dst, 64);
678
        if (tmpErr != noErr)
678
        if (tmpErr != noErr)
679
                outErr = tmpErr;
679
                outErr = tmpErr;
680
        else
680
        else
681
                showmessage_id(MSG_BUILT64_ID);
681
                showmessage_id(MSG_BUILT64_ID);
682
 
682
 
683
        return outErr;
683
        return outErr;
684
}
684
}
685
 
685
 
686
 
686