2 * PE (Portable Execute) File Resources
5 * Copyright 1995 Thomas Sandford
6 * Copyright 1996 Martin von Loewis
8 * Based on the Win16 resource handling code in loader/resource.c
9 * Copyright 1993 Robert J. Amstadt
10 * Copyright 1995 Alexandre Julliard
11 * Copyright 1997 Marcus Meissner
13 * Modified for use with MPlayer, detailed CVS changelog at
14 * http://www.mplayerhq.hu/cgi-bin/cvsweb.cgi/main/
16 * File now distributed as part of VLC media player with no modifications.
18 * This program is free software; you can redistribute it and/or modify
19 * it under the terms of the GNU General Public License as published by
20 * the Free Software Foundation; either version 2 of the License, or
21 * (at your option) any later version.
23 * This program is distributed in the hope that it will be useful,
24 * but WITHOUT ANY WARRANTY; without even the implied warranty of
25 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
26 * GNU General Public License for more details.
28 * You should have received a copy of the GNU General Public License
29 * along with this program; if not, write to the Free Software
30 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301, USA.
35 #include <sys/types.h>
36 #include "wine/winestring.h"
37 #include "wine/windef.h"
38 #include "wine/pe_image.h"
39 #include "wine/module.h"
40 #include "wine/heap.h"
42 //#include "process.h"
43 //#include "stackframe.h"
44 #include "wine/debugtools.h"
47 /**********************************************************************
48 * HMODULE32toPE_MODREF
50 * small helper function to get a PE_MODREF from a passed HMODULE32
53 HMODULE32toPE_MODREF(HMODULE hmod
) {
56 wm
= MODULE32_LookupHMODULE( hmod
);
57 if (!wm
|| wm
->type
!=MODULE32_PE
)
59 return &(wm
->binfmt
.pe
);
62 /**********************************************************************
65 * Helper function - goes down one level of PE resource tree
68 PIMAGE_RESOURCE_DIRECTORY
GetResDirEntryW(PIMAGE_RESOURCE_DIRECTORY resdirptr
,
69 LPCWSTR name
,DWORD root
,
70 WIN_BOOL allowdefault
)
73 PIMAGE_RESOURCE_DIRECTORY_ENTRY entryTable
;
80 lstrcpynWtoA(buf
,name
+1,10);
81 return GetResDirEntryW(resdirptr
,(LPCWSTR
)atoi(buf
),root
,allowdefault
);
83 entryTable
= (PIMAGE_RESOURCE_DIRECTORY_ENTRY
) (
85 sizeof(IMAGE_RESOURCE_DIRECTORY
));
86 namelen
= lstrlenW(name
);
87 for (entrynum
= 0; entrynum
< resdirptr
->NumberOfNamedEntries
; entrynum
++)
89 PIMAGE_RESOURCE_DIR_STRING_U str
=
90 (PIMAGE_RESOURCE_DIR_STRING_U
) (root
+
91 entryTable
[entrynum
].u1
.s
.NameOffset
);
92 if(namelen
!= str
->Length
)
94 if(wcsnicmp(name
,str
->NameString
,str
->Length
)==0)
95 return (PIMAGE_RESOURCE_DIRECTORY
) (
97 entryTable
[entrynum
].u2
.s
.OffsetToDirectory
);
101 entryTable
= (PIMAGE_RESOURCE_DIRECTORY_ENTRY
) (
103 sizeof(IMAGE_RESOURCE_DIRECTORY
) +
104 resdirptr
->NumberOfNamedEntries
* sizeof(IMAGE_RESOURCE_DIRECTORY_ENTRY
));
105 for (entrynum
= 0; entrynum
< resdirptr
->NumberOfIdEntries
; entrynum
++)
106 if ((DWORD
)entryTable
[entrynum
].u1
.Name
== (DWORD
)name
)
107 return (PIMAGE_RESOURCE_DIRECTORY
) (
109 entryTable
[entrynum
].u2
.s
.OffsetToDirectory
);
110 /* just use first entry if no default can be found */
111 if (allowdefault
&& !name
&& resdirptr
->NumberOfIdEntries
)
112 return (PIMAGE_RESOURCE_DIRECTORY
) (
114 entryTable
[0].u2
.s
.OffsetToDirectory
);
119 /**********************************************************************
122 PIMAGE_RESOURCE_DIRECTORY
GetResDirEntryA( PIMAGE_RESOURCE_DIRECTORY resdirptr
,
123 LPCSTR name
, DWORD root
,
124 WIN_BOOL allowdefault
)
126 PIMAGE_RESOURCE_DIRECTORY retv
;
127 LPWSTR nameW
= HIWORD(name
)? HEAP_strdupAtoW( GetProcessHeap(), 0, name
)
130 retv
= GetResDirEntryW( resdirptr
, nameW
, root
, allowdefault
);
132 if ( HIWORD(name
) ) HeapFree( GetProcessHeap(), 0, nameW
);
137 /**********************************************************************
138 * PE_FindResourceEx32W
140 HANDLE
PE_FindResourceExW(
141 WINE_MODREF
*wm
,LPCWSTR name
,LPCWSTR type
,WORD lang
143 PIMAGE_RESOURCE_DIRECTORY resdirptr
;
146 PE_MODREF
*pem
= &(wm
->binfmt
.pe
);
148 if (!pem
|| !pem
->pe_resource
)
151 resdirptr
= pem
->pe_resource
;
152 root
= (DWORD
) resdirptr
;
153 if ((resdirptr
= GetResDirEntryW(resdirptr
, type
, root
, FALSE
)) == NULL
)
155 if ((resdirptr
= GetResDirEntryW(resdirptr
, name
, root
, FALSE
)) == NULL
)
157 result
= (HANDLE
)GetResDirEntryW(resdirptr
, (LPCWSTR
)(UINT
)lang
, root
, FALSE
);
158 /* Try LANG_NEUTRAL, too */
160 return (HANDLE
)GetResDirEntryW(resdirptr
, (LPCWSTR
)0, root
, TRUE
);
165 /**********************************************************************
168 HANDLE
PE_LoadResource( WINE_MODREF
*wm
, HANDLE hRsrc
)
170 if (!hRsrc
|| !wm
|| wm
->type
!=MODULE32_PE
)
172 return (HANDLE
) (wm
->module
+ ((PIMAGE_RESOURCE_DATA_ENTRY
)hRsrc
)->OffsetToData
);
176 /**********************************************************************
177 * PE_SizeofResource32
179 DWORD
PE_SizeofResource( HINSTANCE hModule
, HANDLE hRsrc
)
181 /* we don't need hModule */
184 return ((PIMAGE_RESOURCE_DATA_ENTRY
)hRsrc
)->Size
;
187 /**********************************************************************
188 * PE_EnumResourceTypes32A
191 PE_EnumResourceTypesA(HMODULE hmod
,ENUMRESTYPEPROCA lpfun
,LONG lparam
) {
192 PE_MODREF
*pem
= HMODULE32toPE_MODREF(hmod
);
194 PIMAGE_RESOURCE_DIRECTORY resdir
;
195 PIMAGE_RESOURCE_DIRECTORY_ENTRY et
;
197 HANDLE heap
= GetProcessHeap();
199 if (!pem
|| !pem
->pe_resource
)
202 resdir
= (PIMAGE_RESOURCE_DIRECTORY
)pem
->pe_resource
;
203 et
=(PIMAGE_RESOURCE_DIRECTORY_ENTRY
)((LPBYTE
)resdir
+sizeof(IMAGE_RESOURCE_DIRECTORY
));
205 for (i
=0;i
<resdir
->NumberOfNamedEntries
+resdir
->NumberOfIdEntries
;i
++) {
208 if (et
[i
].u1
.s
.NameIsString
)
209 name
= HEAP_strdupWtoA(heap
,0,(LPWSTR
)((LPBYTE
)pem
->pe_resource
+et
[i
].u1
.s
.NameOffset
));
211 name
= (LPSTR
)(int)et
[i
].u1
.Id
;
212 ret
= lpfun(hmod
,name
,lparam
);
214 HeapFree(heap
,0,name
);
221 /**********************************************************************
222 * PE_EnumResourceTypes32W
225 PE_EnumResourceTypesW(HMODULE hmod
,ENUMRESTYPEPROCW lpfun
,LONG lparam
) {
226 PE_MODREF
*pem
= HMODULE32toPE_MODREF(hmod
);
228 PIMAGE_RESOURCE_DIRECTORY resdir
;
229 PIMAGE_RESOURCE_DIRECTORY_ENTRY et
;
232 if (!pem
|| !pem
->pe_resource
)
235 resdir
= (PIMAGE_RESOURCE_DIRECTORY
)pem
->pe_resource
;
236 et
=(PIMAGE_RESOURCE_DIRECTORY_ENTRY
)((LPBYTE
)resdir
+sizeof(IMAGE_RESOURCE_DIRECTORY
));
238 for (i
=0;i
<resdir
->NumberOfNamedEntries
+resdir
->NumberOfIdEntries
;i
++) {
240 if (et
[i
].u1
.s
.NameIsString
)
241 type
= (LPWSTR
)((LPBYTE
)pem
->pe_resource
+et
[i
].u1
.s
.NameOffset
);
243 type
= (LPWSTR
)(int)et
[i
].u1
.Id
;
245 ret
= lpfun(hmod
,type
,lparam
);
252 /**********************************************************************
253 * PE_EnumResourceNames32A
256 PE_EnumResourceNamesA(
257 HMODULE hmod
,LPCSTR type
,ENUMRESNAMEPROCA lpfun
,LONG lparam
259 PE_MODREF
*pem
= HMODULE32toPE_MODREF(hmod
);
261 PIMAGE_RESOURCE_DIRECTORY resdir
;
262 PIMAGE_RESOURCE_DIRECTORY_ENTRY et
;
264 HANDLE heap
= GetProcessHeap();
267 if (!pem
|| !pem
->pe_resource
)
269 resdir
= (PIMAGE_RESOURCE_DIRECTORY
)pem
->pe_resource
;
271 typeW
= HEAP_strdupAtoW(heap
,0,type
);
273 typeW
= (LPWSTR
)type
;
274 resdir
= GetResDirEntryW(resdir
,typeW
,(DWORD
)pem
->pe_resource
,FALSE
);
276 HeapFree(heap
,0,typeW
);
279 et
=(PIMAGE_RESOURCE_DIRECTORY_ENTRY
)((LPBYTE
)resdir
+sizeof(IMAGE_RESOURCE_DIRECTORY
));
281 for (i
=0;i
<resdir
->NumberOfNamedEntries
+resdir
->NumberOfIdEntries
;i
++) {
284 if (et
[i
].u1
.s
.NameIsString
)
285 name
= HEAP_strdupWtoA(heap
,0,(LPWSTR
)((LPBYTE
)pem
->pe_resource
+et
[i
].u1
.s
.NameOffset
));
287 name
= (LPSTR
)(int)et
[i
].u1
.Id
;
288 ret
= lpfun(hmod
,type
,name
,lparam
);
289 if (HIWORD(name
)) HeapFree(heap
,0,name
);
296 /**********************************************************************
297 * PE_EnumResourceNames32W
300 PE_EnumResourceNamesW(
301 HMODULE hmod
,LPCWSTR type
,ENUMRESNAMEPROCW lpfun
,LONG lparam
303 PE_MODREF
*pem
= HMODULE32toPE_MODREF(hmod
);
305 PIMAGE_RESOURCE_DIRECTORY resdir
;
306 PIMAGE_RESOURCE_DIRECTORY_ENTRY et
;
309 if (!pem
|| !pem
->pe_resource
)
312 resdir
= (PIMAGE_RESOURCE_DIRECTORY
)pem
->pe_resource
;
313 resdir
= GetResDirEntryW(resdir
,type
,(DWORD
)pem
->pe_resource
,FALSE
);
316 et
=(PIMAGE_RESOURCE_DIRECTORY_ENTRY
)((LPBYTE
)resdir
+sizeof(IMAGE_RESOURCE_DIRECTORY
));
318 for (i
=0;i
<resdir
->NumberOfNamedEntries
+resdir
->NumberOfIdEntries
;i
++) {
320 if (et
[i
].u1
.s
.NameIsString
)
321 name
= (LPWSTR
)((LPBYTE
)pem
->pe_resource
+et
[i
].u1
.s
.NameOffset
);
323 name
= (LPWSTR
)(int)et
[i
].u1
.Id
;
324 ret
= lpfun(hmod
,type
,name
,lparam
);
331 /**********************************************************************
332 * PE_EnumResourceNames32A
335 PE_EnumResourceLanguagesA(
336 HMODULE hmod
,LPCSTR name
,LPCSTR type
,ENUMRESLANGPROCA lpfun
,
339 PE_MODREF
*pem
= HMODULE32toPE_MODREF(hmod
);
341 PIMAGE_RESOURCE_DIRECTORY resdir
;
342 PIMAGE_RESOURCE_DIRECTORY_ENTRY et
;
344 HANDLE heap
= GetProcessHeap();
347 if (!pem
|| !pem
->pe_resource
)
350 resdir
= (PIMAGE_RESOURCE_DIRECTORY
)pem
->pe_resource
;
352 nameW
= HEAP_strdupAtoW(heap
,0,name
);
354 nameW
= (LPWSTR
)name
;
355 resdir
= GetResDirEntryW(resdir
,nameW
,(DWORD
)pem
->pe_resource
,FALSE
);
357 HeapFree(heap
,0,nameW
);
361 typeW
= HEAP_strdupAtoW(heap
,0,type
);
363 typeW
= (LPWSTR
)type
;
364 resdir
= GetResDirEntryW(resdir
,typeW
,(DWORD
)pem
->pe_resource
,FALSE
);
366 HeapFree(heap
,0,typeW
);
369 et
=(PIMAGE_RESOURCE_DIRECTORY_ENTRY
)((LPBYTE
)resdir
+sizeof(IMAGE_RESOURCE_DIRECTORY
));
371 for (i
=0;i
<resdir
->NumberOfNamedEntries
+resdir
->NumberOfIdEntries
;i
++) {
372 /* languages are just ids... I hopem */
373 ret
= lpfun(hmod
,name
,type
,et
[i
].u1
.Id
,lparam
);
380 /**********************************************************************
381 * PE_EnumResourceLanguages32W
384 PE_EnumResourceLanguagesW(
385 HMODULE hmod
,LPCWSTR name
,LPCWSTR type
,ENUMRESLANGPROCW lpfun
,
388 PE_MODREF
*pem
= HMODULE32toPE_MODREF(hmod
);
390 PIMAGE_RESOURCE_DIRECTORY resdir
;
391 PIMAGE_RESOURCE_DIRECTORY_ENTRY et
;
394 if (!pem
|| !pem
->pe_resource
)
397 resdir
= (PIMAGE_RESOURCE_DIRECTORY
)pem
->pe_resource
;
398 resdir
= GetResDirEntryW(resdir
,name
,(DWORD
)pem
->pe_resource
,FALSE
);
401 resdir
= GetResDirEntryW(resdir
,type
,(DWORD
)pem
->pe_resource
,FALSE
);
404 et
=(PIMAGE_RESOURCE_DIRECTORY_ENTRY
)((LPBYTE
)resdir
+sizeof(IMAGE_RESOURCE_DIRECTORY
));
406 for (i
=0;i
<resdir
->NumberOfNamedEntries
+resdir
->NumberOfIdEntries
;i
++) {
407 ret
= lpfun(hmod
,name
,type
,et
[i
].u1
.Id
,lparam
);