Mercurial > mplayer.hg
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 } |