3 * PE (Portable Execute) File Resources
5 * Copyright 1995 Thomas Sandford
6 * Copyright 1996 Martin von Loewis
8 * Based on the Win16 resource handling code in loader/resource.c
9 * Copyright 1993 Robert J. Amstadt
10 * Copyright 1995 Alexandre Julliard
11 * Copyright 1997 Marcus Meissner
15 #include <sys/types.h>
22 #include "stackframe.h"
27 /**********************************************************************
28 * HMODULE32toPE_MODULE
30 * small helper function to get a PE_MODULE from a passed HMODULE32
33 HMODULE32toPE_MODULE(HMODULE32 hmod
) {
36 if (!hmod
) hmod
= GetTaskDS(); /* FIXME: correct? */
37 hmod
= GetExePtr( hmod
); /* In case we were passed an hInstance */
39 if (!(pModule
= MODULE_GetPtr( hmod
))) return 0;
40 if (!(pModule
->flags
& NE_FFLAGS_WIN32
)) return 0;
41 return pModule
->pe_module
;
44 /**********************************************************************
47 * Helper function - goes down one level of PE resource tree
50 LPIMAGE_RESOURCE_DIRECTORY
GetResDirEntryW(LPIMAGE_RESOURCE_DIRECTORY resdirptr
,
51 LPCWSTR name
,DWORD root
)
54 LPIMAGE_RESOURCE_DIRECTORY_ENTRY entryTable
;
61 lstrcpynWtoA(buf
,name
+1,10);
62 return GetResDirEntryW(resdirptr
,(LPCWSTR
)atoi(buf
),root
);
64 entryTable
= (LPIMAGE_RESOURCE_DIRECTORY_ENTRY
) (
66 sizeof(IMAGE_RESOURCE_DIRECTORY
));
67 namelen
= lstrlen32W(name
);
68 for (entrynum
= 0; entrynum
< resdirptr
->NumberOfNamedEntries
; entrynum
++)
70 LPIMAGE_RESOURCE_DIR_STRING_U str
=
71 (LPIMAGE_RESOURCE_DIR_STRING_U
) (root
+
72 entryTable
[entrynum
].u1
.s
.NameOffset
);
73 if(namelen
!= str
->Length
)
75 if(lstrncmpi32W(name
,str
->NameString
,str
->Length
)==0)
76 return (LPIMAGE_RESOURCE_DIRECTORY
) (
78 entryTable
[entrynum
].u2
.s
.OffsetToDirectory
);
82 entryTable
= (LPIMAGE_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 (LPIMAGE_RESOURCE_DIRECTORY
) (
90 entryTable
[entrynum
].u2
.s
.OffsetToDirectory
);
91 /* just use first entry if no default can be found */
92 if (!name
&& resdirptr
->NumberOfIdEntries
)
93 return (LPIMAGE_RESOURCE_DIRECTORY
) (
95 entryTable
[0].u2
.s
.OffsetToDirectory
);
100 /**********************************************************************
101 * PE_FindResourceEx32W
103 HANDLE32
PE_FindResourceEx32W(
104 HINSTANCE32 hModule
,LPCWSTR name
,LPCWSTR type
,WORD lang
106 LPIMAGE_RESOURCE_DIRECTORY resdirptr
;
109 PE_MODULE
*pe
= HMODULE32toPE_MODULE(hModule
);
111 if (!pe
|| !pe
->pe_resource
)
114 resdirptr
= pe
->pe_resource
;
115 root
= (DWORD
) resdirptr
;
116 if ((resdirptr
= GetResDirEntryW(resdirptr
, type
, root
)) == NULL
)
118 if ((resdirptr
= GetResDirEntryW(resdirptr
, name
, root
)) == NULL
)
120 result
= (HANDLE32
)GetResDirEntryW(resdirptr
, (LPCWSTR
)(UINT32
)lang
, root
);
121 /* Try LANG_NEUTRAL, too */
123 return (HANDLE32
)GetResDirEntryW(resdirptr
, (LPCWSTR
)0, root
);
128 /**********************************************************************
131 HANDLE32
PE_LoadResource32( HINSTANCE32 hModule
, HANDLE32 hRsrc
)
133 PE_MODULE
*pe
= HMODULE32toPE_MODULE(hModule
);
135 if (!pe
|| !pe
->pe_resource
)
139 return (HANDLE32
) (pe
->load_addr
+((LPIMAGE_RESOURCE_DATA_ENTRY
)hRsrc
)->OffsetToData
);
143 /**********************************************************************
144 * PE_SizeofResource32
147 _check_ptr(DWORD x
,DWORD start
,LPDWORD lastmax
) {
148 if ((x
>start
) && (x
<*lastmax
))
153 walk_resdir(DWORD loadaddr
,DWORD rootresdir
,DWORD xres
,DWORD data
,DWORD lvl
,LPDWORD max
){
154 LPIMAGE_RESOURCE_DIRECTORY resdir
;
155 LPIMAGE_RESOURCE_DATA_ENTRY dataent
;
156 LPIMAGE_RESOURCE_DIRECTORY_ENTRY et
;
160 dataent
= (LPIMAGE_RESOURCE_DATA_ENTRY
)(rootresdir
+xres
);
161 _check_ptr(loadaddr
+dataent
->OffsetToData
,data
,max
);
164 resdir
= (LPIMAGE_RESOURCE_DIRECTORY
)(rootresdir
+xres
);
165 et
=(LPIMAGE_RESOURCE_DIRECTORY_ENTRY
)((LPBYTE
)resdir
+sizeof(IMAGE_RESOURCE_DIRECTORY
));
166 for (i
=0;i
<resdir
->NumberOfNamedEntries
+resdir
->NumberOfIdEntries
;i
++)
167 walk_resdir(loadaddr
,rootresdir
,(lvl
==2)?et
[i
].u2
.OffsetToData
:et
[i
].u2
.s
.OffsetToDirectory
,data
,lvl
+1,max
);
170 DWORD
PE_SizeofResource32( HINSTANCE32 hModule
, HANDLE32 hRsrc
)
172 PE_MODULE
*pe
= HMODULE32toPE_MODULE(hModule
);
174 IMAGE_DATA_DIRECTORY dir
;
176 if (!pe
|| !pe
->pe_resource
)
178 if (!hRsrc
) return 0;
181 dir
=pe
->pe_header
->OptionalHeader
.DataDirectory
[IMAGE_DIRECTORY_ENTRY_RESOURCE
];
183 max
=(DWORD
)pe
->pe_resource
+dir
.Size
;
185 data
=((DWORD
)pe
->load_addr
+((LPIMAGE_RESOURCE_DATA_ENTRY
)hRsrc
)->OffsetToData
);
186 walk_resdir(pe
->load_addr
,(DWORD
)pe
->pe_resource
,0,data
,0,&max
);
190 /**********************************************************************
191 * PE_EnumResourceTypes32A
194 PE_EnumResourceTypes32A(HMODULE32 hmod
,ENUMRESTYPEPROC32A lpfun
,LONG lparam
) {
195 PE_MODULE
*pe
= HMODULE32toPE_MODULE(hmod
);
197 LPIMAGE_RESOURCE_DIRECTORY resdir
;
198 LPIMAGE_RESOURCE_DIRECTORY_ENTRY et
;
200 HANDLE32 heap
= GetProcessHeap();
202 if (!pe
|| !pe
->pe_resource
)
205 resdir
= (LPIMAGE_RESOURCE_DIRECTORY
)pe
->pe_resource
;
206 et
=(LPIMAGE_RESOURCE_DIRECTORY_ENTRY
)((LPBYTE
)resdir
+sizeof(IMAGE_RESOURCE_DIRECTORY
));
208 for (i
=0;i
<resdir
->NumberOfNamedEntries
+resdir
->NumberOfIdEntries
;i
++) {
211 if (HIWORD(et
[i
].u1
.Name
))
212 name
= HEAP_strdupWtoA(heap
,0,(LPWSTR
)((LPBYTE
)pe
->pe_resource
+et
[i
].u1
.Name
));
214 name
= (LPSTR
)et
[i
].u1
.Name
;
215 ret
= lpfun(hmod
,name
,lparam
);
217 HeapFree(heap
,0,name
);
224 /**********************************************************************
225 * PE_EnumResourceTypes32W
228 PE_EnumResourceTypes32W(HMODULE32 hmod
,ENUMRESTYPEPROC32W lpfun
,LONG lparam
) {
229 PE_MODULE
*pe
= HMODULE32toPE_MODULE(hmod
);
231 LPIMAGE_RESOURCE_DIRECTORY resdir
;
232 LPIMAGE_RESOURCE_DIRECTORY_ENTRY et
;
235 if (!pe
|| !pe
->pe_resource
)
238 resdir
= (LPIMAGE_RESOURCE_DIRECTORY
)pe
->pe_resource
;
239 et
=(LPIMAGE_RESOURCE_DIRECTORY_ENTRY
)((LPBYTE
)resdir
+sizeof(IMAGE_RESOURCE_DIRECTORY
));
241 for (i
=0;i
<resdir
->NumberOfNamedEntries
+resdir
->NumberOfIdEntries
;i
++) {
243 if (HIWORD(et
[i
].u1
.Name
))
244 type
= (LPWSTR
)((LPBYTE
)pe
->pe_resource
+et
[i
].u1
.Name
);
246 type
= (LPWSTR
)et
[i
].u1
.Name
;
248 ret
= lpfun(hmod
,type
,lparam
);
255 /**********************************************************************
256 * PE_EnumResourceNames32A
259 PE_EnumResourceNames32A(
260 HMODULE32 hmod
,LPCSTR type
,ENUMRESNAMEPROC32A lpfun
,LONG lparam
262 PE_MODULE
*pe
= HMODULE32toPE_MODULE(hmod
);
264 LPIMAGE_RESOURCE_DIRECTORY resdir
;
265 LPIMAGE_RESOURCE_DIRECTORY_ENTRY et
;
267 HANDLE32 heap
= GetProcessHeap();
270 if (!pe
|| !pe
->pe_resource
)
272 resdir
= (LPIMAGE_RESOURCE_DIRECTORY
)pe
->pe_resource
;
274 typeW
= HEAP_strdupAtoW(heap
,0,type
);
276 typeW
= (LPWSTR
)type
;
277 resdir
= GetResDirEntryW(resdir
,typeW
,(DWORD
)pe
->pe_resource
);
279 HeapFree(heap
,0,typeW
);
282 et
=(LPIMAGE_RESOURCE_DIRECTORY_ENTRY
)((LPBYTE
)resdir
+sizeof(IMAGE_RESOURCE_DIRECTORY
));
284 for (i
=0;i
<resdir
->NumberOfNamedEntries
+resdir
->NumberOfIdEntries
;i
++) {
287 if (HIWORD(et
[i
].u1
.Name
))
288 name
= HEAP_strdupWtoA(heap
,0,(LPWSTR
)((LPBYTE
)pe
->pe_resource
+et
[i
].u1
.Name
));
290 name
= (LPSTR
)et
[i
].u1
.Name
;
291 ret
= lpfun(hmod
,type
,name
,lparam
);
292 if (HIWORD(name
)) HeapFree(heap
,0,name
);
299 /**********************************************************************
300 * PE_EnumResourceNames32W
303 PE_EnumResourceNames32W(
304 HMODULE32 hmod
,LPCWSTR type
,ENUMRESNAMEPROC32W lpfun
,LONG lparam
306 PE_MODULE
*pe
= HMODULE32toPE_MODULE(hmod
);
308 LPIMAGE_RESOURCE_DIRECTORY resdir
;
309 LPIMAGE_RESOURCE_DIRECTORY_ENTRY et
;
312 if (!pe
|| !pe
->pe_resource
)
315 resdir
= (LPIMAGE_RESOURCE_DIRECTORY
)pe
->pe_resource
;
316 resdir
= GetResDirEntryW(resdir
,type
,(DWORD
)pe
->pe_resource
);
319 et
=(LPIMAGE_RESOURCE_DIRECTORY_ENTRY
)((LPBYTE
)resdir
+sizeof(IMAGE_RESOURCE_DIRECTORY
));
321 for (i
=0;i
<resdir
->NumberOfNamedEntries
+resdir
->NumberOfIdEntries
;i
++) {
323 if (HIWORD(et
[i
].u1
.Name
))
324 name
= (LPWSTR
)((LPBYTE
)pe
->pe_resource
+et
[i
].u1
.Name
);
326 name
= (LPWSTR
)et
[i
].u1
.Name
;
327 ret
= lpfun(hmod
,type
,name
,lparam
);
334 /**********************************************************************
335 * PE_EnumResourceNames32A
338 PE_EnumResourceLanguages32A(
339 HMODULE32 hmod
,LPCSTR name
,LPCSTR type
,ENUMRESLANGPROC32A lpfun
,
342 PE_MODULE
*pe
= HMODULE32toPE_MODULE(hmod
);
344 LPIMAGE_RESOURCE_DIRECTORY resdir
;
345 LPIMAGE_RESOURCE_DIRECTORY_ENTRY et
;
347 HANDLE32 heap
= GetProcessHeap();
350 if (!pe
|| !pe
->pe_resource
)
353 resdir
= (LPIMAGE_RESOURCE_DIRECTORY
)pe
->pe_resource
;
355 nameW
= HEAP_strdupAtoW(heap
,0,name
);
357 nameW
= (LPWSTR
)name
;
358 resdir
= GetResDirEntryW(resdir
,nameW
,(DWORD
)pe
->pe_resource
);
360 HeapFree(heap
,0,nameW
);
364 typeW
= HEAP_strdupAtoW(heap
,0,type
);
366 typeW
= (LPWSTR
)type
;
367 resdir
= GetResDirEntryW(resdir
,typeW
,(DWORD
)pe
->pe_resource
);
369 HeapFree(heap
,0,typeW
);
372 et
=(LPIMAGE_RESOURCE_DIRECTORY_ENTRY
)((LPBYTE
)resdir
+sizeof(IMAGE_RESOURCE_DIRECTORY
));
374 for (i
=0;i
<resdir
->NumberOfNamedEntries
+resdir
->NumberOfIdEntries
;i
++) {
375 /* languages are just ids... I hope */
376 ret
= lpfun(hmod
,name
,type
,et
[i
].u1
.Id
,lparam
);
383 /**********************************************************************
384 * PE_EnumResourceLanguages32W
387 PE_EnumResourceLanguages32W(
388 HMODULE32 hmod
,LPCWSTR name
,LPCWSTR type
,ENUMRESLANGPROC32W lpfun
,
391 PE_MODULE
*pe
= HMODULE32toPE_MODULE(hmod
);
393 LPIMAGE_RESOURCE_DIRECTORY resdir
;
394 LPIMAGE_RESOURCE_DIRECTORY_ENTRY et
;
397 if (!pe
|| !pe
->pe_resource
)
400 resdir
= (LPIMAGE_RESOURCE_DIRECTORY
)pe
->pe_resource
;
401 resdir
= GetResDirEntryW(resdir
,name
,(DWORD
)pe
->pe_resource
);
404 resdir
= GetResDirEntryW(resdir
,type
,(DWORD
)pe
->pe_resource
);
407 et
=(LPIMAGE_RESOURCE_DIRECTORY_ENTRY
)((LPBYTE
)resdir
+sizeof(IMAGE_RESOURCE_DIRECTORY
));
409 for (i
=0;i
<resdir
->NumberOfNamedEntries
+resdir
->NumberOfIdEntries
;i
++) {
410 ret
= lpfun(hmod
,name
,type
,et
[i
].u1
.Id
,lparam
);