Add media key to X11 vouts. Patch by loox.thefuture
[vlc.git] / loader / pe_resource.c
blob5e54e5e711d7f287e860ad24e494238679ca244e
1 /*
2 * PE (Portable Execute) File Resources
3 * $Id$
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.
32 #include "config.h"
34 #include <stdlib.h>
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"
41 //#include "task.h"
42 //#include "process.h"
43 //#include "stackframe.h"
44 #include "wine/debugtools.h"
45 #include "ext.h"
47 /**********************************************************************
48 * HMODULE32toPE_MODREF
50 * small helper function to get a PE_MODREF from a passed HMODULE32
52 static PE_MODREF*
53 HMODULE32toPE_MODREF(HMODULE hmod) {
54 WINE_MODREF *wm;
56 wm = MODULE32_LookupHMODULE( hmod );
57 if (!wm || wm->type!=MODULE32_PE)
58 return NULL;
59 return &(wm->binfmt.pe);
62 /**********************************************************************
63 * GetResDirEntryW
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)
72 int entrynum;
73 PIMAGE_RESOURCE_DIRECTORY_ENTRY entryTable;
74 int namelen;
76 if (HIWORD(name)) {
77 if (name[0]=='#') {
78 char buf[10];
80 lstrcpynWtoA(buf,name+1,10);
81 return GetResDirEntryW(resdirptr,(LPCWSTR)atoi(buf),root,allowdefault);
83 entryTable = (PIMAGE_RESOURCE_DIRECTORY_ENTRY) (
84 (BYTE *) resdirptr +
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)
93 continue;
94 if(wcsnicmp(name,str->NameString,str->Length)==0)
95 return (PIMAGE_RESOURCE_DIRECTORY) (
96 root +
97 entryTable[entrynum].u2.s.OffsetToDirectory);
99 return NULL;
100 } else {
101 entryTable = (PIMAGE_RESOURCE_DIRECTORY_ENTRY) (
102 (BYTE *) resdirptr +
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) (
108 root +
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) (
113 root +
114 entryTable[0].u2.s.OffsetToDirectory);
115 return NULL;
119 /**********************************************************************
120 * GetResDirEntryA
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 )
128 : (LPWSTR)name;
130 retv = GetResDirEntryW( resdirptr, nameW, root, allowdefault );
132 if ( HIWORD(name) ) HeapFree( GetProcessHeap(), 0, nameW );
134 return retv;
137 /**********************************************************************
138 * PE_FindResourceEx32W
140 HANDLE PE_FindResourceExW(
141 WINE_MODREF *wm,LPCWSTR name,LPCWSTR type,WORD lang
143 PIMAGE_RESOURCE_DIRECTORY resdirptr;
144 DWORD root;
145 HANDLE result;
146 PE_MODREF *pem = &(wm->binfmt.pe);
148 if (!pem || !pem->pe_resource)
149 return 0;
151 resdirptr = pem->pe_resource;
152 root = (DWORD) resdirptr;
153 if ((resdirptr = GetResDirEntryW(resdirptr, type, root, FALSE)) == NULL)
154 return 0;
155 if ((resdirptr = GetResDirEntryW(resdirptr, name, root, FALSE)) == NULL)
156 return 0;
157 result = (HANDLE)GetResDirEntryW(resdirptr, (LPCWSTR)(UINT)lang, root, FALSE);
158 /* Try LANG_NEUTRAL, too */
159 if(!result)
160 return (HANDLE)GetResDirEntryW(resdirptr, (LPCWSTR)0, root, TRUE);
161 return result;
165 /**********************************************************************
166 * PE_LoadResource32
168 HANDLE PE_LoadResource( WINE_MODREF *wm, HANDLE hRsrc )
170 if (!hRsrc || !wm || wm->type!=MODULE32_PE)
171 return 0;
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 */
182 if (!hRsrc)
183 return 0;
184 return ((PIMAGE_RESOURCE_DATA_ENTRY)hRsrc)->Size;
187 /**********************************************************************
188 * PE_EnumResourceTypes32A
190 WIN_BOOL
191 PE_EnumResourceTypesA(HMODULE hmod,ENUMRESTYPEPROCA lpfun,LONG lparam) {
192 PE_MODREF *pem = HMODULE32toPE_MODREF(hmod);
193 int i;
194 PIMAGE_RESOURCE_DIRECTORY resdir;
195 PIMAGE_RESOURCE_DIRECTORY_ENTRY et;
196 WIN_BOOL ret;
197 HANDLE heap = GetProcessHeap();
199 if (!pem || !pem->pe_resource)
200 return FALSE;
202 resdir = (PIMAGE_RESOURCE_DIRECTORY)pem->pe_resource;
203 et =(PIMAGE_RESOURCE_DIRECTORY_ENTRY)((LPBYTE)resdir+sizeof(IMAGE_RESOURCE_DIRECTORY));
204 ret = FALSE;
205 for (i=0;i<resdir->NumberOfNamedEntries+resdir->NumberOfIdEntries;i++) {
206 LPSTR name;
208 if (et[i].u1.s.NameIsString)
209 name = HEAP_strdupWtoA(heap,0,(LPWSTR)((LPBYTE)pem->pe_resource+et[i].u1.s.NameOffset));
210 else
211 name = (LPSTR)(int)et[i].u1.Id;
212 ret = lpfun(hmod,name,lparam);
213 if (HIWORD(name))
214 HeapFree(heap,0,name);
215 if (!ret)
216 break;
218 return ret;
221 /**********************************************************************
222 * PE_EnumResourceTypes32W
224 WIN_BOOL
225 PE_EnumResourceTypesW(HMODULE hmod,ENUMRESTYPEPROCW lpfun,LONG lparam) {
226 PE_MODREF *pem = HMODULE32toPE_MODREF(hmod);
227 int i;
228 PIMAGE_RESOURCE_DIRECTORY resdir;
229 PIMAGE_RESOURCE_DIRECTORY_ENTRY et;
230 WIN_BOOL ret;
232 if (!pem || !pem->pe_resource)
233 return FALSE;
235 resdir = (PIMAGE_RESOURCE_DIRECTORY)pem->pe_resource;
236 et =(PIMAGE_RESOURCE_DIRECTORY_ENTRY)((LPBYTE)resdir+sizeof(IMAGE_RESOURCE_DIRECTORY));
237 ret = FALSE;
238 for (i=0;i<resdir->NumberOfNamedEntries+resdir->NumberOfIdEntries;i++) {
239 LPWSTR type;
240 if (et[i].u1.s.NameIsString)
241 type = (LPWSTR)((LPBYTE)pem->pe_resource+et[i].u1.s.NameOffset);
242 else
243 type = (LPWSTR)(int)et[i].u1.Id;
245 ret = lpfun(hmod,type,lparam);
246 if (!ret)
247 break;
249 return ret;
252 /**********************************************************************
253 * PE_EnumResourceNames32A
255 WIN_BOOL
256 PE_EnumResourceNamesA(
257 HMODULE hmod,LPCSTR type,ENUMRESNAMEPROCA lpfun,LONG lparam
259 PE_MODREF *pem = HMODULE32toPE_MODREF(hmod);
260 int i;
261 PIMAGE_RESOURCE_DIRECTORY resdir;
262 PIMAGE_RESOURCE_DIRECTORY_ENTRY et;
263 WIN_BOOL ret;
264 HANDLE heap = GetProcessHeap();
265 LPWSTR typeW;
267 if (!pem || !pem->pe_resource)
268 return FALSE;
269 resdir = (PIMAGE_RESOURCE_DIRECTORY)pem->pe_resource;
270 if (HIWORD(type))
271 typeW = HEAP_strdupAtoW(heap,0,type);
272 else
273 typeW = (LPWSTR)type;
274 resdir = GetResDirEntryW(resdir,typeW,(DWORD)pem->pe_resource,FALSE);
275 if (HIWORD(typeW))
276 HeapFree(heap,0,typeW);
277 if (!resdir)
278 return FALSE;
279 et =(PIMAGE_RESOURCE_DIRECTORY_ENTRY)((LPBYTE)resdir+sizeof(IMAGE_RESOURCE_DIRECTORY));
280 ret = FALSE;
281 for (i=0;i<resdir->NumberOfNamedEntries+resdir->NumberOfIdEntries;i++) {
282 LPSTR name;
284 if (et[i].u1.s.NameIsString)
285 name = HEAP_strdupWtoA(heap,0,(LPWSTR)((LPBYTE)pem->pe_resource+et[i].u1.s.NameOffset));
286 else
287 name = (LPSTR)(int)et[i].u1.Id;
288 ret = lpfun(hmod,type,name,lparam);
289 if (HIWORD(name)) HeapFree(heap,0,name);
290 if (!ret)
291 break;
293 return ret;
296 /**********************************************************************
297 * PE_EnumResourceNames32W
299 WIN_BOOL
300 PE_EnumResourceNamesW(
301 HMODULE hmod,LPCWSTR type,ENUMRESNAMEPROCW lpfun,LONG lparam
303 PE_MODREF *pem = HMODULE32toPE_MODREF(hmod);
304 int i;
305 PIMAGE_RESOURCE_DIRECTORY resdir;
306 PIMAGE_RESOURCE_DIRECTORY_ENTRY et;
307 WIN_BOOL ret;
309 if (!pem || !pem->pe_resource)
310 return FALSE;
312 resdir = (PIMAGE_RESOURCE_DIRECTORY)pem->pe_resource;
313 resdir = GetResDirEntryW(resdir,type,(DWORD)pem->pe_resource,FALSE);
314 if (!resdir)
315 return FALSE;
316 et =(PIMAGE_RESOURCE_DIRECTORY_ENTRY)((LPBYTE)resdir+sizeof(IMAGE_RESOURCE_DIRECTORY));
317 ret = FALSE;
318 for (i=0;i<resdir->NumberOfNamedEntries+resdir->NumberOfIdEntries;i++) {
319 LPWSTR name;
320 if (et[i].u1.s.NameIsString)
321 name = (LPWSTR)((LPBYTE)pem->pe_resource+et[i].u1.s.NameOffset);
322 else
323 name = (LPWSTR)(int)et[i].u1.Id;
324 ret = lpfun(hmod,type,name,lparam);
325 if (!ret)
326 break;
328 return ret;
331 /**********************************************************************
332 * PE_EnumResourceNames32A
334 WIN_BOOL
335 PE_EnumResourceLanguagesA(
336 HMODULE hmod,LPCSTR name,LPCSTR type,ENUMRESLANGPROCA lpfun,
337 LONG lparam
339 PE_MODREF *pem = HMODULE32toPE_MODREF(hmod);
340 int i;
341 PIMAGE_RESOURCE_DIRECTORY resdir;
342 PIMAGE_RESOURCE_DIRECTORY_ENTRY et;
343 WIN_BOOL ret;
344 HANDLE heap = GetProcessHeap();
345 LPWSTR nameW,typeW;
347 if (!pem || !pem->pe_resource)
348 return FALSE;
350 resdir = (PIMAGE_RESOURCE_DIRECTORY)pem->pe_resource;
351 if (HIWORD(name))
352 nameW = HEAP_strdupAtoW(heap,0,name);
353 else
354 nameW = (LPWSTR)name;
355 resdir = GetResDirEntryW(resdir,nameW,(DWORD)pem->pe_resource,FALSE);
356 if (HIWORD(nameW))
357 HeapFree(heap,0,nameW);
358 if (!resdir)
359 return FALSE;
360 if (HIWORD(type))
361 typeW = HEAP_strdupAtoW(heap,0,type);
362 else
363 typeW = (LPWSTR)type;
364 resdir = GetResDirEntryW(resdir,typeW,(DWORD)pem->pe_resource,FALSE);
365 if (HIWORD(typeW))
366 HeapFree(heap,0,typeW);
367 if (!resdir)
368 return FALSE;
369 et =(PIMAGE_RESOURCE_DIRECTORY_ENTRY)((LPBYTE)resdir+sizeof(IMAGE_RESOURCE_DIRECTORY));
370 ret = FALSE;
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);
374 if (!ret)
375 break;
377 return ret;
380 /**********************************************************************
381 * PE_EnumResourceLanguages32W
383 WIN_BOOL
384 PE_EnumResourceLanguagesW(
385 HMODULE hmod,LPCWSTR name,LPCWSTR type,ENUMRESLANGPROCW lpfun,
386 LONG lparam
388 PE_MODREF *pem = HMODULE32toPE_MODREF(hmod);
389 int i;
390 PIMAGE_RESOURCE_DIRECTORY resdir;
391 PIMAGE_RESOURCE_DIRECTORY_ENTRY et;
392 WIN_BOOL ret;
394 if (!pem || !pem->pe_resource)
395 return FALSE;
397 resdir = (PIMAGE_RESOURCE_DIRECTORY)pem->pe_resource;
398 resdir = GetResDirEntryW(resdir,name,(DWORD)pem->pe_resource,FALSE);
399 if (!resdir)
400 return FALSE;
401 resdir = GetResDirEntryW(resdir,type,(DWORD)pem->pe_resource,FALSE);
402 if (!resdir)
403 return FALSE;
404 et =(PIMAGE_RESOURCE_DIRECTORY_ENTRY)((LPBYTE)resdir+sizeof(IMAGE_RESOURCE_DIRECTORY));
405 ret = FALSE;
406 for (i=0;i<resdir->NumberOfNamedEntries+resdir->NumberOfIdEntries;i++) {
407 ret = lpfun(hmod,name,type,et[i].u1.Id,lparam);
408 if (!ret)
409 break;
411 return ret;