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
12 * Modified for use with MPlayer, detailed changelog at
13 * http://svn.mplayerhq.hu/mplayer/trunk/
19 #include <sys/types.h>
20 #include "wine/winestring.h"
21 #include "wine/windef.h"
22 #include "wine/pe_image.h"
23 #include "wine/module.h"
24 #include "wine/heap.h"
26 //#include "process.h"
27 //#include "stackframe.h"
28 #include "wine/debugtools.h"
31 /**********************************************************************
32 * HMODULE32toPE_MODREF
34 * small helper function to get a PE_MODREF from a passed HMODULE32
37 HMODULE32toPE_MODREF(HMODULE hmod
) {
40 wm
= MODULE32_LookupHMODULE( hmod
);
41 if (!wm
|| wm
->type
!=MODULE32_PE
)
43 return &(wm
->binfmt
.pe
);
46 /**********************************************************************
49 * Helper function - goes down one level of PE resource tree
52 PIMAGE_RESOURCE_DIRECTORY
GetResDirEntryW(PIMAGE_RESOURCE_DIRECTORY resdirptr
,
53 LPCWSTR name
,DWORD root
,
54 WIN_BOOL allowdefault
)
57 PIMAGE_RESOURCE_DIRECTORY_ENTRY entryTable
;
64 lstrcpynWtoA(buf
,name
+1,10);
65 return GetResDirEntryW(resdirptr
,(LPCWSTR
)atoi(buf
),root
,allowdefault
);
67 entryTable
= (PIMAGE_RESOURCE_DIRECTORY_ENTRY
) (
69 sizeof(IMAGE_RESOURCE_DIRECTORY
));
70 namelen
= lstrlenW(name
);
71 for (entrynum
= 0; entrynum
< resdirptr
->NumberOfNamedEntries
; entrynum
++)
73 PIMAGE_RESOURCE_DIR_STRING_U str
=
74 (PIMAGE_RESOURCE_DIR_STRING_U
) (root
+
75 entryTable
[entrynum
].u1
.s
.NameOffset
);
76 if(namelen
!= str
->Length
)
78 if(wcsnicmp(name
,str
->NameString
,str
->Length
)==0)
79 return (PIMAGE_RESOURCE_DIRECTORY
) (
81 entryTable
[entrynum
].u2
.s
.OffsetToDirectory
);
85 entryTable
= (PIMAGE_RESOURCE_DIRECTORY_ENTRY
) (
87 sizeof(IMAGE_RESOURCE_DIRECTORY
) +
88 resdirptr
->NumberOfNamedEntries
* sizeof(IMAGE_RESOURCE_DIRECTORY_ENTRY
));
89 for (entrynum
= 0; entrynum
< resdirptr
->NumberOfIdEntries
; entrynum
++)
90 if ((DWORD
)entryTable
[entrynum
].u1
.Name
== (DWORD
)name
)
91 return (PIMAGE_RESOURCE_DIRECTORY
) (
93 entryTable
[entrynum
].u2
.s
.OffsetToDirectory
);
94 /* just use first entry if no default can be found */
95 if (allowdefault
&& !name
&& resdirptr
->NumberOfIdEntries
)
96 return (PIMAGE_RESOURCE_DIRECTORY
) (
98 entryTable
[0].u2
.s
.OffsetToDirectory
);
103 /**********************************************************************
106 PIMAGE_RESOURCE_DIRECTORY
GetResDirEntryA( PIMAGE_RESOURCE_DIRECTORY resdirptr
,
107 LPCSTR name
, DWORD root
,
108 WIN_BOOL allowdefault
)
110 PIMAGE_RESOURCE_DIRECTORY retv
;
111 LPWSTR nameW
= HIWORD(name
)? HEAP_strdupAtoW( GetProcessHeap(), 0, name
)
114 retv
= GetResDirEntryW( resdirptr
, nameW
, root
, allowdefault
);
116 if ( HIWORD(name
) ) HeapFree( GetProcessHeap(), 0, nameW
);
121 /**********************************************************************
122 * PE_FindResourceEx32W
124 HANDLE
PE_FindResourceExW(
125 WINE_MODREF
*wm
,LPCWSTR name
,LPCWSTR type
,WORD lang
127 PIMAGE_RESOURCE_DIRECTORY resdirptr
;
130 PE_MODREF
*pem
= &(wm
->binfmt
.pe
);
132 if (!pem
|| !pem
->pe_resource
)
135 resdirptr
= pem
->pe_resource
;
136 root
= (DWORD
) resdirptr
;
137 if ((resdirptr
= GetResDirEntryW(resdirptr
, type
, root
, FALSE
)) == NULL
)
139 if ((resdirptr
= GetResDirEntryW(resdirptr
, name
, root
, FALSE
)) == NULL
)
141 result
= (HANDLE
)GetResDirEntryW(resdirptr
, (LPCWSTR
)(UINT
)lang
, root
, FALSE
);
142 /* Try LANG_NEUTRAL, too */
144 return (HANDLE
)GetResDirEntryW(resdirptr
, (LPCWSTR
)0, root
, TRUE
);
149 /**********************************************************************
152 HANDLE
PE_LoadResource( WINE_MODREF
*wm
, HANDLE hRsrc
)
154 if (!hRsrc
|| !wm
|| wm
->type
!=MODULE32_PE
)
156 return (HANDLE
) (wm
->module
+ ((PIMAGE_RESOURCE_DATA_ENTRY
)hRsrc
)->OffsetToData
);
160 /**********************************************************************
161 * PE_SizeofResource32
163 DWORD
PE_SizeofResource( HINSTANCE hModule
, HANDLE hRsrc
)
165 /* we don't need hModule */
168 return ((PIMAGE_RESOURCE_DATA_ENTRY
)hRsrc
)->Size
;
171 /**********************************************************************
172 * PE_EnumResourceTypes32A
175 PE_EnumResourceTypesA(HMODULE hmod
,ENUMRESTYPEPROCA lpfun
,LONG lparam
) {
176 PE_MODREF
*pem
= HMODULE32toPE_MODREF(hmod
);
178 PIMAGE_RESOURCE_DIRECTORY resdir
;
179 PIMAGE_RESOURCE_DIRECTORY_ENTRY et
;
181 HANDLE heap
= GetProcessHeap();
183 if (!pem
|| !pem
->pe_resource
)
186 resdir
= (PIMAGE_RESOURCE_DIRECTORY
)pem
->pe_resource
;
187 et
=(PIMAGE_RESOURCE_DIRECTORY_ENTRY
)((LPBYTE
)resdir
+sizeof(IMAGE_RESOURCE_DIRECTORY
));
189 for (i
=0;i
<resdir
->NumberOfNamedEntries
+resdir
->NumberOfIdEntries
;i
++) {
192 if (et
[i
].u1
.s
.NameIsString
)
193 name
= HEAP_strdupWtoA(heap
,0,(LPWSTR
)((LPBYTE
)pem
->pe_resource
+et
[i
].u1
.s
.NameOffset
));
195 name
= (LPSTR
)(int)et
[i
].u1
.Id
;
196 ret
= lpfun(hmod
,name
,lparam
);
198 HeapFree(heap
,0,name
);
205 /**********************************************************************
206 * PE_EnumResourceTypes32W
209 PE_EnumResourceTypesW(HMODULE hmod
,ENUMRESTYPEPROCW lpfun
,LONG lparam
) {
210 PE_MODREF
*pem
= HMODULE32toPE_MODREF(hmod
);
212 PIMAGE_RESOURCE_DIRECTORY resdir
;
213 PIMAGE_RESOURCE_DIRECTORY_ENTRY et
;
216 if (!pem
|| !pem
->pe_resource
)
219 resdir
= (PIMAGE_RESOURCE_DIRECTORY
)pem
->pe_resource
;
220 et
=(PIMAGE_RESOURCE_DIRECTORY_ENTRY
)((LPBYTE
)resdir
+sizeof(IMAGE_RESOURCE_DIRECTORY
));
222 for (i
=0;i
<resdir
->NumberOfNamedEntries
+resdir
->NumberOfIdEntries
;i
++) {
224 if (et
[i
].u1
.s
.NameIsString
)
225 type
= (LPWSTR
)((LPBYTE
)pem
->pe_resource
+et
[i
].u1
.s
.NameOffset
);
227 type
= (LPWSTR
)(int)et
[i
].u1
.Id
;
229 ret
= lpfun(hmod
,type
,lparam
);
236 /**********************************************************************
237 * PE_EnumResourceNames32A
240 PE_EnumResourceNamesA(
241 HMODULE hmod
,LPCSTR type
,ENUMRESNAMEPROCA lpfun
,LONG lparam
243 PE_MODREF
*pem
= HMODULE32toPE_MODREF(hmod
);
245 PIMAGE_RESOURCE_DIRECTORY resdir
;
246 PIMAGE_RESOURCE_DIRECTORY_ENTRY et
;
248 HANDLE heap
= GetProcessHeap();
251 if (!pem
|| !pem
->pe_resource
)
253 resdir
= (PIMAGE_RESOURCE_DIRECTORY
)pem
->pe_resource
;
255 typeW
= HEAP_strdupAtoW(heap
,0,type
);
257 typeW
= (LPWSTR
)type
;
258 resdir
= GetResDirEntryW(resdir
,typeW
,(DWORD
)pem
->pe_resource
,FALSE
);
260 HeapFree(heap
,0,typeW
);
263 et
=(PIMAGE_RESOURCE_DIRECTORY_ENTRY
)((LPBYTE
)resdir
+sizeof(IMAGE_RESOURCE_DIRECTORY
));
265 for (i
=0;i
<resdir
->NumberOfNamedEntries
+resdir
->NumberOfIdEntries
;i
++) {
268 if (et
[i
].u1
.s
.NameIsString
)
269 name
= HEAP_strdupWtoA(heap
,0,(LPWSTR
)((LPBYTE
)pem
->pe_resource
+et
[i
].u1
.s
.NameOffset
));
271 name
= (LPSTR
)(int)et
[i
].u1
.Id
;
272 ret
= lpfun(hmod
,type
,name
,lparam
);
273 if (HIWORD(name
)) HeapFree(heap
,0,name
);
280 /**********************************************************************
281 * PE_EnumResourceNames32W
284 PE_EnumResourceNamesW(
285 HMODULE hmod
,LPCWSTR type
,ENUMRESNAMEPROCW lpfun
,LONG lparam
287 PE_MODREF
*pem
= HMODULE32toPE_MODREF(hmod
);
289 PIMAGE_RESOURCE_DIRECTORY resdir
;
290 PIMAGE_RESOURCE_DIRECTORY_ENTRY et
;
293 if (!pem
|| !pem
->pe_resource
)
296 resdir
= (PIMAGE_RESOURCE_DIRECTORY
)pem
->pe_resource
;
297 resdir
= GetResDirEntryW(resdir
,type
,(DWORD
)pem
->pe_resource
,FALSE
);
300 et
=(PIMAGE_RESOURCE_DIRECTORY_ENTRY
)((LPBYTE
)resdir
+sizeof(IMAGE_RESOURCE_DIRECTORY
));
302 for (i
=0;i
<resdir
->NumberOfNamedEntries
+resdir
->NumberOfIdEntries
;i
++) {
304 if (et
[i
].u1
.s
.NameIsString
)
305 name
= (LPWSTR
)((LPBYTE
)pem
->pe_resource
+et
[i
].u1
.s
.NameOffset
);
307 name
= (LPWSTR
)(int)et
[i
].u1
.Id
;
308 ret
= lpfun(hmod
,type
,name
,lparam
);
315 /**********************************************************************
316 * PE_EnumResourceNames32A
319 PE_EnumResourceLanguagesA(
320 HMODULE hmod
,LPCSTR name
,LPCSTR type
,ENUMRESLANGPROCA lpfun
,
323 PE_MODREF
*pem
= HMODULE32toPE_MODREF(hmod
);
325 PIMAGE_RESOURCE_DIRECTORY resdir
;
326 PIMAGE_RESOURCE_DIRECTORY_ENTRY et
;
328 HANDLE heap
= GetProcessHeap();
331 if (!pem
|| !pem
->pe_resource
)
334 resdir
= (PIMAGE_RESOURCE_DIRECTORY
)pem
->pe_resource
;
336 nameW
= HEAP_strdupAtoW(heap
,0,name
);
338 nameW
= (LPWSTR
)name
;
339 resdir
= GetResDirEntryW(resdir
,nameW
,(DWORD
)pem
->pe_resource
,FALSE
);
341 HeapFree(heap
,0,nameW
);
345 typeW
= HEAP_strdupAtoW(heap
,0,type
);
347 typeW
= (LPWSTR
)type
;
348 resdir
= GetResDirEntryW(resdir
,typeW
,(DWORD
)pem
->pe_resource
,FALSE
);
350 HeapFree(heap
,0,typeW
);
353 et
=(PIMAGE_RESOURCE_DIRECTORY_ENTRY
)((LPBYTE
)resdir
+sizeof(IMAGE_RESOURCE_DIRECTORY
));
355 for (i
=0;i
<resdir
->NumberOfNamedEntries
+resdir
->NumberOfIdEntries
;i
++) {
356 /* languages are just ids... I hopem */
357 ret
= lpfun(hmod
,name
,type
,et
[i
].u1
.Id
,lparam
);
364 /**********************************************************************
365 * PE_EnumResourceLanguages32W
368 PE_EnumResourceLanguagesW(
369 HMODULE hmod
,LPCWSTR name
,LPCWSTR type
,ENUMRESLANGPROCW lpfun
,
372 PE_MODREF
*pem
= HMODULE32toPE_MODREF(hmod
);
374 PIMAGE_RESOURCE_DIRECTORY resdir
;
375 PIMAGE_RESOURCE_DIRECTORY_ENTRY et
;
378 if (!pem
|| !pem
->pe_resource
)
381 resdir
= (PIMAGE_RESOURCE_DIRECTORY
)pem
->pe_resource
;
382 resdir
= GetResDirEntryW(resdir
,name
,(DWORD
)pem
->pe_resource
,FALSE
);
385 resdir
= GetResDirEntryW(resdir
,type
,(DWORD
)pem
->pe_resource
,FALSE
);
388 et
=(PIMAGE_RESOURCE_DIRECTORY_ENTRY
)((LPBYTE
)resdir
+sizeof(IMAGE_RESOURCE_DIRECTORY
));
390 for (i
=0;i
<resdir
->NumberOfNamedEntries
+resdir
->NumberOfIdEntries
;i
++) {
391 ret
= lpfun(hmod
,name
,type
,et
[i
].u1
.Id
,lparam
);