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