kernelbase: Sanitize flags in GetModuleHandleExW().
[wine.git] / dlls / kernelbase / loader.c
blob9aff460c955bfe6430159e1359065906481e9f8b
1 /*
2 * Module loader
4 * Copyright 1993 Robert J. Amstadt
5 * Copyright 2006 Mike McCormack
6 * Copyright 1995, 2003, 2019 Alexandre Julliard
8 * This library is free software; you can redistribute it and/or
9 * modify it under the terms of the GNU Lesser General Public
10 * License as published by the Free Software Foundation; either
11 * version 2.1 of the License, or (at your option) any later version.
13 * This library is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16 * Lesser General Public License for more details.
18 * You should have received a copy of the GNU Lesser General Public
19 * License along with this library; if not, write to the Free Software
20 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
23 #include <stdarg.h>
25 #define NONAMELESSUNION
26 #define NONAMELESSSTRUCT
27 #include "ntstatus.h"
28 #define WIN32_NO_STATUS
29 #include "windef.h"
30 #include "winbase.h"
31 #include "winnls.h"
32 #include "winternl.h"
33 #include "kernelbase.h"
34 #include "wine/list.h"
35 #include "wine/asm.h"
36 #include "wine/debug.h"
37 #include "wine/exception.h"
39 WINE_DEFAULT_DEBUG_CHANNEL(module);
42 /* to keep track of LOAD_LIBRARY_AS_DATAFILE_EXCLUSIVE file handles */
43 struct exclusive_datafile
45 struct list entry;
46 HMODULE module;
47 HANDLE file;
49 static struct list exclusive_datafile_list = LIST_INIT( exclusive_datafile_list );
52 /***********************************************************************
53 * Modules
54 ***********************************************************************/
57 /******************************************************************
58 * get_proc_address
60 FARPROC WINAPI get_proc_address( HMODULE module, LPCSTR function )
62 FARPROC proc;
63 ANSI_STRING str;
65 if (!module) module = NtCurrentTeb()->Peb->ImageBaseAddress;
67 if ((ULONG_PTR)function >> 16)
69 RtlInitAnsiString( &str, function );
70 if (!set_ntstatus( LdrGetProcedureAddress( module, &str, 0, (void**)&proc ))) return NULL;
72 else if (!set_ntstatus( LdrGetProcedureAddress( module, NULL, LOWORD(function), (void**)&proc )))
73 return NULL;
75 return proc;
79 /******************************************************************
80 * load_library_as_datafile
82 static BOOL load_library_as_datafile( LPCWSTR load_path, DWORD flags, LPCWSTR name, HMODULE *mod_ret )
84 WCHAR filenameW[MAX_PATH];
85 HANDLE mapping, file = INVALID_HANDLE_VALUE;
86 HMODULE module = 0;
87 DWORD protect = PAGE_READONLY;
89 *mod_ret = 0;
91 if (flags & LOAD_LIBRARY_AS_IMAGE_RESOURCE) protect |= SEC_IMAGE;
93 if (SearchPathW( NULL, name, L".dll", ARRAY_SIZE( filenameW ), filenameW, NULL ))
95 file = CreateFileW( filenameW, GENERIC_READ, FILE_SHARE_READ | FILE_SHARE_DELETE,
96 NULL, OPEN_EXISTING, 0, 0 );
98 if (file == INVALID_HANDLE_VALUE) return FALSE;
100 mapping = CreateFileMappingW( file, NULL, protect, 0, 0, NULL );
101 if (!mapping) goto failed;
103 module = MapViewOfFile( mapping, FILE_MAP_READ, 0, 0, 0 );
104 CloseHandle( mapping );
105 if (!module) goto failed;
107 if (!(flags & LOAD_LIBRARY_AS_IMAGE_RESOURCE))
109 /* make sure it's a valid PE file */
110 if (!RtlImageNtHeader( module ))
112 SetLastError( ERROR_BAD_EXE_FORMAT );
113 goto failed;
115 *mod_ret = (HMODULE)((char *)module + 1); /* set bit 0 for data file module */
117 if (flags & LOAD_LIBRARY_AS_DATAFILE_EXCLUSIVE)
119 struct exclusive_datafile *datafile = HeapAlloc( GetProcessHeap(), 0, sizeof(*datafile) );
120 if (!datafile) goto failed;
121 datafile->module = *mod_ret;
122 datafile->file = file;
123 list_add_head( &exclusive_datafile_list, &datafile->entry );
124 TRACE( "delaying close %p for module %p\n", datafile->file, datafile->module );
125 return TRUE;
128 else *mod_ret = (HMODULE)((char *)module + 2); /* set bit 1 for image resource module */
130 CloseHandle( file );
131 return TRUE;
133 failed:
134 if (module) UnmapViewOfFile( module );
135 CloseHandle( file );
136 return FALSE;
140 /******************************************************************
141 * load_library
143 static HMODULE load_library( const UNICODE_STRING *libname, DWORD flags )
145 const DWORD unsupported_flags = LOAD_IGNORE_CODE_AUTHZ_LEVEL | LOAD_LIBRARY_REQUIRE_SIGNED_TARGET;
146 NTSTATUS status;
147 HMODULE module;
148 WCHAR *load_path, *dummy;
150 if (flags & unsupported_flags) FIXME( "unsupported flag(s) used %#08x\n", flags );
152 if (!set_ntstatus( LdrGetDllPath( libname->Buffer, flags, &load_path, &dummy ))) return 0;
154 if (flags & (LOAD_LIBRARY_AS_DATAFILE | LOAD_LIBRARY_AS_DATAFILE_EXCLUSIVE |
155 LOAD_LIBRARY_AS_IMAGE_RESOURCE))
157 ULONG_PTR magic;
159 LdrLockLoaderLock( 0, NULL, &magic );
160 if (!LdrGetDllHandle( load_path, flags, libname, &module ))
161 LdrAddRefDll( 0, module );
162 else
163 load_library_as_datafile( load_path, flags, libname->Buffer, &module );
164 LdrUnlockLoaderLock( 0, magic );
166 else
168 status = LdrLoadDll( load_path, flags, libname, &module );
169 if (!set_ntstatus( status ))
171 module = 0;
172 if (status == STATUS_DLL_NOT_FOUND && (GetVersion() & 0x80000000))
173 SetLastError( ERROR_DLL_NOT_FOUND );
177 RtlReleasePath( load_path );
178 return module;
182 /****************************************************************************
183 * AddDllDirectory (kernelbase.@)
185 DLL_DIRECTORY_COOKIE WINAPI DECLSPEC_HOTPATCH AddDllDirectory( const WCHAR *dir )
187 UNICODE_STRING str;
188 void *cookie;
190 RtlInitUnicodeString( &str, dir );
191 if (!set_ntstatus( LdrAddDllDirectory( &str, &cookie ))) return NULL;
192 return cookie;
196 /***********************************************************************
197 * DelayLoadFailureHook (kernelbase.@)
199 FARPROC WINAPI DECLSPEC_HOTPATCH DelayLoadFailureHook( LPCSTR name, LPCSTR function )
201 ULONG_PTR args[2];
203 if ((ULONG_PTR)function >> 16)
204 ERR( "failed to delay load %s.%s\n", name, function );
205 else
206 ERR( "failed to delay load %s.%u\n", name, LOWORD(function) );
207 args[0] = (ULONG_PTR)name;
208 args[1] = (ULONG_PTR)function;
209 RaiseException( EXCEPTION_WINE_STUB, EH_NONCONTINUABLE, 2, args );
210 return NULL;
214 /****************************************************************************
215 * DisableThreadLibraryCalls (kernelbase.@)
217 BOOL WINAPI DECLSPEC_HOTPATCH DisableThreadLibraryCalls( HMODULE module )
219 return set_ntstatus( LdrDisableThreadCalloutsForDll( module ));
223 /***********************************************************************
224 * FreeLibrary (kernelbase.@)
226 BOOL WINAPI DECLSPEC_HOTPATCH FreeLibrary( HINSTANCE module )
228 if (!module)
230 SetLastError( ERROR_INVALID_HANDLE );
231 return FALSE;
234 if ((ULONG_PTR)module & 3) /* this is a datafile module */
236 void *ptr = (void *)((ULONG_PTR)module & ~3);
237 if (!RtlImageNtHeader( ptr ))
239 SetLastError( ERROR_BAD_EXE_FORMAT );
240 return FALSE;
242 if ((ULONG_PTR)module & 1)
244 struct exclusive_datafile *file;
245 ULONG_PTR magic;
247 LdrLockLoaderLock( 0, NULL, &magic );
248 LIST_FOR_EACH_ENTRY( file, &exclusive_datafile_list, struct exclusive_datafile, entry )
250 if (file->module != module) continue;
251 TRACE( "closing %p for module %p\n", file->file, file->module );
252 CloseHandle( file->file );
253 list_remove( &file->entry );
254 HeapFree( GetProcessHeap(), 0, file );
255 break;
257 LdrUnlockLoaderLock( 0, magic );
259 return UnmapViewOfFile( ptr );
262 return set_ntstatus( LdrUnloadDll( module ));
266 /***********************************************************************
267 * GetModuleFileNameA (kernelbase.@)
269 DWORD WINAPI DECLSPEC_HOTPATCH GetModuleFileNameA( HMODULE module, LPSTR filename, DWORD size )
271 LPWSTR filenameW = HeapAlloc( GetProcessHeap(), 0, size * sizeof(WCHAR) );
272 DWORD len;
274 if (!filenameW)
276 SetLastError( ERROR_NOT_ENOUGH_MEMORY );
277 return 0;
279 if ((len = GetModuleFileNameW( module, filenameW, size )))
281 len = file_name_WtoA( filenameW, len, filename, size );
282 if (len < size)
283 filename[len] = 0;
284 else
285 SetLastError( ERROR_INSUFFICIENT_BUFFER );
287 HeapFree( GetProcessHeap(), 0, filenameW );
288 return len;
292 /***********************************************************************
293 * GetModuleFileNameW (kernelbase.@)
295 DWORD WINAPI DECLSPEC_HOTPATCH GetModuleFileNameW( HMODULE module, LPWSTR filename, DWORD size )
297 ULONG len = 0;
298 ULONG_PTR magic;
299 LDR_DATA_TABLE_ENTRY *pldr;
300 WIN16_SUBSYSTEM_TIB *win16_tib;
302 if (!module && ((win16_tib = NtCurrentTeb()->Tib.SubSystemTib)) && win16_tib->exe_name)
304 len = min( size, win16_tib->exe_name->Length / sizeof(WCHAR) );
305 memcpy( filename, win16_tib->exe_name->Buffer, len * sizeof(WCHAR) );
306 if (len < size) filename[len] = 0;
307 goto done;
310 LdrLockLoaderLock( 0, NULL, &magic );
312 if (!module) module = NtCurrentTeb()->Peb->ImageBaseAddress;
313 if (set_ntstatus( LdrFindEntryForAddress( module, &pldr )))
315 len = min( size, pldr->FullDllName.Length / sizeof(WCHAR) );
316 memcpy( filename, pldr->FullDllName.Buffer, len * sizeof(WCHAR) );
317 if (len < size)
319 filename[len] = 0;
320 SetLastError( 0 );
322 else SetLastError( ERROR_INSUFFICIENT_BUFFER );
325 LdrUnlockLoaderLock( 0, magic );
326 done:
327 TRACE( "%s\n", debugstr_wn(filename, len) );
328 return len;
332 /***********************************************************************
333 * GetModuleHandleA (kernelbase.@)
335 HMODULE WINAPI DECLSPEC_HOTPATCH GetModuleHandleA( LPCSTR module )
337 HMODULE ret;
339 GetModuleHandleExA( GET_MODULE_HANDLE_EX_FLAG_UNCHANGED_REFCOUNT, module, &ret );
340 return ret;
344 /***********************************************************************
345 * GetModuleHandleW (kernelbase.@)
347 HMODULE WINAPI DECLSPEC_HOTPATCH GetModuleHandleW( LPCWSTR module )
349 HMODULE ret;
351 GetModuleHandleExW( GET_MODULE_HANDLE_EX_FLAG_UNCHANGED_REFCOUNT, module, &ret );
352 return ret;
356 /***********************************************************************
357 * GetModuleHandleExA (kernelbase.@)
359 BOOL WINAPI DECLSPEC_HOTPATCH GetModuleHandleExA( DWORD flags, LPCSTR name, HMODULE *module )
361 WCHAR *nameW;
363 if (!name || (flags & GET_MODULE_HANDLE_EX_FLAG_FROM_ADDRESS))
364 return GetModuleHandleExW( flags, (LPCWSTR)name, module );
366 if (!(nameW = file_name_AtoW( name, FALSE ))) return FALSE;
367 return GetModuleHandleExW( flags, nameW, module );
371 /***********************************************************************
372 * GetModuleHandleExW (kernelbase.@)
374 BOOL WINAPI DECLSPEC_HOTPATCH GetModuleHandleExW( DWORD flags, LPCWSTR name, HMODULE *module )
376 NTSTATUS status = STATUS_SUCCESS;
377 HMODULE ret = NULL;
378 ULONG_PTR magic;
379 BOOL lock;
381 if (!module)
383 SetLastError( ERROR_INVALID_PARAMETER );
384 return FALSE;
387 if ((flags & ~(GET_MODULE_HANDLE_EX_FLAG_PIN | GET_MODULE_HANDLE_EX_FLAG_UNCHANGED_REFCOUNT
388 | GET_MODULE_HANDLE_EX_FLAG_FROM_ADDRESS))
389 || (flags & (GET_MODULE_HANDLE_EX_FLAG_PIN | GET_MODULE_HANDLE_EX_FLAG_UNCHANGED_REFCOUNT))
390 == (GET_MODULE_HANDLE_EX_FLAG_PIN | GET_MODULE_HANDLE_EX_FLAG_UNCHANGED_REFCOUNT))
392 *module = NULL;
393 SetLastError( ERROR_INVALID_PARAMETER );
394 return FALSE;
397 /* if we are messing with the refcount, grab the loader lock */
398 lock = (flags & GET_MODULE_HANDLE_EX_FLAG_PIN) || !(flags & GET_MODULE_HANDLE_EX_FLAG_UNCHANGED_REFCOUNT);
399 if (lock) LdrLockLoaderLock( 0, NULL, &magic );
401 if (!name)
403 ret = NtCurrentTeb()->Peb->ImageBaseAddress;
405 else if (flags & GET_MODULE_HANDLE_EX_FLAG_FROM_ADDRESS)
407 void *dummy;
408 if (!(ret = RtlPcToFileHeader( (void *)name, &dummy ))) status = STATUS_DLL_NOT_FOUND;
410 else
412 UNICODE_STRING wstr;
413 RtlInitUnicodeString( &wstr, name );
414 status = LdrGetDllHandle( NULL, 0, &wstr, &ret );
417 if (status == STATUS_SUCCESS)
419 if (flags & GET_MODULE_HANDLE_EX_FLAG_PIN)
420 LdrAddRefDll( LDR_ADDREF_DLL_PIN, ret );
421 else if (!(flags & GET_MODULE_HANDLE_EX_FLAG_UNCHANGED_REFCOUNT))
422 LdrAddRefDll( 0, ret );
425 if (lock) LdrUnlockLoaderLock( 0, magic );
427 *module = ret;
428 return set_ntstatus( status );
432 /***********************************************************************
433 * GetProcAddress (kernelbase.@)
436 #ifdef __x86_64__
438 * Work around a Delphi bug on x86_64. When delay loading a symbol,
439 * Delphi saves rcx, rdx, r8 and r9 to the stack. It then calls
440 * GetProcAddress(), pops the saved registers and calls the function.
441 * This works fine if all of the parameters are ints. However, since
442 * it does not save xmm0 - 3, it relies on GetProcAddress() preserving
443 * these registers if the function takes floating point parameters.
444 * This wrapper saves xmm0 - 3 to the stack.
446 __ASM_GLOBAL_FUNC( GetProcAddress,
447 ".byte 0x48\n\t" /* hotpatch prolog */
448 "pushq %rbp\n\t"
449 __ASM_SEH(".seh_pushreg %rbp\n\t")
450 __ASM_CFI(".cfi_adjust_cfa_offset 8\n\t")
451 __ASM_CFI(".cfi_rel_offset %rbp,0\n\t")
452 "movq %rsp,%rbp\n\t"
453 __ASM_SEH(".seh_setframe %rbp,0\n\t")
454 __ASM_CFI(".cfi_def_cfa_register %rbp\n\t")
455 __ASM_SEH(".seh_endprologue\n\t")
456 "subq $0x60,%rsp\n\t"
457 "andq $~15,%rsp\n\t"
458 "movaps %xmm0,0x20(%rsp)\n\t"
459 "movaps %xmm1,0x30(%rsp)\n\t"
460 "movaps %xmm2,0x40(%rsp)\n\t"
461 "movaps %xmm3,0x50(%rsp)\n\t"
462 "call " __ASM_NAME("get_proc_address") "\n\t"
463 "movaps 0x50(%rsp), %xmm3\n\t"
464 "movaps 0x40(%rsp), %xmm2\n\t"
465 "movaps 0x30(%rsp), %xmm1\n\t"
466 "movaps 0x20(%rsp), %xmm0\n\t"
467 "leaq 0(%rbp),%rsp\n\t"
468 __ASM_CFI(".cfi_def_cfa_register %rsp\n\t")
469 "popq %rbp\n\t"
470 __ASM_CFI(".cfi_adjust_cfa_offset -8\n\t")
471 __ASM_CFI(".cfi_same_value %rbp\n\t")
472 "ret" )
473 #else /* __x86_64__ */
475 FARPROC WINAPI DECLSPEC_HOTPATCH GetProcAddress( HMODULE module, LPCSTR function )
477 return get_proc_address( module, function );
480 #endif /* __x86_64__ */
483 /***********************************************************************
484 * LoadLibraryA (kernelbase.@)
486 HMODULE WINAPI DECLSPEC_HOTPATCH LoadLibraryA( LPCSTR name )
488 return LoadLibraryExA( name, 0, 0 );
492 /***********************************************************************
493 * LoadLibraryW (kernelbase.@)
495 HMODULE WINAPI DECLSPEC_HOTPATCH LoadLibraryW( LPCWSTR name )
497 return LoadLibraryExW( name, 0, 0 );
501 /******************************************************************
502 * LoadLibraryExA (kernelbase.@)
504 HMODULE WINAPI DECLSPEC_HOTPATCH LoadLibraryExA( LPCSTR name, HANDLE file, DWORD flags )
506 WCHAR *nameW;
508 if (!(nameW = file_name_AtoW( name, FALSE ))) return 0;
509 return LoadLibraryExW( nameW, file, flags );
513 /***********************************************************************
514 * LoadLibraryExW (kernelbase.@)
516 HMODULE WINAPI DECLSPEC_HOTPATCH LoadLibraryExW( LPCWSTR name, HANDLE file, DWORD flags )
518 UNICODE_STRING str;
519 HMODULE module;
521 if (!name)
523 SetLastError( ERROR_INVALID_PARAMETER );
524 return 0;
526 RtlInitUnicodeString( &str, name );
527 if (str.Buffer[str.Length/sizeof(WCHAR) - 1] != ' ') return load_library( &str, flags );
529 /* library name has trailing spaces */
530 RtlCreateUnicodeString( &str, name );
531 while (str.Length > sizeof(WCHAR) && str.Buffer[str.Length/sizeof(WCHAR) - 1] == ' ')
532 str.Length -= sizeof(WCHAR);
534 str.Buffer[str.Length/sizeof(WCHAR)] = 0;
535 module = load_library( &str, flags );
536 RtlFreeUnicodeString( &str );
537 return module;
541 /***********************************************************************
542 * LoadPackagedLibrary (kernelbase.@)
544 HMODULE WINAPI /* DECLSPEC_HOTPATCH */ LoadPackagedLibrary( LPCWSTR name, DWORD reserved )
546 FIXME( "semi-stub, name %s, reserved %#x.\n", debugstr_w(name), reserved );
547 SetLastError( APPMODEL_ERROR_NO_PACKAGE );
548 return NULL;
552 /***********************************************************************
553 * LoadAppInitDlls (kernelbase.@)
555 void WINAPI LoadAppInitDlls(void)
557 TRACE( "\n" );
561 /****************************************************************************
562 * RemoveDllDirectory (kernelbase.@)
564 BOOL WINAPI DECLSPEC_HOTPATCH RemoveDllDirectory( DLL_DIRECTORY_COOKIE cookie )
566 return set_ntstatus( LdrRemoveDllDirectory( cookie ));
570 /*************************************************************************
571 * SetDefaultDllDirectories (kernelbase.@)
573 BOOL WINAPI DECLSPEC_HOTPATCH SetDefaultDllDirectories( DWORD flags )
575 return set_ntstatus( LdrSetDefaultDllDirectories( flags ));
579 /***********************************************************************
580 * Resources
581 ***********************************************************************/
584 #define IS_INTRESOURCE(x) (((ULONG_PTR)(x) >> 16) == 0)
586 /* retrieve the resource name to pass to the ntdll functions */
587 static NTSTATUS get_res_nameA( LPCSTR name, UNICODE_STRING *str )
589 if (IS_INTRESOURCE(name))
591 str->Buffer = ULongToPtr( LOWORD(name) );
592 return STATUS_SUCCESS;
594 if (name[0] == '#')
596 ULONG value;
597 if (RtlCharToInteger( name + 1, 10, &value ) != STATUS_SUCCESS || HIWORD(value))
598 return STATUS_INVALID_PARAMETER;
599 str->Buffer = ULongToPtr(value);
600 return STATUS_SUCCESS;
602 RtlCreateUnicodeStringFromAsciiz( str, name );
603 RtlUpcaseUnicodeString( str, str, FALSE );
604 return STATUS_SUCCESS;
607 /* retrieve the resource name to pass to the ntdll functions */
608 static NTSTATUS get_res_nameW( LPCWSTR name, UNICODE_STRING *str )
610 if (IS_INTRESOURCE(name))
612 str->Buffer = ULongToPtr( LOWORD(name) );
613 return STATUS_SUCCESS;
615 if (name[0] == '#')
617 ULONG value;
618 RtlInitUnicodeString( str, name + 1 );
619 if (RtlUnicodeStringToInteger( str, 10, &value ) != STATUS_SUCCESS || HIWORD(value))
620 return STATUS_INVALID_PARAMETER;
621 str->Buffer = ULongToPtr(value);
622 return STATUS_SUCCESS;
624 RtlCreateUnicodeString( str, name );
625 RtlUpcaseUnicodeString( str, str, FALSE );
626 return STATUS_SUCCESS;
630 /**********************************************************************
631 * EnumResourceLanguagesExA (kernelbase.@)
633 BOOL WINAPI DECLSPEC_HOTPATCH EnumResourceLanguagesExA( HMODULE module, LPCSTR type, LPCSTR name,
634 ENUMRESLANGPROCA func, LONG_PTR param,
635 DWORD flags, LANGID lang )
637 int i;
638 BOOL ret = FALSE;
639 NTSTATUS status;
640 UNICODE_STRING typeW, nameW;
641 LDR_RESOURCE_INFO info;
642 const IMAGE_RESOURCE_DIRECTORY *basedir, *resdir;
643 const IMAGE_RESOURCE_DIRECTORY_ENTRY *et;
645 TRACE( "%p %s %s %p %lx %x %d\n", module, debugstr_a(type), debugstr_a(name),
646 func, param, flags, lang );
648 if (flags & (RESOURCE_ENUM_MUI | RESOURCE_ENUM_MUI_SYSTEM | RESOURCE_ENUM_VALIDATE))
649 FIXME( "unimplemented flags: %x\n", flags );
651 if (!flags) flags = RESOURCE_ENUM_LN | RESOURCE_ENUM_MUI;
652 if (!(flags & RESOURCE_ENUM_LN)) return ret;
654 if (!module) module = GetModuleHandleW( 0 );
655 typeW.Buffer = nameW.Buffer = NULL;
656 if ((status = LdrFindResourceDirectory_U( module, NULL, 0, &basedir )) != STATUS_SUCCESS)
657 goto done;
658 if ((status = get_res_nameA( type, &typeW )) != STATUS_SUCCESS)
659 goto done;
660 if ((status = get_res_nameA( name, &nameW )) != STATUS_SUCCESS)
661 goto done;
662 info.Type = (ULONG_PTR)typeW.Buffer;
663 info.Name = (ULONG_PTR)nameW.Buffer;
664 if ((status = LdrFindResourceDirectory_U( module, &info, 2, &resdir )) != STATUS_SUCCESS)
665 goto done;
667 et = (const IMAGE_RESOURCE_DIRECTORY_ENTRY *)(resdir + 1);
668 __TRY
670 for (i = 0; i < resdir->NumberOfNamedEntries + resdir->NumberOfIdEntries; i++)
672 ret = func( module, type, name, et[i].u.Id, param );
673 if (!ret) break;
676 __EXCEPT_PAGE_FAULT
678 ret = FALSE;
679 status = STATUS_ACCESS_VIOLATION;
681 __ENDTRY
682 done:
683 if (!IS_INTRESOURCE(typeW.Buffer)) HeapFree( GetProcessHeap(), 0, typeW.Buffer );
684 if (!IS_INTRESOURCE(nameW.Buffer)) HeapFree( GetProcessHeap(), 0, nameW.Buffer );
685 if (status != STATUS_SUCCESS) SetLastError( RtlNtStatusToDosError(status) );
686 return ret;
690 /**********************************************************************
691 * EnumResourceLanguagesExW (kernelbase.@)
693 BOOL WINAPI DECLSPEC_HOTPATCH EnumResourceLanguagesExW( HMODULE module, LPCWSTR type, LPCWSTR name,
694 ENUMRESLANGPROCW func, LONG_PTR param,
695 DWORD flags, LANGID lang )
697 int i;
698 BOOL ret = FALSE;
699 NTSTATUS status;
700 UNICODE_STRING typeW, nameW;
701 LDR_RESOURCE_INFO info;
702 const IMAGE_RESOURCE_DIRECTORY *basedir, *resdir;
703 const IMAGE_RESOURCE_DIRECTORY_ENTRY *et;
705 TRACE( "%p %s %s %p %lx %x %d\n", module, debugstr_w(type), debugstr_w(name),
706 func, param, flags, lang );
708 if (flags & (RESOURCE_ENUM_MUI | RESOURCE_ENUM_MUI_SYSTEM | RESOURCE_ENUM_VALIDATE))
709 FIXME( "unimplemented flags: %x\n", flags );
711 if (!flags) flags = RESOURCE_ENUM_LN | RESOURCE_ENUM_MUI;
712 if (!(flags & RESOURCE_ENUM_LN)) return ret;
714 if (!module) module = GetModuleHandleW( 0 );
715 typeW.Buffer = nameW.Buffer = NULL;
716 if ((status = LdrFindResourceDirectory_U( module, NULL, 0, &basedir )) != STATUS_SUCCESS)
717 goto done;
718 if ((status = get_res_nameW( type, &typeW )) != STATUS_SUCCESS)
719 goto done;
720 if ((status = get_res_nameW( name, &nameW )) != STATUS_SUCCESS)
721 goto done;
722 info.Type = (ULONG_PTR)typeW.Buffer;
723 info.Name = (ULONG_PTR)nameW.Buffer;
724 if ((status = LdrFindResourceDirectory_U( module, &info, 2, &resdir )) != STATUS_SUCCESS)
725 goto done;
727 et = (const IMAGE_RESOURCE_DIRECTORY_ENTRY *)(resdir + 1);
728 __TRY
730 for (i = 0; i < resdir->NumberOfNamedEntries + resdir->NumberOfIdEntries; i++)
732 ret = func( module, type, name, et[i].u.Id, param );
733 if (!ret) break;
736 __EXCEPT_PAGE_FAULT
738 ret = FALSE;
739 status = STATUS_ACCESS_VIOLATION;
741 __ENDTRY
742 done:
743 if (!IS_INTRESOURCE(typeW.Buffer)) HeapFree( GetProcessHeap(), 0, typeW.Buffer );
744 if (!IS_INTRESOURCE(nameW.Buffer)) HeapFree( GetProcessHeap(), 0, nameW.Buffer );
745 if (status != STATUS_SUCCESS) SetLastError( RtlNtStatusToDosError(status) );
746 return ret;
750 /**********************************************************************
751 * EnumResourceNamesExA (kernelbase.@)
753 BOOL WINAPI DECLSPEC_HOTPATCH EnumResourceNamesExA( HMODULE module, LPCSTR type, ENUMRESNAMEPROCA func,
754 LONG_PTR param, DWORD flags, LANGID lang )
756 int i;
757 BOOL ret = FALSE;
758 DWORD len = 0, newlen;
759 LPSTR name = NULL;
760 NTSTATUS status;
761 UNICODE_STRING typeW;
762 LDR_RESOURCE_INFO info;
763 const IMAGE_RESOURCE_DIRECTORY *basedir, *resdir;
764 const IMAGE_RESOURCE_DIRECTORY_ENTRY *et;
765 const IMAGE_RESOURCE_DIR_STRING_U *str;
767 TRACE( "%p %s %p %lx\n", module, debugstr_a(type), func, param );
769 if (flags & (RESOURCE_ENUM_MUI | RESOURCE_ENUM_MUI_SYSTEM | RESOURCE_ENUM_VALIDATE))
770 FIXME( "unimplemented flags: %x\n", flags );
772 if (!flags) flags = RESOURCE_ENUM_LN | RESOURCE_ENUM_MUI;
773 if (!(flags & RESOURCE_ENUM_LN)) return ret;
775 if (!module) module = GetModuleHandleW( 0 );
776 typeW.Buffer = NULL;
777 if ((status = LdrFindResourceDirectory_U( module, NULL, 0, &basedir )) != STATUS_SUCCESS)
778 goto done;
779 if ((status = get_res_nameA( type, &typeW )) != STATUS_SUCCESS)
780 goto done;
781 info.Type = (ULONG_PTR)typeW.Buffer;
782 if ((status = LdrFindResourceDirectory_U( module, &info, 1, &resdir )) != STATUS_SUCCESS)
783 goto done;
785 et = (const IMAGE_RESOURCE_DIRECTORY_ENTRY *)(resdir + 1);
786 __TRY
788 for (i = 0; i < resdir->NumberOfNamedEntries+resdir->NumberOfIdEntries; i++)
790 if (et[i].u.s.NameIsString)
792 str = (const IMAGE_RESOURCE_DIR_STRING_U *)((const BYTE *)basedir + et[i].u.s.NameOffset);
793 newlen = WideCharToMultiByte(CP_ACP, 0, str->NameString, str->Length, NULL, 0, NULL, NULL);
794 if (newlen + 1 > len)
796 len = newlen + 1;
797 HeapFree( GetProcessHeap(), 0, name );
798 if (!(name = HeapAlloc( GetProcessHeap(), 0, len + 1 )))
800 ret = FALSE;
801 break;
804 WideCharToMultiByte( CP_ACP, 0, str->NameString, str->Length, name, len, NULL, NULL );
805 name[newlen] = 0;
806 ret = func( module, type, name, param );
808 else
810 ret = func( module, type, UIntToPtr(et[i].u.Id), param );
812 if (!ret) break;
815 __EXCEPT_PAGE_FAULT
817 ret = FALSE;
818 status = STATUS_ACCESS_VIOLATION;
820 __ENDTRY
822 done:
823 HeapFree( GetProcessHeap(), 0, name );
824 if (!IS_INTRESOURCE(typeW.Buffer)) HeapFree( GetProcessHeap(), 0, typeW.Buffer );
825 if (status != STATUS_SUCCESS) SetLastError( RtlNtStatusToDosError(status) );
826 return ret;
830 /**********************************************************************
831 * EnumResourceNamesExW (kernelbase.@)
833 BOOL WINAPI DECLSPEC_HOTPATCH EnumResourceNamesExW( HMODULE module, LPCWSTR type, ENUMRESNAMEPROCW func,
834 LONG_PTR param, DWORD flags, LANGID lang )
836 int i, len = 0;
837 BOOL ret = FALSE;
838 LPWSTR name = NULL;
839 NTSTATUS status;
840 UNICODE_STRING typeW;
841 LDR_RESOURCE_INFO info;
842 const IMAGE_RESOURCE_DIRECTORY *basedir, *resdir;
843 const IMAGE_RESOURCE_DIRECTORY_ENTRY *et;
844 const IMAGE_RESOURCE_DIR_STRING_U *str;
846 TRACE( "%p %s %p %lx\n", module, debugstr_w(type), func, param );
848 if (flags & (RESOURCE_ENUM_MUI | RESOURCE_ENUM_MUI_SYSTEM | RESOURCE_ENUM_VALIDATE))
849 FIXME( "unimplemented flags: %x\n", flags );
851 if (!flags) flags = RESOURCE_ENUM_LN | RESOURCE_ENUM_MUI;
852 if (!(flags & RESOURCE_ENUM_LN)) return ret;
854 if (!module) module = GetModuleHandleW( 0 );
855 typeW.Buffer = NULL;
856 if ((status = LdrFindResourceDirectory_U( module, NULL, 0, &basedir )) != STATUS_SUCCESS)
857 goto done;
858 if ((status = get_res_nameW( type, &typeW )) != STATUS_SUCCESS)
859 goto done;
860 info.Type = (ULONG_PTR)typeW.Buffer;
861 if ((status = LdrFindResourceDirectory_U( module, &info, 1, &resdir )) != STATUS_SUCCESS)
862 goto done;
864 et = (const IMAGE_RESOURCE_DIRECTORY_ENTRY *)(resdir + 1);
865 __TRY
867 for (i = 0; i < resdir->NumberOfNamedEntries+resdir->NumberOfIdEntries; i++)
869 if (et[i].u.s.NameIsString)
871 str = (const IMAGE_RESOURCE_DIR_STRING_U *)((const BYTE *)basedir + et[i].u.s.NameOffset);
872 if (str->Length + 1 > len)
874 len = str->Length + 1;
875 HeapFree( GetProcessHeap(), 0, name );
876 if (!(name = HeapAlloc( GetProcessHeap(), 0, len * sizeof(WCHAR) )))
878 ret = FALSE;
879 break;
882 memcpy(name, str->NameString, str->Length * sizeof (WCHAR));
883 name[str->Length] = 0;
884 ret = func( module, type, name, param );
886 else
888 ret = func( module, type, UIntToPtr(et[i].u.Id), param );
890 if (!ret) break;
893 __EXCEPT_PAGE_FAULT
895 ret = FALSE;
896 status = STATUS_ACCESS_VIOLATION;
898 __ENDTRY
899 done:
900 HeapFree( GetProcessHeap(), 0, name );
901 if (!IS_INTRESOURCE(typeW.Buffer)) HeapFree( GetProcessHeap(), 0, typeW.Buffer );
902 if (status != STATUS_SUCCESS) SetLastError( RtlNtStatusToDosError(status) );
903 return ret;
907 /**********************************************************************
908 * EnumResourceNamesW (kernelbase.@)
910 BOOL WINAPI DECLSPEC_HOTPATCH EnumResourceNamesW( HMODULE module, LPCWSTR type,
911 ENUMRESNAMEPROCW func, LONG_PTR param )
913 return EnumResourceNamesExW( module, type, func, param, 0, 0 );
917 /**********************************************************************
918 * EnumResourceTypesExA (kernelbase.@)
920 BOOL WINAPI DECLSPEC_HOTPATCH EnumResourceTypesExA( HMODULE module, ENUMRESTYPEPROCA func, LONG_PTR param,
921 DWORD flags, LANGID lang )
923 int i;
924 BOOL ret = FALSE;
925 LPSTR type = NULL;
926 DWORD len = 0, newlen;
927 const IMAGE_RESOURCE_DIRECTORY *resdir;
928 const IMAGE_RESOURCE_DIRECTORY_ENTRY *et;
929 const IMAGE_RESOURCE_DIR_STRING_U *str;
931 TRACE( "%p %p %lx\n", module, func, param );
933 if (flags & (RESOURCE_ENUM_MUI | RESOURCE_ENUM_MUI_SYSTEM | RESOURCE_ENUM_VALIDATE))
934 FIXME( "unimplemented flags: %x\n", flags );
936 if (!flags) flags = RESOURCE_ENUM_LN | RESOURCE_ENUM_MUI;
937 if (!(flags & RESOURCE_ENUM_LN)) return ret;
939 if (!module) module = GetModuleHandleW( 0 );
941 if (!set_ntstatus( LdrFindResourceDirectory_U( module, NULL, 0, &resdir ))) return FALSE;
943 et = (const IMAGE_RESOURCE_DIRECTORY_ENTRY *)(resdir + 1);
944 for (i = 0; i < resdir->NumberOfNamedEntries+resdir->NumberOfIdEntries; i++)
946 if (et[i].u.s.NameIsString)
948 str = (const IMAGE_RESOURCE_DIR_STRING_U *)((const BYTE *)resdir + et[i].u.s.NameOffset);
949 newlen = WideCharToMultiByte( CP_ACP, 0, str->NameString, str->Length, NULL, 0, NULL, NULL);
950 if (newlen + 1 > len)
952 len = newlen + 1;
953 HeapFree( GetProcessHeap(), 0, type );
954 if (!(type = HeapAlloc( GetProcessHeap(), 0, len ))) return FALSE;
956 WideCharToMultiByte( CP_ACP, 0, str->NameString, str->Length, type, len, NULL, NULL);
957 type[newlen] = 0;
958 ret = func( module, type, param );
960 else
962 ret = func( module, UIntToPtr(et[i].u.Id), param );
964 if (!ret) break;
966 HeapFree( GetProcessHeap(), 0, type );
967 return ret;
971 /**********************************************************************
972 * EnumResourceTypesExW (kernelbase.@)
974 BOOL WINAPI DECLSPEC_HOTPATCH EnumResourceTypesExW( HMODULE module, ENUMRESTYPEPROCW func, LONG_PTR param,
975 DWORD flags, LANGID lang )
977 int i, len = 0;
978 BOOL ret = FALSE;
979 LPWSTR type = NULL;
980 const IMAGE_RESOURCE_DIRECTORY *resdir;
981 const IMAGE_RESOURCE_DIRECTORY_ENTRY *et;
982 const IMAGE_RESOURCE_DIR_STRING_U *str;
984 TRACE( "%p %p %lx\n", module, func, param );
986 if (!flags) flags = RESOURCE_ENUM_LN | RESOURCE_ENUM_MUI;
987 if (!(flags & RESOURCE_ENUM_LN)) return ret;
989 if (!module) module = GetModuleHandleW( 0 );
991 if (!set_ntstatus( LdrFindResourceDirectory_U( module, NULL, 0, &resdir ))) return FALSE;
993 et = (const IMAGE_RESOURCE_DIRECTORY_ENTRY *)(resdir + 1);
994 for (i = 0; i < resdir->NumberOfNamedEntries + resdir->NumberOfIdEntries; i++)
996 if (et[i].u.s.NameIsString)
998 str = (const IMAGE_RESOURCE_DIR_STRING_U *)((const BYTE *)resdir + et[i].u.s.NameOffset);
999 if (str->Length + 1 > len)
1001 len = str->Length + 1;
1002 HeapFree( GetProcessHeap(), 0, type );
1003 if (!(type = HeapAlloc( GetProcessHeap(), 0, len * sizeof(WCHAR) ))) return FALSE;
1005 memcpy(type, str->NameString, str->Length * sizeof (WCHAR));
1006 type[str->Length] = 0;
1007 ret = func( module, type, param );
1009 else
1011 ret = func( module, UIntToPtr(et[i].u.Id), param );
1013 if (!ret) break;
1015 HeapFree( GetProcessHeap(), 0, type );
1016 return ret;
1020 /**********************************************************************
1021 * FindResourceExW (kernelbase.@)
1023 HRSRC WINAPI DECLSPEC_HOTPATCH FindResourceExW( HMODULE module, LPCWSTR type, LPCWSTR name, WORD lang )
1025 NTSTATUS status;
1026 UNICODE_STRING nameW, typeW;
1027 LDR_RESOURCE_INFO info;
1028 const IMAGE_RESOURCE_DATA_ENTRY *entry = NULL;
1030 TRACE( "%p %s %s %04x\n", module, debugstr_w(type), debugstr_w(name), lang );
1032 if (!module) module = GetModuleHandleW( 0 );
1033 nameW.Buffer = typeW.Buffer = NULL;
1035 __TRY
1037 if ((status = get_res_nameW( name, &nameW )) != STATUS_SUCCESS) goto done;
1038 if ((status = get_res_nameW( type, &typeW )) != STATUS_SUCCESS) goto done;
1039 info.Type = (ULONG_PTR)typeW.Buffer;
1040 info.Name = (ULONG_PTR)nameW.Buffer;
1041 info.Language = lang;
1042 status = LdrFindResource_U( module, &info, 3, &entry );
1043 done:
1044 if (status != STATUS_SUCCESS) SetLastError( RtlNtStatusToDosError(status) );
1046 __EXCEPT_PAGE_FAULT
1048 SetLastError( ERROR_INVALID_PARAMETER );
1050 __ENDTRY
1052 if (!IS_INTRESOURCE(nameW.Buffer)) HeapFree( GetProcessHeap(), 0, nameW.Buffer );
1053 if (!IS_INTRESOURCE(typeW.Buffer)) HeapFree( GetProcessHeap(), 0, typeW.Buffer );
1054 return (HRSRC)entry;
1058 /**********************************************************************
1059 * FindResourceW (kernelbase.@)
1061 HRSRC WINAPI DECLSPEC_HOTPATCH FindResourceW( HINSTANCE module, LPCWSTR name, LPCWSTR type )
1063 return FindResourceExW( module, type, name, MAKELANGID( LANG_NEUTRAL, SUBLANG_NEUTRAL ) );
1067 /**********************************************************************
1068 * FreeResource (kernelbase.@)
1070 BOOL WINAPI DECLSPEC_HOTPATCH FreeResource( HGLOBAL handle )
1072 return FALSE;
1076 /**********************************************************************
1077 * LoadResource (kernelbase.@)
1079 HGLOBAL WINAPI DECLSPEC_HOTPATCH LoadResource( HINSTANCE module, HRSRC rsrc )
1081 void *ret;
1083 TRACE( "%p %p\n", module, rsrc );
1085 if (!rsrc) return 0;
1086 if (!module) module = GetModuleHandleW( 0 );
1087 if (!set_ntstatus( LdrAccessResource( module, (IMAGE_RESOURCE_DATA_ENTRY *)rsrc, &ret, NULL )))
1088 return 0;
1089 return ret;
1093 /**********************************************************************
1094 * LockResource (kernelbase.@)
1096 LPVOID WINAPI DECLSPEC_HOTPATCH LockResource( HGLOBAL handle )
1098 return handle;
1102 /**********************************************************************
1103 * SizeofResource (kernelbase.@)
1105 DWORD WINAPI DECLSPEC_HOTPATCH SizeofResource( HINSTANCE module, HRSRC rsrc )
1107 if (!rsrc) return 0;
1108 return ((IMAGE_RESOURCE_DATA_ENTRY *)rsrc)->Size;
1112 /***********************************************************************
1113 * Activation contexts
1114 ***********************************************************************/
1117 /***********************************************************************
1118 * ActivateActCtx (kernelbase.@)
1120 BOOL WINAPI DECLSPEC_HOTPATCH ActivateActCtx( HANDLE context, ULONG_PTR *cookie )
1122 return set_ntstatus( RtlActivateActivationContext( 0, context, cookie ));
1126 /***********************************************************************
1127 * AddRefActCtx (kernelbase.@)
1129 void WINAPI DECLSPEC_HOTPATCH AddRefActCtx( HANDLE context )
1131 RtlAddRefActivationContext( context );
1135 /***********************************************************************
1136 * CreateActCtxW (kernelbase.@)
1138 HANDLE WINAPI DECLSPEC_HOTPATCH CreateActCtxW( PCACTCTXW ctx )
1140 HANDLE context;
1142 TRACE( "%p %08x\n", ctx, ctx ? ctx->dwFlags : 0 );
1144 if (!set_ntstatus( RtlCreateActivationContext( &context, ctx ))) return INVALID_HANDLE_VALUE;
1145 return context;
1149 /***********************************************************************
1150 * DeactivateActCtx (kernelbase.@)
1152 BOOL WINAPI DECLSPEC_HOTPATCH DeactivateActCtx( DWORD flags, ULONG_PTR cookie )
1154 RtlDeactivateActivationContext( flags, cookie );
1155 return TRUE;
1159 /***********************************************************************
1160 * FindActCtxSectionGuid (kernelbase.@)
1162 BOOL WINAPI DECLSPEC_HOTPATCH FindActCtxSectionGuid( DWORD flags, const GUID *ext_guid, ULONG id,
1163 const GUID *guid, PACTCTX_SECTION_KEYED_DATA info )
1165 return set_ntstatus( RtlFindActivationContextSectionGuid( flags, ext_guid, id, guid, info ));
1169 /***********************************************************************
1170 * FindActCtxSectionStringW (kernelbase.@)
1172 BOOL WINAPI DECLSPEC_HOTPATCH FindActCtxSectionStringW( DWORD flags, const GUID *ext_guid, ULONG id,
1173 LPCWSTR str, PACTCTX_SECTION_KEYED_DATA info )
1175 UNICODE_STRING us;
1177 if (!info)
1179 SetLastError( ERROR_INVALID_PARAMETER );
1180 return FALSE;
1182 RtlInitUnicodeString( &us, str );
1183 return set_ntstatus( RtlFindActivationContextSectionString( flags, ext_guid, id, &us, info ));
1187 /***********************************************************************
1188 * GetCurrentActCtx (kernelbase.@)
1190 BOOL WINAPI DECLSPEC_HOTPATCH GetCurrentActCtx( HANDLE *pcontext )
1192 return set_ntstatus( RtlGetActiveActivationContext( pcontext ));
1196 /***********************************************************************
1197 * QueryActCtxSettingsW (kernelbase.@)
1199 BOOL WINAPI DECLSPEC_HOTPATCH QueryActCtxSettingsW( DWORD flags, HANDLE ctx, const WCHAR *ns,
1200 const WCHAR *settings, WCHAR *buffer, SIZE_T size,
1201 SIZE_T *written )
1203 return set_ntstatus( RtlQueryActivationContextApplicationSettings( flags, ctx, ns, settings,
1204 buffer, size, written ));
1208 /***********************************************************************
1209 * QueryActCtxW (kernelbase.@)
1211 BOOL WINAPI DECLSPEC_HOTPATCH QueryActCtxW( DWORD flags, HANDLE context, PVOID inst, ULONG class,
1212 PVOID buffer, SIZE_T size, SIZE_T *written )
1214 return set_ntstatus( RtlQueryInformationActivationContext( flags, context, inst, class,
1215 buffer, size, written ));
1219 /***********************************************************************
1220 * ReleaseActCtx (kernelbase.@)
1222 void WINAPI DECLSPEC_HOTPATCH ReleaseActCtx( HANDLE context )
1224 RtlReleaseActivationContext( context );
1228 /***********************************************************************
1229 * ZombifyActCtx (kernelbase.@)
1231 BOOL WINAPI DECLSPEC_HOTPATCH ZombifyActCtx( HANDLE context )
1233 return set_ntstatus( RtlZombifyActivationContext( context ));