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