reshuffling of dlls
[reactos.git] / reactos / dll / win32 / kernel32 / misc / res.c
1 /* $Id$
2 *
3 * COPYRIGHT: See COPYING in the top level directory
4 * PROJECT : ReactOS user mode libraries
5 * MODULE : kernel32.dll
6 * FILE : reactos/lib/kernel32/misc/res.c
7 * AUTHOR : ???
8 */
9
10 #include <k32.h>
11
12 #define NDEBUG
13 #include "../include/debug.h"
14
15
16 /*
17 * @implemented
18 */
19 HRSRC
20 STDCALL
21 FindResourceA (
22 HINSTANCE hModule,
23 LPCSTR lpName,
24 LPCSTR lpType
25 )
26 {
27 return FindResourceExA (hModule, lpType, lpName, 0);
28 }
29
30
31 /*
32 * @implemented
33 */
34 HRSRC
35 STDCALL
36 FindResourceExA(
37 HINSTANCE hModule,
38 LPCSTR lpType,
39 LPCSTR lpName,
40 WORD wLanguage
41 )
42 {
43 UNICODE_STRING TypeU;
44 UNICODE_STRING NameU;
45 ANSI_STRING Type;
46 ANSI_STRING Name;
47 HRSRC Res;
48
49 RtlInitUnicodeString (&NameU,
50 NULL);
51 RtlInitUnicodeString (&TypeU,
52 NULL);
53
54 if (HIWORD(lpName) != 0)
55 {
56 RtlInitAnsiString (&Name,
57 (LPSTR)lpName);
58 RtlAnsiStringToUnicodeString (&NameU,
59 &Name,
60 TRUE);
61 }
62 else
63 NameU.Buffer = (PWSTR)lpName;
64
65 if (HIWORD(lpType) != 0)
66 {
67 RtlInitAnsiString (&Type,
68 (LPSTR)lpType);
69 RtlAnsiStringToUnicodeString (&TypeU,
70 &Type,
71 TRUE);
72 }
73 else
74 TypeU.Buffer = (PWSTR)lpType;
75
76 Res = FindResourceExW (hModule,
77 TypeU.Buffer,
78 NameU.Buffer,
79 wLanguage);
80
81 if (HIWORD(lpName) != 0)
82 RtlFreeUnicodeString (&NameU);
83
84 if (HIWORD(lpType) != 0)
85 RtlFreeUnicodeString (&TypeU);
86
87 return Res;
88 }
89
90
91 /*
92 * @implemented
93 */
94 HRSRC
95 STDCALL
96 FindResourceW (
97 HINSTANCE hModule,
98 LPCWSTR lpName,
99 LPCWSTR lpType
100 )
101 {
102 return FindResourceExW (hModule, lpType, lpName, 0);
103 }
104
105
106 /*
107 * @implemented
108 */
109 HRSRC
110 STDCALL
111 FindResourceExW (
112 HINSTANCE hModule,
113 LPCWSTR lpType,
114 LPCWSTR lpName,
115 WORD wLanguage
116 )
117 {
118 PIMAGE_RESOURCE_DATA_ENTRY ResourceDataEntry = NULL;
119 LDR_RESOURCE_INFO ResourceInfo;
120 NTSTATUS Status;
121
122 if ( hModule == NULL )
123 hModule = (HINSTANCE)GetModuleHandleW(NULL);
124
125 if ( !IS_INTRESOURCE(lpName) && lpName[0] == L'#' ) {
126 lpName = MAKEINTRESOURCEW(wcstoul(lpName + 1, NULL, 10));
127 }
128 if ( !IS_INTRESOURCE(lpType) && lpType[0] == L'#' ) {
129 lpType = MAKEINTRESOURCEW(wcstoul(lpType + 1, NULL, 10));
130 }
131
132 ResourceInfo.Type = (ULONG)lpType;
133 ResourceInfo.Name = (ULONG)lpName;
134 ResourceInfo.Language = (ULONG)wLanguage;
135
136 Status = LdrFindResource_U (hModule,
137 &ResourceInfo,
138 RESOURCE_DATA_LEVEL,
139 &ResourceDataEntry);
140 if (!NT_SUCCESS(Status))
141 {
142 SetLastErrorByStatus (Status);
143 return NULL;
144 }
145
146 return (HRSRC)ResourceDataEntry;
147 }
148
149
150 /*
151 * @implemented
152 */
153 HGLOBAL
154 STDCALL
155 LoadResource (
156 HINSTANCE hModule,
157 HRSRC hResInfo
158 )
159 {
160 NTSTATUS Status;
161 PVOID Data;
162 PIMAGE_RESOURCE_DATA_ENTRY ResInfo = (PIMAGE_RESOURCE_DATA_ENTRY)hResInfo;
163
164 if (hModule == NULL)
165 {
166 hModule = (HINSTANCE)GetModuleHandleW(NULL);
167 }
168
169 Status = LdrAccessResource (hModule, ResInfo, &Data, NULL);
170 if (!NT_SUCCESS(Status))
171 {
172 SetLastErrorByStatus (Status);
173 return NULL;
174 }
175
176 return Data;
177 }
178
179
180 /*
181 * @implemented
182 */
183 DWORD
184 STDCALL
185 SizeofResource (
186 HINSTANCE hModule,
187 HRSRC hResInfo
188 )
189 {
190 return ((PIMAGE_RESOURCE_DATA_ENTRY)hResInfo)->Size;
191 }
192
193
194 /*
195 * @unimplemented
196 */
197 BOOL
198 STDCALL
199 FreeResource (
200 HGLOBAL hResData
201 )
202 {
203 return TRUE;
204 }
205
206
207 /*
208 * @unimplemented
209 */
210 LPVOID
211 STDCALL
212 LockResource (
213 HGLOBAL hResData
214 )
215 {
216 return hResData;
217 }
218
219
220 /*
221 * @unimplemented
222 */
223 HANDLE
224 STDCALL
225 BeginUpdateResourceW (
226 LPCWSTR pFileName,
227 BOOL bDeleteExistingResources
228 )
229 {
230 SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
231 return FALSE;
232 }
233
234
235 /*
236 * @unimplemented
237 */
238 HANDLE
239 STDCALL
240 BeginUpdateResourceA (
241 LPCSTR pFileName,
242 BOOL bDeleteExistingResources
243 )
244 {
245 SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
246 return FALSE;
247 }
248
249
250 /*
251 * @unimplemented
252 */
253 BOOL
254 STDCALL
255 EndUpdateResourceW (
256 HANDLE hUpdate,
257 BOOL fDiscard
258 )
259 {
260 SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
261 return FALSE;
262 }
263
264
265 /*
266 * @unimplemented
267 */
268 BOOL
269 STDCALL
270 EndUpdateResourceA (
271 HANDLE hUpdate,
272 BOOL fDiscard
273 )
274 {
275 return EndUpdateResourceW(
276 hUpdate,
277 fDiscard
278 );
279 }
280
281
282 /*
283 * @unimplemented
284 */
285 BOOL
286 STDCALL
287 EnumResourceLanguagesW (
288 HINSTANCE hModule,
289 LPCWSTR lpType,
290 LPCWSTR lpName,
291 ENUMRESLANGPROCW lpEnumFunc,
292 LONG lParam
293 )
294 {
295 SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
296 return FALSE;
297 }
298
299
300 BOOL
301 STDCALL
302 EnumResourceLanguagesA (
303 HINSTANCE hModule,
304 LPCSTR lpType,
305 LPCSTR lpName,
306 ENUMRESLANGPROCA lpEnumFunc,
307 LONG lParam
308 )
309 {
310 SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
311 return FALSE;
312 }
313
314
315
316 /* retrieve the resource name to pass to the ntdll functions */
317 static NTSTATUS get_res_nameA( LPCSTR name, UNICODE_STRING *str )
318 {
319 if (!HIWORD(name))
320 {
321 str->Buffer = (LPWSTR)name;
322 return STATUS_SUCCESS;
323 }
324 if (name[0] == '#')
325 {
326 ULONG value;
327 if (RtlCharToInteger( name + 1, 10, &value ) != STATUS_SUCCESS || HIWORD(value))
328 return STATUS_INVALID_PARAMETER;
329 str->Buffer = (LPWSTR)value;
330 return STATUS_SUCCESS;
331 }
332 RtlCreateUnicodeStringFromAsciiz( str, name );
333 RtlUpcaseUnicodeString( str, str, FALSE );
334 return STATUS_SUCCESS;
335 }
336
337 /* retrieve the resource name to pass to the ntdll functions */
338 static NTSTATUS get_res_nameW( LPCWSTR name, UNICODE_STRING *str )
339 {
340 if (!HIWORD(name))
341 {
342 str->Buffer = (LPWSTR)name;
343 return STATUS_SUCCESS;
344 }
345 if (name[0] == '#')
346 {
347 ULONG value;
348 RtlInitUnicodeString( str, name + 1 );
349 if (RtlUnicodeStringToInteger( str, 10, &value ) != STATUS_SUCCESS || HIWORD(value))
350 return STATUS_INVALID_PARAMETER;
351 str->Buffer = (LPWSTR)value;
352 return STATUS_SUCCESS;
353 }
354 RtlCreateUnicodeString( str, name );
355 RtlUpcaseUnicodeString( str, str, FALSE );
356 return STATUS_SUCCESS;
357 }
358
359 /**********************************************************************
360 * EnumResourceNamesA (KERNEL32.@)
361 */
362 BOOL STDCALL EnumResourceNamesA( HMODULE hmod, LPCSTR type, ENUMRESNAMEPROCA lpfun, LONG_PTR lparam )
363 {
364 int i;
365 BOOL ret = FALSE;
366 DWORD len = 0, newlen;
367 LPSTR name = NULL;
368 NTSTATUS status;
369 UNICODE_STRING typeW;
370 LDR_RESOURCE_INFO info;
371 PIMAGE_RESOURCE_DIRECTORY basedir, resdir;
372 const IMAGE_RESOURCE_DIRECTORY_ENTRY *et;
373 const IMAGE_RESOURCE_DIR_STRING_U *str;
374
375 DPRINT( "%p %s %p %lx\n", hmod, type, lpfun, lparam );
376
377 if (!hmod) hmod = GetModuleHandleA( NULL );
378 typeW.Buffer = NULL;
379 if ((status = LdrFindResourceDirectory_U( hmod, NULL, 0, &basedir )) != STATUS_SUCCESS)
380 goto done;
381 if ((status = get_res_nameA( type, &typeW )) != STATUS_SUCCESS)
382 goto done;
383 info.Type = (ULONG)typeW.Buffer;
384 if ((status = LdrFindResourceDirectory_U( hmod, &info, 1, &resdir )) != STATUS_SUCCESS)
385 goto done;
386
387 et = (IMAGE_RESOURCE_DIRECTORY_ENTRY *)(resdir + 1);
388 for (i = 0; i < resdir->NumberOfNamedEntries+resdir->NumberOfIdEntries; i++)
389 {
390 if (et[i].NameIsString)
391 {
392 str = (IMAGE_RESOURCE_DIR_STRING_U *) ((LPBYTE) basedir + et[i].NameOffset);
393 newlen = WideCharToMultiByte(CP_ACP, 0, str->NameString, str->Length, NULL, 0, NULL, NULL);
394 if (newlen + 1 > len)
395 {
396 len = newlen + 1;
397 HeapFree( GetProcessHeap(), 0, name );
398 if (!(name = HeapAlloc(GetProcessHeap(), 0, len + 1 )))
399 {
400 ret = FALSE;
401 break;
402 }
403 }
404 WideCharToMultiByte( CP_ACP, 0, str->NameString, str->Length, name, len, NULL, NULL );
405 name[newlen] = 0;
406 ret = lpfun(hmod,type,name,lparam);
407 }
408 else
409 {
410 ret = lpfun( hmod, type, (LPSTR)(int)et[i].Id, lparam );
411 }
412 if (!ret) break;
413 }
414 done:
415 HeapFree( GetProcessHeap(), 0, name );
416 if (HIWORD(typeW.Buffer)) HeapFree( GetProcessHeap(), 0, typeW.Buffer );
417 if (status != STATUS_SUCCESS) SetLastError( RtlNtStatusToDosError(status) );
418 return ret;
419 }
420
421
422 /**********************************************************************
423 * EnumResourceNamesW (KERNEL32.@)
424 */
425 BOOL STDCALL EnumResourceNamesW( HMODULE hmod, LPCWSTR type, ENUMRESNAMEPROCW lpfun, LONG_PTR lparam )
426 {
427 int i, len = 0;
428 BOOL ret = FALSE;
429 LPWSTR name = NULL;
430 NTSTATUS status;
431 UNICODE_STRING typeW;
432 LDR_RESOURCE_INFO info;
433 PIMAGE_RESOURCE_DIRECTORY basedir, resdir;
434 const IMAGE_RESOURCE_DIRECTORY_ENTRY *et;
435 const IMAGE_RESOURCE_DIR_STRING_U *str;
436
437 DPRINT( "%p %s %p %lx\n", hmod, type, lpfun, lparam );
438
439 if (!hmod) hmod = GetModuleHandleW( NULL );
440 typeW.Buffer = NULL;
441 if ((status = LdrFindResourceDirectory_U( hmod, NULL, 0, &basedir )) != STATUS_SUCCESS)
442 goto done;
443 if ((status = get_res_nameW( type, &typeW )) != STATUS_SUCCESS)
444 goto done;
445 info.Type = (ULONG)typeW.Buffer;
446 if ((status = LdrFindResourceDirectory_U( hmod, &info, 1, &resdir )) != STATUS_SUCCESS)
447 goto done;
448
449 et = (PIMAGE_RESOURCE_DIRECTORY_ENTRY)(resdir + 1);
450 for (i = 0; i < resdir->NumberOfNamedEntries+resdir->NumberOfIdEntries; i++)
451 {
452 if (et[i].NameIsString)
453 {
454 str = (IMAGE_RESOURCE_DIR_STRING_U *) ((LPBYTE) basedir + et[i].NameOffset);
455 if (str->Length + 1 > len)
456 {
457 len = str->Length + 1;
458 HeapFree( GetProcessHeap(), 0, name );
459 if (!(name = HeapAlloc( GetProcessHeap(), 0, len * sizeof(WCHAR) )))
460 {
461 ret = FALSE;
462 break;
463 }
464 }
465 memcpy(name, str->NameString, str->Length * sizeof (WCHAR));
466 name[str->Length] = 0;
467 ret = lpfun(hmod,type,name,lparam);
468 }
469 else
470 {
471 ret = lpfun( hmod, type, (LPWSTR)(int)et[i].Id, lparam );
472 }
473 if (!ret) break;
474 }
475 done:
476 HeapFree( GetProcessHeap(), 0, name );
477 if (HIWORD(typeW.Buffer)) HeapFree( GetProcessHeap(), 0, typeW.Buffer );
478 if (status != STATUS_SUCCESS) SetLastError( RtlNtStatusToDosError(status) );
479 return ret;
480 }
481
482 /*
483 * @unimplemented
484 */
485 BOOL
486 STDCALL
487 EnumResourceTypesW (
488 HINSTANCE hModule,
489 ENUMRESTYPEPROCW lpEnumFunc,
490 LONG lParam
491 )
492 {
493 SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
494 return FALSE;
495 }
496
497
498 /*
499 * @unimplemented
500 */
501 BOOL
502 STDCALL
503 EnumResourceTypesA (
504 HINSTANCE hModule,
505 ENUMRESTYPEPROCA lpEnumFunc,
506 LONG lParam
507 )
508 {
509 SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
510 return FALSE;
511 }
512
513
514 /*
515 * @unimplemented
516 */
517 BOOL
518 STDCALL
519 UpdateResourceA (
520 HANDLE hUpdate,
521 LPCSTR lpType,
522 LPCSTR lpName,
523 WORD wLanguage,
524 LPVOID lpData,
525 DWORD cbData
526 )
527 {
528 SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
529 return FALSE;
530 }
531
532
533 /*
534 * @unimplemented
535 */
536 BOOL
537 STDCALL
538 UpdateResourceW (
539 HANDLE hUpdate,
540 LPCWSTR lpType,
541 LPCWSTR lpName,
542 WORD wLanguage,
543 LPVOID lpData,
544 DWORD cbData
545 )
546 {
547 SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
548 return FALSE;
549 }
550
551 /* EOF */