DOCS/man/zh_CN: Synced with rev. 32066
[mplayer/glamo.git] / loader / pe_resource.c
blobb818adb2a8492f8dfb167961a1c0a1c0af83a634
1 /*
2 * PE (Portable Execute) File Resources
4 * Copyright 1995 Thomas Sandford
5 * Copyright 1996 Martin von Loewis
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
12 * Modified for use with MPlayer, detailed changelog at
13 * http://svn.mplayerhq.hu/mplayer/trunk/
16 #include "config.h"
18 #include <stdlib.h>
19 #include <sys/types.h>
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"
25 //#include "task.h"
26 //#include "process.h"
27 //#include "stackframe.h"
28 #include "wine/debugtools.h"
29 #include "ext.h"
31 /**********************************************************************
32 * HMODULE32toPE_MODREF
34 * small helper function to get a PE_MODREF from a passed HMODULE32
36 static PE_MODREF*
37 HMODULE32toPE_MODREF(HMODULE hmod) {
38 WINE_MODREF *wm;
40 wm = MODULE32_LookupHMODULE( hmod );
41 if (!wm || wm->type!=MODULE32_PE)
42 return NULL;
43 return &(wm->binfmt.pe);
46 /**********************************************************************
47 * GetResDirEntryW
49 * Helper function - goes down one level of PE resource tree
52 PIMAGE_RESOURCE_DIRECTORY GetResDirEntryW(PIMAGE_RESOURCE_DIRECTORY resdirptr,
53 LPCWSTR name,DWORD root,
54 WIN_BOOL allowdefault)
56 int entrynum;
57 PIMAGE_RESOURCE_DIRECTORY_ENTRY entryTable;
58 int namelen;
60 if (HIWORD(name)) {
61 if (name[0]=='#') {
62 char buf[10];
64 lstrcpynWtoA(buf,name+1,10);
65 return GetResDirEntryW(resdirptr,(LPCWSTR)atoi(buf),root,allowdefault);
67 entryTable = (PIMAGE_RESOURCE_DIRECTORY_ENTRY) (
68 (BYTE *) resdirptr +
69 sizeof(IMAGE_RESOURCE_DIRECTORY));
70 namelen = lstrlenW(name);
71 for (entrynum = 0; entrynum < resdirptr->NumberOfNamedEntries; entrynum++)
73 PIMAGE_RESOURCE_DIR_STRING_U str =
74 (PIMAGE_RESOURCE_DIR_STRING_U) (root +
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);
83 return NULL;
84 } else {
85 entryTable = (PIMAGE_RESOURCE_DIRECTORY_ENTRY) (
86 (BYTE *) resdirptr +
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;
103 /**********************************************************************
104 * GetResDirEntryA
106 PIMAGE_RESOURCE_DIRECTORY GetResDirEntryA( PIMAGE_RESOURCE_DIRECTORY resdirptr,
107 LPCSTR name, DWORD root,
108 WIN_BOOL allowdefault )
110 PIMAGE_RESOURCE_DIRECTORY retv;
111 LPWSTR nameW = HIWORD(name)? HEAP_strdupAtoW( GetProcessHeap(), 0, name )
112 : (LPWSTR)name;
114 retv = GetResDirEntryW( resdirptr, nameW, root, allowdefault );
116 if ( HIWORD(name) ) HeapFree( GetProcessHeap(), 0, nameW );
118 return retv;
121 /**********************************************************************
122 * PE_FindResourceEx32W
124 HANDLE PE_FindResourceExW(
125 WINE_MODREF *wm,LPCWSTR name,LPCWSTR type,WORD lang
127 PIMAGE_RESOURCE_DIRECTORY resdirptr;
128 DWORD root;
129 HANDLE result;
130 PE_MODREF *pem = &(wm->binfmt.pe);
132 if (!pem || !pem->pe_resource)
133 return 0;
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;
149 /**********************************************************************
150 * PE_LoadResource32
152 HANDLE PE_LoadResource( WINE_MODREF *wm, HANDLE hRsrc )
154 if (!hRsrc || !wm || wm->type!=MODULE32_PE)
155 return 0;
156 return (HANDLE) (wm->module + ((PIMAGE_RESOURCE_DATA_ENTRY)hRsrc)->OffsetToData);
160 /**********************************************************************
161 * PE_SizeofResource32
163 DWORD PE_SizeofResource( HINSTANCE hModule, HANDLE hRsrc )
165 /* we don't need hModule */
166 if (!hRsrc)
167 return 0;
168 return ((PIMAGE_RESOURCE_DATA_ENTRY)hRsrc)->Size;
171 /**********************************************************************
172 * PE_EnumResourceTypes32A
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;
181 HANDLE heap = GetProcessHeap();
183 if (!pem || !pem->pe_resource)
184 return FALSE;
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;
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;
202 return ret;
205 /**********************************************************************
206 * PE_EnumResourceTypes32W
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;
216 if (!pem || !pem->pe_resource)
217 return FALSE;
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;
229 ret = lpfun(hmod,type,lparam);
230 if (!ret)
231 break;
233 return ret;
236 /**********************************************************************
237 * PE_EnumResourceNames32A
239 WIN_BOOL
240 PE_EnumResourceNamesA(
241 HMODULE hmod,LPCSTR type,ENUMRESNAMEPROCA lpfun,LONG lparam
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;
248 HANDLE heap = GetProcessHeap();
249 LPWSTR typeW;
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;
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;
277 return ret;
280 /**********************************************************************
281 * PE_EnumResourceNames32W
283 WIN_BOOL
284 PE_EnumResourceNamesW(
285 HMODULE hmod,LPCWSTR type,ENUMRESNAMEPROCW lpfun,LONG lparam
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;
293 if (!pem || !pem->pe_resource)
294 return FALSE;
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;
312 return ret;
315 /**********************************************************************
316 * PE_EnumResourceNames32A
318 WIN_BOOL
319 PE_EnumResourceLanguagesA(
320 HMODULE hmod,LPCSTR name,LPCSTR type,ENUMRESLANGPROCA lpfun,
321 LONG lparam
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;
328 HANDLE heap = GetProcessHeap();
329 LPWSTR nameW,typeW;
331 if (!pem || !pem->pe_resource)
332 return FALSE;
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;
361 return ret;
364 /**********************************************************************
365 * PE_EnumResourceLanguages32W
367 WIN_BOOL
368 PE_EnumResourceLanguagesW(
369 HMODULE hmod,LPCWSTR name,LPCWSTR type,ENUMRESLANGPROCW lpfun,
370 LONG lparam
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;
378 if (!pem || !pem->pe_resource)
379 return FALSE;
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;
395 return ret;