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