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