Fix signed/unsigned comparison warnings.
[wine] / dlls / kernel / resource.c
1 /*
2  * Resources
3  *
4  * Copyright 1993 Robert J. Amstadt
5  * Copyright 1995, 2003 Alexandre Julliard
6  *
7  * This library is free software; you can redistribute it and/or
8  * modify it under the terms of the GNU Lesser General Public
9  * License as published by the Free Software Foundation; either
10  * version 2.1 of the License, or (at your option) any later version.
11  *
12  * This library is distributed in the hope that it will be useful,
13  * but WITHOUT ANY WARRANTY; without even the implied warranty of
14  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
15  * Lesser General Public License for more details.
16  *
17  * You should have received a copy of the GNU Lesser General Public
18  * License along with this library; if not, write to the Free Software
19  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
20  */
21
22 #include "config.h"
23 #include "wine/port.h"
24
25 #include <stdarg.h>
26
27 #define NONAMELESSUNION
28 #define NONAMELESSSTRUCT
29 #include "ntstatus.h"
30 #include "windef.h"
31 #include "winbase.h"
32 #include "winreg.h"
33 #include "winternl.h"
34 #include "wownt32.h"
35 #include "wine/winbase16.h"
36 #include "wine/debug.h"
37 #include "excpt.h"
38 #include "wine/exception.h"
39
40 WINE_DEFAULT_DEBUG_CHANNEL(resource);
41
42 /* handle conversions */
43 #define HRSRC_32(h16)   ((HRSRC)(ULONG_PTR)(h16))
44 #define HRSRC_16(h32)   (LOWORD(h32))
45 #define HGLOBAL_32(h16) ((HGLOBAL)(ULONG_PTR)(h16))
46 #define HGLOBAL_16(h32) (LOWORD(h32))
47 #define HMODULE_16(h32) (LOWORD(h32))
48
49 static WINE_EXCEPTION_FILTER(page_fault)
50 {
51     if (GetExceptionCode() == EXCEPTION_ACCESS_VIOLATION ||
52         GetExceptionCode() == EXCEPTION_PRIV_INSTRUCTION)
53         return EXCEPTION_EXECUTE_HANDLER;
54     return EXCEPTION_CONTINUE_SEARCH;
55 }
56
57 /* retrieve the resource name to pass to the ntdll functions */
58 static NTSTATUS get_res_nameA( LPCSTR name, UNICODE_STRING *str )
59 {
60     if (!HIWORD(name))
61     {
62         str->Buffer = (LPWSTR)name;
63         return STATUS_SUCCESS;
64     }
65     if (name[0] == '#')
66     {
67         ULONG value;
68         if (RtlCharToInteger( name + 1, 10, &value ) != STATUS_SUCCESS || HIWORD(value))
69             return STATUS_INVALID_PARAMETER;
70         str->Buffer = (LPWSTR)value;
71         return STATUS_SUCCESS;
72     }
73     RtlCreateUnicodeStringFromAsciiz( str, name );
74     RtlUpcaseUnicodeString( str, str, FALSE );
75     return STATUS_SUCCESS;
76 }
77
78 /* retrieve the resource name to pass to the ntdll functions */
79 static NTSTATUS get_res_nameW( LPCWSTR name, UNICODE_STRING *str )
80 {
81     if (!HIWORD(name))
82     {
83         str->Buffer = (LPWSTR)name;
84         return STATUS_SUCCESS;
85     }
86     if (name[0] == '#')
87     {
88         ULONG value;
89         RtlInitUnicodeString( str, name + 1 );
90         if (RtlUnicodeStringToInteger( str, 10, &value ) != STATUS_SUCCESS || HIWORD(value))
91             return STATUS_INVALID_PARAMETER;
92         str->Buffer = (LPWSTR)value;
93         return STATUS_SUCCESS;
94     }
95     RtlCreateUnicodeString( str, name );
96     RtlUpcaseUnicodeString( str, str, FALSE );
97     return STATUS_SUCCESS;
98 }
99
100 /* retrieve the resource names for the 16-bit FindResource function */
101 static BOOL get_res_name_type_WtoA( LPCWSTR name, LPCWSTR type, LPSTR *nameA, LPSTR *typeA )
102 {
103     *nameA = *typeA = NULL;
104
105     __TRY
106     {
107         if (HIWORD(name))
108         {
109             DWORD len = WideCharToMultiByte( CP_ACP, 0, name, -1, NULL, 0, NULL, NULL );
110             *nameA = HeapAlloc( GetProcessHeap(), 0, len );
111             if (*nameA) WideCharToMultiByte( CP_ACP, 0, name, -1, *nameA, len, NULL, NULL );
112         }
113         else *nameA = (LPSTR)name;
114
115         if (HIWORD(type))
116         {
117             DWORD len = WideCharToMultiByte( CP_ACP, 0, type, -1, NULL, 0, NULL, NULL );
118             *typeA = HeapAlloc( GetProcessHeap(), 0, len );
119             if (*typeA) WideCharToMultiByte( CP_ACP, 0, type, -1, *typeA, len, NULL, NULL );
120         }
121         else *typeA = (LPSTR)type;
122     }
123     __EXCEPT(page_fault)
124     {
125         if (HIWORD(*nameA)) HeapFree( GetProcessHeap(), 0, *nameA );
126         if (HIWORD(*typeA)) HeapFree( GetProcessHeap(), 0, *typeA );
127         SetLastError( ERROR_INVALID_PARAMETER );
128         return FALSE;
129     }
130     __ENDTRY
131     return TRUE;
132 }
133
134 /* implementation of FindResourceExA */
135 static HRSRC find_resourceA( HMODULE hModule, LPCSTR type, LPCSTR name, WORD lang )
136 {
137     NTSTATUS status;
138     UNICODE_STRING nameW, typeW;
139     LDR_RESOURCE_INFO info;
140     const IMAGE_RESOURCE_DATA_ENTRY *entry = NULL;
141
142     __TRY
143     {
144         if ((status = get_res_nameA( name, &nameW )) != STATUS_SUCCESS) goto done;
145         if ((status = get_res_nameA( type, &typeW )) != STATUS_SUCCESS) goto done;
146         info.Type = (ULONG)typeW.Buffer;
147         info.Name = (ULONG)nameW.Buffer;
148         info.Language = lang;
149         status = LdrFindResource_U( hModule, &info, 3, &entry );
150     done:
151         if (status != STATUS_SUCCESS) SetLastError( RtlNtStatusToDosError(status) );
152     }
153     __EXCEPT(page_fault)
154     {
155         SetLastError( ERROR_INVALID_PARAMETER );
156     }
157     __ENDTRY
158
159     if (HIWORD(nameW.Buffer)) HeapFree( GetProcessHeap(), 0, nameW.Buffer );
160     if (HIWORD(typeW.Buffer)) HeapFree( GetProcessHeap(), 0, typeW.Buffer );
161     return (HRSRC)entry;
162 }
163
164
165 /* implementation of FindResourceExW */
166 static HRSRC find_resourceW( HMODULE hModule, LPCWSTR type, LPCWSTR name, WORD lang )
167 {
168     NTSTATUS status;
169     UNICODE_STRING nameW, typeW;
170     LDR_RESOURCE_INFO info;
171     const IMAGE_RESOURCE_DATA_ENTRY *entry = NULL;
172
173     nameW.Buffer = typeW.Buffer = NULL;
174
175     __TRY
176     {
177         if ((status = get_res_nameW( name, &nameW )) != STATUS_SUCCESS) goto done;
178         if ((status = get_res_nameW( type, &typeW )) != STATUS_SUCCESS) goto done;
179         info.Type = (ULONG)typeW.Buffer;
180         info.Name = (ULONG)nameW.Buffer;
181         info.Language = lang;
182         status = LdrFindResource_U( hModule, &info, 3, &entry );
183     done:
184         if (status != STATUS_SUCCESS) SetLastError( RtlNtStatusToDosError(status) );
185     }
186     __EXCEPT(page_fault)
187     {
188         SetLastError( ERROR_INVALID_PARAMETER );
189     }
190     __ENDTRY
191
192     if (HIWORD(nameW.Buffer)) HeapFree( GetProcessHeap(), 0, nameW.Buffer );
193     if (HIWORD(typeW.Buffer)) HeapFree( GetProcessHeap(), 0, typeW.Buffer );
194     return (HRSRC)entry;
195 }
196
197 /**********************************************************************
198  *          FindResourceExA  (KERNEL32.@)
199  */
200 HRSRC WINAPI FindResourceExA( HMODULE hModule, LPCSTR type, LPCSTR name, WORD lang )
201 {
202     TRACE( "%p %s %s %04x\n", hModule, debugstr_a(type), debugstr_a(name), lang );
203
204     if (!hModule) hModule = GetModuleHandleW(0);
205     else if (!HIWORD(hModule))
206     {
207         return HRSRC_32( FindResource16( HMODULE_16(hModule), name, type ) );
208     }
209     return find_resourceA( hModule, type, name, lang );
210 }
211
212
213 /**********************************************************************
214  *          FindResourceA    (KERNEL32.@)
215  */
216 HRSRC WINAPI FindResourceA( HMODULE hModule, LPCSTR name, LPCSTR type )
217 {
218     return FindResourceExA( hModule, type, name, MAKELANGID( LANG_NEUTRAL, SUBLANG_NEUTRAL ) );
219 }
220
221
222 /**********************************************************************
223  *          FindResourceExW  (KERNEL32.@)
224  */
225 HRSRC WINAPI FindResourceExW( HMODULE hModule, LPCWSTR type, LPCWSTR name, WORD lang )
226 {
227     TRACE( "%p %s %s %04x\n", hModule, debugstr_w(type), debugstr_w(name), lang );
228
229     if (!hModule) hModule = GetModuleHandleW(0);
230     else if (!HIWORD(hModule))
231     {
232         LPSTR nameA, typeA;
233         HRSRC16 ret;
234
235         if (!get_res_name_type_WtoA( name, type, &nameA, &typeA )) return NULL;
236
237         ret = FindResource16( HMODULE_16(hModule), nameA, typeA );
238         if (HIWORD(nameA)) HeapFree( GetProcessHeap(), 0, nameA );
239         if (HIWORD(typeA)) HeapFree( GetProcessHeap(), 0, typeA );
240         return HRSRC_32(ret);
241     }
242
243     return find_resourceW( hModule, type, name, lang );
244 }
245
246
247 /**********************************************************************
248  *          FindResourceW    (KERNEL32.@)
249  */
250 HRSRC WINAPI FindResourceW( HINSTANCE hModule, LPCWSTR name, LPCWSTR type )
251 {
252     return FindResourceExW( hModule, type, name, MAKELANGID( LANG_NEUTRAL, SUBLANG_NEUTRAL ) );
253 }
254
255
256 /**********************************************************************
257  *      EnumResourceTypesA      (KERNEL32.@)
258  */
259 BOOL WINAPI EnumResourceTypesA( HMODULE hmod, ENUMRESTYPEPROCA lpfun, LONG_PTR lparam )
260 {
261     int i;
262     BOOL ret = FALSE;
263     LPSTR type = NULL;
264     DWORD len = 0, newlen;
265     NTSTATUS status;
266     const IMAGE_RESOURCE_DIRECTORY *resdir;
267     const IMAGE_RESOURCE_DIRECTORY_ENTRY *et;
268     const IMAGE_RESOURCE_DIR_STRING_U *str;
269
270     TRACE( "%p %p %lx\n", hmod, lpfun, lparam );
271
272     if (!hmod) hmod = GetModuleHandleA( NULL );
273
274     if ((status = LdrFindResourceDirectory_U( hmod, NULL, 0, &resdir )) != STATUS_SUCCESS)
275     {
276         SetLastError( RtlNtStatusToDosError(status) );
277         return FALSE;
278     }
279     et = (PIMAGE_RESOURCE_DIRECTORY_ENTRY)(resdir + 1);
280     for (i = 0; i < resdir->NumberOfNamedEntries+resdir->NumberOfIdEntries; i++)
281     {
282         if (et[i].u1.s1.NameIsString)
283         {
284             str = (PIMAGE_RESOURCE_DIR_STRING_U) ((LPBYTE) resdir + et[i].u1.s1.NameOffset);
285             newlen = WideCharToMultiByte( CP_ACP, 0, str->NameString, str->Length, NULL, 0, NULL, NULL);
286             if (newlen + 1 > len)
287             {
288                 len = newlen + 1;
289                 if (type) HeapFree( GetProcessHeap(), 0, type );
290                 if (!(type = HeapAlloc( GetProcessHeap(), 0, len ))) return FALSE;
291             }
292             WideCharToMultiByte( CP_ACP, 0, str->NameString, str->Length, type, len, NULL, NULL);
293             type[newlen] = 0;
294             ret = lpfun(hmod,type,lparam);
295         }
296         else
297         {
298             ret = lpfun( hmod, (LPSTR)(int)et[i].u1.s2.Id, lparam );
299         }
300         if (!ret) break;
301     }
302     if (type) HeapFree( GetProcessHeap(), 0, type );
303     return ret;
304 }
305
306
307 /**********************************************************************
308  *      EnumResourceTypesW      (KERNEL32.@)
309  */
310 BOOL WINAPI EnumResourceTypesW( HMODULE hmod, ENUMRESTYPEPROCW lpfun, LONG_PTR lparam )
311 {
312     int i, len = 0;
313     BOOL ret = FALSE;
314     LPWSTR type = NULL;
315     NTSTATUS status;
316     const IMAGE_RESOURCE_DIRECTORY *resdir;
317     const IMAGE_RESOURCE_DIRECTORY_ENTRY *et;
318     const IMAGE_RESOURCE_DIR_STRING_U *str;
319
320     TRACE( "%p %p %lx\n", hmod, lpfun, lparam );
321
322     if (!hmod) hmod = GetModuleHandleW( NULL );
323
324     if ((status = LdrFindResourceDirectory_U( hmod, NULL, 0, &resdir )) != STATUS_SUCCESS)
325     {
326         SetLastError( RtlNtStatusToDosError(status) );
327         return FALSE;
328     }
329     et = (PIMAGE_RESOURCE_DIRECTORY_ENTRY)(resdir + 1);
330     for (i = 0; i < resdir->NumberOfNamedEntries + resdir->NumberOfIdEntries; i++)
331     {
332         if (et[i].u1.s1.NameIsString)
333         {
334             str = (PIMAGE_RESOURCE_DIR_STRING_U) ((LPBYTE) resdir + et[i].u1.s1.NameOffset);
335             if (str->Length + 1 > len)
336             {
337                 len = str->Length + 1;
338                 if (type) HeapFree( GetProcessHeap(), 0, type );
339                 if (!(type = HeapAlloc( GetProcessHeap(), 0, len * sizeof(WCHAR) ))) return FALSE;
340             }
341             memcpy(type, str->NameString, str->Length * sizeof (WCHAR));
342             type[str->Length] = 0;
343             ret = lpfun(hmod,type,lparam);
344         }
345         else
346         {
347             ret = lpfun( hmod, (LPWSTR)(int)et[i].u1.s2.Id, lparam );
348         }
349         if (!ret) break;
350     }
351     if (type) HeapFree( GetProcessHeap(), 0, type );
352     return ret;
353 }
354
355
356 /**********************************************************************
357  *      EnumResourceNamesA      (KERNEL32.@)
358  */
359 BOOL WINAPI EnumResourceNamesA( HMODULE hmod, LPCSTR type, ENUMRESNAMEPROCA lpfun, LONG_PTR lparam )
360 {
361     int i;
362     BOOL ret = FALSE;
363     DWORD len = 0, newlen;
364     LPSTR name = NULL;
365     NTSTATUS status;
366     UNICODE_STRING typeW;
367     LDR_RESOURCE_INFO info;
368     const IMAGE_RESOURCE_DIRECTORY *basedir, *resdir;
369     const IMAGE_RESOURCE_DIRECTORY_ENTRY *et;
370     const IMAGE_RESOURCE_DIR_STRING_U *str;
371
372     TRACE( "%p %s %p %lx\n", hmod, debugstr_a(type), lpfun, lparam );
373
374     if (!hmod) hmod = GetModuleHandleA( NULL );
375     typeW.Buffer = NULL;
376     if ((status = LdrFindResourceDirectory_U( hmod, NULL, 0, &basedir )) != STATUS_SUCCESS)
377         goto done;
378     if ((status = get_res_nameA( type, &typeW )) != STATUS_SUCCESS)
379         goto done;
380     info.Type = (ULONG)typeW.Buffer;
381     if ((status = LdrFindResourceDirectory_U( hmod, &info, 1, &resdir )) != STATUS_SUCCESS)
382         goto done;
383
384     et = (IMAGE_RESOURCE_DIRECTORY_ENTRY *)(resdir + 1);
385     for (i = 0; i < resdir->NumberOfNamedEntries+resdir->NumberOfIdEntries; i++)
386     {
387         if (et[i].u1.s1.NameIsString)
388         {
389             str = (IMAGE_RESOURCE_DIR_STRING_U *) ((LPBYTE) basedir + et[i].u1.s1.NameOffset);
390             newlen = WideCharToMultiByte(CP_ACP, 0, str->NameString, str->Length, NULL, 0, NULL, NULL);
391             if (newlen + 1 > len)
392             {
393                 len = newlen + 1;
394                 if (name) HeapFree( GetProcessHeap(), 0, name );
395                 if (!(name = HeapAlloc(GetProcessHeap(), 0, len + 1 )))
396                 {
397                     ret = FALSE;
398                     break;
399                 }
400             }
401             WideCharToMultiByte( CP_ACP, 0, str->NameString, str->Length, name, len, NULL, NULL );
402             name[newlen] = 0;
403             ret = lpfun(hmod,type,name,lparam);
404         }
405         else
406         {
407             ret = lpfun( hmod, type, (LPSTR)(int)et[i].u1.s2.Id, lparam );
408         }
409         if (!ret) break;
410     }
411 done:
412     if (name) HeapFree( GetProcessHeap(), 0, name );
413     if (HIWORD(typeW.Buffer)) HeapFree( GetProcessHeap(), 0, typeW.Buffer );
414     if (status != STATUS_SUCCESS) SetLastError( RtlNtStatusToDosError(status) );
415     return ret;
416 }
417
418
419 /**********************************************************************
420  *      EnumResourceNamesW      (KERNEL32.@)
421  */
422 BOOL WINAPI EnumResourceNamesW( HMODULE hmod, LPCWSTR type, ENUMRESNAMEPROCW lpfun, LONG_PTR lparam )
423 {
424     int i, len = 0;
425     BOOL ret = FALSE;
426     LPWSTR name = NULL;
427     NTSTATUS status;
428     UNICODE_STRING typeW;
429     LDR_RESOURCE_INFO info;
430     const IMAGE_RESOURCE_DIRECTORY *basedir, *resdir;
431     const IMAGE_RESOURCE_DIRECTORY_ENTRY *et;
432     const IMAGE_RESOURCE_DIR_STRING_U *str;
433
434     TRACE( "%p %s %p %lx\n", hmod, debugstr_w(type), lpfun, lparam );
435
436     if (!hmod) hmod = GetModuleHandleW( NULL );
437     typeW.Buffer = NULL;
438     if ((status = LdrFindResourceDirectory_U( hmod, NULL, 0, &basedir )) != STATUS_SUCCESS)
439         goto done;
440     if ((status = get_res_nameW( type, &typeW )) != STATUS_SUCCESS)
441         goto done;
442     info.Type = (ULONG)typeW.Buffer;
443     if ((status = LdrFindResourceDirectory_U( hmod, &info, 1, &resdir )) != STATUS_SUCCESS)
444         goto done;
445
446     et = (PIMAGE_RESOURCE_DIRECTORY_ENTRY)(resdir + 1);
447     for (i = 0; i < resdir->NumberOfNamedEntries+resdir->NumberOfIdEntries; i++)
448     {
449         if (et[i].u1.s1.NameIsString)
450         {
451             str = (IMAGE_RESOURCE_DIR_STRING_U *) ((LPBYTE) basedir + et[i].u1.s1.NameOffset);
452             if (str->Length + 1 > len)
453             {
454                 len = str->Length + 1;
455                 if (name) HeapFree( GetProcessHeap(), 0, name );
456                 if (!(name = HeapAlloc( GetProcessHeap(), 0, len * sizeof(WCHAR) )))
457                 {
458                     ret = FALSE;
459                     break;
460                 }
461             }
462             memcpy(name, str->NameString, str->Length * sizeof (WCHAR));
463             name[str->Length] = 0;
464             ret = lpfun(hmod,type,name,lparam);
465         }
466         else
467         {
468             ret = lpfun( hmod, type, (LPWSTR)(int)et[i].u1.s2.Id, lparam );
469         }
470         if (!ret) break;
471     }
472 done:
473     if (name) HeapFree( GetProcessHeap(), 0, name );
474     if (HIWORD(typeW.Buffer)) HeapFree( GetProcessHeap(), 0, typeW.Buffer );
475     if (status != STATUS_SUCCESS) SetLastError( RtlNtStatusToDosError(status) );
476     return ret;
477 }
478
479
480 /**********************************************************************
481  *      EnumResourceLanguagesA  (KERNEL32.@)
482  */
483 BOOL WINAPI EnumResourceLanguagesA( HMODULE hmod, LPCSTR type, LPCSTR name,
484                                     ENUMRESLANGPROCA lpfun, LONG_PTR lparam )
485 {
486     int i;
487     BOOL ret = FALSE;
488     NTSTATUS status;
489     UNICODE_STRING typeW, nameW;
490     LDR_RESOURCE_INFO info;
491     const IMAGE_RESOURCE_DIRECTORY *basedir, *resdir;
492     const IMAGE_RESOURCE_DIRECTORY_ENTRY *et;
493
494     TRACE( "%p %s %s %p %lx\n", hmod, debugstr_a(type), debugstr_a(name), lpfun, lparam );
495
496     if (!hmod) hmod = GetModuleHandleA( NULL );
497     typeW.Buffer = nameW.Buffer = NULL;
498     if ((status = LdrFindResourceDirectory_U( hmod, NULL, 0, &basedir )) != STATUS_SUCCESS)
499         goto done;
500     if ((status = get_res_nameA( type, &typeW )) != STATUS_SUCCESS)
501         goto done;
502     if ((status = get_res_nameA( name, &nameW )) != STATUS_SUCCESS)
503         goto done;
504     info.Type = (ULONG)typeW.Buffer;
505     info.Name = (ULONG)nameW.Buffer;
506     if ((status = LdrFindResourceDirectory_U( hmod, &info, 2, &resdir )) != STATUS_SUCCESS)
507         goto done;
508
509     et = (PIMAGE_RESOURCE_DIRECTORY_ENTRY)(resdir + 1);
510     for (i = 0; i < resdir->NumberOfNamedEntries + resdir->NumberOfIdEntries; i++)
511     {
512         ret = lpfun( hmod, type, name, et[i].u1.s2.Id, lparam );
513         if (!ret) break;
514     }
515 done:
516     if (HIWORD(typeW.Buffer)) HeapFree( GetProcessHeap(), 0, typeW.Buffer );
517     if (HIWORD(nameW.Buffer)) HeapFree( GetProcessHeap(), 0, nameW.Buffer );
518     if (status != STATUS_SUCCESS) SetLastError( RtlNtStatusToDosError(status) );
519     return ret;
520 }
521
522
523 /**********************************************************************
524  *      EnumResourceLanguagesW  (KERNEL32.@)
525  */
526 BOOL WINAPI EnumResourceLanguagesW( HMODULE hmod, LPCWSTR type, LPCWSTR name,
527                                     ENUMRESLANGPROCW lpfun, LONG_PTR lparam )
528 {
529     int i;
530     BOOL ret = FALSE;
531     NTSTATUS status;
532     UNICODE_STRING typeW, nameW;
533     LDR_RESOURCE_INFO info;
534     const IMAGE_RESOURCE_DIRECTORY *basedir, *resdir;
535     const IMAGE_RESOURCE_DIRECTORY_ENTRY *et;
536
537     TRACE( "%p %s %s %p %lx\n", hmod, debugstr_w(type), debugstr_w(name), lpfun, lparam );
538
539     if (!hmod) hmod = GetModuleHandleW( NULL );
540     typeW.Buffer = nameW.Buffer = NULL;
541     if ((status = LdrFindResourceDirectory_U( hmod, NULL, 0, &basedir )) != STATUS_SUCCESS)
542         goto done;
543     if ((status = get_res_nameW( type, &typeW )) != STATUS_SUCCESS)
544         goto done;
545     if ((status = get_res_nameW( name, &nameW )) != STATUS_SUCCESS)
546         goto done;
547     info.Type = (ULONG)typeW.Buffer;
548     info.Name = (ULONG)nameW.Buffer;
549     if ((status = LdrFindResourceDirectory_U( hmod, &info, 2, &resdir )) != STATUS_SUCCESS)
550         goto done;
551
552     et = (PIMAGE_RESOURCE_DIRECTORY_ENTRY)(resdir + 1);
553     for (i = 0; i < resdir->NumberOfNamedEntries + resdir->NumberOfIdEntries; i++)
554     {
555         ret = lpfun( hmod, type, name, et[i].u1.s2.Id, lparam );
556         if (!ret) break;
557     }
558 done:
559     if (HIWORD(typeW.Buffer)) HeapFree( GetProcessHeap(), 0, typeW.Buffer );
560     if (HIWORD(nameW.Buffer)) HeapFree( GetProcessHeap(), 0, nameW.Buffer );
561     if (status != STATUS_SUCCESS) SetLastError( RtlNtStatusToDosError(status) );
562     return ret;
563 }
564
565
566 /**********************************************************************
567  *          LoadResource     (KERNEL32.@)
568  */
569 HGLOBAL WINAPI LoadResource( HINSTANCE hModule, HRSRC hRsrc )
570 {
571     NTSTATUS status;
572     void *ret = NULL;
573
574     TRACE( "%p %p\n", hModule, hRsrc );
575
576     if (hModule && !HIWORD(hModule))
577         /* FIXME: should convert return to 32-bit resource */
578         return HGLOBAL_32( LoadResource16( HMODULE_16(hModule), HRSRC_16(hRsrc) ) );
579
580     if (!hRsrc) return 0;
581     if (!hModule) hModule = GetModuleHandleA( NULL );
582     status = LdrAccessResource( hModule, (IMAGE_RESOURCE_DATA_ENTRY *)hRsrc, &ret, NULL );
583     if (status != STATUS_SUCCESS) SetLastError( RtlNtStatusToDosError(status) );
584     return ret;
585 }
586
587
588 /**********************************************************************
589  *          LockResource     (KERNEL32.@)
590  */
591 LPVOID WINAPI LockResource( HGLOBAL handle )
592 {
593     TRACE("(%p)\n", handle );
594
595     if (HIWORD( handle ))  /* 32-bit memory handle */
596         return (LPVOID)handle;
597
598     /* 16-bit memory handle */
599     return LockResource16( HGLOBAL_16(handle) );
600 }
601
602
603 /**********************************************************************
604  *          FreeResource     (KERNEL32.@)
605  */
606 BOOL WINAPI FreeResource( HGLOBAL handle )
607 {
608     if (HIWORD(handle)) return 0; /* 32-bit memory handle: nothing to do */
609     return FreeResource16( HGLOBAL_16(handle) );
610 }
611
612
613 /**********************************************************************
614  *          SizeofResource   (KERNEL32.@)
615  */
616 DWORD WINAPI SizeofResource( HINSTANCE hModule, HRSRC hRsrc )
617 {
618     if (hModule && !HIWORD(hModule))
619         return SizeofResource16( HMODULE_16(hModule), HRSRC_16(hRsrc) );
620
621     if (!hRsrc) return 0;
622     return ((PIMAGE_RESOURCE_DATA_ENTRY)hRsrc)->Size;
623 }
624
625
626 /***********************************************************************
627  *          BeginUpdateResourceA                 (KERNEL32.@)
628  */
629 HANDLE WINAPI BeginUpdateResourceA( LPCSTR pFileName, BOOL bDeleteExistingResources )
630 {
631   FIXME("(%s,%d): stub\n",debugstr_a(pFileName),bDeleteExistingResources);
632   SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
633   return 0;
634 }
635
636
637 /***********************************************************************
638  *          BeginUpdateResourceW                 (KERNEL32.@)
639  */
640 HANDLE WINAPI BeginUpdateResourceW( LPCWSTR pFileName, BOOL bDeleteExistingResources )
641 {
642   FIXME("(%s,%d): stub\n",debugstr_w(pFileName),bDeleteExistingResources);
643   SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
644   return 0;
645 }
646
647
648 /***********************************************************************
649  *          EndUpdateResourceA                 (KERNEL32.@)
650  */
651 BOOL WINAPI EndUpdateResourceA( HANDLE hUpdate, BOOL fDiscard )
652 {
653   FIXME("(%p,%d): stub\n",hUpdate, fDiscard);
654   SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
655   return FALSE;
656 }
657
658
659 /***********************************************************************
660  *          EndUpdateResourceW                 (KERNEL32.@)
661  */
662 BOOL WINAPI EndUpdateResourceW( HANDLE hUpdate, BOOL fDiscard )
663 {
664   FIXME("(%p,%d): stub\n",hUpdate, fDiscard);
665   SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
666   return FALSE;
667 }
668
669
670 /***********************************************************************
671  *           UpdateResourceA                 (KERNEL32.@)
672  */
673 BOOL WINAPI UpdateResourceA(
674   HANDLE  hUpdate,
675   LPCSTR  lpType,
676   LPCSTR  lpName,
677   WORD    wLanguage,
678   LPVOID  lpData,
679   DWORD   cbData)
680 {
681   FIXME(": stub\n");
682   SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
683   return FALSE;
684 }
685
686
687 /***********************************************************************
688  *           UpdateResourceW                 (KERNEL32.@)
689  */
690 BOOL WINAPI UpdateResourceW(
691   HANDLE  hUpdate,
692   LPCWSTR lpType,
693   LPCWSTR lpName,
694   WORD    wLanguage,
695   LPVOID  lpData,
696   DWORD   cbData)
697 {
698   FIXME(": stub\n");
699   SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
700   return FALSE;
701 }