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>
23 #include "stackframe.h"
28 /**********************************************************************
29 * HMODULE32toPE_MODREF
31 * small helper function to get a PE_MODREF from a passed HMODULE32
34 HMODULE32toPE_MODREF(HMODULE32 hmod
) {
36 PDB32
*pdb
= (PDB32
*)GetCurrentProcessId();
39 if (!hmod
) hmod
= GetTaskDS(); /* FIXME: correct? */
40 hmod
= MODULE_HANDLEtoHMODULE32( hmod
);
41 if (!hmod
) return NULL
;
42 if (!(pModule
= MODULE_GetPtr( hmod
))) return 0;
43 pem
= pdb
->modref_list
;
44 while (pem
&& pem
->pe_module
->mappeddll
!= hmod
)
49 /**********************************************************************
52 * Helper function - goes down one level of PE resource tree
55 LPIMAGE_RESOURCE_DIRECTORY
GetResDirEntryW(LPIMAGE_RESOURCE_DIRECTORY resdirptr
,
56 LPCWSTR name
,DWORD root
)
59 LPIMAGE_RESOURCE_DIRECTORY_ENTRY entryTable
;
66 lstrcpynWtoA(buf
,name
+1,10);
67 return GetResDirEntryW(resdirptr
,(LPCWSTR
)atoi(buf
),root
);
69 entryTable
= (LPIMAGE_RESOURCE_DIRECTORY_ENTRY
) (
71 sizeof(IMAGE_RESOURCE_DIRECTORY
));
72 namelen
= lstrlen32W(name
);
73 for (entrynum
= 0; entrynum
< resdirptr
->NumberOfNamedEntries
; entrynum
++)
75 LPIMAGE_RESOURCE_DIR_STRING_U str
=
76 (LPIMAGE_RESOURCE_DIR_STRING_U
) (root
+
77 entryTable
[entrynum
].u1
.s
.NameOffset
);
78 if(namelen
!= str
->Length
)
80 if(lstrncmpi32W(name
,str
->NameString
,str
->Length
)==0)
81 return (LPIMAGE_RESOURCE_DIRECTORY
) (
83 entryTable
[entrynum
].u2
.s
.OffsetToDirectory
);
87 entryTable
= (LPIMAGE_RESOURCE_DIRECTORY_ENTRY
) (
89 sizeof(IMAGE_RESOURCE_DIRECTORY
) +
90 resdirptr
->NumberOfNamedEntries
* sizeof(IMAGE_RESOURCE_DIRECTORY_ENTRY
));
91 for (entrynum
= 0; entrynum
< resdirptr
->NumberOfIdEntries
; entrynum
++)
92 if ((DWORD
)entryTable
[entrynum
].u1
.Name
== (DWORD
)name
)
93 return (LPIMAGE_RESOURCE_DIRECTORY
) (
95 entryTable
[entrynum
].u2
.s
.OffsetToDirectory
);
96 /* just use first entry if no default can be found */
97 if (!name
&& resdirptr
->NumberOfIdEntries
)
98 return (LPIMAGE_RESOURCE_DIRECTORY
) (
100 entryTable
[0].u2
.s
.OffsetToDirectory
);
105 /**********************************************************************
106 * PE_FindResourceEx32W
108 HANDLE32
PE_FindResourceEx32W(
109 HINSTANCE32 hModule
,LPCWSTR name
,LPCWSTR type
,WORD lang
111 LPIMAGE_RESOURCE_DIRECTORY resdirptr
;
114 PE_MODREF
*pem
= HMODULE32toPE_MODREF(hModule
);
116 if (!pem
|| !pem
->pe_resource
)
119 resdirptr
= pem
->pe_resource
;
120 root
= (DWORD
) resdirptr
;
121 if ((resdirptr
= GetResDirEntryW(resdirptr
, type
, root
)) == NULL
)
123 if ((resdirptr
= GetResDirEntryW(resdirptr
, name
, root
)) == NULL
)
125 result
= (HANDLE32
)GetResDirEntryW(resdirptr
, (LPCWSTR
)(UINT32
)lang
, root
);
126 /* Try LANG_NEUTRAL, too */
128 return (HANDLE32
)GetResDirEntryW(resdirptr
, (LPCWSTR
)0, root
);
133 /**********************************************************************
136 HANDLE32
PE_LoadResource32( HINSTANCE32 hModule
, HANDLE32 hRsrc
)
138 PE_MODREF
*pem
= HMODULE32toPE_MODREF(hModule
);
140 if (!pem
|| !pem
->pe_resource
)
144 return (HANDLE32
) (pem
->load_addr
+((LPIMAGE_RESOURCE_DATA_ENTRY
)hRsrc
)->OffsetToData
);
148 /**********************************************************************
149 * PE_SizeofResource32
151 DWORD
PE_SizeofResource32( HINSTANCE32 hModule
, HANDLE32 hRsrc
)
153 /* we don't need hModule */
156 return ((LPIMAGE_RESOURCE_DATA_ENTRY
)hRsrc
)->Size
;
159 /**********************************************************************
160 * PE_EnumResourceTypes32A
163 PE_EnumResourceTypes32A(HMODULE32 hmod
,ENUMRESTYPEPROC32A lpfun
,LONG lparam
) {
164 PE_MODREF
*pem
= HMODULE32toPE_MODREF(hmod
);
166 LPIMAGE_RESOURCE_DIRECTORY resdir
;
167 LPIMAGE_RESOURCE_DIRECTORY_ENTRY et
;
169 HANDLE32 heap
= GetProcessHeap();
171 if (!pem
|| !pem
->pe_resource
)
174 resdir
= (LPIMAGE_RESOURCE_DIRECTORY
)pem
->pe_resource
;
175 et
=(LPIMAGE_RESOURCE_DIRECTORY_ENTRY
)((LPBYTE
)resdir
+sizeof(IMAGE_RESOURCE_DIRECTORY
));
177 for (i
=0;i
<resdir
->NumberOfNamedEntries
+resdir
->NumberOfIdEntries
;i
++) {
180 if (HIWORD(et
[i
].u1
.Name
))
181 name
= HEAP_strdupWtoA(heap
,0,(LPWSTR
)((LPBYTE
)pem
->pe_resource
+et
[i
].u1
.Name
));
183 name
= (LPSTR
)et
[i
].u1
.Name
;
184 ret
= lpfun(hmod
,name
,lparam
);
186 HeapFree(heap
,0,name
);
193 /**********************************************************************
194 * PE_EnumResourceTypes32W
197 PE_EnumResourceTypes32W(HMODULE32 hmod
,ENUMRESTYPEPROC32W lpfun
,LONG lparam
) {
198 PE_MODREF
*pem
= HMODULE32toPE_MODREF(hmod
);
200 LPIMAGE_RESOURCE_DIRECTORY resdir
;
201 LPIMAGE_RESOURCE_DIRECTORY_ENTRY et
;
204 if (!pem
|| !pem
->pe_resource
)
207 resdir
= (LPIMAGE_RESOURCE_DIRECTORY
)pem
->pe_resource
;
208 et
=(LPIMAGE_RESOURCE_DIRECTORY_ENTRY
)((LPBYTE
)resdir
+sizeof(IMAGE_RESOURCE_DIRECTORY
));
210 for (i
=0;i
<resdir
->NumberOfNamedEntries
+resdir
->NumberOfIdEntries
;i
++) {
212 if (HIWORD(et
[i
].u1
.Name
))
213 type
= (LPWSTR
)((LPBYTE
)pem
->pe_resource
+et
[i
].u1
.Name
);
215 type
= (LPWSTR
)et
[i
].u1
.Name
;
217 ret
= lpfun(hmod
,type
,lparam
);
224 /**********************************************************************
225 * PE_EnumResourceNames32A
228 PE_EnumResourceNames32A(
229 HMODULE32 hmod
,LPCSTR type
,ENUMRESNAMEPROC32A lpfun
,LONG lparam
231 PE_MODREF
*pem
= HMODULE32toPE_MODREF(hmod
);
233 LPIMAGE_RESOURCE_DIRECTORY resdir
;
234 LPIMAGE_RESOURCE_DIRECTORY_ENTRY et
;
236 HANDLE32 heap
= GetProcessHeap();
239 if (!pem
|| !pem
->pe_resource
)
241 resdir
= (LPIMAGE_RESOURCE_DIRECTORY
)pem
->pe_resource
;
243 typeW
= HEAP_strdupAtoW(heap
,0,type
);
245 typeW
= (LPWSTR
)type
;
246 resdir
= GetResDirEntryW(resdir
,typeW
,(DWORD
)pem
->pe_resource
);
248 HeapFree(heap
,0,typeW
);
251 et
=(LPIMAGE_RESOURCE_DIRECTORY_ENTRY
)((LPBYTE
)resdir
+sizeof(IMAGE_RESOURCE_DIRECTORY
));
253 for (i
=0;i
<resdir
->NumberOfNamedEntries
+resdir
->NumberOfIdEntries
;i
++) {
256 if (HIWORD(et
[i
].u1
.Name
))
257 name
= HEAP_strdupWtoA(heap
,0,(LPWSTR
)((LPBYTE
)pem
->pe_resource
+et
[i
].u1
.Name
));
259 name
= (LPSTR
)et
[i
].u1
.Name
;
260 ret
= lpfun(hmod
,type
,name
,lparam
);
261 if (HIWORD(name
)) HeapFree(heap
,0,name
);
268 /**********************************************************************
269 * PE_EnumResourceNames32W
272 PE_EnumResourceNames32W(
273 HMODULE32 hmod
,LPCWSTR type
,ENUMRESNAMEPROC32W lpfun
,LONG lparam
275 PE_MODREF
*pem
= HMODULE32toPE_MODREF(hmod
);
277 LPIMAGE_RESOURCE_DIRECTORY resdir
;
278 LPIMAGE_RESOURCE_DIRECTORY_ENTRY et
;
281 if (!pem
|| !pem
->pe_resource
)
284 resdir
= (LPIMAGE_RESOURCE_DIRECTORY
)pem
->pe_resource
;
285 resdir
= GetResDirEntryW(resdir
,type
,(DWORD
)pem
->pe_resource
);
288 et
=(LPIMAGE_RESOURCE_DIRECTORY_ENTRY
)((LPBYTE
)resdir
+sizeof(IMAGE_RESOURCE_DIRECTORY
));
290 for (i
=0;i
<resdir
->NumberOfNamedEntries
+resdir
->NumberOfIdEntries
;i
++) {
292 if (HIWORD(et
[i
].u1
.Name
))
293 name
= (LPWSTR
)((LPBYTE
)pem
->pe_resource
+et
[i
].u1
.Name
);
295 name
= (LPWSTR
)et
[i
].u1
.Name
;
296 ret
= lpfun(hmod
,type
,name
,lparam
);
303 /**********************************************************************
304 * PE_EnumResourceNames32A
307 PE_EnumResourceLanguages32A(
308 HMODULE32 hmod
,LPCSTR name
,LPCSTR type
,ENUMRESLANGPROC32A lpfun
,
311 PE_MODREF
*pem
= HMODULE32toPE_MODREF(hmod
);
313 LPIMAGE_RESOURCE_DIRECTORY resdir
;
314 LPIMAGE_RESOURCE_DIRECTORY_ENTRY et
;
316 HANDLE32 heap
= GetProcessHeap();
319 if (!pem
|| !pem
->pe_resource
)
322 resdir
= (LPIMAGE_RESOURCE_DIRECTORY
)pem
->pe_resource
;
324 nameW
= HEAP_strdupAtoW(heap
,0,name
);
326 nameW
= (LPWSTR
)name
;
327 resdir
= GetResDirEntryW(resdir
,nameW
,(DWORD
)pem
->pe_resource
);
329 HeapFree(heap
,0,nameW
);
333 typeW
= HEAP_strdupAtoW(heap
,0,type
);
335 typeW
= (LPWSTR
)type
;
336 resdir
= GetResDirEntryW(resdir
,typeW
,(DWORD
)pem
->pe_resource
);
338 HeapFree(heap
,0,typeW
);
341 et
=(LPIMAGE_RESOURCE_DIRECTORY_ENTRY
)((LPBYTE
)resdir
+sizeof(IMAGE_RESOURCE_DIRECTORY
));
343 for (i
=0;i
<resdir
->NumberOfNamedEntries
+resdir
->NumberOfIdEntries
;i
++) {
344 /* languages are just ids... I hopem */
345 ret
= lpfun(hmod
,name
,type
,et
[i
].u1
.Id
,lparam
);
352 /**********************************************************************
353 * PE_EnumResourceLanguages32W
356 PE_EnumResourceLanguages32W(
357 HMODULE32 hmod
,LPCWSTR name
,LPCWSTR type
,ENUMRESLANGPROC32W lpfun
,
360 PE_MODREF
*pem
= HMODULE32toPE_MODREF(hmod
);
362 LPIMAGE_RESOURCE_DIRECTORY resdir
;
363 LPIMAGE_RESOURCE_DIRECTORY_ENTRY et
;
366 if (!pem
|| !pem
->pe_resource
)
369 resdir
= (LPIMAGE_RESOURCE_DIRECTORY
)pem
->pe_resource
;
370 resdir
= GetResDirEntryW(resdir
,name
,(DWORD
)pem
->pe_resource
);
373 resdir
= GetResDirEntryW(resdir
,type
,(DWORD
)pem
->pe_resource
);
376 et
=(LPIMAGE_RESOURCE_DIRECTORY_ENTRY
)((LPBYTE
)resdir
+sizeof(IMAGE_RESOURCE_DIRECTORY
));
378 for (i
=0;i
<resdir
->NumberOfNamedEntries
+resdir
->NumberOfIdEntries
;i
++) {
379 ret
= lpfun(hmod
,name
,type
,et
[i
].u1
.Id
,lparam
);