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"
26 #include "debugtools.h"
28 /**********************************************************************
29 * HMODULE32toPE_MODREF
31 * small helper function to get a PE_MODREF from a passed HMODULE32
34 HMODULE32toPE_MODREF(HMODULE hmod
) {
37 wm
= MODULE32_LookupHMODULE( hmod
);
38 if (!wm
|| wm
->type
!=MODULE32_PE
)
40 return &(wm
->binfmt
.pe
);
43 /**********************************************************************
46 * Helper function - goes down one level of PE resource tree
49 PIMAGE_RESOURCE_DIRECTORY
GetResDirEntryW(PIMAGE_RESOURCE_DIRECTORY resdirptr
,
50 LPCWSTR name
,DWORD root
,
54 PIMAGE_RESOURCE_DIRECTORY_ENTRY entryTable
;
61 lstrcpynWtoA(buf
,name
+1,10);
62 return GetResDirEntryW(resdirptr
,(LPCWSTR
)atoi(buf
),root
,allowdefault
);
64 entryTable
= (PIMAGE_RESOURCE_DIRECTORY_ENTRY
) (
66 sizeof(IMAGE_RESOURCE_DIRECTORY
));
67 namelen
= lstrlenW(name
);
68 for (entrynum
= 0; entrynum
< resdirptr
->NumberOfNamedEntries
; entrynum
++)
70 PIMAGE_RESOURCE_DIR_STRING_U str
=
71 (PIMAGE_RESOURCE_DIR_STRING_U
) (root
+
72 entryTable
[entrynum
].u1
.s
.NameOffset
);
73 if(namelen
!= str
->Length
)
75 if(CRTDLL__wcsnicmp(name
,str
->NameString
,str
->Length
)==0)
76 return (PIMAGE_RESOURCE_DIRECTORY
) (
78 entryTable
[entrynum
].u2
.s
.OffsetToDirectory
);
82 entryTable
= (PIMAGE_RESOURCE_DIRECTORY_ENTRY
) (
84 sizeof(IMAGE_RESOURCE_DIRECTORY
) +
85 resdirptr
->NumberOfNamedEntries
* sizeof(IMAGE_RESOURCE_DIRECTORY_ENTRY
));
86 for (entrynum
= 0; entrynum
< resdirptr
->NumberOfIdEntries
; entrynum
++)
87 if ((DWORD
)entryTable
[entrynum
].u1
.Name
== (DWORD
)name
)
88 return (PIMAGE_RESOURCE_DIRECTORY
) (
90 entryTable
[entrynum
].u2
.s
.OffsetToDirectory
);
91 /* just use first entry if no default can be found */
92 if (allowdefault
&& !name
&& resdirptr
->NumberOfIdEntries
)
93 return (PIMAGE_RESOURCE_DIRECTORY
) (
95 entryTable
[0].u2
.s
.OffsetToDirectory
);
100 /**********************************************************************
103 PIMAGE_RESOURCE_DIRECTORY
GetResDirEntryA( PIMAGE_RESOURCE_DIRECTORY resdirptr
,
104 LPCSTR name
, DWORD root
,
107 PIMAGE_RESOURCE_DIRECTORY retv
;
108 LPWSTR nameW
= HIWORD(name
)? HEAP_strdupAtoW( GetProcessHeap(), 0, name
)
111 retv
= GetResDirEntryW( resdirptr
, nameW
, root
, allowdefault
);
113 if ( HIWORD(name
) ) HeapFree( GetProcessHeap(), 0, nameW
);
118 /**********************************************************************
119 * PE_FindResourceEx32W
121 HANDLE
PE_FindResourceExW(
122 WINE_MODREF
*wm
,LPCWSTR name
,LPCWSTR type
,WORD lang
124 PIMAGE_RESOURCE_DIRECTORY resdirptr
;
127 PE_MODREF
*pem
= &(wm
->binfmt
.pe
);
129 if (!pem
|| !pem
->pe_resource
)
132 resdirptr
= pem
->pe_resource
;
133 root
= (DWORD
) resdirptr
;
134 if ((resdirptr
= GetResDirEntryW(resdirptr
, type
, root
, FALSE
)) == NULL
)
136 if ((resdirptr
= GetResDirEntryW(resdirptr
, name
, root
, FALSE
)) == NULL
)
138 result
= (HANDLE
)GetResDirEntryW(resdirptr
, (LPCWSTR
)(UINT
)lang
, root
, FALSE
);
140 /* Try with only the primary language set */
143 lang
= MAKELANGID(PRIMARYLANGID(lang
), SUBLANG_DEFAULT
);
144 result
= (HANDLE
)GetResDirEntryW(resdirptr
, (LPCWSTR
)(UINT
)lang
, root
, FALSE
);
146 /* Try LANG_NEUTRAL, too */
148 return (HANDLE
)GetResDirEntryW(resdirptr
, (LPCWSTR
)0, root
, TRUE
);
153 /**********************************************************************
156 HANDLE
PE_LoadResource( WINE_MODREF
*wm
, HANDLE hRsrc
)
158 if (!hRsrc
|| !wm
|| wm
->type
!=MODULE32_PE
)
160 return (HANDLE
) (wm
->module
+ ((PIMAGE_RESOURCE_DATA_ENTRY
)hRsrc
)->OffsetToData
);
164 /**********************************************************************
165 * PE_SizeofResource32
167 DWORD
PE_SizeofResource( HINSTANCE hModule
, HANDLE hRsrc
)
169 /* we don't need hModule */
172 return ((PIMAGE_RESOURCE_DATA_ENTRY
)hRsrc
)->Size
;
175 /**********************************************************************
176 * PE_EnumResourceTypes32A
179 PE_EnumResourceTypesA(HMODULE hmod
,ENUMRESTYPEPROCA lpfun
,LONG lparam
) {
180 PE_MODREF
*pem
= HMODULE32toPE_MODREF(hmod
);
182 PIMAGE_RESOURCE_DIRECTORY resdir
;
183 PIMAGE_RESOURCE_DIRECTORY_ENTRY et
;
185 HANDLE heap
= GetProcessHeap();
187 if (!pem
|| !pem
->pe_resource
)
190 resdir
= (PIMAGE_RESOURCE_DIRECTORY
)pem
->pe_resource
;
191 et
=(PIMAGE_RESOURCE_DIRECTORY_ENTRY
)((LPBYTE
)resdir
+sizeof(IMAGE_RESOURCE_DIRECTORY
));
193 for (i
=0;i
<resdir
->NumberOfNamedEntries
+resdir
->NumberOfIdEntries
;i
++) {
196 if (et
[i
].u1
.s
.NameIsString
)
197 name
= HEAP_strdupWtoA(heap
,0,(LPWSTR
)((LPBYTE
)pem
->pe_resource
+et
[i
].u1
.s
.NameOffset
));
199 name
= (LPSTR
)(int)et
[i
].u1
.Id
;
200 ret
= lpfun(hmod
,name
,lparam
);
202 HeapFree(heap
,0,name
);
209 /**********************************************************************
210 * PE_EnumResourceTypes32W
213 PE_EnumResourceTypesW(HMODULE hmod
,ENUMRESTYPEPROCW lpfun
,LONG lparam
) {
214 PE_MODREF
*pem
= HMODULE32toPE_MODREF(hmod
);
216 PIMAGE_RESOURCE_DIRECTORY resdir
;
217 PIMAGE_RESOURCE_DIRECTORY_ENTRY et
;
220 if (!pem
|| !pem
->pe_resource
)
223 resdir
= (PIMAGE_RESOURCE_DIRECTORY
)pem
->pe_resource
;
224 et
=(PIMAGE_RESOURCE_DIRECTORY_ENTRY
)((LPBYTE
)resdir
+sizeof(IMAGE_RESOURCE_DIRECTORY
));
226 for (i
=0;i
<resdir
->NumberOfNamedEntries
+resdir
->NumberOfIdEntries
;i
++) {
228 if (et
[i
].u1
.s
.NameIsString
)
229 type
= (LPWSTR
)((LPBYTE
)pem
->pe_resource
+et
[i
].u1
.s
.NameOffset
);
231 type
= (LPWSTR
)(int)et
[i
].u1
.Id
;
233 ret
= lpfun(hmod
,type
,lparam
);
240 /**********************************************************************
241 * PE_EnumResourceNames32A
244 PE_EnumResourceNamesA(
245 HMODULE hmod
,LPCSTR type
,ENUMRESNAMEPROCA lpfun
,LONG lparam
247 PE_MODREF
*pem
= HMODULE32toPE_MODREF(hmod
);
249 PIMAGE_RESOURCE_DIRECTORY resdir
;
250 PIMAGE_RESOURCE_DIRECTORY_ENTRY et
;
252 HANDLE heap
= GetProcessHeap();
255 if (!pem
|| !pem
->pe_resource
)
257 resdir
= (PIMAGE_RESOURCE_DIRECTORY
)pem
->pe_resource
;
259 typeW
= HEAP_strdupAtoW(heap
,0,type
);
261 typeW
= (LPWSTR
)type
;
262 resdir
= GetResDirEntryW(resdir
,typeW
,(DWORD
)pem
->pe_resource
,FALSE
);
264 HeapFree(heap
,0,typeW
);
267 et
=(PIMAGE_RESOURCE_DIRECTORY_ENTRY
)((LPBYTE
)resdir
+sizeof(IMAGE_RESOURCE_DIRECTORY
));
269 for (i
=0;i
<resdir
->NumberOfNamedEntries
+resdir
->NumberOfIdEntries
;i
++) {
272 if (et
[i
].u1
.s
.NameIsString
)
273 name
= HEAP_strdupWtoA(heap
,0,(LPWSTR
)((LPBYTE
)pem
->pe_resource
+et
[i
].u1
.s
.NameOffset
));
275 name
= (LPSTR
)(int)et
[i
].u1
.Id
;
276 ret
= lpfun(hmod
,type
,name
,lparam
);
277 if (HIWORD(name
)) HeapFree(heap
,0,name
);
284 /**********************************************************************
285 * PE_EnumResourceNames32W
288 PE_EnumResourceNamesW(
289 HMODULE hmod
,LPCWSTR type
,ENUMRESNAMEPROCW lpfun
,LONG lparam
291 PE_MODREF
*pem
= HMODULE32toPE_MODREF(hmod
);
293 PIMAGE_RESOURCE_DIRECTORY resdir
;
294 PIMAGE_RESOURCE_DIRECTORY_ENTRY et
;
297 if (!pem
|| !pem
->pe_resource
)
300 resdir
= (PIMAGE_RESOURCE_DIRECTORY
)pem
->pe_resource
;
301 resdir
= GetResDirEntryW(resdir
,type
,(DWORD
)pem
->pe_resource
,FALSE
);
304 et
=(PIMAGE_RESOURCE_DIRECTORY_ENTRY
)((LPBYTE
)resdir
+sizeof(IMAGE_RESOURCE_DIRECTORY
));
306 for (i
=0;i
<resdir
->NumberOfNamedEntries
+resdir
->NumberOfIdEntries
;i
++) {
308 if (et
[i
].u1
.s
.NameIsString
)
309 name
= (LPWSTR
)((LPBYTE
)pem
->pe_resource
+et
[i
].u1
.s
.NameOffset
);
311 name
= (LPWSTR
)(int)et
[i
].u1
.Id
;
312 ret
= lpfun(hmod
,type
,name
,lparam
);
319 /**********************************************************************
320 * PE_EnumResourceNames32A
323 PE_EnumResourceLanguagesA(
324 HMODULE hmod
,LPCSTR name
,LPCSTR type
,ENUMRESLANGPROCA lpfun
,
327 PE_MODREF
*pem
= HMODULE32toPE_MODREF(hmod
);
329 PIMAGE_RESOURCE_DIRECTORY resdir
;
330 PIMAGE_RESOURCE_DIRECTORY_ENTRY et
;
332 HANDLE heap
= GetProcessHeap();
335 if (!pem
|| !pem
->pe_resource
)
338 resdir
= (PIMAGE_RESOURCE_DIRECTORY
)pem
->pe_resource
;
340 nameW
= HEAP_strdupAtoW(heap
,0,name
);
342 nameW
= (LPWSTR
)name
;
343 resdir
= GetResDirEntryW(resdir
,nameW
,(DWORD
)pem
->pe_resource
,FALSE
);
345 HeapFree(heap
,0,nameW
);
349 typeW
= HEAP_strdupAtoW(heap
,0,type
);
351 typeW
= (LPWSTR
)type
;
352 resdir
= GetResDirEntryW(resdir
,typeW
,(DWORD
)pem
->pe_resource
,FALSE
);
354 HeapFree(heap
,0,typeW
);
357 et
=(PIMAGE_RESOURCE_DIRECTORY_ENTRY
)((LPBYTE
)resdir
+sizeof(IMAGE_RESOURCE_DIRECTORY
));
359 for (i
=0;i
<resdir
->NumberOfNamedEntries
+resdir
->NumberOfIdEntries
;i
++) {
360 /* languages are just ids... I hopem */
361 ret
= lpfun(hmod
,name
,type
,et
[i
].u1
.Id
,lparam
);
368 /**********************************************************************
369 * PE_EnumResourceLanguages32W
372 PE_EnumResourceLanguagesW(
373 HMODULE hmod
,LPCWSTR name
,LPCWSTR type
,ENUMRESLANGPROCW lpfun
,
376 PE_MODREF
*pem
= HMODULE32toPE_MODREF(hmod
);
378 PIMAGE_RESOURCE_DIRECTORY resdir
;
379 PIMAGE_RESOURCE_DIRECTORY_ENTRY et
;
382 if (!pem
|| !pem
->pe_resource
)
385 resdir
= (PIMAGE_RESOURCE_DIRECTORY
)pem
->pe_resource
;
386 resdir
= GetResDirEntryW(resdir
,name
,(DWORD
)pem
->pe_resource
,FALSE
);
389 resdir
= GetResDirEntryW(resdir
,type
,(DWORD
)pem
->pe_resource
,FALSE
);
392 et
=(PIMAGE_RESOURCE_DIRECTORY_ENTRY
)((LPBYTE
)resdir
+sizeof(IMAGE_RESOURCE_DIRECTORY
));
394 for (i
=0;i
<resdir
->NumberOfNamedEntries
+resdir
->NumberOfIdEntries
;i
++) {
395 ret
= lpfun(hmod
,name
,type
,et
[i
].u1
.Id
,lparam
);