include: Add some new ProcThreadAttribute definitions.
[wine.git] / dlls / kernelbase / loader.c
blob22dff7ba56bf2528a7424a0b5735905805cd62d8
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 );
51 static CRITICAL_SECTION exclusive_datafile_list_section;
52 static CRITICAL_SECTION_DEBUG critsect_debug =
54 0, 0, &exclusive_datafile_list_section,
55 { &critsect_debug.ProcessLocksList, &critsect_debug.ProcessLocksList },
56 0, 0, { (DWORD_PTR)(__FILE__ ": exclusive_datafile_list_section") }
58 static CRITICAL_SECTION exclusive_datafile_list_section = { &critsect_debug, -1, 0, 0, 0, 0 };
60 /***********************************************************************
61 * Modules
62 ***********************************************************************/
65 /******************************************************************
66 * get_proc_address
68 FARPROC WINAPI get_proc_address( HMODULE module, LPCSTR function )
70 FARPROC proc;
71 ANSI_STRING str;
73 if (!module) module = NtCurrentTeb()->Peb->ImageBaseAddress;
75 if ((ULONG_PTR)function >> 16)
77 RtlInitAnsiString( &str, function );
78 if (!set_ntstatus( LdrGetProcedureAddress( module, &str, 0, (void**)&proc ))) return NULL;
80 else if (!set_ntstatus( LdrGetProcedureAddress( module, NULL, LOWORD(function), (void**)&proc )))
81 return NULL;
83 return proc;
87 /******************************************************************
88 * load_library_as_datafile
90 static BOOL load_library_as_datafile( LPCWSTR load_path, DWORD flags, LPCWSTR name, HMODULE *mod_ret )
92 WCHAR filenameW[MAX_PATH];
93 HANDLE mapping, file = INVALID_HANDLE_VALUE;
94 HMODULE module = 0;
95 DWORD protect = PAGE_READONLY;
97 *mod_ret = 0;
99 if (flags & LOAD_LIBRARY_AS_IMAGE_RESOURCE) protect |= SEC_IMAGE;
101 if (SearchPathW( NULL, name, L".dll", ARRAY_SIZE( filenameW ), filenameW, NULL ))
103 file = CreateFileW( filenameW, GENERIC_READ, FILE_SHARE_READ | FILE_SHARE_DELETE,
104 NULL, OPEN_EXISTING, 0, 0 );
106 if (file == INVALID_HANDLE_VALUE) return FALSE;
108 mapping = CreateFileMappingW( file, NULL, protect, 0, 0, NULL );
109 if (!mapping) goto failed;
111 module = MapViewOfFile( mapping, FILE_MAP_READ, 0, 0, 0 );
112 CloseHandle( mapping );
113 if (!module) goto failed;
115 if (!(flags & LOAD_LIBRARY_AS_IMAGE_RESOURCE))
117 /* make sure it's a valid PE file */
118 if (!RtlImageNtHeader( module ))
120 SetLastError( ERROR_BAD_EXE_FORMAT );
121 goto failed;
123 *mod_ret = (HMODULE)((char *)module + 1); /* set bit 0 for data file module */
125 if (flags & LOAD_LIBRARY_AS_DATAFILE_EXCLUSIVE)
127 struct exclusive_datafile *datafile = HeapAlloc( GetProcessHeap(), 0, sizeof(*datafile) );
128 if (!datafile) goto failed;
129 datafile->module = *mod_ret;
130 datafile->file = file;
131 RtlEnterCriticalSection( &exclusive_datafile_list_section );
132 list_add_head( &exclusive_datafile_list, &datafile->entry );
133 RtlLeaveCriticalSection( &exclusive_datafile_list_section );
134 TRACE( "delaying close %p for module %p\n", datafile->file, datafile->module );
135 return TRUE;
138 else *mod_ret = (HMODULE)((char *)module + 2); /* set bit 1 for image resource module */
140 CloseHandle( file );
141 return TRUE;
143 failed:
144 if (module) UnmapViewOfFile( module );
145 CloseHandle( file );
146 return FALSE;
150 /******************************************************************
151 * load_library
153 static HMODULE load_library( const UNICODE_STRING *libname, DWORD flags )
155 const DWORD unsupported_flags = LOAD_IGNORE_CODE_AUTHZ_LEVEL | LOAD_LIBRARY_REQUIRE_SIGNED_TARGET;
156 NTSTATUS status;
157 HMODULE module;
158 WCHAR *load_path, *dummy;
160 if (flags & unsupported_flags) FIXME( "unsupported flag(s) used %#08lx\n", flags );
162 if (!set_ntstatus( LdrGetDllPath( libname->Buffer, flags, &load_path, &dummy ))) return 0;
164 if (flags & (LOAD_LIBRARY_AS_DATAFILE | LOAD_LIBRARY_AS_DATAFILE_EXCLUSIVE |
165 LOAD_LIBRARY_AS_IMAGE_RESOURCE))
167 if (LdrGetDllHandleEx( 0, load_path, NULL, libname, &module ))
168 load_library_as_datafile( load_path, flags, libname->Buffer, &module );
170 else
172 status = LdrLoadDll( load_path, flags, libname, &module );
173 if (!set_ntstatus( status ))
175 module = 0;
176 if (status == STATUS_DLL_NOT_FOUND && (GetVersion() & 0x80000000))
177 SetLastError( ERROR_DLL_NOT_FOUND );
181 RtlReleasePath( load_path );
182 return module;
186 /****************************************************************************
187 * AddDllDirectory (kernelbase.@)
189 DLL_DIRECTORY_COOKIE WINAPI DECLSPEC_HOTPATCH AddDllDirectory( const WCHAR *dir )
191 UNICODE_STRING str;
192 void *cookie;
194 RtlInitUnicodeString( &str, dir );
195 if (!set_ntstatus( LdrAddDllDirectory( &str, &cookie ))) return NULL;
196 return cookie;
200 /***********************************************************************
201 * DelayLoadFailureHook (kernelbase.@)
203 FARPROC WINAPI DECLSPEC_HOTPATCH DelayLoadFailureHook( LPCSTR name, LPCSTR function )
205 ULONG_PTR args[2];
207 if ((ULONG_PTR)function >> 16)
208 ERR( "failed to delay load %s.%s\n", name, function );
209 else
210 ERR( "failed to delay load %s.%u\n", name, LOWORD(function) );
211 args[0] = (ULONG_PTR)name;
212 args[1] = (ULONG_PTR)function;
213 RaiseException( EXCEPTION_WINE_STUB, EH_NONCONTINUABLE, 2, args );
214 return NULL;
218 /****************************************************************************
219 * DisableThreadLibraryCalls (kernelbase.@)
221 BOOL WINAPI DECLSPEC_HOTPATCH DisableThreadLibraryCalls( HMODULE module )
223 return set_ntstatus( LdrDisableThreadCalloutsForDll( module ));
227 /***********************************************************************
228 * FreeLibrary (kernelbase.@)
230 BOOL WINAPI DECLSPEC_HOTPATCH FreeLibrary( HINSTANCE module )
232 if (!module)
234 SetLastError( ERROR_INVALID_HANDLE );
235 return FALSE;
238 if ((ULONG_PTR)module & 3) /* this is a datafile module */
240 void *ptr = (void *)((ULONG_PTR)module & ~3);
241 if (!RtlImageNtHeader( ptr ))
243 SetLastError( ERROR_BAD_EXE_FORMAT );
244 return FALSE;
246 if ((ULONG_PTR)module & 1)
248 struct exclusive_datafile *file;
250 RtlEnterCriticalSection( &exclusive_datafile_list_section );
251 LIST_FOR_EACH_ENTRY( file, &exclusive_datafile_list, struct exclusive_datafile, entry )
253 if (file->module != module) continue;
254 TRACE( "closing %p for module %p\n", file->file, file->module );
255 CloseHandle( file->file );
256 list_remove( &file->entry );
257 HeapFree( GetProcessHeap(), 0, file );
258 break;
260 RtlLeaveCriticalSection( &exclusive_datafile_list_section );
262 return UnmapViewOfFile( ptr );
265 return set_ntstatus( LdrUnloadDll( module ));
269 /***********************************************************************
270 * GetModuleFileNameA (kernelbase.@)
272 DWORD WINAPI DECLSPEC_HOTPATCH GetModuleFileNameA( HMODULE module, LPSTR filename, DWORD size )
274 LPWSTR filenameW = HeapAlloc( GetProcessHeap(), 0, size * sizeof(WCHAR) );
275 DWORD len;
277 if (!filenameW)
279 SetLastError( ERROR_NOT_ENOUGH_MEMORY );
280 return 0;
282 if ((len = GetModuleFileNameW( module, filenameW, size )))
284 len = file_name_WtoA( filenameW, len, filename, size );
285 if (len < size)
286 filename[len] = 0;
287 else
288 SetLastError( ERROR_INSUFFICIENT_BUFFER );
290 HeapFree( GetProcessHeap(), 0, filenameW );
291 return len;
295 /***********************************************************************
296 * GetModuleFileNameW (kernelbase.@)
298 DWORD WINAPI DECLSPEC_HOTPATCH GetModuleFileNameW( HMODULE module, LPWSTR filename, DWORD size )
300 ULONG len = 0;
301 WIN16_SUBSYSTEM_TIB *win16_tib;
302 UNICODE_STRING name;
303 NTSTATUS status;
305 if (!module && ((win16_tib = NtCurrentTeb()->Tib.SubSystemTib)) && win16_tib->exe_name)
307 len = min( size, win16_tib->exe_name->Length / sizeof(WCHAR) );
308 memcpy( filename, win16_tib->exe_name->Buffer, len * sizeof(WCHAR) );
309 if (len < size) filename[len] = 0;
310 goto done;
313 name.Buffer = filename;
314 name.MaximumLength = min( size, UNICODE_STRING_MAX_CHARS ) * sizeof(WCHAR);
315 status = LdrGetDllFullName( module, &name );
316 if (!status || status == STATUS_BUFFER_TOO_SMALL) len = name.Length / sizeof(WCHAR);
317 SetLastError( RtlNtStatusToDosError( status ));
318 done:
319 TRACE( "%s\n", debugstr_wn(filename, len) );
320 return len;
324 /***********************************************************************
325 * GetModuleHandleA (kernelbase.@)
327 HMODULE WINAPI DECLSPEC_HOTPATCH GetModuleHandleA( LPCSTR module )
329 HMODULE ret;
331 GetModuleHandleExA( GET_MODULE_HANDLE_EX_FLAG_UNCHANGED_REFCOUNT, module, &ret );
332 return ret;
336 /***********************************************************************
337 * GetModuleHandleW (kernelbase.@)
339 HMODULE WINAPI DECLSPEC_HOTPATCH GetModuleHandleW( LPCWSTR module )
341 HMODULE ret;
343 GetModuleHandleExW( GET_MODULE_HANDLE_EX_FLAG_UNCHANGED_REFCOUNT, module, &ret );
344 return ret;
348 /***********************************************************************
349 * GetModuleHandleExA (kernelbase.@)
351 BOOL WINAPI DECLSPEC_HOTPATCH GetModuleHandleExA( DWORD flags, LPCSTR name, HMODULE *module )
353 WCHAR *nameW;
355 if (!module)
357 SetLastError( ERROR_INVALID_PARAMETER );
358 return FALSE;
361 if (!name || (flags & GET_MODULE_HANDLE_EX_FLAG_FROM_ADDRESS))
362 return GetModuleHandleExW( flags, (LPCWSTR)name, module );
364 if (!(nameW = file_name_AtoW( name, FALSE )))
366 *module = NULL;
367 SetLastError( ERROR_MOD_NOT_FOUND );
368 return FALSE;
370 return GetModuleHandleExW( flags, nameW, module );
374 /***********************************************************************
375 * GetModuleHandleExW (kernelbase.@)
377 BOOL WINAPI DECLSPEC_HOTPATCH GetModuleHandleExW( DWORD flags, LPCWSTR name, HMODULE *module )
379 HMODULE ret = NULL;
380 NTSTATUS status;
381 void *dummy;
383 if (!module)
385 SetLastError( ERROR_INVALID_PARAMETER );
386 return FALSE;
389 if ((flags & ~(GET_MODULE_HANDLE_EX_FLAG_PIN | GET_MODULE_HANDLE_EX_FLAG_UNCHANGED_REFCOUNT
390 | GET_MODULE_HANDLE_EX_FLAG_FROM_ADDRESS))
391 || (flags & (GET_MODULE_HANDLE_EX_FLAG_PIN | GET_MODULE_HANDLE_EX_FLAG_UNCHANGED_REFCOUNT))
392 == (GET_MODULE_HANDLE_EX_FLAG_PIN | GET_MODULE_HANDLE_EX_FLAG_UNCHANGED_REFCOUNT))
394 *module = NULL;
395 SetLastError( ERROR_INVALID_PARAMETER );
396 return FALSE;
399 if (name && !(flags & GET_MODULE_HANDLE_EX_FLAG_FROM_ADDRESS))
401 UNICODE_STRING wstr;
402 ULONG ldr_flags = 0;
404 if (flags & GET_MODULE_HANDLE_EX_FLAG_PIN)
405 ldr_flags |= LDR_GET_DLL_HANDLE_EX_FLAG_PIN;
406 if (flags & GET_MODULE_HANDLE_EX_FLAG_UNCHANGED_REFCOUNT)
407 ldr_flags |= LDR_GET_DLL_HANDLE_EX_FLAG_UNCHANGED_REFCOUNT;
409 RtlInitUnicodeString( &wstr, name );
410 status = LdrGetDllHandleEx( ldr_flags, NULL, NULL, &wstr, &ret );
412 else
414 ret = name ? RtlPcToFileHeader( (void *)name, &dummy ) : NtCurrentTeb()->Peb->ImageBaseAddress;
416 if (ret)
418 if (!(flags & GET_MODULE_HANDLE_EX_FLAG_UNCHANGED_REFCOUNT))
419 status = LdrAddRefDll( flags & GET_MODULE_HANDLE_EX_FLAG_PIN ? LDR_ADDREF_DLL_PIN : 0, ret );
420 else
421 status = STATUS_SUCCESS;
422 } else status = STATUS_DLL_NOT_FOUND;
425 *module = ret;
426 return set_ntstatus( status );
430 /***********************************************************************
431 * GetProcAddress (kernelbase.@)
434 #ifdef __x86_64__
436 * Work around a Delphi bug on x86_64. When delay loading a symbol,
437 * Delphi saves rcx, rdx, r8 and r9 to the stack. It then calls
438 * GetProcAddress(), pops the saved registers and calls the function.
439 * This works fine if all of the parameters are ints. However, since
440 * it does not save xmm0 - 3, it relies on GetProcAddress() preserving
441 * these registers if the function takes floating point parameters.
442 * This wrapper saves xmm0 - 3 to the stack.
444 __ASM_GLOBAL_FUNC( GetProcAddress,
445 ".byte 0x48\n\t" /* hotpatch prolog */
446 "pushq %rbp\n\t"
447 __ASM_SEH(".seh_pushreg %rbp\n\t")
448 __ASM_CFI(".cfi_adjust_cfa_offset 8\n\t")
449 __ASM_CFI(".cfi_rel_offset %rbp,0\n\t")
450 "movq %rsp,%rbp\n\t"
451 __ASM_SEH(".seh_setframe %rbp,0\n\t")
452 __ASM_CFI(".cfi_def_cfa_register %rbp\n\t")
453 __ASM_SEH(".seh_endprologue\n\t")
454 "subq $0x60,%rsp\n\t"
455 "andq $~15,%rsp\n\t"
456 "movaps %xmm0,0x20(%rsp)\n\t"
457 "movaps %xmm1,0x30(%rsp)\n\t"
458 "movaps %xmm2,0x40(%rsp)\n\t"
459 "movaps %xmm3,0x50(%rsp)\n\t"
460 "call " __ASM_NAME("get_proc_address") "\n\t"
461 "movaps 0x50(%rsp), %xmm3\n\t"
462 "movaps 0x40(%rsp), %xmm2\n\t"
463 "movaps 0x30(%rsp), %xmm1\n\t"
464 "movaps 0x20(%rsp), %xmm0\n\t"
465 "leaq 0(%rbp),%rsp\n\t"
466 __ASM_CFI(".cfi_def_cfa_register %rsp\n\t")
467 "popq %rbp\n\t"
468 __ASM_CFI(".cfi_adjust_cfa_offset -8\n\t")
469 __ASM_CFI(".cfi_same_value %rbp\n\t")
470 "ret" )
471 #else /* __x86_64__ */
473 FARPROC WINAPI DECLSPEC_HOTPATCH GetProcAddress( HMODULE module, LPCSTR function )
475 return get_proc_address( module, function );
478 #endif /* __x86_64__ */
481 /***********************************************************************
482 * IsApiSetImplemented (kernelbase.@)
484 BOOL WINAPI IsApiSetImplemented( LPCSTR name )
486 UNICODE_STRING str;
487 NTSTATUS status;
488 BOOLEAN in_schema, present;
490 if (!RtlCreateUnicodeStringFromAsciiz( &str, name )) return FALSE;
491 status = ApiSetQueryApiSetPresenceEx( &str, &in_schema, &present );
492 RtlFreeUnicodeString( &str );
493 return !status && present;
497 /***********************************************************************
498 * LoadLibraryA (kernelbase.@)
500 HMODULE WINAPI DECLSPEC_HOTPATCH LoadLibraryA( LPCSTR name )
502 return LoadLibraryExA( name, 0, 0 );
506 /***********************************************************************
507 * LoadLibraryW (kernelbase.@)
509 HMODULE WINAPI DECLSPEC_HOTPATCH LoadLibraryW( LPCWSTR name )
511 return LoadLibraryExW( name, 0, 0 );
515 /******************************************************************
516 * LoadLibraryExA (kernelbase.@)
518 HMODULE WINAPI DECLSPEC_HOTPATCH LoadLibraryExA( LPCSTR name, HANDLE file, DWORD flags )
520 WCHAR *nameW;
522 if (!(nameW = file_name_AtoW( name, FALSE ))) return 0;
523 return LoadLibraryExW( nameW, file, flags );
527 /***********************************************************************
528 * LoadLibraryExW (kernelbase.@)
530 HMODULE WINAPI DECLSPEC_HOTPATCH LoadLibraryExW( LPCWSTR name, HANDLE file, DWORD flags )
532 UNICODE_STRING str;
533 HMODULE module;
535 if (!name)
537 SetLastError( ERROR_INVALID_PARAMETER );
538 return 0;
540 RtlInitUnicodeString( &str, name );
541 if (str.Buffer[str.Length/sizeof(WCHAR) - 1] != ' ') return load_library( &str, flags );
543 /* library name has trailing spaces */
544 RtlCreateUnicodeString( &str, name );
545 while (str.Length > sizeof(WCHAR) && str.Buffer[str.Length/sizeof(WCHAR) - 1] == ' ')
546 str.Length -= sizeof(WCHAR);
548 str.Buffer[str.Length/sizeof(WCHAR)] = 0;
549 module = load_library( &str, flags );
550 RtlFreeUnicodeString( &str );
551 return module;
555 /***********************************************************************
556 * LoadPackagedLibrary (kernelbase.@)
558 HMODULE WINAPI /* DECLSPEC_HOTPATCH */ LoadPackagedLibrary( LPCWSTR name, DWORD reserved )
560 FIXME( "semi-stub, name %s, reserved %#lx.\n", debugstr_w(name), reserved );
561 SetLastError( APPMODEL_ERROR_NO_PACKAGE );
562 return NULL;
566 /***********************************************************************
567 * LoadAppInitDlls (kernelbase.@)
569 void WINAPI LoadAppInitDlls(void)
571 TRACE( "\n" );
575 /****************************************************************************
576 * RemoveDllDirectory (kernelbase.@)
578 BOOL WINAPI DECLSPEC_HOTPATCH RemoveDllDirectory( DLL_DIRECTORY_COOKIE cookie )
580 return set_ntstatus( LdrRemoveDllDirectory( cookie ));
584 /*************************************************************************
585 * SetDefaultDllDirectories (kernelbase.@)
587 BOOL WINAPI DECLSPEC_HOTPATCH SetDefaultDllDirectories( DWORD flags )
589 return set_ntstatus( LdrSetDefaultDllDirectories( flags ));
593 /***********************************************************************
594 * Resources
595 ***********************************************************************/
598 #define IS_INTRESOURCE(x) (((ULONG_PTR)(x) >> 16) == 0)
600 /* retrieve the resource name to pass to the ntdll functions */
601 static NTSTATUS get_res_nameA( LPCSTR name, UNICODE_STRING *str )
603 if (IS_INTRESOURCE(name))
605 str->Buffer = ULongToPtr( LOWORD(name) );
606 return STATUS_SUCCESS;
608 if (name[0] == '#')
610 ULONG value;
611 if (RtlCharToInteger( name + 1, 10, &value ) != STATUS_SUCCESS || HIWORD(value))
612 return STATUS_INVALID_PARAMETER;
613 str->Buffer = ULongToPtr(value);
614 return STATUS_SUCCESS;
616 RtlCreateUnicodeStringFromAsciiz( str, name );
617 RtlUpcaseUnicodeString( str, str, FALSE );
618 return STATUS_SUCCESS;
621 /* retrieve the resource name to pass to the ntdll functions */
622 static NTSTATUS get_res_nameW( LPCWSTR name, UNICODE_STRING *str )
624 if (IS_INTRESOURCE(name))
626 str->Buffer = ULongToPtr( LOWORD(name) );
627 return STATUS_SUCCESS;
629 if (name[0] == '#')
631 ULONG value;
632 RtlInitUnicodeString( str, name + 1 );
633 if (RtlUnicodeStringToInteger( str, 10, &value ) != STATUS_SUCCESS || HIWORD(value))
634 return STATUS_INVALID_PARAMETER;
635 str->Buffer = ULongToPtr(value);
636 return STATUS_SUCCESS;
638 RtlCreateUnicodeString( str, name );
639 RtlUpcaseUnicodeString( str, str, FALSE );
640 return STATUS_SUCCESS;
644 /**********************************************************************
645 * EnumResourceLanguagesExA (kernelbase.@)
647 BOOL WINAPI DECLSPEC_HOTPATCH EnumResourceLanguagesExA( HMODULE module, LPCSTR type, LPCSTR name,
648 ENUMRESLANGPROCA func, LONG_PTR param,
649 DWORD flags, LANGID lang )
651 int i;
652 BOOL ret = FALSE;
653 NTSTATUS status;
654 UNICODE_STRING typeW, nameW;
655 LDR_RESOURCE_INFO info;
656 const IMAGE_RESOURCE_DIRECTORY *basedir, *resdir;
657 const IMAGE_RESOURCE_DIRECTORY_ENTRY *et;
659 TRACE( "%p %s %s %p %Ix %lx %d\n", module, debugstr_a(type), debugstr_a(name),
660 func, param, flags, lang );
662 if (flags & (RESOURCE_ENUM_MUI | RESOURCE_ENUM_MUI_SYSTEM | RESOURCE_ENUM_VALIDATE))
663 FIXME( "unimplemented flags: %lx\n", flags );
665 if (!flags) flags = RESOURCE_ENUM_LN | RESOURCE_ENUM_MUI;
666 if (!(flags & RESOURCE_ENUM_LN)) return ret;
668 if (!module) module = GetModuleHandleW( 0 );
669 typeW.Buffer = nameW.Buffer = NULL;
670 if ((status = LdrFindResourceDirectory_U( module, NULL, 0, &basedir )) != STATUS_SUCCESS)
671 goto done;
672 if ((status = get_res_nameA( type, &typeW )) != STATUS_SUCCESS)
673 goto done;
674 if ((status = get_res_nameA( name, &nameW )) != STATUS_SUCCESS)
675 goto done;
676 info.Type = (ULONG_PTR)typeW.Buffer;
677 info.Name = (ULONG_PTR)nameW.Buffer;
678 if ((status = LdrFindResourceDirectory_U( module, &info, 2, &resdir )) != STATUS_SUCCESS)
679 goto done;
681 et = (const IMAGE_RESOURCE_DIRECTORY_ENTRY *)(resdir + 1);
682 __TRY
684 for (i = 0; i < resdir->NumberOfNamedEntries + resdir->NumberOfIdEntries; i++)
686 ret = func( module, type, name, et[i].u.Id, param );
687 if (!ret) break;
690 __EXCEPT_PAGE_FAULT
692 ret = FALSE;
693 status = STATUS_ACCESS_VIOLATION;
695 __ENDTRY
696 done:
697 if (!IS_INTRESOURCE(typeW.Buffer)) HeapFree( GetProcessHeap(), 0, typeW.Buffer );
698 if (!IS_INTRESOURCE(nameW.Buffer)) HeapFree( GetProcessHeap(), 0, nameW.Buffer );
699 if (status != STATUS_SUCCESS) SetLastError( RtlNtStatusToDosError(status) );
700 return ret;
704 /**********************************************************************
705 * EnumResourceLanguagesExW (kernelbase.@)
707 BOOL WINAPI DECLSPEC_HOTPATCH EnumResourceLanguagesExW( HMODULE module, LPCWSTR type, LPCWSTR name,
708 ENUMRESLANGPROCW func, LONG_PTR param,
709 DWORD flags, LANGID lang )
711 int i;
712 BOOL ret = FALSE;
713 NTSTATUS status;
714 UNICODE_STRING typeW, nameW;
715 LDR_RESOURCE_INFO info;
716 const IMAGE_RESOURCE_DIRECTORY *basedir, *resdir;
717 const IMAGE_RESOURCE_DIRECTORY_ENTRY *et;
719 TRACE( "%p %s %s %p %Ix %lx %d\n", module, debugstr_w(type), debugstr_w(name),
720 func, param, flags, lang );
722 if (flags & (RESOURCE_ENUM_MUI | RESOURCE_ENUM_MUI_SYSTEM | RESOURCE_ENUM_VALIDATE))
723 FIXME( "unimplemented flags: %lx\n", flags );
725 if (!flags) flags = RESOURCE_ENUM_LN | RESOURCE_ENUM_MUI;
726 if (!(flags & RESOURCE_ENUM_LN)) return ret;
728 if (!module) module = GetModuleHandleW( 0 );
729 typeW.Buffer = nameW.Buffer = NULL;
730 if ((status = LdrFindResourceDirectory_U( module, NULL, 0, &basedir )) != STATUS_SUCCESS)
731 goto done;
732 if ((status = get_res_nameW( type, &typeW )) != STATUS_SUCCESS)
733 goto done;
734 if ((status = get_res_nameW( name, &nameW )) != STATUS_SUCCESS)
735 goto done;
736 info.Type = (ULONG_PTR)typeW.Buffer;
737 info.Name = (ULONG_PTR)nameW.Buffer;
738 if ((status = LdrFindResourceDirectory_U( module, &info, 2, &resdir )) != STATUS_SUCCESS)
739 goto done;
741 et = (const IMAGE_RESOURCE_DIRECTORY_ENTRY *)(resdir + 1);
742 __TRY
744 for (i = 0; i < resdir->NumberOfNamedEntries + resdir->NumberOfIdEntries; i++)
746 ret = func( module, type, name, et[i].u.Id, param );
747 if (!ret) break;
750 __EXCEPT_PAGE_FAULT
752 ret = FALSE;
753 status = STATUS_ACCESS_VIOLATION;
755 __ENDTRY
756 done:
757 if (!IS_INTRESOURCE(typeW.Buffer)) HeapFree( GetProcessHeap(), 0, typeW.Buffer );
758 if (!IS_INTRESOURCE(nameW.Buffer)) HeapFree( GetProcessHeap(), 0, nameW.Buffer );
759 if (status != STATUS_SUCCESS) SetLastError( RtlNtStatusToDosError(status) );
760 return ret;
764 /**********************************************************************
765 * EnumResourceNamesExA (kernelbase.@)
767 BOOL WINAPI DECLSPEC_HOTPATCH EnumResourceNamesExA( HMODULE module, LPCSTR type, ENUMRESNAMEPROCA func,
768 LONG_PTR param, DWORD flags, LANGID lang )
770 int i;
771 BOOL ret = FALSE;
772 DWORD len = 0, newlen;
773 LPSTR name = NULL;
774 NTSTATUS status;
775 UNICODE_STRING typeW;
776 LDR_RESOURCE_INFO info;
777 const IMAGE_RESOURCE_DIRECTORY *basedir, *resdir;
778 const IMAGE_RESOURCE_DIRECTORY_ENTRY *et;
779 const IMAGE_RESOURCE_DIR_STRING_U *str;
781 TRACE( "%p %s %p %Ix\n", module, debugstr_a(type), func, param );
783 if (flags & (RESOURCE_ENUM_MUI | RESOURCE_ENUM_MUI_SYSTEM | RESOURCE_ENUM_VALIDATE))
784 FIXME( "unimplemented flags: %lx\n", flags );
786 if (!flags) flags = RESOURCE_ENUM_LN | RESOURCE_ENUM_MUI;
787 if (!(flags & RESOURCE_ENUM_LN)) return ret;
789 if (!module) module = GetModuleHandleW( 0 );
790 typeW.Buffer = NULL;
791 if ((status = LdrFindResourceDirectory_U( module, NULL, 0, &basedir )) != STATUS_SUCCESS)
792 goto done;
793 if ((status = get_res_nameA( type, &typeW )) != STATUS_SUCCESS)
794 goto done;
795 info.Type = (ULONG_PTR)typeW.Buffer;
796 if ((status = LdrFindResourceDirectory_U( module, &info, 1, &resdir )) != STATUS_SUCCESS)
797 goto done;
799 et = (const IMAGE_RESOURCE_DIRECTORY_ENTRY *)(resdir + 1);
800 __TRY
802 for (i = 0; i < resdir->NumberOfNamedEntries+resdir->NumberOfIdEntries; i++)
804 if (et[i].u.s.NameIsString)
806 str = (const IMAGE_RESOURCE_DIR_STRING_U *)((const BYTE *)basedir + et[i].u.s.NameOffset);
807 newlen = WideCharToMultiByte(CP_ACP, 0, str->NameString, str->Length, NULL, 0, NULL, NULL);
808 if (newlen + 1 > len)
810 len = newlen + 1;
811 HeapFree( GetProcessHeap(), 0, name );
812 if (!(name = HeapAlloc( GetProcessHeap(), 0, len + 1 )))
814 ret = FALSE;
815 break;
818 WideCharToMultiByte( CP_ACP, 0, str->NameString, str->Length, name, len, NULL, NULL );
819 name[newlen] = 0;
820 ret = func( module, type, name, param );
822 else
824 ret = func( module, type, UIntToPtr(et[i].u.Id), param );
826 if (!ret) break;
829 __EXCEPT_PAGE_FAULT
831 ret = FALSE;
832 status = STATUS_ACCESS_VIOLATION;
834 __ENDTRY
836 done:
837 HeapFree( GetProcessHeap(), 0, name );
838 if (!IS_INTRESOURCE(typeW.Buffer)) HeapFree( GetProcessHeap(), 0, typeW.Buffer );
839 if (status != STATUS_SUCCESS) SetLastError( RtlNtStatusToDosError(status) );
840 return ret;
844 /**********************************************************************
845 * EnumResourceNamesExW (kernelbase.@)
847 BOOL WINAPI DECLSPEC_HOTPATCH EnumResourceNamesExW( HMODULE module, LPCWSTR type, ENUMRESNAMEPROCW func,
848 LONG_PTR param, DWORD flags, LANGID lang )
850 int i, len = 0;
851 BOOL ret = FALSE;
852 LPWSTR name = NULL;
853 NTSTATUS status;
854 UNICODE_STRING typeW;
855 LDR_RESOURCE_INFO info;
856 const IMAGE_RESOURCE_DIRECTORY *basedir, *resdir;
857 const IMAGE_RESOURCE_DIRECTORY_ENTRY *et;
858 const IMAGE_RESOURCE_DIR_STRING_U *str;
860 TRACE( "%p %s %p %Ix\n", module, debugstr_w(type), func, param );
862 if (flags & (RESOURCE_ENUM_MUI | RESOURCE_ENUM_MUI_SYSTEM | RESOURCE_ENUM_VALIDATE))
863 FIXME( "unimplemented flags: %lx\n", flags );
865 if (!flags) flags = RESOURCE_ENUM_LN | RESOURCE_ENUM_MUI;
866 if (!(flags & RESOURCE_ENUM_LN)) return ret;
868 if (!module) module = GetModuleHandleW( 0 );
869 typeW.Buffer = NULL;
870 if ((status = LdrFindResourceDirectory_U( module, NULL, 0, &basedir )) != STATUS_SUCCESS)
871 goto done;
872 if ((status = get_res_nameW( type, &typeW )) != STATUS_SUCCESS)
873 goto done;
874 info.Type = (ULONG_PTR)typeW.Buffer;
875 if ((status = LdrFindResourceDirectory_U( module, &info, 1, &resdir )) != STATUS_SUCCESS)
876 goto done;
878 et = (const IMAGE_RESOURCE_DIRECTORY_ENTRY *)(resdir + 1);
879 __TRY
881 for (i = 0; i < resdir->NumberOfNamedEntries+resdir->NumberOfIdEntries; i++)
883 if (et[i].u.s.NameIsString)
885 str = (const IMAGE_RESOURCE_DIR_STRING_U *)((const BYTE *)basedir + et[i].u.s.NameOffset);
886 if (str->Length + 1 > len)
888 len = str->Length + 1;
889 HeapFree( GetProcessHeap(), 0, name );
890 if (!(name = HeapAlloc( GetProcessHeap(), 0, len * sizeof(WCHAR) )))
892 ret = FALSE;
893 break;
896 memcpy(name, str->NameString, str->Length * sizeof (WCHAR));
897 name[str->Length] = 0;
898 ret = func( module, type, name, param );
900 else
902 ret = func( module, type, UIntToPtr(et[i].u.Id), param );
904 if (!ret) break;
907 __EXCEPT_PAGE_FAULT
909 ret = FALSE;
910 status = STATUS_ACCESS_VIOLATION;
912 __ENDTRY
913 done:
914 HeapFree( GetProcessHeap(), 0, name );
915 if (!IS_INTRESOURCE(typeW.Buffer)) HeapFree( GetProcessHeap(), 0, typeW.Buffer );
916 if (status != STATUS_SUCCESS) SetLastError( RtlNtStatusToDosError(status) );
917 return ret;
921 /**********************************************************************
922 * EnumResourceNamesW (kernelbase.@)
924 BOOL WINAPI DECLSPEC_HOTPATCH EnumResourceNamesW( HMODULE module, LPCWSTR type,
925 ENUMRESNAMEPROCW func, LONG_PTR param )
927 return EnumResourceNamesExW( module, type, func, param, 0, 0 );
931 /**********************************************************************
932 * EnumResourceTypesExA (kernelbase.@)
934 BOOL WINAPI DECLSPEC_HOTPATCH EnumResourceTypesExA( HMODULE module, ENUMRESTYPEPROCA func, LONG_PTR param,
935 DWORD flags, LANGID lang )
937 int i;
938 BOOL ret = FALSE;
939 LPSTR type = NULL;
940 DWORD len = 0, newlen;
941 const IMAGE_RESOURCE_DIRECTORY *resdir;
942 const IMAGE_RESOURCE_DIRECTORY_ENTRY *et;
943 const IMAGE_RESOURCE_DIR_STRING_U *str;
945 TRACE( "%p %p %Ix\n", module, func, param );
947 if (flags & (RESOURCE_ENUM_MUI | RESOURCE_ENUM_MUI_SYSTEM | RESOURCE_ENUM_VALIDATE))
948 FIXME( "unimplemented flags: %lx\n", flags );
950 if (!flags) flags = RESOURCE_ENUM_LN | RESOURCE_ENUM_MUI;
951 if (!(flags & RESOURCE_ENUM_LN)) return ret;
953 if (!module) module = GetModuleHandleW( 0 );
955 if (!set_ntstatus( LdrFindResourceDirectory_U( module, NULL, 0, &resdir ))) return FALSE;
957 et = (const IMAGE_RESOURCE_DIRECTORY_ENTRY *)(resdir + 1);
958 for (i = 0; i < resdir->NumberOfNamedEntries+resdir->NumberOfIdEntries; i++)
960 if (et[i].u.s.NameIsString)
962 str = (const IMAGE_RESOURCE_DIR_STRING_U *)((const BYTE *)resdir + et[i].u.s.NameOffset);
963 newlen = WideCharToMultiByte( CP_ACP, 0, str->NameString, str->Length, NULL, 0, NULL, NULL);
964 if (newlen + 1 > len)
966 len = newlen + 1;
967 HeapFree( GetProcessHeap(), 0, type );
968 if (!(type = HeapAlloc( GetProcessHeap(), 0, len ))) return FALSE;
970 WideCharToMultiByte( CP_ACP, 0, str->NameString, str->Length, type, len, NULL, NULL);
971 type[newlen] = 0;
972 ret = func( module, type, param );
974 else
976 ret = func( module, UIntToPtr(et[i].u.Id), param );
978 if (!ret) break;
980 HeapFree( GetProcessHeap(), 0, type );
981 return ret;
985 /**********************************************************************
986 * EnumResourceTypesExW (kernelbase.@)
988 BOOL WINAPI DECLSPEC_HOTPATCH EnumResourceTypesExW( HMODULE module, ENUMRESTYPEPROCW func, LONG_PTR param,
989 DWORD flags, LANGID lang )
991 int i, len = 0;
992 BOOL ret = FALSE;
993 LPWSTR type = NULL;
994 const IMAGE_RESOURCE_DIRECTORY *resdir;
995 const IMAGE_RESOURCE_DIRECTORY_ENTRY *et;
996 const IMAGE_RESOURCE_DIR_STRING_U *str;
998 TRACE( "%p %p %Ix\n", module, func, param );
1000 if (!flags) flags = RESOURCE_ENUM_LN | RESOURCE_ENUM_MUI;
1001 if (!(flags & RESOURCE_ENUM_LN)) return ret;
1003 if (!module) module = GetModuleHandleW( 0 );
1005 if (!set_ntstatus( LdrFindResourceDirectory_U( module, NULL, 0, &resdir ))) return FALSE;
1007 et = (const IMAGE_RESOURCE_DIRECTORY_ENTRY *)(resdir + 1);
1008 for (i = 0; i < resdir->NumberOfNamedEntries + resdir->NumberOfIdEntries; i++)
1010 if (et[i].u.s.NameIsString)
1012 str = (const IMAGE_RESOURCE_DIR_STRING_U *)((const BYTE *)resdir + et[i].u.s.NameOffset);
1013 if (str->Length + 1 > len)
1015 len = str->Length + 1;
1016 HeapFree( GetProcessHeap(), 0, type );
1017 if (!(type = HeapAlloc( GetProcessHeap(), 0, len * sizeof(WCHAR) ))) return FALSE;
1019 memcpy(type, str->NameString, str->Length * sizeof (WCHAR));
1020 type[str->Length] = 0;
1021 ret = func( module, type, param );
1023 else
1025 ret = func( module, UIntToPtr(et[i].u.Id), param );
1027 if (!ret) break;
1029 HeapFree( GetProcessHeap(), 0, type );
1030 return ret;
1034 /**********************************************************************
1035 * FindResourceExW (kernelbase.@)
1037 HRSRC WINAPI DECLSPEC_HOTPATCH FindResourceExW( HMODULE module, LPCWSTR type, LPCWSTR name, WORD lang )
1039 NTSTATUS status;
1040 UNICODE_STRING nameW, typeW;
1041 LDR_RESOURCE_INFO info;
1042 const IMAGE_RESOURCE_DATA_ENTRY *entry = NULL;
1044 TRACE( "%p %s %s %04x\n", module, debugstr_w(type), debugstr_w(name), lang );
1046 if (!module) module = GetModuleHandleW( 0 );
1047 nameW.Buffer = typeW.Buffer = NULL;
1049 __TRY
1051 if ((status = get_res_nameW( name, &nameW )) != STATUS_SUCCESS) goto done;
1052 if ((status = get_res_nameW( type, &typeW )) != STATUS_SUCCESS) goto done;
1053 info.Type = (ULONG_PTR)typeW.Buffer;
1054 info.Name = (ULONG_PTR)nameW.Buffer;
1055 info.Language = lang;
1056 status = LdrFindResource_U( module, &info, 3, &entry );
1057 done:
1058 if (status != STATUS_SUCCESS) SetLastError( RtlNtStatusToDosError(status) );
1060 __EXCEPT_PAGE_FAULT
1062 SetLastError( ERROR_INVALID_PARAMETER );
1064 __ENDTRY
1066 if (!IS_INTRESOURCE(nameW.Buffer)) HeapFree( GetProcessHeap(), 0, nameW.Buffer );
1067 if (!IS_INTRESOURCE(typeW.Buffer)) HeapFree( GetProcessHeap(), 0, typeW.Buffer );
1068 return (HRSRC)entry;
1072 /**********************************************************************
1073 * FindResourceW (kernelbase.@)
1075 HRSRC WINAPI DECLSPEC_HOTPATCH FindResourceW( HINSTANCE module, LPCWSTR name, LPCWSTR type )
1077 return FindResourceExW( module, type, name, MAKELANGID( LANG_NEUTRAL, SUBLANG_NEUTRAL ) );
1081 /**********************************************************************
1082 * FreeResource (kernelbase.@)
1084 BOOL WINAPI DECLSPEC_HOTPATCH FreeResource( HGLOBAL handle )
1086 return FALSE;
1090 /**********************************************************************
1091 * LoadResource (kernelbase.@)
1093 HGLOBAL WINAPI DECLSPEC_HOTPATCH LoadResource( HINSTANCE module, HRSRC rsrc )
1095 void *ret;
1097 TRACE( "%p %p\n", module, rsrc );
1099 if (!rsrc) return 0;
1100 if (!module) module = GetModuleHandleW( 0 );
1101 if (!set_ntstatus( LdrAccessResource( module, (IMAGE_RESOURCE_DATA_ENTRY *)rsrc, &ret, NULL )))
1102 return 0;
1103 return ret;
1107 /**********************************************************************
1108 * LockResource (kernelbase.@)
1110 LPVOID WINAPI DECLSPEC_HOTPATCH LockResource( HGLOBAL handle )
1112 return handle;
1116 /**********************************************************************
1117 * SizeofResource (kernelbase.@)
1119 DWORD WINAPI DECLSPEC_HOTPATCH SizeofResource( HINSTANCE module, HRSRC rsrc )
1121 if (!rsrc) return 0;
1122 return ((IMAGE_RESOURCE_DATA_ENTRY *)rsrc)->Size;
1126 /***********************************************************************
1127 * Activation contexts
1128 ***********************************************************************/
1131 /***********************************************************************
1132 * ActivateActCtx (kernelbase.@)
1134 BOOL WINAPI DECLSPEC_HOTPATCH ActivateActCtx( HANDLE context, ULONG_PTR *cookie )
1136 return set_ntstatus( RtlActivateActivationContext( 0, context, cookie ));
1140 /***********************************************************************
1141 * AddRefActCtx (kernelbase.@)
1143 void WINAPI DECLSPEC_HOTPATCH AddRefActCtx( HANDLE context )
1145 RtlAddRefActivationContext( context );
1149 /***********************************************************************
1150 * CreateActCtxW (kernelbase.@)
1152 HANDLE WINAPI DECLSPEC_HOTPATCH CreateActCtxW( PCACTCTXW ctx )
1154 HANDLE context;
1156 TRACE( "%p %08lx\n", ctx, ctx ? ctx->dwFlags : 0 );
1158 if (!set_ntstatus( RtlCreateActivationContext( &context, ctx ))) return INVALID_HANDLE_VALUE;
1159 return context;
1163 /***********************************************************************
1164 * DeactivateActCtx (kernelbase.@)
1166 BOOL WINAPI DECLSPEC_HOTPATCH DeactivateActCtx( DWORD flags, ULONG_PTR cookie )
1168 RtlDeactivateActivationContext( flags, cookie );
1169 return TRUE;
1173 /***********************************************************************
1174 * FindActCtxSectionGuid (kernelbase.@)
1176 BOOL WINAPI DECLSPEC_HOTPATCH FindActCtxSectionGuid( DWORD flags, const GUID *ext_guid, ULONG id,
1177 const GUID *guid, PACTCTX_SECTION_KEYED_DATA info )
1179 return set_ntstatus( RtlFindActivationContextSectionGuid( flags, ext_guid, id, guid, info ));
1183 /***********************************************************************
1184 * FindActCtxSectionStringW (kernelbase.@)
1186 BOOL WINAPI DECLSPEC_HOTPATCH FindActCtxSectionStringW( DWORD flags, const GUID *ext_guid, ULONG id,
1187 LPCWSTR str, PACTCTX_SECTION_KEYED_DATA info )
1189 UNICODE_STRING us;
1191 if (!info)
1193 SetLastError( ERROR_INVALID_PARAMETER );
1194 return FALSE;
1196 RtlInitUnicodeString( &us, str );
1197 return set_ntstatus( RtlFindActivationContextSectionString( flags, ext_guid, id, &us, info ));
1201 /***********************************************************************
1202 * GetCurrentActCtx (kernelbase.@)
1204 BOOL WINAPI DECLSPEC_HOTPATCH GetCurrentActCtx( HANDLE *pcontext )
1206 return set_ntstatus( RtlGetActiveActivationContext( pcontext ));
1210 /***********************************************************************
1211 * QueryActCtxSettingsW (kernelbase.@)
1213 BOOL WINAPI DECLSPEC_HOTPATCH QueryActCtxSettingsW( DWORD flags, HANDLE ctx, const WCHAR *ns,
1214 const WCHAR *settings, WCHAR *buffer, SIZE_T size,
1215 SIZE_T *written )
1217 return set_ntstatus( RtlQueryActivationContextApplicationSettings( flags, ctx, ns, settings,
1218 buffer, size, written ));
1222 /***********************************************************************
1223 * QueryActCtxW (kernelbase.@)
1225 BOOL WINAPI DECLSPEC_HOTPATCH QueryActCtxW( DWORD flags, HANDLE context, PVOID inst, ULONG class,
1226 PVOID buffer, SIZE_T size, SIZE_T *written )
1228 return set_ntstatus( RtlQueryInformationActivationContext( flags, context, inst, class,
1229 buffer, size, written ));
1233 /***********************************************************************
1234 * ReleaseActCtx (kernelbase.@)
1236 void WINAPI DECLSPEC_HOTPATCH ReleaseActCtx( HANDLE context )
1238 RtlReleaseActivationContext( context );
1242 /***********************************************************************
1243 * ZombifyActCtx (kernelbase.@)
1245 BOOL WINAPI DECLSPEC_HOTPATCH ZombifyActCtx( HANDLE context )
1247 return set_ntstatus( RtlZombifyActivationContext( context ));