]> git.sesse.net Git - vlc/blob - loader/pe_resource.c
don't use float32 by default (should fix sound issues under windows)
[vlc] / loader / pe_resource.c
1 /*
2  * PE (Portable Execute) File Resources
3  *
4  * Copyright 1995 Thomas Sandford
5  * Copyright 1996 Martin von Loewis
6  *
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
11  *
12  * Modified for use with MPlayer, detailed CVS changelog at
13  * http://www.mplayerhq.hu/cgi-bin/cvsweb.cgi/main/
14  * $Id$
15  *
16  */
17 #include "config.h"
18
19 #include <stdlib.h>
20 #include <sys/types.h>
21 #include "wine/winestring.h"
22 #include "wine/windef.h"
23 #include "wine/pe_image.h"
24 #include "wine/module.h"
25 #include "wine/heap.h"
26 //#include "task.h"
27 //#include "process.h"
28 //#include "stackframe.h"
29 #include "wine/debugtools.h"
30 #include "ext.h"
31
32 /**********************************************************************
33  *  HMODULE32toPE_MODREF 
34  *
35  * small helper function to get a PE_MODREF from a passed HMODULE32
36  */
37 static PE_MODREF*
38 HMODULE32toPE_MODREF(HMODULE hmod) {
39         WINE_MODREF     *wm;
40
41         wm = MODULE32_LookupHMODULE( hmod );
42         if (!wm || wm->type!=MODULE32_PE)
43                 return NULL;
44         return &(wm->binfmt.pe);
45 }
46
47 /**********************************************************************
48  *          GetResDirEntryW
49  *
50  *      Helper function - goes down one level of PE resource tree
51  *
52  */
53 PIMAGE_RESOURCE_DIRECTORY GetResDirEntryW(PIMAGE_RESOURCE_DIRECTORY resdirptr,
54                                            LPCWSTR name,DWORD root,
55                                            WIN_BOOL allowdefault)
56 {
57     int entrynum;
58     PIMAGE_RESOURCE_DIRECTORY_ENTRY entryTable;
59     int namelen;
60
61     if (HIWORD(name)) {
62         if (name[0]=='#') {
63                 char    buf[10];
64
65                 lstrcpynWtoA(buf,name+1,10);
66                 return GetResDirEntryW(resdirptr,(LPCWSTR)atoi(buf),root,allowdefault);
67         }
68         entryTable = (PIMAGE_RESOURCE_DIRECTORY_ENTRY) (
69                         (BYTE *) resdirptr + 
70                         sizeof(IMAGE_RESOURCE_DIRECTORY));
71         namelen = lstrlenW(name);
72         for (entrynum = 0; entrynum < resdirptr->NumberOfNamedEntries; entrynum++)
73         {
74                 PIMAGE_RESOURCE_DIR_STRING_U str =
75                 (PIMAGE_RESOURCE_DIR_STRING_U) (root + 
76                         entryTable[entrynum].u1.s.NameOffset);
77                 if(namelen != str->Length)
78                         continue;
79                 if(wcsnicmp(name,str->NameString,str->Length)==0)
80                         return (PIMAGE_RESOURCE_DIRECTORY) (
81                                 root +
82                                 entryTable[entrynum].u2.s.OffsetToDirectory);
83         }
84         return NULL;
85     } else {
86         entryTable = (PIMAGE_RESOURCE_DIRECTORY_ENTRY) (
87                         (BYTE *) resdirptr + 
88                         sizeof(IMAGE_RESOURCE_DIRECTORY) +
89                         resdirptr->NumberOfNamedEntries * sizeof(IMAGE_RESOURCE_DIRECTORY_ENTRY));
90         for (entrynum = 0; entrynum < resdirptr->NumberOfIdEntries; entrynum++)
91             if ((DWORD)entryTable[entrynum].u1.Name == (DWORD)name)
92                 return (PIMAGE_RESOURCE_DIRECTORY) (
93                         root +
94                         entryTable[entrynum].u2.s.OffsetToDirectory);
95         /* just use first entry if no default can be found */
96         if (allowdefault && !name && resdirptr->NumberOfIdEntries)
97                 return (PIMAGE_RESOURCE_DIRECTORY) (
98                         root +
99                         entryTable[0].u2.s.OffsetToDirectory);
100         return NULL;
101     }
102 }
103
104 /**********************************************************************
105  *          GetResDirEntryA
106  */
107 PIMAGE_RESOURCE_DIRECTORY GetResDirEntryA( PIMAGE_RESOURCE_DIRECTORY resdirptr,
108                                            LPCSTR name, DWORD root,
109                                            WIN_BOOL allowdefault )
110 {
111     PIMAGE_RESOURCE_DIRECTORY retv;
112     LPWSTR nameW = HIWORD(name)? HEAP_strdupAtoW( GetProcessHeap(), 0, name ) 
113                                : (LPWSTR)name;
114
115     retv = GetResDirEntryW( resdirptr, nameW, root, allowdefault );
116
117     if ( HIWORD(name) ) HeapFree( GetProcessHeap(), 0, nameW );
118
119     return retv;
120 }
121
122 /**********************************************************************
123  *          PE_FindResourceEx32W
124  */
125 HANDLE PE_FindResourceExW(
126         WINE_MODREF *wm,LPCWSTR name,LPCWSTR type,WORD lang
127 ) {
128     PIMAGE_RESOURCE_DIRECTORY resdirptr;
129     DWORD root;
130     HANDLE result;
131     PE_MODREF   *pem = &(wm->binfmt.pe);
132
133     if (!pem || !pem->pe_resource)
134         return 0;
135
136     resdirptr = pem->pe_resource;
137     root = (DWORD) resdirptr;
138     if ((resdirptr = GetResDirEntryW(resdirptr, type, root, FALSE)) == NULL)
139         return 0;
140     if ((resdirptr = GetResDirEntryW(resdirptr, name, root, FALSE)) == NULL)
141         return 0;
142     result = (HANDLE)GetResDirEntryW(resdirptr, (LPCWSTR)(UINT)lang, root, FALSE);
143         /* Try LANG_NEUTRAL, too */
144     if(!result)
145         return (HANDLE)GetResDirEntryW(resdirptr, (LPCWSTR)0, root, TRUE);
146     return result;
147 }
148
149
150 /**********************************************************************
151  *          PE_LoadResource32
152  */
153 HANDLE PE_LoadResource( WINE_MODREF *wm, HANDLE hRsrc )
154 {
155     if (!hRsrc || !wm || wm->type!=MODULE32_PE)
156         return 0;
157     return (HANDLE) (wm->module + ((PIMAGE_RESOURCE_DATA_ENTRY)hRsrc)->OffsetToData);
158 }
159
160
161 /**********************************************************************
162  *          PE_SizeofResource32
163  */
164 DWORD PE_SizeofResource( HINSTANCE hModule, HANDLE hRsrc )
165 {
166     /* we don't need hModule */
167     if (!hRsrc)
168          return 0;
169     return ((PIMAGE_RESOURCE_DATA_ENTRY)hRsrc)->Size;
170 }
171
172 /**********************************************************************
173  *          PE_EnumResourceTypes32A
174  */
175 WIN_BOOL
176 PE_EnumResourceTypesA(HMODULE hmod,ENUMRESTYPEPROCA lpfun,LONG lparam) {
177     PE_MODREF   *pem = HMODULE32toPE_MODREF(hmod);
178     int         i;
179     PIMAGE_RESOURCE_DIRECTORY           resdir;
180     PIMAGE_RESOURCE_DIRECTORY_ENTRY     et;
181     WIN_BOOL    ret;
182     HANDLE      heap = GetProcessHeap();        
183
184     if (!pem || !pem->pe_resource)
185         return FALSE;
186
187     resdir = (PIMAGE_RESOURCE_DIRECTORY)pem->pe_resource;
188     et =(PIMAGE_RESOURCE_DIRECTORY_ENTRY)((LPBYTE)resdir+sizeof(IMAGE_RESOURCE_DIRECTORY));
189     ret = FALSE;
190     for (i=0;i<resdir->NumberOfNamedEntries+resdir->NumberOfIdEntries;i++) {
191         LPSTR   name;
192
193         if (et[i].u1.s.NameIsString)
194                 name = HEAP_strdupWtoA(heap,0,(LPWSTR)((LPBYTE)pem->pe_resource+et[i].u1.s.NameOffset));
195         else
196                 name = (LPSTR)(int)et[i].u1.Id;
197         ret = lpfun(hmod,name,lparam);
198         if (HIWORD(name))
199                 HeapFree(heap,0,name);
200         if (!ret)
201                 break;
202     }
203     return ret;
204 }
205
206 /**********************************************************************
207  *          PE_EnumResourceTypes32W
208  */
209 WIN_BOOL
210 PE_EnumResourceTypesW(HMODULE hmod,ENUMRESTYPEPROCW lpfun,LONG lparam) {
211     PE_MODREF   *pem = HMODULE32toPE_MODREF(hmod);
212     int         i;
213     PIMAGE_RESOURCE_DIRECTORY           resdir;
214     PIMAGE_RESOURCE_DIRECTORY_ENTRY     et;
215     WIN_BOOL    ret;
216
217     if (!pem || !pem->pe_resource)
218         return FALSE;
219
220     resdir = (PIMAGE_RESOURCE_DIRECTORY)pem->pe_resource;
221     et =(PIMAGE_RESOURCE_DIRECTORY_ENTRY)((LPBYTE)resdir+sizeof(IMAGE_RESOURCE_DIRECTORY));
222     ret = FALSE;
223     for (i=0;i<resdir->NumberOfNamedEntries+resdir->NumberOfIdEntries;i++) {
224         LPWSTR  type;
225         if (et[i].u1.s.NameIsString)
226                 type = (LPWSTR)((LPBYTE)pem->pe_resource+et[i].u1.s.NameOffset);
227         else
228                 type = (LPWSTR)(int)et[i].u1.Id;
229
230         ret = lpfun(hmod,type,lparam);
231         if (!ret)
232                 break;
233     }
234     return ret;
235 }
236
237 /**********************************************************************
238  *          PE_EnumResourceNames32A
239  */
240 WIN_BOOL
241 PE_EnumResourceNamesA(
242         HMODULE hmod,LPCSTR type,ENUMRESNAMEPROCA lpfun,LONG lparam
243 ) {
244     PE_MODREF   *pem = HMODULE32toPE_MODREF(hmod);
245     int         i;
246     PIMAGE_RESOURCE_DIRECTORY           resdir;
247     PIMAGE_RESOURCE_DIRECTORY_ENTRY     et;
248     WIN_BOOL    ret;
249     HANDLE      heap = GetProcessHeap();        
250     LPWSTR      typeW;
251
252     if (!pem || !pem->pe_resource)
253         return FALSE;
254     resdir = (PIMAGE_RESOURCE_DIRECTORY)pem->pe_resource;
255     if (HIWORD(type))
256         typeW = HEAP_strdupAtoW(heap,0,type);
257     else
258         typeW = (LPWSTR)type;
259     resdir = GetResDirEntryW(resdir,typeW,(DWORD)pem->pe_resource,FALSE);
260     if (HIWORD(typeW))
261         HeapFree(heap,0,typeW);
262     if (!resdir)
263         return FALSE;
264     et =(PIMAGE_RESOURCE_DIRECTORY_ENTRY)((LPBYTE)resdir+sizeof(IMAGE_RESOURCE_DIRECTORY));
265     ret = FALSE;
266     for (i=0;i<resdir->NumberOfNamedEntries+resdir->NumberOfIdEntries;i++) {
267         LPSTR   name;
268
269         if (et[i].u1.s.NameIsString)
270             name = HEAP_strdupWtoA(heap,0,(LPWSTR)((LPBYTE)pem->pe_resource+et[i].u1.s.NameOffset));
271         else
272             name = (LPSTR)(int)et[i].u1.Id;
273         ret = lpfun(hmod,type,name,lparam);
274         if (HIWORD(name)) HeapFree(heap,0,name);
275         if (!ret)
276                 break;
277     }
278     return ret;
279 }
280
281 /**********************************************************************
282  *          PE_EnumResourceNames32W
283  */
284 WIN_BOOL
285 PE_EnumResourceNamesW(
286         HMODULE hmod,LPCWSTR type,ENUMRESNAMEPROCW lpfun,LONG lparam
287 ) {
288     PE_MODREF   *pem = HMODULE32toPE_MODREF(hmod);
289     int         i;
290     PIMAGE_RESOURCE_DIRECTORY           resdir;
291     PIMAGE_RESOURCE_DIRECTORY_ENTRY     et;
292     WIN_BOOL    ret;
293
294     if (!pem || !pem->pe_resource)
295         return FALSE;
296
297     resdir = (PIMAGE_RESOURCE_DIRECTORY)pem->pe_resource;
298     resdir = GetResDirEntryW(resdir,type,(DWORD)pem->pe_resource,FALSE);
299     if (!resdir)
300         return FALSE;
301     et =(PIMAGE_RESOURCE_DIRECTORY_ENTRY)((LPBYTE)resdir+sizeof(IMAGE_RESOURCE_DIRECTORY));
302     ret = FALSE;
303     for (i=0;i<resdir->NumberOfNamedEntries+resdir->NumberOfIdEntries;i++) {
304         LPWSTR  name;
305         if (et[i].u1.s.NameIsString)
306                 name = (LPWSTR)((LPBYTE)pem->pe_resource+et[i].u1.s.NameOffset);
307         else
308                 name = (LPWSTR)(int)et[i].u1.Id;
309         ret = lpfun(hmod,type,name,lparam);
310         if (!ret)
311                 break;
312     }
313     return ret;
314 }
315
316 /**********************************************************************
317  *          PE_EnumResourceNames32A
318  */
319 WIN_BOOL
320 PE_EnumResourceLanguagesA(
321         HMODULE hmod,LPCSTR name,LPCSTR type,ENUMRESLANGPROCA lpfun,
322         LONG lparam
323 ) {
324     PE_MODREF   *pem = HMODULE32toPE_MODREF(hmod);
325     int         i;
326     PIMAGE_RESOURCE_DIRECTORY           resdir;
327     PIMAGE_RESOURCE_DIRECTORY_ENTRY     et;
328     WIN_BOOL    ret;
329     HANDLE      heap = GetProcessHeap();        
330     LPWSTR      nameW,typeW;
331
332     if (!pem || !pem->pe_resource)
333         return FALSE;
334
335     resdir = (PIMAGE_RESOURCE_DIRECTORY)pem->pe_resource;
336     if (HIWORD(name))
337         nameW = HEAP_strdupAtoW(heap,0,name);
338     else
339         nameW = (LPWSTR)name;
340     resdir = GetResDirEntryW(resdir,nameW,(DWORD)pem->pe_resource,FALSE);
341     if (HIWORD(nameW))
342         HeapFree(heap,0,nameW);
343     if (!resdir)
344         return FALSE;
345     if (HIWORD(type))
346         typeW = HEAP_strdupAtoW(heap,0,type);
347     else
348         typeW = (LPWSTR)type;
349     resdir = GetResDirEntryW(resdir,typeW,(DWORD)pem->pe_resource,FALSE);
350     if (HIWORD(typeW))
351         HeapFree(heap,0,typeW);
352     if (!resdir)
353         return FALSE;
354     et =(PIMAGE_RESOURCE_DIRECTORY_ENTRY)((LPBYTE)resdir+sizeof(IMAGE_RESOURCE_DIRECTORY));
355     ret = FALSE;
356     for (i=0;i<resdir->NumberOfNamedEntries+resdir->NumberOfIdEntries;i++) {
357         /* languages are just ids... I hopem */
358         ret = lpfun(hmod,name,type,et[i].u1.Id,lparam);
359         if (!ret)
360                 break;
361     }
362     return ret;
363 }
364
365 /**********************************************************************
366  *          PE_EnumResourceLanguages32W
367  */
368 WIN_BOOL
369 PE_EnumResourceLanguagesW(
370         HMODULE hmod,LPCWSTR name,LPCWSTR type,ENUMRESLANGPROCW lpfun,
371         LONG lparam
372 ) {
373     PE_MODREF   *pem = HMODULE32toPE_MODREF(hmod);
374     int         i;
375     PIMAGE_RESOURCE_DIRECTORY           resdir;
376     PIMAGE_RESOURCE_DIRECTORY_ENTRY     et;
377     WIN_BOOL    ret;
378
379     if (!pem || !pem->pe_resource)
380         return FALSE;
381
382     resdir = (PIMAGE_RESOURCE_DIRECTORY)pem->pe_resource;
383     resdir = GetResDirEntryW(resdir,name,(DWORD)pem->pe_resource,FALSE);
384     if (!resdir)
385         return FALSE;
386     resdir = GetResDirEntryW(resdir,type,(DWORD)pem->pe_resource,FALSE);
387     if (!resdir)
388         return FALSE;
389     et =(PIMAGE_RESOURCE_DIRECTORY_ENTRY)((LPBYTE)resdir+sizeof(IMAGE_RESOURCE_DIRECTORY));
390     ret = FALSE;
391     for (i=0;i<resdir->NumberOfNamedEntries+resdir->NumberOfIdEntries;i++) {
392         ret = lpfun(hmod,name,type,et[i].u1.Id,lparam);
393         if (!ret)
394                 break;
395     }
396     return ret;
397 }