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
14 #include <sys/types.h>
15 #include "wine/winestring.h"
23 #include "stackframe.h"
27 /**********************************************************************
28 * HMODULE32toPE_MODREF
30 * small helper function to get a PE_MODREF from a passed HMODULE32
33 HMODULE32toPE_MODREF(HMODULE hmod) {
36 wm = MODULE32_LookupHMODULE( hmod );
37 if (!wm || wm->type!=MODULE32_PE)
39 return &(wm->binfmt.pe);
42 /**********************************************************************
45 * Helper function - goes down one level of PE resource tree
48 PIMAGE_RESOURCE_DIRECTORY GetResDirEntryW(PIMAGE_RESOURCE_DIRECTORY resdirptr,
49 LPCWSTR name,DWORD root,
53 PIMAGE_RESOURCE_DIRECTORY_ENTRY entryTable;
60 lstrcpynWtoA(buf,name+1,10);
61 return GetResDirEntryW(resdirptr,(LPCWSTR)atoi(buf),root,allowdefault);
63 entryTable = (PIMAGE_RESOURCE_DIRECTORY_ENTRY) (
65 sizeof(IMAGE_RESOURCE_DIRECTORY));
66 namelen = lstrlenW(name);
67 for (entrynum = 0; entrynum < resdirptr->NumberOfNamedEntries; entrynum++)
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)
74 if(lstrncmpiW(name,str->NameString,str->Length)==0)
75 return (PIMAGE_RESOURCE_DIRECTORY) (
77 entryTable[entrynum].u2.s.OffsetToDirectory);
81 entryTable = (PIMAGE_RESOURCE_DIRECTORY_ENTRY) (
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) (
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) (
94 entryTable[0].u2.s.OffsetToDirectory);
99 /**********************************************************************
102 PIMAGE_RESOURCE_DIRECTORY GetResDirEntryA( PIMAGE_RESOURCE_DIRECTORY resdirptr,
103 LPCSTR name, DWORD root,
106 PIMAGE_RESOURCE_DIRECTORY retv;
107 LPWSTR nameW = HIWORD(name)? HEAP_strdupAtoW( GetProcessHeap(), 0, name )
110 retv = GetResDirEntryW( resdirptr, nameW, root, allowdefault );
112 if ( HIWORD(name) ) HeapFree( GetProcessHeap(), 0, nameW );
117 /**********************************************************************
118 * PE_FindResourceEx32W
120 HANDLE PE_FindResourceExW(
121 WINE_MODREF *wm,LPCWSTR name,LPCWSTR type,WORD lang
123 PIMAGE_RESOURCE_DIRECTORY resdirptr;
126 PE_MODREF *pem = &(wm->binfmt.pe);
128 if (!pem || !pem->pe_resource)
131 resdirptr = pem->pe_resource;
132 root = (DWORD) resdirptr;
133 if ((resdirptr = GetResDirEntryW(resdirptr, type, root, FALSE)) == NULL)
135 if ((resdirptr = GetResDirEntryW(resdirptr, name, root, FALSE)) == NULL)
137 result = (HANDLE)GetResDirEntryW(resdirptr, (LPCWSTR)(UINT)lang, root, FALSE);
138 /* Try LANG_NEUTRAL, too */
140 return (HANDLE)GetResDirEntryW(resdirptr, (LPCWSTR)0, root, TRUE);
145 /**********************************************************************
148 HANDLE PE_LoadResource( WINE_MODREF *wm, HANDLE hRsrc )
150 if (!hRsrc || !wm || wm->type!=MODULE32_PE)
152 return (HANDLE) (wm->module + ((PIMAGE_RESOURCE_DATA_ENTRY)hRsrc)->OffsetToData);
156 /**********************************************************************
157 * PE_SizeofResource32
159 DWORD PE_SizeofResource( HINSTANCE hModule, HANDLE hRsrc )
161 /* we don't need hModule */
164 return ((PIMAGE_RESOURCE_DATA_ENTRY)hRsrc)->Size;
167 /**********************************************************************
168 * PE_EnumResourceTypes32A
171 PE_EnumResourceTypesA(HMODULE hmod,ENUMRESTYPEPROCA lpfun,LONG lparam) {
172 PE_MODREF *pem = HMODULE32toPE_MODREF(hmod);
174 PIMAGE_RESOURCE_DIRECTORY resdir;
175 PIMAGE_RESOURCE_DIRECTORY_ENTRY et;
177 HANDLE heap = GetProcessHeap();
179 if (!pem || !pem->pe_resource)
182 resdir = (PIMAGE_RESOURCE_DIRECTORY)pem->pe_resource;
183 et =(PIMAGE_RESOURCE_DIRECTORY_ENTRY)((LPBYTE)resdir+sizeof(IMAGE_RESOURCE_DIRECTORY));
185 for (i=0;i<resdir->NumberOfNamedEntries+resdir->NumberOfIdEntries;i++) {
188 if (HIWORD(et[i].u1.Name))
189 name = HEAP_strdupWtoA(heap,0,(LPWSTR)((LPBYTE)pem->pe_resource+et[i].u1.Name));
191 name = (LPSTR)et[i].u1.Name;
192 ret = lpfun(hmod,name,lparam);
194 HeapFree(heap,0,name);
201 /**********************************************************************
202 * PE_EnumResourceTypes32W
205 PE_EnumResourceTypesW(HMODULE hmod,ENUMRESTYPEPROCW lpfun,LONG lparam) {
206 PE_MODREF *pem = HMODULE32toPE_MODREF(hmod);
208 PIMAGE_RESOURCE_DIRECTORY resdir;
209 PIMAGE_RESOURCE_DIRECTORY_ENTRY et;
212 if (!pem || !pem->pe_resource)
215 resdir = (PIMAGE_RESOURCE_DIRECTORY)pem->pe_resource;
216 et =(PIMAGE_RESOURCE_DIRECTORY_ENTRY)((LPBYTE)resdir+sizeof(IMAGE_RESOURCE_DIRECTORY));
218 for (i=0;i<resdir->NumberOfNamedEntries+resdir->NumberOfIdEntries;i++) {
220 if (HIWORD(et[i].u1.Name))
221 type = (LPWSTR)((LPBYTE)pem->pe_resource+et[i].u1.Name);
223 type = (LPWSTR)et[i].u1.Name;
225 ret = lpfun(hmod,type,lparam);
232 /**********************************************************************
233 * PE_EnumResourceNames32A
236 PE_EnumResourceNamesA(
237 HMODULE hmod,LPCSTR type,ENUMRESNAMEPROCA lpfun,LONG lparam
239 PE_MODREF *pem = HMODULE32toPE_MODREF(hmod);
241 PIMAGE_RESOURCE_DIRECTORY resdir;
242 PIMAGE_RESOURCE_DIRECTORY_ENTRY et;
244 HANDLE heap = GetProcessHeap();
247 if (!pem || !pem->pe_resource)
249 resdir = (PIMAGE_RESOURCE_DIRECTORY)pem->pe_resource;
251 typeW = HEAP_strdupAtoW(heap,0,type);
253 typeW = (LPWSTR)type;
254 resdir = GetResDirEntryW(resdir,typeW,(DWORD)pem->pe_resource,FALSE);
256 HeapFree(heap,0,typeW);
259 et =(PIMAGE_RESOURCE_DIRECTORY_ENTRY)((LPBYTE)resdir+sizeof(IMAGE_RESOURCE_DIRECTORY));
261 for (i=0;i<resdir->NumberOfNamedEntries+resdir->NumberOfIdEntries;i++) {
264 if (HIWORD(et[i].u1.Name))
265 name = HEAP_strdupWtoA(heap,0,(LPWSTR)((LPBYTE)pem->pe_resource+et[i].u1.Name));
267 name = (LPSTR)et[i].u1.Name;
268 ret = lpfun(hmod,type,name,lparam);
269 if (HIWORD(name)) HeapFree(heap,0,name);
276 /**********************************************************************
277 * PE_EnumResourceNames32W
280 PE_EnumResourceNamesW(
281 HMODULE hmod,LPCWSTR type,ENUMRESNAMEPROCW lpfun,LONG lparam
283 PE_MODREF *pem = HMODULE32toPE_MODREF(hmod);
285 PIMAGE_RESOURCE_DIRECTORY resdir;
286 PIMAGE_RESOURCE_DIRECTORY_ENTRY et;
289 if (!pem || !pem->pe_resource)
292 resdir = (PIMAGE_RESOURCE_DIRECTORY)pem->pe_resource;
293 resdir = GetResDirEntryW(resdir,type,(DWORD)pem->pe_resource,FALSE);
296 et =(PIMAGE_RESOURCE_DIRECTORY_ENTRY)((LPBYTE)resdir+sizeof(IMAGE_RESOURCE_DIRECTORY));
298 for (i=0;i<resdir->NumberOfNamedEntries+resdir->NumberOfIdEntries;i++) {
300 if (HIWORD(et[i].u1.Name))
301 name = (LPWSTR)((LPBYTE)pem->pe_resource+et[i].u1.Name);
303 name = (LPWSTR)et[i].u1.Name;
304 ret = lpfun(hmod,type,name,lparam);
311 /**********************************************************************
312 * PE_EnumResourceNames32A
315 PE_EnumResourceLanguagesA(
316 HMODULE hmod,LPCSTR name,LPCSTR type,ENUMRESLANGPROCA lpfun,
319 PE_MODREF *pem = HMODULE32toPE_MODREF(hmod);
321 PIMAGE_RESOURCE_DIRECTORY resdir;
322 PIMAGE_RESOURCE_DIRECTORY_ENTRY et;
324 HANDLE heap = GetProcessHeap();
327 if (!pem || !pem->pe_resource)
330 resdir = (PIMAGE_RESOURCE_DIRECTORY)pem->pe_resource;
332 nameW = HEAP_strdupAtoW(heap,0,name);
334 nameW = (LPWSTR)name;
335 resdir = GetResDirEntryW(resdir,nameW,(DWORD)pem->pe_resource,FALSE);
337 HeapFree(heap,0,nameW);
341 typeW = HEAP_strdupAtoW(heap,0,type);
343 typeW = (LPWSTR)type;
344 resdir = GetResDirEntryW(resdir,typeW,(DWORD)pem->pe_resource,FALSE);
346 HeapFree(heap,0,typeW);
349 et =(PIMAGE_RESOURCE_DIRECTORY_ENTRY)((LPBYTE)resdir+sizeof(IMAGE_RESOURCE_DIRECTORY));
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);
360 /**********************************************************************
361 * PE_EnumResourceLanguages32W
364 PE_EnumResourceLanguagesW(
365 HMODULE hmod,LPCWSTR name,LPCWSTR type,ENUMRESLANGPROCW lpfun,
368 PE_MODREF *pem = HMODULE32toPE_MODREF(hmod);
370 PIMAGE_RESOURCE_DIRECTORY resdir;
371 PIMAGE_RESOURCE_DIRECTORY_ENTRY et;
374 if (!pem || !pem->pe_resource)
377 resdir = (PIMAGE_RESOURCE_DIRECTORY)pem->pe_resource;
378 resdir = GetResDirEntryW(resdir,name,(DWORD)pem->pe_resource,FALSE);
381 resdir = GetResDirEntryW(resdir,type,(DWORD)pem->pe_resource,FALSE);
384 et =(PIMAGE_RESOURCE_DIRECTORY_ENTRY)((LPBYTE)resdir+sizeof(IMAGE_RESOURCE_DIRECTORY));
386 for (i=0;i<resdir->NumberOfNamedEntries+resdir->NumberOfIdEntries;i++) {
387 ret = lpfun(hmod,name,type,et[i].u1.Id,lparam);