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
= PROCESS_Current();
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
->module
!= 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
,
60 LPIMAGE_RESOURCE_DIRECTORY_ENTRY entryTable
;
67 lstrcpynWtoA(buf
,name
+1,10);
68 return GetResDirEntryW(resdirptr
,(LPCWSTR
)atoi(buf
),root
,allowdefault
);
70 entryTable
= (LPIMAGE_RESOURCE_DIRECTORY_ENTRY
) (
72 sizeof(IMAGE_RESOURCE_DIRECTORY
));
73 namelen
= lstrlen32W(name
);
74 for (entrynum
= 0; entrynum
< resdirptr
->NumberOfNamedEntries
; entrynum
++)
76 LPIMAGE_RESOURCE_DIR_STRING_U str
=
77 (LPIMAGE_RESOURCE_DIR_STRING_U
) (root
+
78 entryTable
[entrynum
].u1
.s
.NameOffset
);
79 if(namelen
!= str
->Length
)
81 if(lstrncmpi32W(name
,str
->NameString
,str
->Length
)==0)
82 return (LPIMAGE_RESOURCE_DIRECTORY
) (
84 entryTable
[entrynum
].u2
.s
.OffsetToDirectory
);
88 entryTable
= (LPIMAGE_RESOURCE_DIRECTORY_ENTRY
) (
90 sizeof(IMAGE_RESOURCE_DIRECTORY
) +
91 resdirptr
->NumberOfNamedEntries
* sizeof(IMAGE_RESOURCE_DIRECTORY_ENTRY
));
92 for (entrynum
= 0; entrynum
< resdirptr
->NumberOfIdEntries
; entrynum
++)
93 if ((DWORD
)entryTable
[entrynum
].u1
.Name
== (DWORD
)name
)
94 return (LPIMAGE_RESOURCE_DIRECTORY
) (
96 entryTable
[entrynum
].u2
.s
.OffsetToDirectory
);
97 /* just use first entry if no default can be found */
98 if (allowdefault
&& !name
&& resdirptr
->NumberOfIdEntries
)
99 return (LPIMAGE_RESOURCE_DIRECTORY
) (
101 entryTable
[0].u2
.s
.OffsetToDirectory
);
106 /**********************************************************************
107 * PE_FindResourceEx32W
109 HANDLE32
PE_FindResourceEx32W(
110 HINSTANCE32 hModule
,LPCWSTR name
,LPCWSTR type
,WORD lang
112 LPIMAGE_RESOURCE_DIRECTORY resdirptr
;
115 PE_MODREF
*pem
= HMODULE32toPE_MODREF(hModule
);
117 if (!pem
|| !pem
->pe_resource
)
120 resdirptr
= pem
->pe_resource
;
121 root
= (DWORD
) resdirptr
;
122 if ((resdirptr
= GetResDirEntryW(resdirptr
, type
, root
, FALSE
)) == NULL
)
124 if ((resdirptr
= GetResDirEntryW(resdirptr
, name
, root
, FALSE
)) == NULL
)
126 result
= (HANDLE32
)GetResDirEntryW(resdirptr
, (LPCWSTR
)(UINT32
)lang
, root
, FALSE
);
127 /* Try LANG_NEUTRAL, too */
129 return (HANDLE32
)GetResDirEntryW(resdirptr
, (LPCWSTR
)0, root
, TRUE
);
134 /**********************************************************************
137 HANDLE32
PE_LoadResource32( HINSTANCE32 hModule
, HANDLE32 hRsrc
)
139 PE_MODREF
*pem
= HMODULE32toPE_MODREF(hModule
);
141 if (!pem
|| !pem
->pe_resource
)
145 return (HANDLE32
) (pem
->module
+ ((LPIMAGE_RESOURCE_DATA_ENTRY
)hRsrc
)->OffsetToData
);
149 /**********************************************************************
150 * PE_SizeofResource32
152 DWORD
PE_SizeofResource32( HINSTANCE32 hModule
, HANDLE32 hRsrc
)
154 /* we don't need hModule */
157 return ((LPIMAGE_RESOURCE_DATA_ENTRY
)hRsrc
)->Size
;
160 /**********************************************************************
161 * PE_EnumResourceTypes32A
164 PE_EnumResourceTypes32A(HMODULE32 hmod
,ENUMRESTYPEPROC32A lpfun
,LONG lparam
) {
165 PE_MODREF
*pem
= HMODULE32toPE_MODREF(hmod
);
167 LPIMAGE_RESOURCE_DIRECTORY resdir
;
168 LPIMAGE_RESOURCE_DIRECTORY_ENTRY et
;
170 HANDLE32 heap
= GetProcessHeap();
172 if (!pem
|| !pem
->pe_resource
)
175 resdir
= (LPIMAGE_RESOURCE_DIRECTORY
)pem
->pe_resource
;
176 et
=(LPIMAGE_RESOURCE_DIRECTORY_ENTRY
)((LPBYTE
)resdir
+sizeof(IMAGE_RESOURCE_DIRECTORY
));
178 for (i
=0;i
<resdir
->NumberOfNamedEntries
+resdir
->NumberOfIdEntries
;i
++) {
181 if (HIWORD(et
[i
].u1
.Name
))
182 name
= HEAP_strdupWtoA(heap
,0,(LPWSTR
)((LPBYTE
)pem
->pe_resource
+et
[i
].u1
.Name
));
184 name
= (LPSTR
)et
[i
].u1
.Name
;
185 ret
= lpfun(hmod
,name
,lparam
);
187 HeapFree(heap
,0,name
);
194 /**********************************************************************
195 * PE_EnumResourceTypes32W
198 PE_EnumResourceTypes32W(HMODULE32 hmod
,ENUMRESTYPEPROC32W lpfun
,LONG lparam
) {
199 PE_MODREF
*pem
= HMODULE32toPE_MODREF(hmod
);
201 LPIMAGE_RESOURCE_DIRECTORY resdir
;
202 LPIMAGE_RESOURCE_DIRECTORY_ENTRY et
;
205 if (!pem
|| !pem
->pe_resource
)
208 resdir
= (LPIMAGE_RESOURCE_DIRECTORY
)pem
->pe_resource
;
209 et
=(LPIMAGE_RESOURCE_DIRECTORY_ENTRY
)((LPBYTE
)resdir
+sizeof(IMAGE_RESOURCE_DIRECTORY
));
211 for (i
=0;i
<resdir
->NumberOfNamedEntries
+resdir
->NumberOfIdEntries
;i
++) {
213 if (HIWORD(et
[i
].u1
.Name
))
214 type
= (LPWSTR
)((LPBYTE
)pem
->pe_resource
+et
[i
].u1
.Name
);
216 type
= (LPWSTR
)et
[i
].u1
.Name
;
218 ret
= lpfun(hmod
,type
,lparam
);
225 /**********************************************************************
226 * PE_EnumResourceNames32A
229 PE_EnumResourceNames32A(
230 HMODULE32 hmod
,LPCSTR type
,ENUMRESNAMEPROC32A lpfun
,LONG lparam
232 PE_MODREF
*pem
= HMODULE32toPE_MODREF(hmod
);
234 LPIMAGE_RESOURCE_DIRECTORY resdir
;
235 LPIMAGE_RESOURCE_DIRECTORY_ENTRY et
;
237 HANDLE32 heap
= GetProcessHeap();
240 if (!pem
|| !pem
->pe_resource
)
242 resdir
= (LPIMAGE_RESOURCE_DIRECTORY
)pem
->pe_resource
;
244 typeW
= HEAP_strdupAtoW(heap
,0,type
);
246 typeW
= (LPWSTR
)type
;
247 resdir
= GetResDirEntryW(resdir
,typeW
,(DWORD
)pem
->pe_resource
,FALSE
);
249 HeapFree(heap
,0,typeW
);
252 et
=(LPIMAGE_RESOURCE_DIRECTORY_ENTRY
)((LPBYTE
)resdir
+sizeof(IMAGE_RESOURCE_DIRECTORY
));
254 for (i
=0;i
<resdir
->NumberOfNamedEntries
+resdir
->NumberOfIdEntries
;i
++) {
257 if (HIWORD(et
[i
].u1
.Name
))
258 name
= HEAP_strdupWtoA(heap
,0,(LPWSTR
)((LPBYTE
)pem
->pe_resource
+et
[i
].u1
.Name
));
260 name
= (LPSTR
)et
[i
].u1
.Name
;
261 ret
= lpfun(hmod
,type
,name
,lparam
);
262 if (HIWORD(name
)) HeapFree(heap
,0,name
);
269 /**********************************************************************
270 * PE_EnumResourceNames32W
273 PE_EnumResourceNames32W(
274 HMODULE32 hmod
,LPCWSTR type
,ENUMRESNAMEPROC32W lpfun
,LONG lparam
276 PE_MODREF
*pem
= HMODULE32toPE_MODREF(hmod
);
278 LPIMAGE_RESOURCE_DIRECTORY resdir
;
279 LPIMAGE_RESOURCE_DIRECTORY_ENTRY et
;
282 if (!pem
|| !pem
->pe_resource
)
285 resdir
= (LPIMAGE_RESOURCE_DIRECTORY
)pem
->pe_resource
;
286 resdir
= GetResDirEntryW(resdir
,type
,(DWORD
)pem
->pe_resource
,FALSE
);
289 et
=(LPIMAGE_RESOURCE_DIRECTORY_ENTRY
)((LPBYTE
)resdir
+sizeof(IMAGE_RESOURCE_DIRECTORY
));
291 for (i
=0;i
<resdir
->NumberOfNamedEntries
+resdir
->NumberOfIdEntries
;i
++) {
293 if (HIWORD(et
[i
].u1
.Name
))
294 name
= (LPWSTR
)((LPBYTE
)pem
->pe_resource
+et
[i
].u1
.Name
);
296 name
= (LPWSTR
)et
[i
].u1
.Name
;
297 ret
= lpfun(hmod
,type
,name
,lparam
);
304 /**********************************************************************
305 * PE_EnumResourceNames32A
308 PE_EnumResourceLanguages32A(
309 HMODULE32 hmod
,LPCSTR name
,LPCSTR type
,ENUMRESLANGPROC32A lpfun
,
312 PE_MODREF
*pem
= HMODULE32toPE_MODREF(hmod
);
314 LPIMAGE_RESOURCE_DIRECTORY resdir
;
315 LPIMAGE_RESOURCE_DIRECTORY_ENTRY et
;
317 HANDLE32 heap
= GetProcessHeap();
320 if (!pem
|| !pem
->pe_resource
)
323 resdir
= (LPIMAGE_RESOURCE_DIRECTORY
)pem
->pe_resource
;
325 nameW
= HEAP_strdupAtoW(heap
,0,name
);
327 nameW
= (LPWSTR
)name
;
328 resdir
= GetResDirEntryW(resdir
,nameW
,(DWORD
)pem
->pe_resource
,FALSE
);
330 HeapFree(heap
,0,nameW
);
334 typeW
= HEAP_strdupAtoW(heap
,0,type
);
336 typeW
= (LPWSTR
)type
;
337 resdir
= GetResDirEntryW(resdir
,typeW
,(DWORD
)pem
->pe_resource
,FALSE
);
339 HeapFree(heap
,0,typeW
);
342 et
=(LPIMAGE_RESOURCE_DIRECTORY_ENTRY
)((LPBYTE
)resdir
+sizeof(IMAGE_RESOURCE_DIRECTORY
));
344 for (i
=0;i
<resdir
->NumberOfNamedEntries
+resdir
->NumberOfIdEntries
;i
++) {
345 /* languages are just ids... I hopem */
346 ret
= lpfun(hmod
,name
,type
,et
[i
].u1
.Id
,lparam
);
353 /**********************************************************************
354 * PE_EnumResourceLanguages32W
357 PE_EnumResourceLanguages32W(
358 HMODULE32 hmod
,LPCWSTR name
,LPCWSTR type
,ENUMRESLANGPROC32W lpfun
,
361 PE_MODREF
*pem
= HMODULE32toPE_MODREF(hmod
);
363 LPIMAGE_RESOURCE_DIRECTORY resdir
;
364 LPIMAGE_RESOURCE_DIRECTORY_ENTRY et
;
367 if (!pem
|| !pem
->pe_resource
)
370 resdir
= (LPIMAGE_RESOURCE_DIRECTORY
)pem
->pe_resource
;
371 resdir
= GetResDirEntryW(resdir
,name
,(DWORD
)pem
->pe_resource
,FALSE
);
374 resdir
= GetResDirEntryW(resdir
,type
,(DWORD
)pem
->pe_resource
,FALSE
);
377 et
=(LPIMAGE_RESOURCE_DIRECTORY_ENTRY
)((LPBYTE
)resdir
+sizeof(IMAGE_RESOURCE_DIRECTORY
));
379 for (i
=0;i
<resdir
->NumberOfNamedEntries
+resdir
->NumberOfIdEntries
;i
++) {
380 ret
= lpfun(hmod
,name
,type
,et
[i
].u1
.Id
,lparam
);