Minor updates of Slovenian translations.
[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 #define NONAMELESSUNION
26 #define NONAMELESSSTRUCT
27 #include "windef.h"
28 #include "winternl.h"
29 #include "winbase.h"
30 #include "wownt32.h"
31 #include "wine/winbase16.h"
32 #include "wine/debug.h"
33
34 WINE_DEFAULT_DEBUG_CHANNEL(resource);
35
36 /* handle conversions */
37 #define HRSRC_32(h16)   ((HRSRC)(ULONG_PTR)(h16))
38 #define HRSRC_16(h32)   (LOWORD(h32))
39 #define HGLOBAL_32(h16) ((HGLOBAL)(ULONG_PTR)(h16))
40 #define HGLOBAL_16(h32) (LOWORD(h32))
41 #define HMODULE_16(h32) (LOWORD(h32))
42
43
44 /* retrieve the resource name to pass to the ntdll functions */
45 static NTSTATUS get_res_nameA( LPCSTR name, UNICODE_STRING *str )
46 {
47     if (!HIWORD(name))
48     {
49         str->Buffer = (LPWSTR)name;
50         return STATUS_SUCCESS;
51     }
52     if (name[0] == '#')
53     {
54         ULONG value;
55         if (RtlCharToInteger( name + 1, 10, &value ) != STATUS_SUCCESS || HIWORD(value))
56             return STATUS_INVALID_PARAMETER;
57         str->Buffer = (LPWSTR)value;
58         return STATUS_SUCCESS;
59     }
60     RtlCreateUnicodeStringFromAsciiz( str, name );
61     RtlUpcaseUnicodeString( str, str, FALSE );
62     return STATUS_SUCCESS;
63 }
64
65 /* retrieve the resource name to pass to the ntdll functions */
66 static NTSTATUS get_res_nameW( LPCWSTR name, UNICODE_STRING *str )
67 {
68     if (!HIWORD(name))
69     {
70         str->Buffer = (LPWSTR)name;
71         return STATUS_SUCCESS;
72     }
73     if (name[0] == '#')
74     {
75         ULONG value;
76         RtlInitUnicodeString( str, name + 1 );
77         if (RtlUnicodeStringToInteger( str, 10, &value ) != STATUS_SUCCESS || HIWORD(value))
78             return STATUS_INVALID_PARAMETER;
79         str->Buffer = (LPWSTR)value;
80         return STATUS_SUCCESS;
81     }
82     RtlCreateUnicodeString( str, name );
83     RtlUpcaseUnicodeString( str, str, FALSE );
84     return STATUS_SUCCESS;
85 }
86
87 /**********************************************************************
88  *          FindResourceExA  (KERNEL32.@)
89  */
90 HRSRC WINAPI FindResourceExA( HMODULE hModule, LPCSTR type, LPCSTR name, WORD lang )
91 {
92     NTSTATUS status;
93     UNICODE_STRING nameW, typeW;
94     LDR_RESOURCE_INFO info;
95     const IMAGE_RESOURCE_DATA_ENTRY *entry = NULL;
96
97     TRACE( "%p %s %s %04x\n", hModule, debugstr_a(type), debugstr_a(name), lang );
98
99     if (!hModule) hModule = GetModuleHandleW(0);
100     else if (!HIWORD(hModule))
101     {
102         return HRSRC_32( FindResource16( HMODULE_16(hModule), name, type ) );
103     }
104
105     nameW.Buffer = typeW.Buffer = NULL;
106     if ((status = get_res_nameA( name, &nameW )) != STATUS_SUCCESS) goto done;
107     if ((status = get_res_nameA( type, &typeW )) != STATUS_SUCCESS) goto done;
108     info.Type = (ULONG)typeW.Buffer;
109     info.Name = (ULONG)nameW.Buffer;
110     info.Language = lang;
111     status = LdrFindResource_U( hModule, &info, 3, &entry );
112 done:
113     if (HIWORD(nameW.Buffer)) HeapFree( GetProcessHeap(), 0, nameW.Buffer );
114     if (HIWORD(typeW.Buffer)) HeapFree( GetProcessHeap(), 0, typeW.Buffer );
115     if (status != STATUS_SUCCESS) SetLastError( RtlNtStatusToDosError(status) );
116     return (HRSRC)entry;
117 }
118
119
120 /**********************************************************************
121  *          FindResourceA    (KERNEL32.@)
122  */
123 HRSRC WINAPI FindResourceA( HMODULE hModule, LPCSTR name, LPCSTR type )
124 {
125     return FindResourceExA( hModule, type, name, MAKELANGID( LANG_NEUTRAL, SUBLANG_NEUTRAL ) );
126 }
127
128
129 /**********************************************************************
130  *          FindResourceExW  (KERNEL32.@)
131  */
132 HRSRC WINAPI FindResourceExW( HMODULE hModule, LPCWSTR type, LPCWSTR name, WORD lang )
133 {
134     NTSTATUS status;
135     UNICODE_STRING nameW, typeW;
136     LDR_RESOURCE_INFO info;
137     const IMAGE_RESOURCE_DATA_ENTRY *entry = NULL;
138
139     TRACE( "%p %s %s %04x\n", hModule, debugstr_w(type), debugstr_w(name), lang );
140
141     if (!hModule) hModule = GetModuleHandleW(0);
142     else if (!HIWORD(hModule))
143     {
144         LPSTR nameA, typeA;
145         HRSRC16 ret;
146
147         if (HIWORD(name))
148         {
149             DWORD len = WideCharToMultiByte( CP_ACP, 0, name, -1, NULL, 0, NULL, NULL );
150             nameA = HeapAlloc( GetProcessHeap(), 0, len );
151             if (nameA) WideCharToMultiByte( CP_ACP, 0, name, -1, nameA, len, NULL, NULL );
152         }
153         else nameA = (LPSTR)name;
154
155         if (HIWORD(type))
156         {
157             DWORD len = WideCharToMultiByte( CP_ACP, 0, type, -1, NULL, 0, NULL, NULL );
158             typeA = HeapAlloc( GetProcessHeap(), 0, len );
159             if (typeA) WideCharToMultiByte( CP_ACP, 0, type, -1, typeA, len, NULL, NULL );
160         }
161         else typeA = (LPSTR)type;
162
163         ret = FindResource16( HMODULE_16(hModule), nameA, typeA );
164         if (HIWORD(nameA)) HeapFree( GetProcessHeap(), 0, nameA );
165         if (HIWORD(typeA)) HeapFree( GetProcessHeap(), 0, typeA );
166         return HRSRC_32(ret);
167     }
168
169     nameW.Buffer = typeW.Buffer = NULL;
170     if ((status = get_res_nameW( name, &nameW )) != STATUS_SUCCESS) goto done;
171     if ((status = get_res_nameW( type, &typeW )) != STATUS_SUCCESS) goto done;
172     info.Type = (ULONG)typeW.Buffer;
173     info.Name = (ULONG)nameW.Buffer;
174     info.Language = lang;
175     status = LdrFindResource_U( hModule, &info, 3, &entry );
176 done:
177     if (HIWORD(nameW.Buffer)) HeapFree( GetProcessHeap(), 0, nameW.Buffer );
178     if (HIWORD(typeW.Buffer)) HeapFree( GetProcessHeap(), 0, typeW.Buffer );
179     if (status != STATUS_SUCCESS) SetLastError( RtlNtStatusToDosError(status) );
180     return (HRSRC)entry;
181 }
182
183
184 /**********************************************************************
185  *          FindResourceW    (KERNEL32.@)
186  */
187 HRSRC WINAPI FindResourceW( HINSTANCE hModule, LPCWSTR name, LPCWSTR type )
188 {
189     return FindResourceExW( hModule, type, name, MAKELANGID( LANG_NEUTRAL, SUBLANG_NEUTRAL ) );
190 }
191
192
193 /**********************************************************************
194  *      EnumResourceTypesA      (KERNEL32.@)
195  */
196 BOOL WINAPI EnumResourceTypesA( HMODULE hmod, ENUMRESTYPEPROCA lpfun, LONG_PTR lparam )
197 {
198     int i;
199     BOOL ret = FALSE;
200     LPSTR type = NULL;
201     DWORD len = 0, newlen;
202     NTSTATUS status;
203     const IMAGE_RESOURCE_DIRECTORY *resdir;
204     const IMAGE_RESOURCE_DIRECTORY_ENTRY *et;
205     const IMAGE_RESOURCE_DIR_STRING_U *str;
206
207     TRACE( "%p %p %lx\n", hmod, lpfun, lparam );
208
209     if (!hmod) hmod = GetModuleHandleA( NULL );
210
211     if ((status = LdrFindResourceDirectory_U( hmod, NULL, 0, &resdir )) != STATUS_SUCCESS)
212     {
213         SetLastError( RtlNtStatusToDosError(status) );
214         return FALSE;
215     }
216     et = (PIMAGE_RESOURCE_DIRECTORY_ENTRY)(resdir + 1);
217     for (i = 0; i < resdir->NumberOfNamedEntries+resdir->NumberOfIdEntries; i++)
218     {
219         if (et[i].u1.s1.NameIsString)
220         {
221             str = (PIMAGE_RESOURCE_DIR_STRING_U) ((LPBYTE) resdir + et[i].u1.s1.NameOffset);
222             newlen = WideCharToMultiByte( CP_ACP, 0, str->NameString, str->Length, NULL, 0, NULL, NULL);
223             if (newlen + 1 > len)
224             {
225                 len = newlen + 1;
226                 if (type) HeapFree( GetProcessHeap(), 0, type );
227                 if (!(type = HeapAlloc( GetProcessHeap(), 0, len ))) return FALSE;
228             }
229             WideCharToMultiByte( CP_ACP, 0, str->NameString, str->Length, type, len, NULL, NULL);
230             type[newlen] = 0;
231             ret = lpfun(hmod,type,lparam);
232         }
233         else
234         {
235             ret = lpfun( hmod, (LPSTR)(int)et[i].u1.s2.Id, lparam );
236         }
237         if (!ret) break;
238     }
239     if (type) HeapFree( GetProcessHeap(), 0, type );
240     return ret;
241 }
242
243
244 /**********************************************************************
245  *      EnumResourceTypesW      (KERNEL32.@)
246  */
247 BOOL WINAPI EnumResourceTypesW( HMODULE hmod, ENUMRESTYPEPROCW lpfun, LONG_PTR lparam )
248 {
249     int i;
250     BOOL ret = FALSE;
251     DWORD len = 0;
252     LPWSTR type = NULL;
253     NTSTATUS status;
254     const IMAGE_RESOURCE_DIRECTORY *resdir;
255     const IMAGE_RESOURCE_DIRECTORY_ENTRY *et;
256     const IMAGE_RESOURCE_DIR_STRING_U *str;
257
258     TRACE( "%p %p %lx\n", hmod, lpfun, lparam );
259
260     if (!hmod) hmod = GetModuleHandleW( NULL );
261
262     if ((status = LdrFindResourceDirectory_U( hmod, NULL, 0, &resdir )) != STATUS_SUCCESS)
263     {
264         SetLastError( RtlNtStatusToDosError(status) );
265         return FALSE;
266     }
267     et = (PIMAGE_RESOURCE_DIRECTORY_ENTRY)(resdir + 1);
268     for (i = 0; i < resdir->NumberOfNamedEntries + resdir->NumberOfIdEntries; i++)
269     {
270         if (et[i].u1.s1.NameIsString)
271         {
272             str = (PIMAGE_RESOURCE_DIR_STRING_U) ((LPBYTE) resdir + et[i].u1.s1.NameOffset);
273             if (str->Length + 1 > len)
274             {
275                 len = str->Length + 1;
276                 if (type) HeapFree( GetProcessHeap(), 0, type );
277                 if (!(type = HeapAlloc( GetProcessHeap(), 0, len * sizeof(WCHAR) ))) return FALSE;
278             }
279             memcpy(type, str->NameString, str->Length * sizeof (WCHAR));
280             type[str->Length] = 0;
281             ret = lpfun(hmod,type,lparam);
282         }
283         else
284         {
285             ret = lpfun( hmod, (LPWSTR)(int)et[i].u1.s2.Id, lparam );
286         }
287         if (!ret) break;
288     }
289     if (type) HeapFree( GetProcessHeap(), 0, type );
290     return ret;
291 }
292
293
294 /**********************************************************************
295  *      EnumResourceNamesA      (KERNEL32.@)
296  */
297 BOOL WINAPI EnumResourceNamesA( HMODULE hmod, LPCSTR type, ENUMRESNAMEPROCA lpfun, LONG_PTR lparam )
298 {
299     int i;
300     BOOL ret = FALSE;
301     DWORD len = 0, newlen;
302     LPSTR name = NULL;
303     NTSTATUS status;
304     UNICODE_STRING typeW;
305     LDR_RESOURCE_INFO info;
306     const IMAGE_RESOURCE_DIRECTORY *basedir, *resdir;
307     const IMAGE_RESOURCE_DIRECTORY_ENTRY *et;
308     const IMAGE_RESOURCE_DIR_STRING_U *str;
309
310     TRACE( "%p %s %p %lx\n", hmod, debugstr_a(type), lpfun, lparam );
311
312     if (!hmod) hmod = GetModuleHandleA( NULL );
313     typeW.Buffer = NULL;
314     if ((status = LdrFindResourceDirectory_U( hmod, NULL, 0, &basedir )) != STATUS_SUCCESS)
315         goto done;
316     if ((status = get_res_nameA( type, &typeW )) != STATUS_SUCCESS)
317         goto done;
318     info.Type = (ULONG)typeW.Buffer;
319     if ((status = LdrFindResourceDirectory_U( hmod, &info, 1, &resdir )) != STATUS_SUCCESS)
320         goto done;
321
322     et = (IMAGE_RESOURCE_DIRECTORY_ENTRY *)(resdir + 1);
323     for (i = 0; i < resdir->NumberOfNamedEntries+resdir->NumberOfIdEntries; i++)
324     {
325         if (et[i].u1.s1.NameIsString)
326         {
327             str = (IMAGE_RESOURCE_DIR_STRING_U *) ((LPBYTE) basedir + et[i].u1.s1.NameOffset);
328             newlen = WideCharToMultiByte(CP_ACP, 0, str->NameString, str->Length, NULL, 0, NULL, NULL);
329             if (newlen + 1 > len)
330             {
331                 len = newlen + 1;
332                 if (name) HeapFree( GetProcessHeap(), 0, name );
333                 if (!(name = HeapAlloc(GetProcessHeap(), 0, len + 1 )))
334                 {
335                     ret = FALSE;
336                     break;
337                 }
338             }
339             WideCharToMultiByte( CP_ACP, 0, str->NameString, str->Length, name, len, NULL, NULL );
340             name[newlen] = 0;
341             ret = lpfun(hmod,type,name,lparam);
342         }
343         else
344         {
345             ret = lpfun( hmod, type, (LPSTR)(int)et[i].u1.s2.Id, lparam );
346         }
347         if (!ret) break;
348     }
349 done:
350     if (name) HeapFree( GetProcessHeap(), 0, name );
351     if (HIWORD(typeW.Buffer)) HeapFree( GetProcessHeap(), 0, typeW.Buffer );
352     if (status != STATUS_SUCCESS) SetLastError( RtlNtStatusToDosError(status) );
353     return ret;
354 }
355
356
357 /**********************************************************************
358  *      EnumResourceNamesW      (KERNEL32.@)
359  */
360 BOOL WINAPI EnumResourceNamesW( HMODULE hmod, LPCWSTR type, ENUMRESNAMEPROCW lpfun, LONG_PTR lparam )
361 {
362     int i;
363     BOOL ret = FALSE;
364     LPWSTR name = NULL;
365     DWORD len = 0;
366     NTSTATUS status;
367     UNICODE_STRING typeW;
368     LDR_RESOURCE_INFO info;
369     const IMAGE_RESOURCE_DIRECTORY *basedir, *resdir;
370     const IMAGE_RESOURCE_DIRECTORY_ENTRY *et;
371     const IMAGE_RESOURCE_DIR_STRING_U *str;
372
373     TRACE( "%p %s %p %lx\n", hmod, debugstr_w(type), lpfun, lparam );
374
375     if (!hmod) hmod = GetModuleHandleW( NULL );
376     typeW.Buffer = NULL;
377     if ((status = LdrFindResourceDirectory_U( hmod, NULL, 0, &basedir )) != STATUS_SUCCESS)
378         goto done;
379     if ((status = get_res_nameW( type, &typeW )) != STATUS_SUCCESS)
380         goto done;
381     info.Type = (ULONG)typeW.Buffer;
382     if ((status = LdrFindResourceDirectory_U( hmod, &info, 1, &resdir )) != STATUS_SUCCESS)
383         goto done;
384
385     et = (PIMAGE_RESOURCE_DIRECTORY_ENTRY)(resdir + 1);
386     for (i = 0; i < resdir->NumberOfNamedEntries+resdir->NumberOfIdEntries; i++)
387     {
388         if (et[i].u1.s1.NameIsString)
389         {
390             str = (IMAGE_RESOURCE_DIR_STRING_U *) ((LPBYTE) basedir + et[i].u1.s1.NameOffset);
391             if (str->Length + 1 > len)
392             {
393                 len = str->Length + 1;
394                 if (name) HeapFree( GetProcessHeap(), 0, name );
395                 if (!(name = HeapAlloc( GetProcessHeap(), 0, len * sizeof(WCHAR) )))
396                 {
397                     ret = FALSE;
398                     break;
399                 }
400             }
401             memcpy(name, str->NameString, str->Length * sizeof (WCHAR));
402             name[str->Length] = 0;
403             ret = lpfun(hmod,type,name,lparam);
404         }
405         else
406         {
407             ret = lpfun( hmod, type, (LPWSTR)(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  *      EnumResourceLanguagesA  (KERNEL32.@)
421  */
422 BOOL WINAPI EnumResourceLanguagesA( HMODULE hmod, LPCSTR type, LPCSTR name,
423                                     ENUMRESLANGPROCA lpfun, LONG_PTR lparam )
424 {
425     int i;
426     BOOL ret = FALSE;
427     NTSTATUS status;
428     UNICODE_STRING typeW, nameW;
429     LDR_RESOURCE_INFO info;
430     const IMAGE_RESOURCE_DIRECTORY *basedir, *resdir;
431     const IMAGE_RESOURCE_DIRECTORY_ENTRY *et;
432
433     TRACE( "%p %s %s %p %lx\n", hmod, debugstr_a(type), debugstr_a(name), lpfun, lparam );
434
435     if (!hmod) hmod = GetModuleHandleA( NULL );
436     typeW.Buffer = nameW.Buffer = NULL;
437     if ((status = LdrFindResourceDirectory_U( hmod, NULL, 0, &basedir )) != STATUS_SUCCESS)
438         goto done;
439     if ((status = get_res_nameA( type, &typeW )) != STATUS_SUCCESS)
440         goto done;
441     if ((status = get_res_nameA( name, &nameW )) != STATUS_SUCCESS)
442         goto done;
443     info.Type = (ULONG)typeW.Buffer;
444     info.Name = (ULONG)nameW.Buffer;
445     if ((status = LdrFindResourceDirectory_U( hmod, &info, 2, &resdir )) != STATUS_SUCCESS)
446         goto done;
447
448     et = (PIMAGE_RESOURCE_DIRECTORY_ENTRY)(resdir + 1);
449     for (i = 0; i < resdir->NumberOfNamedEntries + resdir->NumberOfIdEntries; i++)
450     {
451         ret = lpfun( hmod, type, name, et[i].u1.s2.Id, lparam );
452         if (!ret) break;
453     }
454 done:
455     if (HIWORD(typeW.Buffer)) HeapFree( GetProcessHeap(), 0, typeW.Buffer );
456     if (HIWORD(nameW.Buffer)) HeapFree( GetProcessHeap(), 0, nameW.Buffer );
457     if (status != STATUS_SUCCESS) SetLastError( RtlNtStatusToDosError(status) );
458     return ret;
459 }
460
461
462 /**********************************************************************
463  *      EnumResourceLanguagesW  (KERNEL32.@)
464  */
465 BOOL WINAPI EnumResourceLanguagesW( HMODULE hmod, LPCWSTR type, LPCWSTR name,
466                                     ENUMRESLANGPROCW lpfun, LONG_PTR lparam )
467 {
468     int i;
469     BOOL ret = FALSE;
470     NTSTATUS status;
471     UNICODE_STRING typeW, nameW;
472     LDR_RESOURCE_INFO info;
473     const IMAGE_RESOURCE_DIRECTORY *basedir, *resdir;
474     const IMAGE_RESOURCE_DIRECTORY_ENTRY *et;
475
476     TRACE( "%p %s %s %p %lx\n", hmod, debugstr_w(type), debugstr_w(name), lpfun, lparam );
477
478     if (!hmod) hmod = GetModuleHandleW( NULL );
479     typeW.Buffer = nameW.Buffer = NULL;
480     if ((status = LdrFindResourceDirectory_U( hmod, NULL, 0, &basedir )) != STATUS_SUCCESS)
481         goto done;
482     if ((status = get_res_nameW( type, &typeW )) != STATUS_SUCCESS)
483         goto done;
484     if ((status = get_res_nameW( name, &nameW )) != STATUS_SUCCESS)
485         goto done;
486     info.Type = (ULONG)typeW.Buffer;
487     info.Name = (ULONG)nameW.Buffer;
488     if ((status = LdrFindResourceDirectory_U( hmod, &info, 2, &resdir )) != STATUS_SUCCESS)
489         goto done;
490
491     et = (PIMAGE_RESOURCE_DIRECTORY_ENTRY)(resdir + 1);
492     for (i = 0; i < resdir->NumberOfNamedEntries + resdir->NumberOfIdEntries; i++)
493     {
494         ret = lpfun( hmod, type, name, et[i].u1.s2.Id, lparam );
495         if (!ret) break;
496     }
497 done:
498     if (HIWORD(typeW.Buffer)) HeapFree( GetProcessHeap(), 0, typeW.Buffer );
499     if (HIWORD(nameW.Buffer)) HeapFree( GetProcessHeap(), 0, nameW.Buffer );
500     if (status != STATUS_SUCCESS) SetLastError( RtlNtStatusToDosError(status) );
501     return ret;
502 }
503
504
505 /**********************************************************************
506  *          LoadResource     (KERNEL32.@)
507  */
508 HGLOBAL WINAPI LoadResource( HINSTANCE hModule, HRSRC hRsrc )
509 {
510     NTSTATUS status;
511     void *ret = NULL;
512
513     TRACE( "%p %p\n", hModule, hRsrc );
514
515     if (hModule && !HIWORD(hModule))
516         /* FIXME: should convert return to 32-bit resource */
517         return HGLOBAL_32( LoadResource16( HMODULE_16(hModule), HRSRC_16(hRsrc) ) );
518
519     if (!hRsrc) return 0;
520     if (!hModule) hModule = GetModuleHandleA( NULL );
521     status = LdrAccessResource( hModule, (IMAGE_RESOURCE_DATA_ENTRY *)hRsrc, &ret, NULL );
522     if (status != STATUS_SUCCESS) SetLastError( RtlNtStatusToDosError(status) );
523     return ret;
524 }
525
526
527 /**********************************************************************
528  *          LockResource     (KERNEL32.@)
529  */
530 LPVOID WINAPI LockResource( HGLOBAL handle )
531 {
532     TRACE("(%p)\n", handle );
533
534     if (HIWORD( handle ))  /* 32-bit memory handle */
535         return (LPVOID)handle;
536
537     /* 16-bit memory handle */
538     return LockResource16( HGLOBAL_16(handle) );
539 }
540
541
542 /**********************************************************************
543  *          FreeResource     (KERNEL32.@)
544  */
545 BOOL WINAPI FreeResource( HGLOBAL handle )
546 {
547     if (HIWORD(handle)) return 0; /* 32-bit memory handle: nothing to do */
548     return FreeResource16( HGLOBAL_16(handle) );
549 }
550
551
552 /**********************************************************************
553  *          SizeofResource   (KERNEL32.@)
554  */
555 DWORD WINAPI SizeofResource( HINSTANCE hModule, HRSRC hRsrc )
556 {
557     if (hModule && !HIWORD(hModule))
558         return SizeofResource16( HMODULE_16(hModule), HRSRC_16(hRsrc) );
559
560     if (!hRsrc) return 0;
561     return ((PIMAGE_RESOURCE_DATA_ENTRY)hRsrc)->Size;
562 }
563
564
565 /***********************************************************************
566  *          BeginUpdateResourceA                 (KERNEL32.@)
567  */
568 HANDLE WINAPI BeginUpdateResourceA( LPCSTR pFileName, BOOL bDeleteExistingResources )
569 {
570   FIXME("(%s,%d): stub\n",debugstr_a(pFileName),bDeleteExistingResources);
571   SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
572   return 0;
573 }
574
575
576 /***********************************************************************
577  *          BeginUpdateResourceW                 (KERNEL32.@)
578  */
579 HANDLE WINAPI BeginUpdateResourceW( LPCWSTR pFileName, BOOL bDeleteExistingResources )
580 {
581   FIXME("(%s,%d): stub\n",debugstr_w(pFileName),bDeleteExistingResources);
582   SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
583   return 0;
584 }
585
586
587 /***********************************************************************
588  *          EndUpdateResourceA                 (KERNEL32.@)
589  */
590 BOOL WINAPI EndUpdateResourceA( HANDLE hUpdate, BOOL fDiscard )
591 {
592   FIXME("(%p,%d): stub\n",hUpdate, fDiscard);
593   SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
594   return FALSE;
595 }
596
597
598 /***********************************************************************
599  *          EndUpdateResourceW                 (KERNEL32.@)
600  */
601 BOOL WINAPI EndUpdateResourceW( HANDLE hUpdate, BOOL fDiscard )
602 {
603   FIXME("(%p,%d): stub\n",hUpdate, fDiscard);
604   SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
605   return FALSE;
606 }
607
608
609 /***********************************************************************
610  *           UpdateResourceA                 (KERNEL32.@)
611  */
612 BOOL WINAPI UpdateResourceA(
613   HANDLE  hUpdate,
614   LPCSTR  lpType,
615   LPCSTR  lpName,
616   WORD    wLanguage,
617   LPVOID  lpData,
618   DWORD   cbData)
619 {
620   FIXME(": stub\n");
621   SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
622   return FALSE;
623 }
624
625
626 /***********************************************************************
627  *           UpdateResourceW                 (KERNEL32.@)
628  */
629 BOOL WINAPI UpdateResourceW(
630   HANDLE  hUpdate,
631   LPCWSTR lpType,
632   LPCWSTR lpName,
633   WORD    wLanguage,
634   LPVOID  lpData,
635   DWORD   cbData)
636 {
637   FIXME(": stub\n");
638   SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
639   return FALSE;
640 }