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"
22 #include "stackframe.h"
25 #include "debugtools.h"
27 /**********************************************************************
28 * HMODULE32toPE_MODREF
30 * small helper function to get a PE_MODREF from a passed HMODULE32
33 HMODULE32toPE_MODREF(HMODULE hmod
) {
36 wm
= MODULE32_LookupHMODULE( hmod
);
37 if (!wm
|| wm
->type
!=MODULE32_PE
)
39 return &(wm
->binfmt
.pe
);
42 /**********************************************************************
45 * Helper function - goes down one level of PE resource tree
48 PIMAGE_RESOURCE_DIRECTORY
GetResDirEntryW(PIMAGE_RESOURCE_DIRECTORY resdirptr
,
49 LPCWSTR name
,DWORD root
,
53 PIMAGE_RESOURCE_DIRECTORY_ENTRY entryTable
;
60 lstrcpynWtoA(buf
,name
+1,10);
61 return GetResDirEntryW(resdirptr
,(LPCWSTR
)atoi(buf
),root
,allowdefault
);
63 entryTable
= (PIMAGE_RESOURCE_DIRECTORY_ENTRY
) (
65 sizeof(IMAGE_RESOURCE_DIRECTORY
));
66 namelen
= lstrlenW(name
);
67 for (entrynum
= 0; entrynum
< resdirptr
->NumberOfNamedEntries
; entrynum
++)
69 PIMAGE_RESOURCE_DIR_STRING_U str
=
70 (PIMAGE_RESOURCE_DIR_STRING_U
) (root
+
71 entryTable
[entrynum
].u1
.s
.NameOffset
);
72 if(namelen
!= str
->Length
)
74 if(CRTDLL__wcsnicmp(name
,str
->NameString
,str
->Length
)==0)
75 return (PIMAGE_RESOURCE_DIRECTORY
) (
77 entryTable
[entrynum
].u2
.s
.OffsetToDirectory
);
81 entryTable
= (PIMAGE_RESOURCE_DIRECTORY_ENTRY
) (
83 sizeof(IMAGE_RESOURCE_DIRECTORY
) +
84 resdirptr
->NumberOfNamedEntries
* sizeof(IMAGE_RESOURCE_DIRECTORY_ENTRY
));
85 for (entrynum
= 0; entrynum
< resdirptr
->NumberOfIdEntries
; entrynum
++)
86 if ((DWORD
)entryTable
[entrynum
].u1
.Name
== (DWORD
)name
)
87 return (PIMAGE_RESOURCE_DIRECTORY
) (
89 entryTable
[entrynum
].u2
.s
.OffsetToDirectory
);
90 /* just use first entry if no default can be found */
91 if (allowdefault
&& !name
&& resdirptr
->NumberOfIdEntries
)
92 return (PIMAGE_RESOURCE_DIRECTORY
) (
94 entryTable
[0].u2
.s
.OffsetToDirectory
);
99 /**********************************************************************
102 PIMAGE_RESOURCE_DIRECTORY
GetResDirEntryA( PIMAGE_RESOURCE_DIRECTORY resdirptr
,
103 LPCSTR name
, DWORD root
,
106 PIMAGE_RESOURCE_DIRECTORY retv
;
107 LPWSTR nameW
= HIWORD(name
)? HEAP_strdupAtoW( GetProcessHeap(), 0, name
)
110 retv
= GetResDirEntryW( resdirptr
, nameW
, root
, allowdefault
);
112 if ( HIWORD(name
) ) HeapFree( GetProcessHeap(), 0, nameW
);
117 /**********************************************************************
118 * PE_FindResourceEx32W
120 HANDLE
PE_FindResourceExW(
121 WINE_MODREF
*wm
,LPCWSTR name
,LPCWSTR type
,WORD lang
123 PIMAGE_RESOURCE_DIRECTORY resdirptr
;
126 PE_MODREF
*pem
= &(wm
->binfmt
.pe
);
128 if (!pem
|| !pem
->pe_resource
)
131 resdirptr
= pem
->pe_resource
;
132 root
= (DWORD
) resdirptr
;
133 if ((resdirptr
= GetResDirEntryW(resdirptr
, type
, root
, FALSE
)) == NULL
)
135 if ((resdirptr
= GetResDirEntryW(resdirptr
, name
, root
, FALSE
)) == NULL
)
137 result
= (HANDLE
)GetResDirEntryW(resdirptr
, (LPCWSTR
)(UINT
)lang
, root
, FALSE
);
138 /* Try LANG_NEUTRAL, too */
140 return (HANDLE
)GetResDirEntryW(resdirptr
, (LPCWSTR
)0, root
, TRUE
);
145 /**********************************************************************
148 HANDLE
PE_LoadResource( WINE_MODREF
*wm
, HANDLE hRsrc
)
150 if (!hRsrc
|| !wm
|| wm
->type
!=MODULE32_PE
)
152 return (HANDLE
) (wm
->module
+ ((PIMAGE_RESOURCE_DATA_ENTRY
)hRsrc
)->OffsetToData
);
156 /**********************************************************************
157 * PE_SizeofResource32
159 DWORD
PE_SizeofResource( HINSTANCE hModule
, HANDLE hRsrc
)
161 /* we don't need hModule */
164 return ((PIMAGE_RESOURCE_DATA_ENTRY
)hRsrc
)->Size
;
167 /**********************************************************************
168 * PE_EnumResourceTypes32A
171 PE_EnumResourceTypesA(HMODULE hmod
,ENUMRESTYPEPROCA lpfun
,LONG lparam
) {
172 PE_MODREF
*pem
= HMODULE32toPE_MODREF(hmod
);
174 PIMAGE_RESOURCE_DIRECTORY resdir
;
175 PIMAGE_RESOURCE_DIRECTORY_ENTRY et
;
177 HANDLE heap
= GetProcessHeap();
179 if (!pem
|| !pem
->pe_resource
)
182 resdir
= (PIMAGE_RESOURCE_DIRECTORY
)pem
->pe_resource
;
183 et
=(PIMAGE_RESOURCE_DIRECTORY_ENTRY
)((LPBYTE
)resdir
+sizeof(IMAGE_RESOURCE_DIRECTORY
));
185 for (i
=0;i
<resdir
->NumberOfNamedEntries
+resdir
->NumberOfIdEntries
;i
++) {
188 if (et
[i
].u1
.s
.NameIsString
)
189 name
= HEAP_strdupWtoA(heap
,0,(LPWSTR
)((LPBYTE
)pem
->pe_resource
+et
[i
].u1
.s
.NameOffset
));
191 name
= (LPSTR
)(int)et
[i
].u1
.Id
;
192 ret
= lpfun(hmod
,name
,lparam
);
194 HeapFree(heap
,0,name
);
201 /**********************************************************************
202 * PE_EnumResourceTypes32W
205 PE_EnumResourceTypesW(HMODULE hmod
,ENUMRESTYPEPROCW lpfun
,LONG lparam
) {
206 PE_MODREF
*pem
= HMODULE32toPE_MODREF(hmod
);
208 PIMAGE_RESOURCE_DIRECTORY resdir
;
209 PIMAGE_RESOURCE_DIRECTORY_ENTRY et
;
212 if (!pem
|| !pem
->pe_resource
)
215 resdir
= (PIMAGE_RESOURCE_DIRECTORY
)pem
->pe_resource
;
216 et
=(PIMAGE_RESOURCE_DIRECTORY_ENTRY
)((LPBYTE
)resdir
+sizeof(IMAGE_RESOURCE_DIRECTORY
));
218 for (i
=0;i
<resdir
->NumberOfNamedEntries
+resdir
->NumberOfIdEntries
;i
++) {
220 if (et
[i
].u1
.s
.NameIsString
)
221 type
= (LPWSTR
)((LPBYTE
)pem
->pe_resource
+et
[i
].u1
.s
.NameOffset
);
223 type
= (LPWSTR
)(int)et
[i
].u1
.Id
;
225 ret
= lpfun(hmod
,type
,lparam
);
232 /**********************************************************************
233 * PE_EnumResourceNames32A
236 PE_EnumResourceNamesA(
237 HMODULE hmod
,LPCSTR type
,ENUMRESNAMEPROCA lpfun
,LONG lparam
239 PE_MODREF
*pem
= HMODULE32toPE_MODREF(hmod
);
241 PIMAGE_RESOURCE_DIRECTORY resdir
;
242 PIMAGE_RESOURCE_DIRECTORY_ENTRY et
;
244 HANDLE heap
= GetProcessHeap();
247 if (!pem
|| !pem
->pe_resource
)
249 resdir
= (PIMAGE_RESOURCE_DIRECTORY
)pem
->pe_resource
;
251 typeW
= HEAP_strdupAtoW(heap
,0,type
);
253 typeW
= (LPWSTR
)type
;
254 resdir
= GetResDirEntryW(resdir
,typeW
,(DWORD
)pem
->pe_resource
,FALSE
);
256 HeapFree(heap
,0,typeW
);
259 et
=(PIMAGE_RESOURCE_DIRECTORY_ENTRY
)((LPBYTE
)resdir
+sizeof(IMAGE_RESOURCE_DIRECTORY
));
261 for (i
=0;i
<resdir
->NumberOfNamedEntries
+resdir
->NumberOfIdEntries
;i
++) {
264 if (et
[i
].u1
.s
.NameIsString
)
265 name
= HEAP_strdupWtoA(heap
,0,(LPWSTR
)((LPBYTE
)pem
->pe_resource
+et
[i
].u1
.s
.NameOffset
));
267 name
= (LPSTR
)(int)et
[i
].u1
.Id
;
268 ret
= lpfun(hmod
,type
,name
,lparam
);
269 if (HIWORD(name
)) HeapFree(heap
,0,name
);
276 /**********************************************************************
277 * PE_EnumResourceNames32W
280 PE_EnumResourceNamesW(
281 HMODULE hmod
,LPCWSTR type
,ENUMRESNAMEPROCW lpfun
,LONG lparam
283 PE_MODREF
*pem
= HMODULE32toPE_MODREF(hmod
);
285 PIMAGE_RESOURCE_DIRECTORY resdir
;
286 PIMAGE_RESOURCE_DIRECTORY_ENTRY et
;
289 if (!pem
|| !pem
->pe_resource
)
292 resdir
= (PIMAGE_RESOURCE_DIRECTORY
)pem
->pe_resource
;
293 resdir
= GetResDirEntryW(resdir
,type
,(DWORD
)pem
->pe_resource
,FALSE
);
296 et
=(PIMAGE_RESOURCE_DIRECTORY_ENTRY
)((LPBYTE
)resdir
+sizeof(IMAGE_RESOURCE_DIRECTORY
));
298 for (i
=0;i
<resdir
->NumberOfNamedEntries
+resdir
->NumberOfIdEntries
;i
++) {
300 if (et
[i
].u1
.s
.NameIsString
)
301 name
= (LPWSTR
)((LPBYTE
)pem
->pe_resource
+et
[i
].u1
.s
.NameOffset
);
303 name
= (LPWSTR
)(int)et
[i
].u1
.Id
;
304 ret
= lpfun(hmod
,type
,name
,lparam
);
311 /**********************************************************************
312 * PE_EnumResourceNames32A
315 PE_EnumResourceLanguagesA(
316 HMODULE hmod
,LPCSTR name
,LPCSTR type
,ENUMRESLANGPROCA lpfun
,
319 PE_MODREF
*pem
= HMODULE32toPE_MODREF(hmod
);
321 PIMAGE_RESOURCE_DIRECTORY resdir
;
322 PIMAGE_RESOURCE_DIRECTORY_ENTRY et
;
324 HANDLE heap
= GetProcessHeap();
327 if (!pem
|| !pem
->pe_resource
)
330 resdir
= (PIMAGE_RESOURCE_DIRECTORY
)pem
->pe_resource
;
332 nameW
= HEAP_strdupAtoW(heap
,0,name
);
334 nameW
= (LPWSTR
)name
;
335 resdir
= GetResDirEntryW(resdir
,nameW
,(DWORD
)pem
->pe_resource
,FALSE
);
337 HeapFree(heap
,0,nameW
);
341 typeW
= HEAP_strdupAtoW(heap
,0,type
);
343 typeW
= (LPWSTR
)type
;
344 resdir
= GetResDirEntryW(resdir
,typeW
,(DWORD
)pem
->pe_resource
,FALSE
);
346 HeapFree(heap
,0,typeW
);
349 et
=(PIMAGE_RESOURCE_DIRECTORY_ENTRY
)((LPBYTE
)resdir
+sizeof(IMAGE_RESOURCE_DIRECTORY
));
351 for (i
=0;i
<resdir
->NumberOfNamedEntries
+resdir
->NumberOfIdEntries
;i
++) {
352 /* languages are just ids... I hopem */
353 ret
= lpfun(hmod
,name
,type
,et
[i
].u1
.Id
,lparam
);
360 /**********************************************************************
361 * PE_EnumResourceLanguages32W
364 PE_EnumResourceLanguagesW(
365 HMODULE hmod
,LPCWSTR name
,LPCWSTR type
,ENUMRESLANGPROCW lpfun
,
368 PE_MODREF
*pem
= HMODULE32toPE_MODREF(hmod
);
370 PIMAGE_RESOURCE_DIRECTORY resdir
;
371 PIMAGE_RESOURCE_DIRECTORY_ENTRY et
;
374 if (!pem
|| !pem
->pe_resource
)
377 resdir
= (PIMAGE_RESOURCE_DIRECTORY
)pem
->pe_resource
;
378 resdir
= GetResDirEntryW(resdir
,name
,(DWORD
)pem
->pe_resource
,FALSE
);
381 resdir
= GetResDirEntryW(resdir
,type
,(DWORD
)pem
->pe_resource
,FALSE
);
384 et
=(PIMAGE_RESOURCE_DIRECTORY_ENTRY
)((LPBYTE
)resdir
+sizeof(IMAGE_RESOURCE_DIRECTORY
));
386 for (i
=0;i
<resdir
->NumberOfNamedEntries
+resdir
->NumberOfIdEntries
;i
++) {
387 ret
= lpfun(hmod
,name
,type
,et
[i
].u1
.Id
,lparam
);