comparison loader/pe_resource.c @ 1:3b5f5d1c5041

Initial revision
author arpi_esp
date Sat, 24 Feb 2001 20:28:24 +0000
parents
children d8c1b0b38edc
comparison
equal deleted inserted replaced
0:c1bb2c071d63 1:3b5f5d1c5041
1 /*
2 * PE (Portable Execute) File Resources
3 *
4 * Copyright 1995 Thomas Sandford
5 * Copyright 1996 Martin von Loewis
6 *
7 * Based on the Win16 resource handling code in loader/resource.c
8 * Copyright 1993 Robert J. Amstadt
9 * Copyright 1995 Alexandre Julliard
10 * Copyright 1997 Marcus Meissner
11 */
12 #include <config.h>
13
14 #include <stdlib.h>
15 #include <sys/types.h>
16 #include <wine/winestring.h>
17 #include <wine/windef.h>
18 #include <wine/pe_image.h>
19 #include <wine/module.h>
20 #include <wine/heap.h>
21 //#include "task.h"
22 //#include "process.h"
23 //#include "stackframe.h"
24 #include <wine/debugtools.h>
25
26 /**********************************************************************
27 * HMODULE32toPE_MODREF
28 *
29 * small helper function to get a PE_MODREF from a passed HMODULE32
30 */
31 static PE_MODREF*
32 HMODULE32toPE_MODREF(HMODULE hmod) {
33 WINE_MODREF *wm;
34
35 wm = MODULE32_LookupHMODULE( hmod );
36 if (!wm || wm->type!=MODULE32_PE)
37 return NULL;
38 return &(wm->binfmt.pe);
39 }
40
41 /**********************************************************************
42 * GetResDirEntryW
43 *
44 * Helper function - goes down one level of PE resource tree
45 *
46 */
47 PIMAGE_RESOURCE_DIRECTORY GetResDirEntryW(PIMAGE_RESOURCE_DIRECTORY resdirptr,
48 LPCWSTR name,DWORD root,
49 WIN_BOOL allowdefault)
50 {
51 int entrynum;
52 PIMAGE_RESOURCE_DIRECTORY_ENTRY entryTable;
53 int namelen;
54
55 if (HIWORD(name)) {
56 if (name[0]=='#') {
57 char buf[10];
58
59 lstrcpynWtoA(buf,name+1,10);
60 return GetResDirEntryW(resdirptr,(LPCWSTR)atoi(buf),root,allowdefault);
61 }
62 entryTable = (PIMAGE_RESOURCE_DIRECTORY_ENTRY) (
63 (BYTE *) resdirptr +
64 sizeof(IMAGE_RESOURCE_DIRECTORY));
65 namelen = lstrlenW(name);
66 for (entrynum = 0; entrynum < resdirptr->NumberOfNamedEntries; entrynum++)
67 {
68 PIMAGE_RESOURCE_DIR_STRING_U str =
69 (PIMAGE_RESOURCE_DIR_STRING_U) (root +
70 entryTable[entrynum].u1.s.NameOffset);
71 if(namelen != str->Length)
72 continue;
73 if(wcsnicmp(name,str->NameString,str->Length)==0)
74 return (PIMAGE_RESOURCE_DIRECTORY) (
75 root +
76 entryTable[entrynum].u2.s.OffsetToDirectory);
77 }
78 return NULL;
79 } else {
80 entryTable = (PIMAGE_RESOURCE_DIRECTORY_ENTRY) (
81 (BYTE *) resdirptr +
82 sizeof(IMAGE_RESOURCE_DIRECTORY) +
83 resdirptr->NumberOfNamedEntries * sizeof(IMAGE_RESOURCE_DIRECTORY_ENTRY));
84 for (entrynum = 0; entrynum < resdirptr->NumberOfIdEntries; entrynum++)
85 if ((DWORD)entryTable[entrynum].u1.Name == (DWORD)name)
86 return (PIMAGE_RESOURCE_DIRECTORY) (
87 root +
88 entryTable[entrynum].u2.s.OffsetToDirectory);
89 /* just use first entry if no default can be found */
90 if (allowdefault && !name && resdirptr->NumberOfIdEntries)
91 return (PIMAGE_RESOURCE_DIRECTORY) (
92 root +
93 entryTable[0].u2.s.OffsetToDirectory);
94 return NULL;
95 }
96 }
97
98 /**********************************************************************
99 * GetResDirEntryA
100 */
101 PIMAGE_RESOURCE_DIRECTORY GetResDirEntryA( PIMAGE_RESOURCE_DIRECTORY resdirptr,
102 LPCSTR name, DWORD root,
103 WIN_BOOL allowdefault )
104 {
105 PIMAGE_RESOURCE_DIRECTORY retv;
106 LPWSTR nameW = HIWORD(name)? HEAP_strdupAtoW( GetProcessHeap(), 0, name )
107 : (LPWSTR)name;
108
109 retv = GetResDirEntryW( resdirptr, nameW, root, allowdefault );
110
111 if ( HIWORD(name) ) HeapFree( GetProcessHeap(), 0, nameW );
112
113 return retv;
114 }
115
116 /**********************************************************************
117 * PE_FindResourceEx32W
118 */
119 HANDLE PE_FindResourceExW(
120 WINE_MODREF *wm,LPCWSTR name,LPCWSTR type,WORD lang
121 ) {
122 PIMAGE_RESOURCE_DIRECTORY resdirptr;
123 DWORD root;
124 HANDLE result;
125 PE_MODREF *pem = &(wm->binfmt.pe);
126
127 if (!pem || !pem->pe_resource)
128 return 0;
129
130 resdirptr = pem->pe_resource;
131 root = (DWORD) resdirptr;
132 if ((resdirptr = GetResDirEntryW(resdirptr, type, root, FALSE)) == NULL)
133 return 0;
134 if ((resdirptr = GetResDirEntryW(resdirptr, name, root, FALSE)) == NULL)
135 return 0;
136 result = (HANDLE)GetResDirEntryW(resdirptr, (LPCWSTR)(UINT)lang, root, FALSE);
137 /* Try LANG_NEUTRAL, too */
138 if(!result)
139 return (HANDLE)GetResDirEntryW(resdirptr, (LPCWSTR)0, root, TRUE);
140 return result;
141 }
142
143
144 /**********************************************************************
145 * PE_LoadResource32
146 */
147 HANDLE PE_LoadResource( WINE_MODREF *wm, HANDLE hRsrc )
148 {
149 if (!hRsrc || !wm || wm->type!=MODULE32_PE)
150 return 0;
151 return (HANDLE) (wm->module + ((PIMAGE_RESOURCE_DATA_ENTRY)hRsrc)->OffsetToData);
152 }
153
154
155 /**********************************************************************
156 * PE_SizeofResource32
157 */
158 DWORD PE_SizeofResource( HINSTANCE hModule, HANDLE hRsrc )
159 {
160 /* we don't need hModule */
161 if (!hRsrc)
162 return 0;
163 return ((PIMAGE_RESOURCE_DATA_ENTRY)hRsrc)->Size;
164 }
165
166 /**********************************************************************
167 * PE_EnumResourceTypes32A
168 */
169 WIN_BOOL
170 PE_EnumResourceTypesA(HMODULE hmod,ENUMRESTYPEPROCA lpfun,LONG lparam) {
171 PE_MODREF *pem = HMODULE32toPE_MODREF(hmod);
172 int i;
173 PIMAGE_RESOURCE_DIRECTORY resdir;
174 PIMAGE_RESOURCE_DIRECTORY_ENTRY et;
175 WIN_BOOL ret;
176 HANDLE heap = GetProcessHeap();
177
178 if (!pem || !pem->pe_resource)
179 return FALSE;
180
181 resdir = (PIMAGE_RESOURCE_DIRECTORY)pem->pe_resource;
182 et =(PIMAGE_RESOURCE_DIRECTORY_ENTRY)((LPBYTE)resdir+sizeof(IMAGE_RESOURCE_DIRECTORY));
183 ret = FALSE;
184 for (i=0;i<resdir->NumberOfNamedEntries+resdir->NumberOfIdEntries;i++) {
185 LPSTR name;
186
187 if (et[i].u1.s.NameIsString)
188 name = HEAP_strdupWtoA(heap,0,(LPWSTR)((LPBYTE)pem->pe_resource+et[i].u1.s.NameOffset));
189 else
190 name = (LPSTR)(int)et[i].u1.Id;
191 ret = lpfun(hmod,name,lparam);
192 if (HIWORD(name))
193 HeapFree(heap,0,name);
194 if (!ret)
195 break;
196 }
197 return ret;
198 }
199
200 /**********************************************************************
201 * PE_EnumResourceTypes32W
202 */
203 WIN_BOOL
204 PE_EnumResourceTypesW(HMODULE hmod,ENUMRESTYPEPROCW lpfun,LONG lparam) {
205 PE_MODREF *pem = HMODULE32toPE_MODREF(hmod);
206 int i;
207 PIMAGE_RESOURCE_DIRECTORY resdir;
208 PIMAGE_RESOURCE_DIRECTORY_ENTRY et;
209 WIN_BOOL ret;
210
211 if (!pem || !pem->pe_resource)
212 return FALSE;
213
214 resdir = (PIMAGE_RESOURCE_DIRECTORY)pem->pe_resource;
215 et =(PIMAGE_RESOURCE_DIRECTORY_ENTRY)((LPBYTE)resdir+sizeof(IMAGE_RESOURCE_DIRECTORY));
216 ret = FALSE;
217 for (i=0;i<resdir->NumberOfNamedEntries+resdir->NumberOfIdEntries;i++) {
218 LPWSTR type;
219 if (et[i].u1.s.NameIsString)
220 type = (LPWSTR)((LPBYTE)pem->pe_resource+et[i].u1.s.NameOffset);
221 else
222 type = (LPWSTR)(int)et[i].u1.Id;
223
224 ret = lpfun(hmod,type,lparam);
225 if (!ret)
226 break;
227 }
228 return ret;
229 }
230
231 /**********************************************************************
232 * PE_EnumResourceNames32A
233 */
234 WIN_BOOL
235 PE_EnumResourceNamesA(
236 HMODULE hmod,LPCSTR type,ENUMRESNAMEPROCA lpfun,LONG lparam
237 ) {
238 PE_MODREF *pem = HMODULE32toPE_MODREF(hmod);
239 int i;
240 PIMAGE_RESOURCE_DIRECTORY resdir;
241 PIMAGE_RESOURCE_DIRECTORY_ENTRY et;
242 WIN_BOOL ret;
243 HANDLE heap = GetProcessHeap();
244 LPWSTR typeW;
245
246 if (!pem || !pem->pe_resource)
247 return FALSE;
248 resdir = (PIMAGE_RESOURCE_DIRECTORY)pem->pe_resource;
249 if (HIWORD(type))
250 typeW = HEAP_strdupAtoW(heap,0,type);
251 else
252 typeW = (LPWSTR)type;
253 resdir = GetResDirEntryW(resdir,typeW,(DWORD)pem->pe_resource,FALSE);
254 if (HIWORD(typeW))
255 HeapFree(heap,0,typeW);
256 if (!resdir)
257 return FALSE;
258 et =(PIMAGE_RESOURCE_DIRECTORY_ENTRY)((LPBYTE)resdir+sizeof(IMAGE_RESOURCE_DIRECTORY));
259 ret = FALSE;
260 for (i=0;i<resdir->NumberOfNamedEntries+resdir->NumberOfIdEntries;i++) {
261 LPSTR name;
262
263 if (et[i].u1.s.NameIsString)
264 name = HEAP_strdupWtoA(heap,0,(LPWSTR)((LPBYTE)pem->pe_resource+et[i].u1.s.NameOffset));
265 else
266 name = (LPSTR)(int)et[i].u1.Id;
267 ret = lpfun(hmod,type,name,lparam);
268 if (HIWORD(name)) HeapFree(heap,0,name);
269 if (!ret)
270 break;
271 }
272 return ret;
273 }
274
275 /**********************************************************************
276 * PE_EnumResourceNames32W
277 */
278 WIN_BOOL
279 PE_EnumResourceNamesW(
280 HMODULE hmod,LPCWSTR type,ENUMRESNAMEPROCW lpfun,LONG lparam
281 ) {
282 PE_MODREF *pem = HMODULE32toPE_MODREF(hmod);
283 int i;
284 PIMAGE_RESOURCE_DIRECTORY resdir;
285 PIMAGE_RESOURCE_DIRECTORY_ENTRY et;
286 WIN_BOOL ret;
287
288 if (!pem || !pem->pe_resource)
289 return FALSE;
290
291 resdir = (PIMAGE_RESOURCE_DIRECTORY)pem->pe_resource;
292 resdir = GetResDirEntryW(resdir,type,(DWORD)pem->pe_resource,FALSE);
293 if (!resdir)
294 return FALSE;
295 et =(PIMAGE_RESOURCE_DIRECTORY_ENTRY)((LPBYTE)resdir+sizeof(IMAGE_RESOURCE_DIRECTORY));
296 ret = FALSE;
297 for (i=0;i<resdir->NumberOfNamedEntries+resdir->NumberOfIdEntries;i++) {
298 LPWSTR name;
299 if (et[i].u1.s.NameIsString)
300 name = (LPWSTR)((LPBYTE)pem->pe_resource+et[i].u1.s.NameOffset);
301 else
302 name = (LPWSTR)(int)et[i].u1.Id;
303 ret = lpfun(hmod,type,name,lparam);
304 if (!ret)
305 break;
306 }
307 return ret;
308 }
309
310 /**********************************************************************
311 * PE_EnumResourceNames32A
312 */
313 WIN_BOOL
314 PE_EnumResourceLanguagesA(
315 HMODULE hmod,LPCSTR name,LPCSTR type,ENUMRESLANGPROCA lpfun,
316 LONG lparam
317 ) {
318 PE_MODREF *pem = HMODULE32toPE_MODREF(hmod);
319 int i;
320 PIMAGE_RESOURCE_DIRECTORY resdir;
321 PIMAGE_RESOURCE_DIRECTORY_ENTRY et;
322 WIN_BOOL ret;
323 HANDLE heap = GetProcessHeap();
324 LPWSTR nameW,typeW;
325
326 if (!pem || !pem->pe_resource)
327 return FALSE;
328
329 resdir = (PIMAGE_RESOURCE_DIRECTORY)pem->pe_resource;
330 if (HIWORD(name))
331 nameW = HEAP_strdupAtoW(heap,0,name);
332 else
333 nameW = (LPWSTR)name;
334 resdir = GetResDirEntryW(resdir,nameW,(DWORD)pem->pe_resource,FALSE);
335 if (HIWORD(nameW))
336 HeapFree(heap,0,nameW);
337 if (!resdir)
338 return FALSE;
339 if (HIWORD(type))
340 typeW = HEAP_strdupAtoW(heap,0,type);
341 else
342 typeW = (LPWSTR)type;
343 resdir = GetResDirEntryW(resdir,typeW,(DWORD)pem->pe_resource,FALSE);
344 if (HIWORD(typeW))
345 HeapFree(heap,0,typeW);
346 if (!resdir)
347 return FALSE;
348 et =(PIMAGE_RESOURCE_DIRECTORY_ENTRY)((LPBYTE)resdir+sizeof(IMAGE_RESOURCE_DIRECTORY));
349 ret = FALSE;
350 for (i=0;i<resdir->NumberOfNamedEntries+resdir->NumberOfIdEntries;i++) {
351 /* languages are just ids... I hopem */
352 ret = lpfun(hmod,name,type,et[i].u1.Id,lparam);
353 if (!ret)
354 break;
355 }
356 return ret;
357 }
358
359 /**********************************************************************
360 * PE_EnumResourceLanguages32W
361 */
362 WIN_BOOL
363 PE_EnumResourceLanguagesW(
364 HMODULE hmod,LPCWSTR name,LPCWSTR type,ENUMRESLANGPROCW lpfun,
365 LONG lparam
366 ) {
367 PE_MODREF *pem = HMODULE32toPE_MODREF(hmod);
368 int i;
369 PIMAGE_RESOURCE_DIRECTORY resdir;
370 PIMAGE_RESOURCE_DIRECTORY_ENTRY et;
371 WIN_BOOL ret;
372
373 if (!pem || !pem->pe_resource)
374 return FALSE;
375
376 resdir = (PIMAGE_RESOURCE_DIRECTORY)pem->pe_resource;
377 resdir = GetResDirEntryW(resdir,name,(DWORD)pem->pe_resource,FALSE);
378 if (!resdir)
379 return FALSE;
380 resdir = GetResDirEntryW(resdir,type,(DWORD)pem->pe_resource,FALSE);
381 if (!resdir)
382 return FALSE;
383 et =(PIMAGE_RESOURCE_DIRECTORY_ENTRY)((LPBYTE)resdir+sizeof(IMAGE_RESOURCE_DIRECTORY));
384 ret = FALSE;
385 for (i=0;i<resdir->NumberOfNamedEntries+resdir->NumberOfIdEntries;i++) {
386 ret = lpfun(hmod,name,type,et[i].u1.Id,lparam);
387 if (!ret)
388 break;
389 }
390 return ret;
391 }