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