makefiles: Don't use standard libs for programs that specify -nodefaultlibs.
[wine/zf.git] / dlls / kernelbase / loader.c
blob59b775b844450618ca77b91030f81d48619d1e01
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 )) goto failed;
111 *mod_ret = (HMODULE)((char *)module + 1); /* set bit 0 for data file module */
113 if (flags & LOAD_LIBRARY_AS_DATAFILE_EXCLUSIVE)
115 struct exclusive_datafile *datafile = HeapAlloc( GetProcessHeap(), 0, sizeof(*datafile) );
116 if (!datafile) goto failed;
117 datafile->module = *mod_ret;
118 datafile->file = file;
119 list_add_head( &exclusive_datafile_list, &datafile->entry );
120 TRACE( "delaying close %p for module %p\n", datafile->file, datafile->module );
121 return TRUE;
124 else *mod_ret = (HMODULE)((char *)module + 2); /* set bit 1 for image resource module */
126 CloseHandle( file );
127 return TRUE;
129 failed:
130 if (module) UnmapViewOfFile( module );
131 CloseHandle( file );
132 return FALSE;
136 /******************************************************************
137 * load_library
139 static HMODULE load_library( const UNICODE_STRING *libname, DWORD flags )
141 const DWORD unsupported_flags = LOAD_IGNORE_CODE_AUTHZ_LEVEL | LOAD_LIBRARY_REQUIRE_SIGNED_TARGET;
142 NTSTATUS status;
143 HMODULE module;
144 WCHAR *load_path, *dummy;
146 if (flags & unsupported_flags) FIXME( "unsupported flag(s) used %#08x\n", flags );
148 if (!set_ntstatus( LdrGetDllPath( libname->Buffer, flags, &load_path, &dummy ))) return 0;
150 if (flags & (LOAD_LIBRARY_AS_DATAFILE | LOAD_LIBRARY_AS_DATAFILE_EXCLUSIVE |
151 LOAD_LIBRARY_AS_IMAGE_RESOURCE))
153 ULONG_PTR magic;
155 LdrLockLoaderLock( 0, NULL, &magic );
156 if (!LdrGetDllHandle( load_path, flags, libname, &module ))
158 LdrAddRefDll( 0, module );
159 LdrUnlockLoaderLock( 0, magic );
160 goto done;
162 if (load_library_as_datafile( load_path, flags, libname->Buffer, &module ))
164 LdrUnlockLoaderLock( 0, magic );
165 goto done;
167 LdrUnlockLoaderLock( 0, magic );
168 flags |= DONT_RESOLVE_DLL_REFERENCES; /* Just in case */
169 /* Fallback to normal behaviour */
172 status = LdrLoadDll( load_path, flags, libname, &module );
173 if (status != STATUS_SUCCESS)
175 module = 0;
176 if (status == STATUS_DLL_NOT_FOUND && (GetVersion() & 0x80000000))
177 SetLastError( ERROR_DLL_NOT_FOUND );
178 else
179 SetLastError( RtlNtStatusToDosError( status ) );
181 done:
182 RtlReleasePath( load_path );
183 return module;
187 /****************************************************************************
188 * AddDllDirectory (kernelbase.@)
190 DLL_DIRECTORY_COOKIE WINAPI DECLSPEC_HOTPATCH AddDllDirectory( const WCHAR *dir )
192 UNICODE_STRING str;
193 void *cookie;
195 RtlInitUnicodeString( &str, dir );
196 if (!set_ntstatus( LdrAddDllDirectory( &str, &cookie ))) return NULL;
197 return cookie;
201 /***********************************************************************
202 * DelayLoadFailureHook (kernelbase.@)
204 FARPROC WINAPI DECLSPEC_HOTPATCH DelayLoadFailureHook( LPCSTR name, LPCSTR function )
206 ULONG_PTR args[2];
208 if ((ULONG_PTR)function >> 16)
209 ERR( "failed to delay load %s.%s\n", name, function );
210 else
211 ERR( "failed to delay load %s.%u\n", name, LOWORD(function) );
212 args[0] = (ULONG_PTR)name;
213 args[1] = (ULONG_PTR)function;
214 RaiseException( EXCEPTION_WINE_STUB, EH_NONCONTINUABLE, 2, args );
215 return NULL;
219 /****************************************************************************
220 * DisableThreadLibraryCalls (kernelbase.@)
222 BOOL WINAPI DECLSPEC_HOTPATCH DisableThreadLibraryCalls( HMODULE module )
224 return set_ntstatus( LdrDisableThreadCalloutsForDll( module ));
228 /***********************************************************************
229 * FreeLibrary (kernelbase.@)
231 BOOL WINAPI DECLSPEC_HOTPATCH FreeLibrary( HINSTANCE module )
233 if (!module)
235 SetLastError( ERROR_INVALID_HANDLE );
236 return FALSE;
239 if ((ULONG_PTR)module & 3) /* this is a datafile module */
241 void *ptr = (void *)((ULONG_PTR)module & ~3);
242 if (!RtlImageNtHeader( ptr ))
244 SetLastError( ERROR_BAD_EXE_FORMAT );
245 return FALSE;
247 if ((ULONG_PTR)module & 1)
249 struct exclusive_datafile *file;
250 ULONG_PTR magic;
252 LdrLockLoaderLock( 0, NULL, &magic );
253 LIST_FOR_EACH_ENTRY( file, &exclusive_datafile_list, struct exclusive_datafile, entry )
255 if (file->module != module) continue;
256 TRACE( "closing %p for module %p\n", file->file, file->module );
257 CloseHandle( file->file );
258 list_remove( &file->entry );
259 HeapFree( GetProcessHeap(), 0, file );
260 break;
262 LdrUnlockLoaderLock( 0, magic );
264 return UnmapViewOfFile( ptr );
267 return set_ntstatus( LdrUnloadDll( module ));
271 /***********************************************************************
272 * GetModuleFileNameA (kernelbase.@)
274 DWORD WINAPI DECLSPEC_HOTPATCH GetModuleFileNameA( HMODULE module, LPSTR filename, DWORD size )
276 LPWSTR filenameW = HeapAlloc( GetProcessHeap(), 0, size * sizeof(WCHAR) );
277 DWORD len;
279 if (!filenameW)
281 SetLastError( ERROR_NOT_ENOUGH_MEMORY );
282 return 0;
284 if ((len = GetModuleFileNameW( module, filenameW, size )))
286 len = file_name_WtoA( filenameW, len, filename, size );
287 if (len < size)
288 filename[len] = 0;
289 else
290 SetLastError( ERROR_INSUFFICIENT_BUFFER );
292 HeapFree( GetProcessHeap(), 0, filenameW );
293 return len;
297 /***********************************************************************
298 * GetModuleFileNameW (kernelbase.@)
300 DWORD WINAPI DECLSPEC_HOTPATCH GetModuleFileNameW( HMODULE module, LPWSTR filename, DWORD size )
302 ULONG len = 0;
303 ULONG_PTR magic;
304 LDR_MODULE *pldr;
305 WIN16_SUBSYSTEM_TIB *win16_tib;
307 if (!module && ((win16_tib = NtCurrentTeb()->Tib.SubSystemTib)) && win16_tib->exe_name)
309 len = min( size, win16_tib->exe_name->Length / sizeof(WCHAR) );
310 memcpy( filename, win16_tib->exe_name->Buffer, len * sizeof(WCHAR) );
311 if (len < size) filename[len] = 0;
312 goto done;
315 LdrLockLoaderLock( 0, NULL, &magic );
317 if (!module) module = NtCurrentTeb()->Peb->ImageBaseAddress;
318 if (set_ntstatus( LdrFindEntryForAddress( module, &pldr )))
320 len = min( size, pldr->FullDllName.Length / sizeof(WCHAR) );
321 memcpy( filename, pldr->FullDllName.Buffer, len * sizeof(WCHAR) );
322 if (len < size)
324 filename[len] = 0;
325 SetLastError( 0 );
327 else SetLastError( ERROR_INSUFFICIENT_BUFFER );
330 LdrUnlockLoaderLock( 0, magic );
331 done:
332 TRACE( "%s\n", debugstr_wn(filename, len) );
333 return len;
337 /***********************************************************************
338 * GetModuleHandleA (kernelbase.@)
340 HMODULE WINAPI DECLSPEC_HOTPATCH GetModuleHandleA( LPCSTR module )
342 HMODULE ret;
344 GetModuleHandleExA( GET_MODULE_HANDLE_EX_FLAG_UNCHANGED_REFCOUNT, module, &ret );
345 return ret;
349 /***********************************************************************
350 * GetModuleHandleW (kernelbase.@)
352 HMODULE WINAPI DECLSPEC_HOTPATCH GetModuleHandleW( LPCWSTR module )
354 HMODULE ret;
356 GetModuleHandleExW( GET_MODULE_HANDLE_EX_FLAG_UNCHANGED_REFCOUNT, module, &ret );
357 return ret;
361 /***********************************************************************
362 * GetModuleHandleExA (kernelbase.@)
364 BOOL WINAPI DECLSPEC_HOTPATCH GetModuleHandleExA( DWORD flags, LPCSTR name, HMODULE *module )
366 WCHAR *nameW;
368 if (!name || (flags & GET_MODULE_HANDLE_EX_FLAG_FROM_ADDRESS))
369 return GetModuleHandleExW( flags, (LPCWSTR)name, module );
371 if (!(nameW = file_name_AtoW( name, FALSE ))) return FALSE;
372 return GetModuleHandleExW( flags, nameW, module );
376 /***********************************************************************
377 * GetModuleHandleExW (kernelbase.@)
379 BOOL WINAPI DECLSPEC_HOTPATCH GetModuleHandleExW( DWORD flags, LPCWSTR name, HMODULE *module )
381 NTSTATUS status = STATUS_SUCCESS;
382 HMODULE ret = NULL;
383 ULONG_PTR magic;
384 BOOL lock;
386 if (!module)
388 SetLastError( ERROR_INVALID_PARAMETER );
389 return FALSE;
392 /* if we are messing with the refcount, grab the loader lock */
393 lock = (flags & GET_MODULE_HANDLE_EX_FLAG_PIN) || !(flags & GET_MODULE_HANDLE_EX_FLAG_UNCHANGED_REFCOUNT);
394 if (lock) LdrLockLoaderLock( 0, NULL, &magic );
396 if (!name)
398 ret = NtCurrentTeb()->Peb->ImageBaseAddress;
400 else if (flags & GET_MODULE_HANDLE_EX_FLAG_FROM_ADDRESS)
402 void *dummy;
403 if (!(ret = RtlPcToFileHeader( (void *)name, &dummy ))) status = STATUS_DLL_NOT_FOUND;
405 else
407 UNICODE_STRING wstr;
408 RtlInitUnicodeString( &wstr, name );
409 status = LdrGetDllHandle( NULL, 0, &wstr, &ret );
412 if (status == STATUS_SUCCESS)
414 if (flags & GET_MODULE_HANDLE_EX_FLAG_PIN)
415 LdrAddRefDll( LDR_ADDREF_DLL_PIN, ret );
416 else if (!(flags & GET_MODULE_HANDLE_EX_FLAG_UNCHANGED_REFCOUNT))
417 LdrAddRefDll( 0, ret );
420 if (lock) LdrUnlockLoaderLock( 0, magic );
422 *module = ret;
423 return set_ntstatus( status );
427 /***********************************************************************
428 * GetProcAddress (kernelbase.@)
431 #ifdef __x86_64__
433 * Work around a Delphi bug on x86_64. When delay loading a symbol,
434 * Delphi saves rcx, rdx, r8 and r9 to the stack. It then calls
435 * GetProcAddress(), pops the saved registers and calls the function.
436 * This works fine if all of the parameters are ints. However, since
437 * it does not save xmm0 - 3, it relies on GetProcAddress() preserving
438 * these registers if the function takes floating point parameters.
439 * This wrapper saves xmm0 - 3 to the stack.
441 __ASM_GLOBAL_FUNC( GetProcAddress,
442 ".byte 0x48\n\t" /* hotpatch prolog */
443 "pushq %rbp\n\t"
444 __ASM_SEH(".seh_pushreg %rbp\n\t")
445 __ASM_CFI(".cfi_adjust_cfa_offset 8\n\t")
446 __ASM_CFI(".cfi_rel_offset %rbp,0\n\t")
447 "movq %rsp,%rbp\n\t"
448 __ASM_SEH(".seh_setframe %rbp,0\n\t")
449 __ASM_CFI(".cfi_def_cfa_register %rbp\n\t")
450 "subq $0x60,%rsp\n\t"
451 __ASM_SEH(".seh_stackalloc 0x60\n\t")
452 __ASM_SEH(".seh_endprologue\n\t")
453 "movaps %xmm0,-0x10(%rbp)\n\t"
454 "movaps %xmm1,-0x20(%rbp)\n\t"
455 "movaps %xmm2,-0x30(%rbp)\n\t"
456 "movaps %xmm3,-0x40(%rbp)\n\t"
457 "call " __ASM_NAME("get_proc_address") "\n\t"
458 "movaps -0x40(%rbp), %xmm3\n\t"
459 "movaps -0x30(%rbp), %xmm2\n\t"
460 "movaps -0x20(%rbp), %xmm1\n\t"
461 "movaps -0x10(%rbp), %xmm0\n\t"
462 "leaq 0(%rbp),%rsp\n\t"
463 __ASM_CFI(".cfi_def_cfa_register %rsp\n\t")
464 "popq %rbp\n\t"
465 __ASM_CFI(".cfi_adjust_cfa_offset -8\n\t")
466 __ASM_CFI(".cfi_same_value %rbp\n\t")
467 "ret" )
468 #else /* __x86_64__ */
470 FARPROC WINAPI DECLSPEC_HOTPATCH GetProcAddress( HMODULE module, LPCSTR function )
472 return get_proc_address( module, function );
475 #endif /* __x86_64__ */
478 /***********************************************************************
479 * LoadLibraryA (kernelbase.@)
481 HMODULE WINAPI DECLSPEC_HOTPATCH LoadLibraryA( LPCSTR name )
483 return LoadLibraryExA( name, 0, 0 );
487 /***********************************************************************
488 * LoadLibraryW (kernelbase.@)
490 HMODULE WINAPI DECLSPEC_HOTPATCH LoadLibraryW( LPCWSTR name )
492 return LoadLibraryExW( name, 0, 0 );
496 /******************************************************************
497 * LoadLibraryExA (kernelbase.@)
499 HMODULE WINAPI DECLSPEC_HOTPATCH LoadLibraryExA( LPCSTR name, HANDLE file, DWORD flags )
501 WCHAR *nameW;
503 if (!(nameW = file_name_AtoW( name, FALSE ))) return 0;
504 return LoadLibraryExW( nameW, file, flags );
508 /***********************************************************************
509 * LoadLibraryExW (kernelbase.@)
511 HMODULE WINAPI DECLSPEC_HOTPATCH LoadLibraryExW( LPCWSTR name, HANDLE file, DWORD flags )
513 UNICODE_STRING str;
514 HMODULE module;
516 if (!name)
518 SetLastError( ERROR_INVALID_PARAMETER );
519 return 0;
521 RtlInitUnicodeString( &str, name );
522 if (str.Buffer[str.Length/sizeof(WCHAR) - 1] != ' ') return load_library( &str, flags );
524 /* library name has trailing spaces */
525 RtlCreateUnicodeString( &str, name );
526 while (str.Length > sizeof(WCHAR) && str.Buffer[str.Length/sizeof(WCHAR) - 1] == ' ')
527 str.Length -= sizeof(WCHAR);
529 str.Buffer[str.Length/sizeof(WCHAR)] = 0;
530 module = load_library( &str, flags );
531 RtlFreeUnicodeString( &str );
532 return module;
536 /***********************************************************************
537 * LoadPackagedLibrary (kernelbase.@)
539 HMODULE WINAPI /* DECLSPEC_HOTPATCH */ LoadPackagedLibrary( LPCWSTR name, DWORD reserved )
541 FIXME( "semi-stub, name %s, reserved %#x.\n", debugstr_w(name), reserved );
542 SetLastError( APPMODEL_ERROR_NO_PACKAGE );
543 return NULL;
547 /****************************************************************************
548 * RemoveDllDirectory (kernelbase.@)
550 BOOL WINAPI DECLSPEC_HOTPATCH RemoveDllDirectory( DLL_DIRECTORY_COOKIE cookie )
552 return set_ntstatus( LdrRemoveDllDirectory( cookie ));
556 /*************************************************************************
557 * SetDefaultDllDirectories (kernelbase.@)
559 BOOL WINAPI DECLSPEC_HOTPATCH SetDefaultDllDirectories( DWORD flags )
561 return set_ntstatus( LdrSetDefaultDllDirectories( flags ));
565 /***********************************************************************
566 * Resources
567 ***********************************************************************/
570 #define IS_INTRESOURCE(x) (((ULONG_PTR)(x) >> 16) == 0)
572 /* retrieve the resource name to pass to the ntdll functions */
573 static NTSTATUS get_res_nameA( LPCSTR name, UNICODE_STRING *str )
575 if (IS_INTRESOURCE(name))
577 str->Buffer = ULongToPtr( LOWORD(name) );
578 return STATUS_SUCCESS;
580 if (name[0] == '#')
582 ULONG value;
583 if (RtlCharToInteger( name + 1, 10, &value ) != STATUS_SUCCESS || HIWORD(value))
584 return STATUS_INVALID_PARAMETER;
585 str->Buffer = ULongToPtr(value);
586 return STATUS_SUCCESS;
588 RtlCreateUnicodeStringFromAsciiz( str, name );
589 RtlUpcaseUnicodeString( str, str, FALSE );
590 return STATUS_SUCCESS;
593 /* retrieve the resource name to pass to the ntdll functions */
594 static NTSTATUS get_res_nameW( LPCWSTR name, UNICODE_STRING *str )
596 if (IS_INTRESOURCE(name))
598 str->Buffer = ULongToPtr( LOWORD(name) );
599 return STATUS_SUCCESS;
601 if (name[0] == '#')
603 ULONG value;
604 RtlInitUnicodeString( str, name + 1 );
605 if (RtlUnicodeStringToInteger( str, 10, &value ) != STATUS_SUCCESS || HIWORD(value))
606 return STATUS_INVALID_PARAMETER;
607 str->Buffer = ULongToPtr(value);
608 return STATUS_SUCCESS;
610 RtlCreateUnicodeString( str, name );
611 RtlUpcaseUnicodeString( str, str, FALSE );
612 return STATUS_SUCCESS;
616 /**********************************************************************
617 * EnumResourceLanguagesExA (kernelbase.@)
619 BOOL WINAPI DECLSPEC_HOTPATCH EnumResourceLanguagesExA( HMODULE module, LPCSTR type, LPCSTR name,
620 ENUMRESLANGPROCA func, LONG_PTR param,
621 DWORD flags, LANGID lang )
623 int i;
624 BOOL ret = FALSE;
625 NTSTATUS status;
626 UNICODE_STRING typeW, nameW;
627 LDR_RESOURCE_INFO info;
628 const IMAGE_RESOURCE_DIRECTORY *basedir, *resdir;
629 const IMAGE_RESOURCE_DIRECTORY_ENTRY *et;
631 TRACE( "%p %s %s %p %lx %x %d\n", module, debugstr_a(type), debugstr_a(name),
632 func, param, flags, lang );
634 if (flags & (RESOURCE_ENUM_MUI | RESOURCE_ENUM_MUI_SYSTEM | RESOURCE_ENUM_VALIDATE))
635 FIXME( "unimplemented flags: %x\n", flags );
637 if (!flags) flags = RESOURCE_ENUM_LN | RESOURCE_ENUM_MUI;
638 if (!(flags & RESOURCE_ENUM_LN)) return ret;
640 if (!module) module = GetModuleHandleW( 0 );
641 typeW.Buffer = nameW.Buffer = NULL;
642 if ((status = LdrFindResourceDirectory_U( module, NULL, 0, &basedir )) != STATUS_SUCCESS)
643 goto done;
644 if ((status = get_res_nameA( type, &typeW )) != STATUS_SUCCESS)
645 goto done;
646 if ((status = get_res_nameA( name, &nameW )) != STATUS_SUCCESS)
647 goto done;
648 info.Type = (ULONG_PTR)typeW.Buffer;
649 info.Name = (ULONG_PTR)nameW.Buffer;
650 if ((status = LdrFindResourceDirectory_U( module, &info, 2, &resdir )) != STATUS_SUCCESS)
651 goto done;
653 et = (const IMAGE_RESOURCE_DIRECTORY_ENTRY *)(resdir + 1);
654 __TRY
656 for (i = 0; i < resdir->NumberOfNamedEntries + resdir->NumberOfIdEntries; i++)
658 ret = func( module, type, name, et[i].u.Id, param );
659 if (!ret) break;
662 __EXCEPT_PAGE_FAULT
664 ret = FALSE;
665 status = STATUS_ACCESS_VIOLATION;
667 __ENDTRY
668 done:
669 if (!IS_INTRESOURCE(typeW.Buffer)) HeapFree( GetProcessHeap(), 0, typeW.Buffer );
670 if (!IS_INTRESOURCE(nameW.Buffer)) HeapFree( GetProcessHeap(), 0, nameW.Buffer );
671 if (status != STATUS_SUCCESS) SetLastError( RtlNtStatusToDosError(status) );
672 return ret;
676 /**********************************************************************
677 * EnumResourceLanguagesExW (kernelbase.@)
679 BOOL WINAPI DECLSPEC_HOTPATCH EnumResourceLanguagesExW( HMODULE module, LPCWSTR type, LPCWSTR name,
680 ENUMRESLANGPROCW func, LONG_PTR param,
681 DWORD flags, LANGID lang )
683 int i;
684 BOOL ret = FALSE;
685 NTSTATUS status;
686 UNICODE_STRING typeW, nameW;
687 LDR_RESOURCE_INFO info;
688 const IMAGE_RESOURCE_DIRECTORY *basedir, *resdir;
689 const IMAGE_RESOURCE_DIRECTORY_ENTRY *et;
691 TRACE( "%p %s %s %p %lx %x %d\n", module, debugstr_w(type), debugstr_w(name),
692 func, param, flags, lang );
694 if (flags & (RESOURCE_ENUM_MUI | RESOURCE_ENUM_MUI_SYSTEM | RESOURCE_ENUM_VALIDATE))
695 FIXME( "unimplemented flags: %x\n", flags );
697 if (!flags) flags = RESOURCE_ENUM_LN | RESOURCE_ENUM_MUI;
698 if (!(flags & RESOURCE_ENUM_LN)) return ret;
700 if (!module) module = GetModuleHandleW( 0 );
701 typeW.Buffer = nameW.Buffer = NULL;
702 if ((status = LdrFindResourceDirectory_U( module, NULL, 0, &basedir )) != STATUS_SUCCESS)
703 goto done;
704 if ((status = get_res_nameW( type, &typeW )) != STATUS_SUCCESS)
705 goto done;
706 if ((status = get_res_nameW( name, &nameW )) != STATUS_SUCCESS)
707 goto done;
708 info.Type = (ULONG_PTR)typeW.Buffer;
709 info.Name = (ULONG_PTR)nameW.Buffer;
710 if ((status = LdrFindResourceDirectory_U( module, &info, 2, &resdir )) != STATUS_SUCCESS)
711 goto done;
713 et = (const IMAGE_RESOURCE_DIRECTORY_ENTRY *)(resdir + 1);
714 __TRY
716 for (i = 0; i < resdir->NumberOfNamedEntries + resdir->NumberOfIdEntries; i++)
718 ret = func( module, type, name, et[i].u.Id, param );
719 if (!ret) break;
722 __EXCEPT_PAGE_FAULT
724 ret = FALSE;
725 status = STATUS_ACCESS_VIOLATION;
727 __ENDTRY
728 done:
729 if (!IS_INTRESOURCE(typeW.Buffer)) HeapFree( GetProcessHeap(), 0, typeW.Buffer );
730 if (!IS_INTRESOURCE(nameW.Buffer)) HeapFree( GetProcessHeap(), 0, nameW.Buffer );
731 if (status != STATUS_SUCCESS) SetLastError( RtlNtStatusToDosError(status) );
732 return ret;
736 /**********************************************************************
737 * EnumResourceNamesExA (kernelbase.@)
739 BOOL WINAPI DECLSPEC_HOTPATCH EnumResourceNamesExA( HMODULE module, LPCSTR type, ENUMRESNAMEPROCA func,
740 LONG_PTR param, DWORD flags, LANGID lang )
742 int i;
743 BOOL ret = FALSE;
744 DWORD len = 0, newlen;
745 LPSTR name = NULL;
746 NTSTATUS status;
747 UNICODE_STRING typeW;
748 LDR_RESOURCE_INFO info;
749 const IMAGE_RESOURCE_DIRECTORY *basedir, *resdir;
750 const IMAGE_RESOURCE_DIRECTORY_ENTRY *et;
751 const IMAGE_RESOURCE_DIR_STRING_U *str;
753 TRACE( "%p %s %p %lx\n", module, debugstr_a(type), func, param );
755 if (flags & (RESOURCE_ENUM_MUI | RESOURCE_ENUM_MUI_SYSTEM | RESOURCE_ENUM_VALIDATE))
756 FIXME( "unimplemented flags: %x\n", flags );
758 if (!flags) flags = RESOURCE_ENUM_LN | RESOURCE_ENUM_MUI;
759 if (!(flags & RESOURCE_ENUM_LN)) return ret;
761 if (!module) module = GetModuleHandleW( 0 );
762 typeW.Buffer = NULL;
763 if ((status = LdrFindResourceDirectory_U( module, NULL, 0, &basedir )) != STATUS_SUCCESS)
764 goto done;
765 if ((status = get_res_nameA( type, &typeW )) != STATUS_SUCCESS)
766 goto done;
767 info.Type = (ULONG_PTR)typeW.Buffer;
768 if ((status = LdrFindResourceDirectory_U( module, &info, 1, &resdir )) != STATUS_SUCCESS)
769 goto done;
771 et = (const IMAGE_RESOURCE_DIRECTORY_ENTRY *)(resdir + 1);
772 __TRY
774 for (i = 0; i < resdir->NumberOfNamedEntries+resdir->NumberOfIdEntries; i++)
776 if (et[i].u.s.NameIsString)
778 str = (const IMAGE_RESOURCE_DIR_STRING_U *)((const BYTE *)basedir + et[i].u.s.NameOffset);
779 newlen = WideCharToMultiByte(CP_ACP, 0, str->NameString, str->Length, NULL, 0, NULL, NULL);
780 if (newlen + 1 > len)
782 len = newlen + 1;
783 HeapFree( GetProcessHeap(), 0, name );
784 if (!(name = HeapAlloc( GetProcessHeap(), 0, len + 1 )))
786 ret = FALSE;
787 break;
790 WideCharToMultiByte( CP_ACP, 0, str->NameString, str->Length, name, len, NULL, NULL );
791 name[newlen] = 0;
792 ret = func( module, type, name, param );
794 else
796 ret = func( module, type, UIntToPtr(et[i].u.Id), param );
798 if (!ret) break;
801 __EXCEPT_PAGE_FAULT
803 ret = FALSE;
804 status = STATUS_ACCESS_VIOLATION;
806 __ENDTRY
808 done:
809 HeapFree( GetProcessHeap(), 0, name );
810 if (!IS_INTRESOURCE(typeW.Buffer)) HeapFree( GetProcessHeap(), 0, typeW.Buffer );
811 if (status != STATUS_SUCCESS) SetLastError( RtlNtStatusToDosError(status) );
812 return ret;
816 /**********************************************************************
817 * EnumResourceNamesExW (kernelbase.@)
819 BOOL WINAPI DECLSPEC_HOTPATCH EnumResourceNamesExW( HMODULE module, LPCWSTR type, ENUMRESNAMEPROCW func,
820 LONG_PTR param, DWORD flags, LANGID lang )
822 int i, len = 0;
823 BOOL ret = FALSE;
824 LPWSTR name = NULL;
825 NTSTATUS status;
826 UNICODE_STRING typeW;
827 LDR_RESOURCE_INFO info;
828 const IMAGE_RESOURCE_DIRECTORY *basedir, *resdir;
829 const IMAGE_RESOURCE_DIRECTORY_ENTRY *et;
830 const IMAGE_RESOURCE_DIR_STRING_U *str;
832 TRACE( "%p %s %p %lx\n", module, debugstr_w(type), func, param );
834 if (flags & (RESOURCE_ENUM_MUI | RESOURCE_ENUM_MUI_SYSTEM | RESOURCE_ENUM_VALIDATE))
835 FIXME( "unimplemented flags: %x\n", flags );
837 if (!flags) flags = RESOURCE_ENUM_LN | RESOURCE_ENUM_MUI;
838 if (!(flags & RESOURCE_ENUM_LN)) return ret;
840 if (!module) module = GetModuleHandleW( 0 );
841 typeW.Buffer = NULL;
842 if ((status = LdrFindResourceDirectory_U( module, NULL, 0, &basedir )) != STATUS_SUCCESS)
843 goto done;
844 if ((status = get_res_nameW( type, &typeW )) != STATUS_SUCCESS)
845 goto done;
846 info.Type = (ULONG_PTR)typeW.Buffer;
847 if ((status = LdrFindResourceDirectory_U( module, &info, 1, &resdir )) != STATUS_SUCCESS)
848 goto done;
850 et = (const IMAGE_RESOURCE_DIRECTORY_ENTRY *)(resdir + 1);
851 __TRY
853 for (i = 0; i < resdir->NumberOfNamedEntries+resdir->NumberOfIdEntries; i++)
855 if (et[i].u.s.NameIsString)
857 str = (const IMAGE_RESOURCE_DIR_STRING_U *)((const BYTE *)basedir + et[i].u.s.NameOffset);
858 if (str->Length + 1 > len)
860 len = str->Length + 1;
861 HeapFree( GetProcessHeap(), 0, name );
862 if (!(name = HeapAlloc( GetProcessHeap(), 0, len * sizeof(WCHAR) )))
864 ret = FALSE;
865 break;
868 memcpy(name, str->NameString, str->Length * sizeof (WCHAR));
869 name[str->Length] = 0;
870 ret = func( module, type, name, param );
872 else
874 ret = func( module, type, UIntToPtr(et[i].u.Id), param );
876 if (!ret) break;
879 __EXCEPT_PAGE_FAULT
881 ret = FALSE;
882 status = STATUS_ACCESS_VIOLATION;
884 __ENDTRY
885 done:
886 HeapFree( GetProcessHeap(), 0, name );
887 if (!IS_INTRESOURCE(typeW.Buffer)) HeapFree( GetProcessHeap(), 0, typeW.Buffer );
888 if (status != STATUS_SUCCESS) SetLastError( RtlNtStatusToDosError(status) );
889 return ret;
893 /**********************************************************************
894 * EnumResourceNamesW (kernelbase.@)
896 BOOL WINAPI DECLSPEC_HOTPATCH EnumResourceNamesW( HMODULE module, LPCWSTR type,
897 ENUMRESNAMEPROCW func, LONG_PTR param )
899 return EnumResourceNamesExW( module, type, func, param, 0, 0 );
903 /**********************************************************************
904 * EnumResourceTypesExA (kernelbase.@)
906 BOOL WINAPI DECLSPEC_HOTPATCH EnumResourceTypesExA( HMODULE module, ENUMRESTYPEPROCA func, LONG_PTR param,
907 DWORD flags, LANGID lang )
909 int i;
910 BOOL ret = FALSE;
911 LPSTR type = NULL;
912 DWORD len = 0, newlen;
913 const IMAGE_RESOURCE_DIRECTORY *resdir;
914 const IMAGE_RESOURCE_DIRECTORY_ENTRY *et;
915 const IMAGE_RESOURCE_DIR_STRING_U *str;
917 TRACE( "%p %p %lx\n", module, func, param );
919 if (flags & (RESOURCE_ENUM_MUI | RESOURCE_ENUM_MUI_SYSTEM | RESOURCE_ENUM_VALIDATE))
920 FIXME( "unimplemented flags: %x\n", flags );
922 if (!flags) flags = RESOURCE_ENUM_LN | RESOURCE_ENUM_MUI;
923 if (!(flags & RESOURCE_ENUM_LN)) return ret;
925 if (!module) module = GetModuleHandleW( 0 );
927 if (!set_ntstatus( LdrFindResourceDirectory_U( module, NULL, 0, &resdir ))) return FALSE;
929 et = (const IMAGE_RESOURCE_DIRECTORY_ENTRY *)(resdir + 1);
930 for (i = 0; i < resdir->NumberOfNamedEntries+resdir->NumberOfIdEntries; i++)
932 if (et[i].u.s.NameIsString)
934 str = (const IMAGE_RESOURCE_DIR_STRING_U *)((const BYTE *)resdir + et[i].u.s.NameOffset);
935 newlen = WideCharToMultiByte( CP_ACP, 0, str->NameString, str->Length, NULL, 0, NULL, NULL);
936 if (newlen + 1 > len)
938 len = newlen + 1;
939 HeapFree( GetProcessHeap(), 0, type );
940 if (!(type = HeapAlloc( GetProcessHeap(), 0, len ))) return FALSE;
942 WideCharToMultiByte( CP_ACP, 0, str->NameString, str->Length, type, len, NULL, NULL);
943 type[newlen] = 0;
944 ret = func( module, type, param );
946 else
948 ret = func( module, UIntToPtr(et[i].u.Id), param );
950 if (!ret) break;
952 HeapFree( GetProcessHeap(), 0, type );
953 return ret;
957 /**********************************************************************
958 * EnumResourceTypesExW (kernelbase.@)
960 BOOL WINAPI DECLSPEC_HOTPATCH EnumResourceTypesExW( HMODULE module, ENUMRESTYPEPROCW func, LONG_PTR param,
961 DWORD flags, LANGID lang )
963 int i, len = 0;
964 BOOL ret = FALSE;
965 LPWSTR type = NULL;
966 const IMAGE_RESOURCE_DIRECTORY *resdir;
967 const IMAGE_RESOURCE_DIRECTORY_ENTRY *et;
968 const IMAGE_RESOURCE_DIR_STRING_U *str;
970 TRACE( "%p %p %lx\n", module, func, param );
972 if (!flags) flags = RESOURCE_ENUM_LN | RESOURCE_ENUM_MUI;
973 if (!(flags & RESOURCE_ENUM_LN)) return ret;
975 if (!module) module = GetModuleHandleW( 0 );
977 if (!set_ntstatus( LdrFindResourceDirectory_U( module, NULL, 0, &resdir ))) return FALSE;
979 et = (const IMAGE_RESOURCE_DIRECTORY_ENTRY *)(resdir + 1);
980 for (i = 0; i < resdir->NumberOfNamedEntries + resdir->NumberOfIdEntries; i++)
982 if (et[i].u.s.NameIsString)
984 str = (const IMAGE_RESOURCE_DIR_STRING_U *)((const BYTE *)resdir + et[i].u.s.NameOffset);
985 if (str->Length + 1 > len)
987 len = str->Length + 1;
988 HeapFree( GetProcessHeap(), 0, type );
989 if (!(type = HeapAlloc( GetProcessHeap(), 0, len * sizeof(WCHAR) ))) return FALSE;
991 memcpy(type, str->NameString, str->Length * sizeof (WCHAR));
992 type[str->Length] = 0;
993 ret = func( module, type, param );
995 else
997 ret = func( module, UIntToPtr(et[i].u.Id), param );
999 if (!ret) break;
1001 HeapFree( GetProcessHeap(), 0, type );
1002 return ret;
1006 /**********************************************************************
1007 * FindResourceExW (kernelbase.@)
1009 HRSRC WINAPI DECLSPEC_HOTPATCH FindResourceExW( HMODULE module, LPCWSTR type, LPCWSTR name, WORD lang )
1011 NTSTATUS status;
1012 UNICODE_STRING nameW, typeW;
1013 LDR_RESOURCE_INFO info;
1014 const IMAGE_RESOURCE_DATA_ENTRY *entry = NULL;
1016 TRACE( "%p %s %s %04x\n", module, debugstr_w(type), debugstr_w(name), lang );
1018 if (!module) module = GetModuleHandleW( 0 );
1019 nameW.Buffer = typeW.Buffer = NULL;
1021 __TRY
1023 if ((status = get_res_nameW( name, &nameW )) != STATUS_SUCCESS) goto done;
1024 if ((status = get_res_nameW( type, &typeW )) != STATUS_SUCCESS) goto done;
1025 info.Type = (ULONG_PTR)typeW.Buffer;
1026 info.Name = (ULONG_PTR)nameW.Buffer;
1027 info.Language = lang;
1028 status = LdrFindResource_U( module, &info, 3, &entry );
1029 done:
1030 if (status != STATUS_SUCCESS) SetLastError( RtlNtStatusToDosError(status) );
1032 __EXCEPT_PAGE_FAULT
1034 SetLastError( ERROR_INVALID_PARAMETER );
1036 __ENDTRY
1038 if (!IS_INTRESOURCE(nameW.Buffer)) HeapFree( GetProcessHeap(), 0, nameW.Buffer );
1039 if (!IS_INTRESOURCE(typeW.Buffer)) HeapFree( GetProcessHeap(), 0, typeW.Buffer );
1040 return (HRSRC)entry;
1044 /**********************************************************************
1045 * FindResourceW (kernelbase.@)
1047 HRSRC WINAPI DECLSPEC_HOTPATCH FindResourceW( HINSTANCE module, LPCWSTR name, LPCWSTR type )
1049 return FindResourceExW( module, type, name, MAKELANGID( LANG_NEUTRAL, SUBLANG_NEUTRAL ) );
1053 /**********************************************************************
1054 * FreeResource (kernelbase.@)
1056 BOOL WINAPI DECLSPEC_HOTPATCH FreeResource( HGLOBAL handle )
1058 return FALSE;
1062 /**********************************************************************
1063 * LoadResource (kernelbase.@)
1065 HGLOBAL WINAPI DECLSPEC_HOTPATCH LoadResource( HINSTANCE module, HRSRC rsrc )
1067 void *ret;
1069 TRACE( "%p %p\n", module, rsrc );
1071 if (!rsrc) return 0;
1072 if (!module) module = GetModuleHandleW( 0 );
1073 if (!set_ntstatus( LdrAccessResource( module, (IMAGE_RESOURCE_DATA_ENTRY *)rsrc, &ret, NULL )))
1074 return 0;
1075 return ret;
1079 /**********************************************************************
1080 * LockResource (kernelbase.@)
1082 LPVOID WINAPI DECLSPEC_HOTPATCH LockResource( HGLOBAL handle )
1084 return handle;
1088 /**********************************************************************
1089 * SizeofResource (kernelbase.@)
1091 DWORD WINAPI DECLSPEC_HOTPATCH SizeofResource( HINSTANCE module, HRSRC rsrc )
1093 if (!rsrc) return 0;
1094 return ((IMAGE_RESOURCE_DATA_ENTRY *)rsrc)->Size;
1098 /***********************************************************************
1099 * Activation contexts
1100 ***********************************************************************/
1103 /***********************************************************************
1104 * ActivateActCtx (kernelbase.@)
1106 BOOL WINAPI DECLSPEC_HOTPATCH ActivateActCtx( HANDLE context, ULONG_PTR *cookie )
1108 return set_ntstatus( RtlActivateActivationContext( 0, context, cookie ));
1112 /***********************************************************************
1113 * AddRefActCtx (kernelbase.@)
1115 void WINAPI DECLSPEC_HOTPATCH AddRefActCtx( HANDLE context )
1117 RtlAddRefActivationContext( context );
1121 /***********************************************************************
1122 * CreateActCtxW (kernelbase.@)
1124 HANDLE WINAPI DECLSPEC_HOTPATCH CreateActCtxW( PCACTCTXW ctx )
1126 HANDLE context;
1128 TRACE( "%p %08x\n", ctx, ctx ? ctx->dwFlags : 0 );
1130 if (!set_ntstatus( RtlCreateActivationContext( &context, ctx ))) return INVALID_HANDLE_VALUE;
1131 return context;
1135 /***********************************************************************
1136 * DeactivateActCtx (kernelbase.@)
1138 BOOL WINAPI DECLSPEC_HOTPATCH DeactivateActCtx( DWORD flags, ULONG_PTR cookie )
1140 RtlDeactivateActivationContext( flags, cookie );
1141 return TRUE;
1145 /***********************************************************************
1146 * FindActCtxSectionGuid (kernelbase.@)
1148 BOOL WINAPI DECLSPEC_HOTPATCH FindActCtxSectionGuid( DWORD flags, const GUID *ext_guid, ULONG id,
1149 const GUID *guid, PACTCTX_SECTION_KEYED_DATA info )
1151 return set_ntstatus( RtlFindActivationContextSectionGuid( flags, ext_guid, id, guid, info ));
1155 /***********************************************************************
1156 * FindActCtxSectionStringW (kernelbase.@)
1158 BOOL WINAPI DECLSPEC_HOTPATCH FindActCtxSectionStringW( DWORD flags, const GUID *ext_guid, ULONG id,
1159 LPCWSTR str, PACTCTX_SECTION_KEYED_DATA info )
1161 UNICODE_STRING us;
1163 if (!info)
1165 SetLastError( ERROR_INVALID_PARAMETER );
1166 return FALSE;
1168 RtlInitUnicodeString( &us, str );
1169 return set_ntstatus( RtlFindActivationContextSectionString( flags, ext_guid, id, &us, info ));
1173 /***********************************************************************
1174 * GetCurrentActCtx (kernelbase.@)
1176 BOOL WINAPI DECLSPEC_HOTPATCH GetCurrentActCtx( HANDLE *pcontext )
1178 return set_ntstatus( RtlGetActiveActivationContext( pcontext ));
1182 /***********************************************************************
1183 * QueryActCtxSettingsW (kernelbase.@)
1185 BOOL WINAPI DECLSPEC_HOTPATCH QueryActCtxSettingsW( DWORD flags, HANDLE ctx, const WCHAR *ns,
1186 const WCHAR *settings, WCHAR *buffer, SIZE_T size,
1187 SIZE_T *written )
1189 return set_ntstatus( RtlQueryActivationContextApplicationSettings( flags, ctx, ns, settings,
1190 buffer, size, written ));
1194 /***********************************************************************
1195 * QueryActCtxW (kernelbase.@)
1197 BOOL WINAPI DECLSPEC_HOTPATCH QueryActCtxW( DWORD flags, HANDLE context, PVOID inst, ULONG class,
1198 PVOID buffer, SIZE_T size, SIZE_T *written )
1200 return set_ntstatus( RtlQueryInformationActivationContext( flags, context, inst, class,
1201 buffer, size, written ));
1205 /***********************************************************************
1206 * ReleaseActCtx (kernelbase.@)
1208 void WINAPI DECLSPEC_HOTPATCH ReleaseActCtx( HANDLE context )
1210 RtlReleaseActivationContext( context );
1214 /***********************************************************************
1215 * ZombifyActCtx (kernelbase.@)
1217 BOOL WINAPI DECLSPEC_HOTPATCH ZombifyActCtx( HANDLE context )
1219 return set_ntstatus( RtlZombifyActivationContext( context ));