Subversion Repositories filter_foundry

Rev

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

Rev 436 Rev 440
1
/*
1
/*
2
        This file is part of "Filter Foundry", a filter plugin for Adobe Photoshop
2
        This file is part of "Filter Foundry", a filter plugin for Adobe Photoshop
3
        Copyright (C) 2003-2009 Toby Thain, toby@telegraphics.com.au
3
        Copyright (C) 2003-2009 Toby Thain, toby@telegraphics.com.au
4
        Copyright (C) 2018-2021 Daniel Marschall, ViaThinkSoft
4
        Copyright (C) 2018-2021 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 "file_compat.h"
23
#include "file_compat.h"
24
 
24
 
25
#include <string.h>
25
#include <string.h>
26
 
26
 
27
static BOOL CALLBACK enum_find_resname(HMODULE hModule, LPCTSTR lpszType,
27
static BOOL CALLBACK enum_find_resname(HMODULE hModule, LPCTSTR lpszType,
28
        LPTSTR lpszName, LONG_PTR lParam)
28
        LPTSTR lpszName, LONG_PTR lParam)
29
{
29
{
30
        UNREFERENCED_PARAMETER(hModule);
30
        UNREFERENCED_PARAMETER(hModule);
31
        UNREFERENCED_PARAMETER(lpszType);
31
        UNREFERENCED_PARAMETER(lpszType);
32
 
32
 
33
        if (IS_INTRESOURCE(lpszName)) {
33
        if (IS_INTRESOURCE(lpszName)) {
34
                UINT16* pparm_id = (UINT16*)lParam;
34
                UINT16* pparm_id = (UINT16*)lParam;
35
                *pparm_id = (UINT16)((intptr_t)lpszName & 0xFFFF);
35
                *pparm_id = (UINT16)((intptr_t)lpszName & 0xFFFF);
36
                return false; // we only want the first one
36
                return false; // we only want the first one
37
        }
37
        }
38
        else return true;
38
        else return true;
39
}
39
}
40
 
40
 
41
Boolean readPARMresource(HMODULE hm, char** reason, int readobfusc) {
41
Boolean readPARMresource(HMODULE hm, char** reason) {
42
        HRSRC resinfo;
42
        HRSRC resinfo;
43
        HANDLE h;
43
        HANDLE h;
44
        Ptr pparm;
44
        Ptr pparm;
45
 
45
 
46
        UINT16 parm_id = 1;
46
        UINT16 parm_id = 1;
47
        EnumResourceNames(hm, PARM_TYPE, enum_find_resname, (LONG_PTR)&parm_id); // callback function enum_find_resname() will find the actual found parm_id
47
        EnumResourceNames(hm, PARM_TYPE, enum_find_resname, (LONG_PTR)&parm_id); // callback function enum_find_resname() will find the actual found parm_id
48
 
48
 
49
        // load first PARM resource
49
        // load first PARM resource
50
        if ((resinfo = FindResource(hm, MAKEINTRESOURCE(parm_id), PARM_TYPE))) {
50
        if ((resinfo = FindResource(hm, MAKEINTRESOURCE(parm_id), PARM_TYPE))) {
51
                if ((h = LoadResource(hm, resinfo)) && (pparm = (Ptr)LockResource(h))) {
51
                if ((h = LoadResource(hm, resinfo)) && (pparm = (Ptr)LockResource(h))) {
52
                        int res = readPARM(&gdata->parm, pparm);
52
                        int res = readPARM(&gdata->parm, pparm);
53
                        gdata->obfusc = false;
53
                        gdata->obfusc = false;
54
                        return res;
54
                        return res;
55
                }
55
                }
56
        }
56
        }
57
        else if (readobfusc &&
57
        else if (
58
                ((resinfo = FindResource(hm, OBFUSCDATA_ID_NEW, OBFUSCDATA_TYPE_NEW)) ||
58
                ((resinfo = FindResource(hm, OBFUSCDATA_ID_NEW, OBFUSCDATA_TYPE_NEW)) ||
59
                        (resinfo = FindResource(hm, OBFUSCDATA_ID_OLD, OBFUSCDATA_TYPE_OLD)))) {
59
                        (resinfo = FindResource(hm, OBFUSCDATA_ID_OLD, OBFUSCDATA_TYPE_OLD)))) {
60
                if ((h = LoadResource(hm, resinfo)) && (pparm = (Ptr)LockResource(h))) {
60
                if ((h = LoadResource(hm, resinfo)) && (pparm = (Ptr)LockResource(h))) {
61
                        // Fix by DM, 18 Dec 2018:
61
                        // Fix by DM, 18 Dec 2018:
62
                        // We need to copy the information, because the resource data is read-only
62
                        // We need to copy the information, because the resource data is read-only
63
                        DWORD resSize = SizeofResource(hm, resinfo);
63
                        DWORD resSize = SizeofResource(hm, resinfo);
64
                        if (resSize == sizeof(PARM_T)) {
64
                        if (resSize == sizeof(PARM_T)) {
65
                                int res;
65
                                int res;
66
                                PARM_T* copy = (PARM_T*)malloc(resSize);
66
                                PARM_T* copy = (PARM_T*)malloc(resSize);
67
                                if (!copy) return false;
67
                                if (!copy) return false;
68
                                memcpy(copy, pparm, resSize);
68
                                memcpy(copy, pparm, resSize);
69
                                deobfusc(copy);
69
                                deobfusc(copy);
70
                                res = readPARM(&gdata->parm, (Ptr)copy);
70
                                res = readPARM(&gdata->parm, (Ptr)copy);
71
                                if (!res) {
71
                                if (!res) {
72
                                        *reason = _strdup("Incompatible obfuscation.");
72
                                        *reason = _strdup("Incompatible obfuscation.");
73
                                }
73
                                }
74
                                free(copy);
74
                                free(copy);
75
                                gdata->obfusc = true;
75
                                gdata->obfusc = true;
76
                                return res;
76
                                return res;
77
                        }
77
                        }
78
                        else {
78
                        else {
79
                                // Obfuscationed PARM has wrong size. It is probably a file with different RCDATA
79
                                // Obfuscationed PARM has wrong size. It is probably a file with different RCDATA
80
                                gdata->obfusc = false;
80
                                gdata->obfusc = false;
81
                                return false;
81
                                return false;
82
                        }
82
                        }
83
                }
83
                }
84
        }
84
        }
85
        return false;
85
        return false;
86
}
86
}
87
 
87
 
88
Boolean loadfile(StandardFileReply* sfr, char** reason) {
88
Boolean loadfile(StandardFileReply* sfr, char** reason) {
89
        HMODULE hm;
89
        HMODULE hm;
90
 
90
 
91
        // The different read-functions will return true if the resource was successfully loaded,
91
        // The different read-functions will return true if the resource was successfully loaded,
92
        // or false otherwise. If *reason is set, then the answer is clearly "No". If the result
92
        // or false otherwise. If *reason is set, then the answer is clearly "No". If the result
93
        // is just false, it means that the program should continue with the next read-function.
93
        // is just false, it means that the program should continue with the next read-function.
94
        *reason = NULL;
94
        *reason = NULL;
95
 
95
 
96
        // First, try to read the file as AFS/PFF/TXT file
96
        // First, try to read the file as AFS/PFF/TXT file
97
        if (*reason == NULL) {
97
        if (*reason == NULL) {
98
                if (readfile_afs_pff(sfr, reason)) {
98
                if (readfile_afs_pff(sfr, reason)) {
99
                        gdata->obfusc = false;
99
                        gdata->obfusc = false;
100
                        gdata->parmloaded = false;
100
                        gdata->parmloaded = false;
101
                        return true;
101
                        return true;
102
                }
102
                }
103
        }
103
        }
104
 
104
 
105
        // If that didn't work, try to load as Windows image file (Resource API for 8BF/PRM files)
105
        // If that didn't work, try to load as Windows image file (Resource API for 8BF/PRM files)
106
        if (*reason == NULL) {
106
        if (*reason == NULL) {
107
                char name[MAX_PATH + 1];
107
                char name[MAX_PATH + 1];
108
                if (hm = LoadLibraryEx(myp2cstrcpy(name, sfr->sfFile.name), NULL, LOAD_LIBRARY_AS_DATAFILE)) {
108
                if (hm = LoadLibraryEx(myp2cstrcpy(name, sfr->sfFile.name), NULL, LOAD_LIBRARY_AS_DATAFILE)) {
109
                        if (readPARMresource(hm, reason, READ_OBFUSC)) {
109
                        if (readPARMresource(hm, reason)) {
110
                                if (gdata->parm.iProtected) {
110
                                if (gdata->parm.iProtected) {
111
                                        *reason = _strdup("The filter is protected.");
111
                                        *reason = _strdup("The filter is protected.");
112
                                        //gdata->parmloaded = false;
112
                                        //gdata->parmloaded = false;
113
                                }
113
                                }
114
                                else {
114
                                else {
115
                                        gdata->parmloaded = true;
115
                                        gdata->parmloaded = true;
116
                                        FreeLibrary(hm);
116
                                        FreeLibrary(hm);
117
                                        return true;
117
                                        return true;
118
                                }
118
                                }
119
                        }
119
                        }
120
                        FreeLibrary(hm);
120
                        FreeLibrary(hm);
121
                }
121
                }
122
        }
122
        }
123
 
123
 
124
        // Is it a "Filters Unlimited" filter? (Only partially compatible with Filter Factory!!!)
124
        // Is it a "Filters Unlimited" filter? (Only partially compatible with Filter Factory!!!)
125
        if (*reason == NULL) {
125
        if (*reason == NULL) {
126
                if (readfile_ffx(sfr, reason)) {
126
                if (readfile_ffx(sfr, reason)) {
127
                        gdata->parmloaded = true;
127
                        gdata->parmloaded = true;
128
                        return true;
128
                        return true;
129
                }
129
                }
130
        }
130
        }
131
 
131
 
132
        // Is it a "Filters Unlimited" filter? (Only partially compatible with Filter Factory!!!)
132
        // Is it a "Filters Unlimited" filter? (Only partially compatible with Filter Factory!!!)
133
        if (*reason == NULL) {
133
        if (*reason == NULL) {
134
                if (readfile_picotxt(sfr, reason)) {
134
                if (readfile_picotxt(sfr, reason)) {
135
                        gdata->parmloaded = true;
135
                        gdata->parmloaded = true;
136
                        return true;
136
                        return true;
137
                }
137
                }
138
        }
138
        }
139
 
139
 
140
        // If nothing worked, we will try to find a PARM resource (MacOS plugin, or 64 bit 8BF on Win32 OS)
140
        // If nothing worked, we will try to find a PARM resource (MacOS plugin, or 64 bit 8BF on Win32 OS)
141
        // Note that we cannot detect obfuscated filters here!
141
        // Note that we cannot detect obfuscated filters here!
142
        if (*reason == NULL) {
142
        if (*reason == NULL) {
143
                if (readfile_8bf(sfr, reason)) {
143
                if (readfile_8bf(sfr, reason)) {
144
                        if (gdata->parm.iProtected) {
144
                        if (gdata->parm.iProtected) {
145
                                // This is for purely protected filters before the time when obfuscation and protection was merged
145
                                // This is for purely protected filters before the time when obfuscation and protection was merged
146
                                *reason = _strdup("The filter is protected.");
146
                                *reason = _strdup("The filter is protected.");
147
                        }
147
                        }
148
                        else {
148
                        else {
149
                                gdata->parmloaded = true;
149
                                gdata->parmloaded = true;
150
                                return true;
150
                                return true;
151
                        }
151
                        }
152
                }
152
                }
153
        }
153
        }
154
 
154
 
155
        // We didn't had success. If we have a clear reason, return false and the reason.
155
        // We didn't had success. If we have a clear reason, return false and the reason.
156
        // If we don't have a clear reason, set a generic reason and return false.
156
        // If we don't have a clear reason, set a generic reason and return false.
157
        if (*reason == NULL) {
157
        if (*reason == NULL) {
158
                *reason = _strdup("It is not a text parameter file, nor a standalone Mac/PC filter created by Filter Factory/Filter Foundry.");
158
                *reason = _strdup("It is not a text parameter file, nor a standalone Mac/PC filter created by Filter Factory/Filter Foundry.");
159
        }
159
        }
160
        return false;
160
        return false;
161
}
161
}
162
 
162