Subversion Repositories filter_foundry

Rev

Rev 277 | Rev 279 | Go to most recent revision | Details | Compare with Previous | Last modification | View Log | RSS feed

Rev Author Line No. Line
258 daniel-mar 1
/*
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
4
    Copyright (C) 2018-2021 Daniel Marschall, ViaThinkSoft
5
 
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
8
    the Free Software Foundation; either version 2 of the License, or
9
    (at your option) any later version.
10
 
11
    This program is distributed in the hope that it will be useful,
12
    but WITHOUT ANY WARRANTY; without even the implied warranty of
13
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14
    GNU General Public License for more details.
15
 
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
18
    Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
19
*/
20
 
21
#include "ff.h"
22
 
278 daniel-mar 23
#include <time.h>
24
 
258 daniel-mar 25
#include "file_compat.h"
26
#include "compat_string.h"
27
#include "versioninfo_modify_win.h"
28
#include "version.h"
29
 
30
extern HINSTANCE hDllInstance;
31
 
274 daniel-mar 32
Boolean doresources(HMODULE srcmod,char *dstname, int bits);
258 daniel-mar 33
 
34
void dbglasterror(char *func){
35
        char s[0x100];
36
 
37
        strcpy(s,func);
38
        strcat(s," failed: ");
39
        FormatMessage( FORMAT_MESSAGE_FROM_SYSTEM,NULL,GetLastError(),0,s+strlen(s),0x100,NULL );
40
        dbg(s);
41
}
42
 
43
/*
44
BOOL CALLBACK enumfunc(HMODULE hModule,LPCTSTR lpszType,LPCTSTR lpszName,WORD wIDLanguage,LONG lParam){
45
        char s[0x100];
46
        sprintf(s,"EnumResourceLanguages callback: module=%#x type=%s name=%s lang=%d",
47
                hModule,lpszType,lpszName,wIDLanguage);
48
        dbg(s);
49
        return TRUE;
50
}
51
*/
52
 
274 daniel-mar 53
int domanifest(char *newmanifest, const char *manifestp, PARM_T* pparm, int bits) {
258 daniel-mar 54
        char name[1024];
55
        char description[1024];
56
        size_t i;
276 daniel-mar 57
        size_t iname = 0;
258 daniel-mar 58
        int idescription = 0;
59
 
60
        // Description
61
        for (i = 0; i < strlen((char*)pparm->category); i++) {
62
                char c = pparm->category[i];
63
                if ((c != '<') && (c != '>')) {
64
                        description[idescription++] = c;
65
                }
66
        }
67
        description[idescription++] = ' ';
68
        description[idescription++] = '-';
69
        description[idescription++] = ' ';
70
        for (i = 0; i < strlen((char*)pparm->title); i++) {
71
                char c = pparm->title[i];
72
                if ((c != '<') && (c != '>')) {
73
                        description[idescription++] = c;
74
                }
75
        }
76
        description[idescription++] = '\0';
77
 
78
        // Name
79
        strcpy(name, "Telegraphics.FilterFoundry.");
80
        iname = strlen("Telegraphics.FilterFoundry.");
81
        for (i = 0; i < strlen((char*)pparm->category); i++) {
82
                char c = pparm->category[i];
83
                if (((c >= 'A') && (c <= 'Z')) || ((c >= 'a') && (c <= 'z'))) {
84
                        name[iname++] = c;
85
                }
86
        }
87
        name[iname++] = '.';
88
        for (i = 0; i < strlen((char*)pparm->title); i++) {
89
                char c = pparm->title[i];
90
                if (((c >= 'A') && (c <= 'Z')) || ((c >= 'a') && (c <= 'z'))) {
91
                        name[iname++] = c;
92
                }
93
        }
94
        name[iname++] = '\0';
95
 
274 daniel-mar 96
        if (bits == 64) {
97
                return sprintf(newmanifest, manifestp, (char*)name, "amd64", VERSION_STR, (char*)description);
98
        }
99
        else {
100
                return sprintf(newmanifest, manifestp, (char*)name, "x86", VERSION_STR, (char*)description);
101
        }
258 daniel-mar 102
}
103
 
104
void changeVersionInfo(char* dstname, PARM_T* pparm, HGLOBAL hupdate) {
105
        char* soleFilename;
106
        LPWSTR changeRequestStr, tmp;
107
 
108
        if (soleFilename = strrchr(dstname, '\\')) {
109
                ++soleFilename;
110
        }
111
        else {
112
                soleFilename = dstname;
113
        }
114
 
115
        // Format of argument "PCWSTR changes" is "<name>\0<value>\0<name>\0<value>\0....."
116
        // You can CHANGE values for any given name
117
        // You can DELETE entries by setting the value to "\b" (0x08 backspace character)
118
        // You cannot (yet) ADD entries.
119
        changeRequestStr = (LPWSTR)malloc(6 * 2 * 100 + 1);
120
 
121
        tmp = changeRequestStr;
122
 
123
        tmp += mbstowcs(tmp, "Comments", 100);
124
        tmp++;
125
        tmp += mbstowcs(tmp, "Built using Filter Foundry " VERSION_STR, 100);
126
        tmp++;
127
 
128
        tmp += mbstowcs(tmp, "CompanyName", 100);
129
        tmp++;
130
        if (strlen((char*)pparm->author) > 0) {
131
                tmp += mbstowcs(tmp, (char*)pparm->author, 100);
132
        }
133
        else {
134
                tmp += mbstowcs(tmp, "\b", 100); // \b = remove
135
        }
136
        tmp++;
137
 
138
        tmp += mbstowcs(tmp, "LegalCopyright", 100);
139
        tmp++;
140
        if (strlen((char*)pparm->copyright) > 0) {
141
                tmp += mbstowcs(tmp, (char*)pparm->copyright, 100);
142
        }
143
        else {
144
                tmp += mbstowcs(tmp, "\b", 100); // \b = remove
145
        }
146
        tmp++;
147
 
148
        tmp += mbstowcs(tmp, "FileDescription", 100);
149
        tmp++;
150
        if (strlen((char*)pparm->title) > 0) {
151
                tmp += mbstowcs(tmp, (char*)pparm->title, 100);
152
        }
153
        else {
154
                tmp += mbstowcs(tmp, "Untitled filter", 100);
155
        }
156
        tmp++;
157
 
158
        tmp += mbstowcs(tmp, "OriginalFilename", 100);
159
        tmp++;
160
        tmp += mbstowcs(tmp, soleFilename, 100);
161
        tmp++;
162
 
163
        tmp += mbstowcs(tmp, "License", 100);
164
        tmp++;
165
        tmp += mbstowcs(tmp, "\b", 100); // \b = remove, since filter is standalone and might have its own license
166
        tmp++;
167
 
168
        tmp += mbstowcs(tmp, "", 1);
169
 
170
        if (UpdateVersionInfoWithHandle(dstname, hupdate, changeRequestStr) != NOERROR) {
171
                alertuser(_strdup("UpdateVersionInfoWithHandle failed"), _strdup(""));
172
        }
173
 
174
        free(changeRequestStr);
175
}
176
 
278 daniel-mar 177
Boolean update_pe_timestamp(const char* filename, time_t timestamp) {
178
        FILE* fptr = fopen(filename, "rb+");
179
        if (fptr == NULL) return false;
180
 
181
        fseek(fptr, 0x3C, SEEK_SET);
182
        size_t peoffset;
183
        fread(&peoffset, sizeof(peoffset), 1, fptr);
184
 
185
        fseek(fptr, peoffset + 8, SEEK_SET);
186
        fwrite(&timestamp, sizeof(time_t), 1, fptr);
187
 
188
        fclose(fptr);
189
 
190
        return true;
191
}
192
 
276 daniel-mar 193
int binary_replace_file(const char* filename, unsigned int search, unsigned int replace) {
194
        unsigned int srecord = 0;
195
        int found = 0;
196
 
197
        FILE* fptr = fopen(filename, "rb+");
198
        if (fptr == NULL) return -1;
199
 
200
        while ((fread(&srecord, sizeof(srecord), 1, fptr) == 1))
201
        {
202
                if (srecord == search) {
203
                        srecord = replace;
204
                        fseek(fptr, -1*(long)sizeof(srecord), SEEK_CUR);
205
                        fwrite(&srecord, (int)sizeof(srecord), 1, fptr);
206
                        fseek(fptr, 0, SEEK_CUR); // important!
207
                        found++;
208
                }
209
                else {
210
                        fseek(fptr, -1*(long)(sizeof(srecord) - 1), SEEK_CUR);
211
                }
212
        }
213
        fclose(fptr);
214
 
215
        return found;
216
}
217
 
274 daniel-mar 218
Boolean doresources(HMODULE srcmod,char *dstname, int bits){
258 daniel-mar 219
        HRSRC datarsrc,aetersrc,manifestsrc;
220
        HGLOBAL datah,aeteh,hupdate,manifesth;
221
        Ptr newpipl = NULL, newaete = NULL;
222
        LPVOID datap, aetep, manifestp;
223
        PARM_T *pparm = NULL;
224
        size_t piplsize,aetesize,origsize,manifestsize;
225
        Str255 title;
226
        LPCTSTR parm_type;
227
        int i,parm_id;
228
        Boolean discard = true;
276 daniel-mar 229
        unsigned int obfuscseed = 0;
258 daniel-mar 230
        long event_id;
231
 
232
        if( (hupdate = _BeginUpdateResource(dstname,false)) ){
233
                DBG("BeginUpdateResource OK");
234
                if( (datarsrc = FindResource(srcmod,MAKEINTRESOURCE(16000),"TPLT"))
235
                        && (datah = LoadResource(srcmod,datarsrc))
236
                        && (datap = (Ptr)LockResource(datah))
237
                        && (aetersrc = FindResource(srcmod, MAKEINTRESOURCE(16000), "AETE"))
238
                        && (aeteh = LoadResource(srcmod, aetersrc))
239
                        && (aetep = (Ptr)LockResource(aeteh))
240
                        && (manifestsrc = FindResource(srcmod, MAKEINTRESOURCE(50), "TPLT"))
241
                        && (manifesth = LoadResource(srcmod, manifestsrc))
242
                        && (manifestp = (Ptr)LockResource(manifesth)) )
243
                {
244
                        char newmanifest[5000];
245
 
246
                        DBG("loaded DATA, PiPL");
247
 
248
                        PLstrcpy(title,gdata->parm.title);
249
                        if(gdata->parm.popDialog)
250
                                PLstrcat(title,(StringPtr)"\003...");
251
 
252
                        origsize = SizeofResource(srcmod,datarsrc);
253
 
254
                        if( (newpipl = (Ptr)malloc(origsize+0x300))
255
                         && (newaete = (Ptr)malloc(4096))
256
                         && (pparm = (PARM_T*)malloc(sizeof(PARM_T))) )
257
                        {
258
                                // ====== Generate AETE and PIPL
259
 
260
                                /* add user-specified title and category to new PiPL */
261
                                memcpy(newpipl,datap,origsize);
262
                                /* note that Windows PiPLs have 2 byte version datum in front
263
                                   that isn't reflected in struct definition or Mac resource template: */
264
                                piplsize = fixpipl((PIPropertyList*)(newpipl+2),origsize-2,title, &event_id) + 2;
265
 
266
                                /* set up the PARM resource with saved parameters */
267
                                memcpy(pparm,&gdata->parm,sizeof(PARM_T));
268
 
269
                                /* Generate 'aete' resource (contains names of the parameters for the "Actions" tab in Photoshop) */
270
                                aetesize = aete_generate(newaete, pparm, event_id);
271
 
276 daniel-mar 272
                                if (gdata->obfusc) {
273
                                        // Avoid that the same filter can generate with two seeds,
274
                                        // otherwise the comparison would be much easier
275
                                        obfuscseed = (unsigned int)get_parm_hash(pparm);
276
                                }
277
 
258 daniel-mar 278
                                // ====== Change Pascal strings to C-Strings
279
 
280
                                /* convert to C strings for Windows PARM resource */
281
                                // Don't do it before aete_generate, because they need Pascal strings
282
                                myp2cstr(pparm->category);
283
                                myp2cstr(pparm->title);
284
                                myp2cstr(pparm->copyright);
285
                                myp2cstr(pparm->author);
286
                                for (i = 0; i < 4; ++i)
287
                                        myp2cstr(pparm->map[i]);
288
                                for (i = 0; i < 8; ++i)
289
                                        myp2cstr(pparm->ctl[i]);
290
 
274 daniel-mar 291
                                manifestsize = domanifest(newmanifest, (const char*)manifestp, pparm, bits);
258 daniel-mar 292
 
293
                                // ====== Change version attributes
294
 
295
                                changeVersionInfo(dstname, pparm, hupdate);
296
 
297
                                // ====== Obfuscate pparm!
298
 
299
                                if(gdata->obfusc){
300
                                        parm_type = RT_RCDATA;
301
                                        parm_id = OBFUSCDATA_ID;
276 daniel-mar 302
 
303
                                        // Note: After we have finished updating the resources, we will write <obfuscseed> into the binary code of the 8BF file
304
                                        obfusc(pparm, obfuscseed);
258 daniel-mar 305
                                }else{
306
                                        parm_type = "PARM";
307
                                        parm_id = PARM_ID;
308
                                }
309
 
310
                                // ====== Save AETE, PIPL, Manifest and PARM/RCDATA
311
 
312
                                /* Attention: The resource we have found using FindResource() might have a different
313
                                   language than the resource we are saving (Neutral), so we might end up having
314
                                   multiple languages for the same resource. Therefore, the language "Neutral" was
315
                                   set in the Scripting.rc file for the resource AETE and PIPL.rc for the resources PIPL. */
274 daniel-mar 316
 
317
                                if(_UpdateResource(hupdate, "TPLT" /* note: caps!! */, MAKEINTRESOURCE(50), MAKELANGID(LANG_NEUTRAL, SUBLANG_NEUTRAL), NULL, 0)
318
                                        && _UpdateResource(hupdate, "TPLT" /* note: caps!! */, MAKEINTRESOURCE(16000), MAKELANGID(LANG_NEUTRAL, SUBLANG_NEUTRAL), NULL, 0)
319
                                        && _UpdateResource(hupdate, RT_DIALOG, MAKEINTRESOURCE(ID_BUILDDLG), MAKELANGID(LANG_ENGLISH, SUBLANG_ENGLISH_US), NULL, 0)
320
                                        && _UpdateResource(hupdate,"PIPL" /* note: caps!! */,MAKEINTRESOURCE(16000), MAKELANGID(LANG_NEUTRAL,SUBLANG_NEUTRAL),newpipl,(DWORD)piplsize)
258 daniel-mar 321
                                        && _UpdateResource(hupdate, "AETE" /* note: caps!! */, MAKEINTRESOURCE(16000), MAKELANGID(LANG_NEUTRAL, SUBLANG_NEUTRAL), newaete, (DWORD)aetesize)
322
                                        && _UpdateResource(hupdate, RT_MANIFEST, MAKEINTRESOURCE(1), MAKELANGID(LANG_NEUTRAL, SUBLANG_NEUTRAL), newmanifest, (DWORD)manifestsize)
323
                                        && _UpdateResource(hupdate,parm_type,MAKEINTRESOURCE(parm_id), MAKELANGID(LANG_NEUTRAL,SUBLANG_NEUTRAL),pparm,sizeof(PARM_T)) )
324
                                {
325
                                        discard = false;
326
                                } else {
327
                                        dbglasterror(_strdup("UpdateResource"));
328
                                }
329
                        }
330
 
331
                }else dbglasterror(_strdup("Find-, Load- or LockResource"));
332
 
276 daniel-mar 333
                // Here, the file will be saved
258 daniel-mar 334
                if(!_EndUpdateResource(hupdate,discard))
335
                        dbglasterror(_strdup("EndUpdateResource"));
336
 
276 daniel-mar 337
                if (gdata->obfusc) {
277 daniel-mar 338
                        // We modify the binary code to replace the deobfuscate-seed from <cObfuscV4Seed> to <obfuscseed>
278 daniel-mar 339
                        if (binary_replace_file(dstname, cObfuscV4Seed, obfuscseed) != 1) {
340
                                // The seed must only be exactly 1 time inside the 8BF file,
341
                                // since "const volatile" makes sure that the compiler won't place
342
                                // it at several locations in the code.
276 daniel-mar 343
                                dbg("binary_replace_file failed");
344
                                discard = true;
345
                        }
346
                }
347
 
278 daniel-mar 348
                update_pe_timestamp(dstname, time(0));
349
 
258 daniel-mar 350
                if(pparm) free(pparm);
351
                if(newpipl) free(newpipl);
352
                if(newaete) free(newaete);
353
        }else
354
                dbglasterror(_strdup("BeginUpdateResource"));
355
        return !discard;
356
}
357
 
278 daniel-mar 358
Boolean remove_64_filename_prefix(char* dstname) {
274 daniel-mar 359
        // foobar.8bf => foobar.8bf
360
        // foobar64.8bf => foobar.8bf
276 daniel-mar 361
        size_t i;
274 daniel-mar 362
        for (i = strlen(dstname); i > 2; i--) {
363
                if (dstname[i] == '.') {
364
                        if ((dstname[i - 2] == '6') && (dstname[i - 1] == '4')) {
276 daniel-mar 365
                                size_t tmp = strlen(dstname);
274 daniel-mar 366
                                memcpy(&dstname[i - 2], &dstname[i], strlen(dstname) - i + 1);
367
                                dstname[tmp - 2] = 0;
368
                                return true;
369
                        }
370
                }
371
        }
372
        return false;
373
}
374
 
278 daniel-mar 375
Boolean add_64_filename_prefix(char* dstname) {
274 daniel-mar 376
        // foobar.8bf => foobar64.8bf
276 daniel-mar 377
        size_t i;
274 daniel-mar 378
        for (i = strlen(dstname); i > 2; i--) {
379
                if (dstname[i] == '.') {
276 daniel-mar 380
                        size_t tmp = strlen(dstname);
274 daniel-mar 381
                        memcpy(&dstname[i + 2], &dstname[i], strlen(dstname) - i + 1);
382
                        dstname[i] = '6';
383
                        dstname[i + 1] = '4';
384
                        dstname[tmp + 2] = 0;
385
                        return true;
386
                }
387
        }
388
        return false;
389
}
390
 
391
BOOL FileExists(LPCTSTR szPath) {
392
        DWORD dwAttrib = GetFileAttributes(szPath);
393
        return (dwAttrib != INVALID_FILE_ATTRIBUTES &&
394
                !(dwAttrib & FILE_ATTRIBUTE_DIRECTORY));
395
}
396
 
397
BOOL Is32BitOperatingSystem() {
398
#ifdef _WIN64
399
        return false;
400
#else
401
        SYSTEM_INFO info;
402
        _GetNativeSystemInfo(&info);
403
        return info.wProcessorArchitecture == PROCESSOR_ARCHITECTURE_INTEL;
404
#endif
405
}
406
 
407
OSErr do_make_standalone(char* srcname, char* dstname, int bits) {
408
        Boolean res;
409
 
410
        //DeleteFile(dstname);
411
        if (CopyFile(srcname, dstname, false)) {
412
                HMODULE hSrcmod;
413
                hSrcmod = LoadLibraryEx(srcname, NULL, LOAD_LIBRARY_AS_DATAFILE);
414
                if (hSrcmod) {
415
                        res = doresources(hSrcmod, dstname, bits);
416
                        if (!res) {
417
                                DeleteFile(dstname);
418
                        }
419
                        FreeLibrary(hSrcmod);
420
                }
421
                else {
422
                        res = false;
423
                }
424
        }
425
        else {
426
                res = false;
427
        }
428
 
429
        if (!res) {
430
                char err[MAX_PATH + 200];
431
                sprintf(err, "Could not create %d bit standalone plugin.", bits);
432
                alertuser(_strdup(&err[0]), _strdup(""));
433
        }
434
 
435
        return res ? noErr : ioErr;
436
}
437
 
258 daniel-mar 438
OSErr make_standalone(StandardFileReply *sfr){
274 daniel-mar 439
        OSErr tmpErr, outErr;
258 daniel-mar 440
        char dstname[0x100],srcname[MAX_PATH+1];
441
 
442
        if (!isWin32NT()) {
443
                HMODULE hLib;
444
 
445
                hLib = LoadLibraryA("UNICOWS.DLL");
446
                if (!hLib) {
447
                        char* sysdir;
448
 
449
                        sysdir = (char*)malloc(MAX_PATH);
450
                        GetSystemDirectoryA(sysdir, MAX_PATH);
451
                        alertuser(_strdup("To build standalone plugins using this version of\nWindows, you need to install UNICOWS.DLL\n\nPlease download it from the Internet\nand place it into following directory:"), sysdir);
452
                        free(sysdir);
453
 
454
                        return false;
455
                }
456
                else {
457
                        FreeLibrary(hLib);
458
                }
459
        }
460
 
274 daniel-mar 461
        outErr = noErr;
258 daniel-mar 462
 
274 daniel-mar 463
#ifdef _WIN64
464
 
465
        //64 bit DLL makes 64 bit:
466
        // Source file = module filename
467
        GetModuleFileName(hDllInstance, srcname, MAX_PATH);
468
        // Destfile = no64_or_32(chosenname) + 64
469
        myp2cstrcpy(dstname, sfr->sfFile.name);
470
        remove_64_filename_prefix(dstname);
471
        add_64_filename_prefix(dstname);
472
        tmpErr = do_make_standalone(&srcname[0], &dstname[0], 64);
473
        if (tmpErr != noErr)
474
                outErr = tmpErr;
475
        else
476
                showmessage(_strdup("64 bit standalone filter was successfully created"));
477
 
478
        //64 bit DLL makes 32 bit:
479
        // Source file = no32(modulefilename)
480
        GetModuleFileName(hDllInstance, srcname, MAX_PATH);
481
        if (!remove_64_filename_prefix(srcname)) {
482
                char err[MAX_PATH + 200];
483
                sprintf(err, "Cannot create the %d bit version of this filter, because the 32-bit variant of this plugin could not be found", 32);
484
                alertuser(_strdup(&err[0]), _strdup(""));
258 daniel-mar 485
        }
274 daniel-mar 486
        else if (!FileExists(srcname)) {
487
                char err[MAX_PATH + 200];
488
                sprintf(err, "%s was not found. Therefore, the %d bit version of the standalone filter could not be created!", srcname, 32);
489
                alertuser(_strdup(&err[0]), _strdup(""));
490
        }
491
        else {
492
                // Destfile = no64_or_32(chosenname)
493
                myp2cstrcpy(dstname, sfr->sfFile.name);
494
                remove_64_filename_prefix(dstname);
495
                tmpErr = do_make_standalone(&srcname[0], &dstname[0], 32);
496
                if (tmpErr != noErr)
497
                        outErr = tmpErr;
498
                else
499
                        showmessage(_strdup("32 bit standalone filter was successfully created"));
277 daniel-mar 500
        }
258 daniel-mar 501
 
274 daniel-mar 502
#else
503
 
504
        //32 bit DLL makes 32 bit:
505
        // Source file = module filename
506
        GetModuleFileName(hDllInstance, srcname, MAX_PATH);
507
        // Destfile = no64_or_32(chosenname)
508
        myp2cstrcpy(dstname, sfr->sfFile.name);
509
        remove_64_filename_prefix(dstname);
510
        tmpErr = do_make_standalone(&srcname[0], &dstname[0], 32);
511
        if (tmpErr != noErr)
512
                outErr = tmpErr;
513
        else
514
                showmessage(_strdup("32 bit standalone filter was successfully created"));
515
 
516
        if (!Is32BitOperatingSystem()) {
517
                //32 bit DLL makes 64 bit:
518
                // Source file = module filename + 64
519
                GetModuleFileName(hDllInstance, srcname, MAX_PATH);
520
                add_64_filename_prefix(srcname);
521
                if (!FileExists(srcname)) {
522
                        char err[MAX_PATH + 200];
523
                        sprintf(err, "%s was not found. Therefore, the %d bit version of the standalone filter could not be created!", srcname, 64);
524
                        alertuser(_strdup(&err[0]), _strdup(""));
525
                }
526
                else {
527
                        // Destfile = no64_or_32(chosenname) + 64
528
                        myp2cstrcpy(dstname, sfr->sfFile.name);
529
                        remove_64_filename_prefix(dstname);
530
                        add_64_filename_prefix(dstname);
531
                        tmpErr = do_make_standalone(&srcname[0], &dstname[0], 64);
532
                        if (tmpErr != noErr)
533
                                outErr = tmpErr;
534
                        else
535
                                showmessage(_strdup("64 bit standalone filter was successfully created"));
536
                }
537
        }
538
#endif
539
 
540
        return outErr;
258 daniel-mar 541
}