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"
27 /**********************************************************************
28 * HMODULE32toPE_MODREF
30 * small helper function to get a PE_MODREF from a passed HMODULE32
33 HMODULE32toPE_MODREF(HMODULE32 hmod
) {
35 PDB32
*pdb
= PROCESS_Current();
37 wm
= MODULE32_LookupHMODULE( pdb
, 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
= lstrlen32W(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(lstrncmpi32W(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 /**********************************************************************
101 * PE_FindResourceEx32W
103 HANDLE32
PE_FindResourceEx32W(
104 WINE_MODREF
*wm
,LPCWSTR name
,LPCWSTR type
,WORD lang
106 PIMAGE_RESOURCE_DIRECTORY resdirptr
;
109 PE_MODREF
*pem
= &(wm
->binfmt
.pe
);
111 if (!pem
|| !pem
->pe_resource
)
114 resdirptr
= pem
->pe_resource
;
115 root
= (DWORD
) resdirptr
;
116 if ((resdirptr
= GetResDirEntryW(resdirptr
, type
, root
, FALSE
)) == NULL
)
118 if ((resdirptr
= GetResDirEntryW(resdirptr
, name
, root
, FALSE
)) == NULL
)
120 result
= (HANDLE32
)GetResDirEntryW(resdirptr
, (LPCWSTR
)(UINT32
)lang
, root
, FALSE
);
121 /* Try LANG_NEUTRAL, too */
123 return (HANDLE32
)GetResDirEntryW(resdirptr
, (LPCWSTR
)0, root
, TRUE
);
128 /**********************************************************************
131 HANDLE32
PE_LoadResource32( WINE_MODREF
*wm
, HANDLE32 hRsrc
)
133 if (!hRsrc
|| !wm
|| wm
->type
!=MODULE32_PE
)
135 return (HANDLE32
) (wm
->module
+ ((PIMAGE_RESOURCE_DATA_ENTRY
)hRsrc
)->OffsetToData
);
139 /**********************************************************************
140 * PE_SizeofResource32
142 DWORD
PE_SizeofResource32( HINSTANCE32 hModule
, HANDLE32 hRsrc
)
144 /* we don't need hModule */
147 return ((PIMAGE_RESOURCE_DATA_ENTRY
)hRsrc
)->Size
;
150 /**********************************************************************
151 * PE_EnumResourceTypes32A
154 PE_EnumResourceTypes32A(HMODULE32 hmod
,ENUMRESTYPEPROC32A lpfun
,LONG lparam
) {
155 PE_MODREF
*pem
= HMODULE32toPE_MODREF(hmod
);
157 PIMAGE_RESOURCE_DIRECTORY resdir
;
158 PIMAGE_RESOURCE_DIRECTORY_ENTRY et
;
160 HANDLE32 heap
= GetProcessHeap();
162 if (!pem
|| !pem
->pe_resource
)
165 resdir
= (PIMAGE_RESOURCE_DIRECTORY
)pem
->pe_resource
;
166 et
=(PIMAGE_RESOURCE_DIRECTORY_ENTRY
)((LPBYTE
)resdir
+sizeof(IMAGE_RESOURCE_DIRECTORY
));
168 for (i
=0;i
<resdir
->NumberOfNamedEntries
+resdir
->NumberOfIdEntries
;i
++) {
171 if (HIWORD(et
[i
].u1
.Name
))
172 name
= HEAP_strdupWtoA(heap
,0,(LPWSTR
)((LPBYTE
)pem
->pe_resource
+et
[i
].u1
.Name
));
174 name
= (LPSTR
)et
[i
].u1
.Name
;
175 ret
= lpfun(hmod
,name
,lparam
);
177 HeapFree(heap
,0,name
);
184 /**********************************************************************
185 * PE_EnumResourceTypes32W
188 PE_EnumResourceTypes32W(HMODULE32 hmod
,ENUMRESTYPEPROC32W lpfun
,LONG lparam
) {
189 PE_MODREF
*pem
= HMODULE32toPE_MODREF(hmod
);
191 PIMAGE_RESOURCE_DIRECTORY resdir
;
192 PIMAGE_RESOURCE_DIRECTORY_ENTRY et
;
195 if (!pem
|| !pem
->pe_resource
)
198 resdir
= (PIMAGE_RESOURCE_DIRECTORY
)pem
->pe_resource
;
199 et
=(PIMAGE_RESOURCE_DIRECTORY_ENTRY
)((LPBYTE
)resdir
+sizeof(IMAGE_RESOURCE_DIRECTORY
));
201 for (i
=0;i
<resdir
->NumberOfNamedEntries
+resdir
->NumberOfIdEntries
;i
++) {
203 if (HIWORD(et
[i
].u1
.Name
))
204 type
= (LPWSTR
)((LPBYTE
)pem
->pe_resource
+et
[i
].u1
.Name
);
206 type
= (LPWSTR
)et
[i
].u1
.Name
;
208 ret
= lpfun(hmod
,type
,lparam
);
215 /**********************************************************************
216 * PE_EnumResourceNames32A
219 PE_EnumResourceNames32A(
220 HMODULE32 hmod
,LPCSTR type
,ENUMRESNAMEPROC32A lpfun
,LONG lparam
222 PE_MODREF
*pem
= HMODULE32toPE_MODREF(hmod
);
224 PIMAGE_RESOURCE_DIRECTORY resdir
;
225 PIMAGE_RESOURCE_DIRECTORY_ENTRY et
;
227 HANDLE32 heap
= GetProcessHeap();
230 if (!pem
|| !pem
->pe_resource
)
232 resdir
= (PIMAGE_RESOURCE_DIRECTORY
)pem
->pe_resource
;
234 typeW
= HEAP_strdupAtoW(heap
,0,type
);
236 typeW
= (LPWSTR
)type
;
237 resdir
= GetResDirEntryW(resdir
,typeW
,(DWORD
)pem
->pe_resource
,FALSE
);
239 HeapFree(heap
,0,typeW
);
242 et
=(PIMAGE_RESOURCE_DIRECTORY_ENTRY
)((LPBYTE
)resdir
+sizeof(IMAGE_RESOURCE_DIRECTORY
));
244 for (i
=0;i
<resdir
->NumberOfNamedEntries
+resdir
->NumberOfIdEntries
;i
++) {
247 if (HIWORD(et
[i
].u1
.Name
))
248 name
= HEAP_strdupWtoA(heap
,0,(LPWSTR
)((LPBYTE
)pem
->pe_resource
+et
[i
].u1
.Name
));
250 name
= (LPSTR
)et
[i
].u1
.Name
;
251 ret
= lpfun(hmod
,type
,name
,lparam
);
252 if (HIWORD(name
)) HeapFree(heap
,0,name
);
259 /**********************************************************************
260 * PE_EnumResourceNames32W
263 PE_EnumResourceNames32W(
264 HMODULE32 hmod
,LPCWSTR type
,ENUMRESNAMEPROC32W lpfun
,LONG lparam
266 PE_MODREF
*pem
= HMODULE32toPE_MODREF(hmod
);
268 PIMAGE_RESOURCE_DIRECTORY resdir
;
269 PIMAGE_RESOURCE_DIRECTORY_ENTRY et
;
272 if (!pem
|| !pem
->pe_resource
)
275 resdir
= (PIMAGE_RESOURCE_DIRECTORY
)pem
->pe_resource
;
276 resdir
= GetResDirEntryW(resdir
,type
,(DWORD
)pem
->pe_resource
,FALSE
);
279 et
=(PIMAGE_RESOURCE_DIRECTORY_ENTRY
)((LPBYTE
)resdir
+sizeof(IMAGE_RESOURCE_DIRECTORY
));
281 for (i
=0;i
<resdir
->NumberOfNamedEntries
+resdir
->NumberOfIdEntries
;i
++) {
283 if (HIWORD(et
[i
].u1
.Name
))
284 name
= (LPWSTR
)((LPBYTE
)pem
->pe_resource
+et
[i
].u1
.Name
);
286 name
= (LPWSTR
)et
[i
].u1
.Name
;
287 ret
= lpfun(hmod
,type
,name
,lparam
);
294 /**********************************************************************
295 * PE_EnumResourceNames32A
298 PE_EnumResourceLanguages32A(
299 HMODULE32 hmod
,LPCSTR name
,LPCSTR type
,ENUMRESLANGPROC32A lpfun
,
302 PE_MODREF
*pem
= HMODULE32toPE_MODREF(hmod
);
304 PIMAGE_RESOURCE_DIRECTORY resdir
;
305 PIMAGE_RESOURCE_DIRECTORY_ENTRY et
;
307 HANDLE32 heap
= GetProcessHeap();
310 if (!pem
|| !pem
->pe_resource
)
313 resdir
= (PIMAGE_RESOURCE_DIRECTORY
)pem
->pe_resource
;
315 nameW
= HEAP_strdupAtoW(heap
,0,name
);
317 nameW
= (LPWSTR
)name
;
318 resdir
= GetResDirEntryW(resdir
,nameW
,(DWORD
)pem
->pe_resource
,FALSE
);
320 HeapFree(heap
,0,nameW
);
324 typeW
= HEAP_strdupAtoW(heap
,0,type
);
326 typeW
= (LPWSTR
)type
;
327 resdir
= GetResDirEntryW(resdir
,typeW
,(DWORD
)pem
->pe_resource
,FALSE
);
329 HeapFree(heap
,0,typeW
);
332 et
=(PIMAGE_RESOURCE_DIRECTORY_ENTRY
)((LPBYTE
)resdir
+sizeof(IMAGE_RESOURCE_DIRECTORY
));
334 for (i
=0;i
<resdir
->NumberOfNamedEntries
+resdir
->NumberOfIdEntries
;i
++) {
335 /* languages are just ids... I hopem */
336 ret
= lpfun(hmod
,name
,type
,et
[i
].u1
.Id
,lparam
);
343 /**********************************************************************
344 * PE_EnumResourceLanguages32W
347 PE_EnumResourceLanguages32W(
348 HMODULE32 hmod
,LPCWSTR name
,LPCWSTR type
,ENUMRESLANGPROC32W lpfun
,
351 PE_MODREF
*pem
= HMODULE32toPE_MODREF(hmod
);
353 PIMAGE_RESOURCE_DIRECTORY resdir
;
354 PIMAGE_RESOURCE_DIRECTORY_ENTRY et
;
357 if (!pem
|| !pem
->pe_resource
)
360 resdir
= (PIMAGE_RESOURCE_DIRECTORY
)pem
->pe_resource
;
361 resdir
= GetResDirEntryW(resdir
,name
,(DWORD
)pem
->pe_resource
,FALSE
);
364 resdir
= GetResDirEntryW(resdir
,type
,(DWORD
)pem
->pe_resource
,FALSE
);
367 et
=(PIMAGE_RESOURCE_DIRECTORY_ENTRY
)((LPBYTE
)resdir
+sizeof(IMAGE_RESOURCE_DIRECTORY
));
369 for (i
=0;i
<resdir
->NumberOfNamedEntries
+resdir
->NumberOfIdEntries
;i
++) {
370 ret
= lpfun(hmod
,name
,type
,et
[i
].u1
.Id
,lparam
);