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
25 #define NONAMELESSUNION
26 #define NONAMELESSSTRUCT
28 #define WIN32_NO_STATUS
33 #include "kernelbase.h"
34 #include "wine/list.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
49 static struct list exclusive_datafile_list
= LIST_INIT( exclusive_datafile_list
);
52 /***********************************************************************
54 ***********************************************************************/
57 /******************************************************************
60 FARPROC WINAPI
get_proc_address( HMODULE module
, LPCSTR function
)
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
)))
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
;
87 DWORD protect
= PAGE_READONLY
;
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
);
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
);
128 else *mod_ret
= (HMODULE
)((char *)module
+ 2); /* set bit 1 for image resource module */
134 if (module
) UnmapViewOfFile( module
);
140 /******************************************************************
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
;
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
))
159 LdrLockLoaderLock( 0, NULL
, &magic
);
160 if (!LdrGetDllHandle( load_path
, flags
, libname
, &module
))
161 LdrAddRefDll( 0, module
);
163 load_library_as_datafile( load_path
, flags
, libname
->Buffer
, &module
);
164 LdrUnlockLoaderLock( 0, magic
);
168 status
= LdrLoadDll( load_path
, flags
, libname
, &module
);
169 if (!set_ntstatus( status
))
172 if (status
== STATUS_DLL_NOT_FOUND
&& (GetVersion() & 0x80000000))
173 SetLastError( ERROR_DLL_NOT_FOUND
);
177 RtlReleasePath( load_path
);
182 /****************************************************************************
183 * AddDllDirectory (kernelbase.@)
185 DLL_DIRECTORY_COOKIE WINAPI DECLSPEC_HOTPATCH
AddDllDirectory( const WCHAR
*dir
)
190 RtlInitUnicodeString( &str
, dir
);
191 if (!set_ntstatus( LdrAddDllDirectory( &str
, &cookie
))) return NULL
;
196 /***********************************************************************
197 * DelayLoadFailureHook (kernelbase.@)
199 FARPROC WINAPI DECLSPEC_HOTPATCH
DelayLoadFailureHook( LPCSTR name
, LPCSTR function
)
203 if ((ULONG_PTR
)function
>> 16)
204 ERR( "failed to delay load %s.%s\n", name
, function
);
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
);
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
)
230 SetLastError( ERROR_INVALID_HANDLE
);
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
);
242 if ((ULONG_PTR
)module
& 1)
244 struct exclusive_datafile
*file
;
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
);
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
) );
276 SetLastError( ERROR_NOT_ENOUGH_MEMORY
);
279 if ((len
= GetModuleFileNameW( module
, filenameW
, size
)))
281 len
= file_name_WtoA( filenameW
, len
, filename
, size
);
285 SetLastError( ERROR_INSUFFICIENT_BUFFER
);
287 HeapFree( GetProcessHeap(), 0, filenameW
);
292 /***********************************************************************
293 * GetModuleFileNameW (kernelbase.@)
295 DWORD WINAPI DECLSPEC_HOTPATCH
GetModuleFileNameW( HMODULE module
, LPWSTR filename
, DWORD size
)
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;
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
) );
322 else SetLastError( ERROR_INSUFFICIENT_BUFFER
);
325 LdrUnlockLoaderLock( 0, magic
);
327 TRACE( "%s\n", debugstr_wn(filename
, len
) );
332 /***********************************************************************
333 * GetModuleHandleA (kernelbase.@)
335 HMODULE WINAPI DECLSPEC_HOTPATCH
GetModuleHandleA( LPCSTR module
)
339 GetModuleHandleExA( GET_MODULE_HANDLE_EX_FLAG_UNCHANGED_REFCOUNT
, module
, &ret
);
344 /***********************************************************************
345 * GetModuleHandleW (kernelbase.@)
347 HMODULE WINAPI DECLSPEC_HOTPATCH
GetModuleHandleW( LPCWSTR module
)
351 GetModuleHandleExW( GET_MODULE_HANDLE_EX_FLAG_UNCHANGED_REFCOUNT
, module
, &ret
);
356 /***********************************************************************
357 * GetModuleHandleExA (kernelbase.@)
359 BOOL WINAPI DECLSPEC_HOTPATCH
GetModuleHandleExA( DWORD flags
, LPCSTR name
, HMODULE
*module
)
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
;
383 SetLastError( ERROR_INVALID_PARAMETER
);
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
))
393 SetLastError( ERROR_INVALID_PARAMETER
);
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
);
403 ret
= NtCurrentTeb()->Peb
->ImageBaseAddress
;
405 else if (flags
& GET_MODULE_HANDLE_EX_FLAG_FROM_ADDRESS
)
408 if (!(ret
= RtlPcToFileHeader( (void *)name
, &dummy
))) status
= STATUS_DLL_NOT_FOUND
;
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
);
428 return set_ntstatus( status
);
432 /***********************************************************************
433 * GetProcAddress (kernelbase.@)
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 */
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")
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"
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")
470 __ASM_CFI(".cfi_adjust_cfa_offset -8\n\t")
471 __ASM_CFI(".cfi_same_value %rbp\n\t")
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
)
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
)
523 SetLastError( ERROR_INVALID_PARAMETER
);
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
);
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
);
552 /***********************************************************************
553 * LoadAppInitDlls (kernelbase.@)
555 void WINAPI
LoadAppInitDlls(void)
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 /***********************************************************************
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
;
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
;
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
)
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
)
658 if ((status
= get_res_nameA( type
, &typeW
)) != STATUS_SUCCESS
)
660 if ((status
= get_res_nameA( name
, &nameW
)) != STATUS_SUCCESS
)
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
)
667 et
= (const IMAGE_RESOURCE_DIRECTORY_ENTRY
*)(resdir
+ 1);
670 for (i
= 0; i
< resdir
->NumberOfNamedEntries
+ resdir
->NumberOfIdEntries
; i
++)
672 ret
= func( module
, type
, name
, et
[i
].u
.Id
, param
);
679 status
= STATUS_ACCESS_VIOLATION
;
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
) );
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
)
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
)
718 if ((status
= get_res_nameW( type
, &typeW
)) != STATUS_SUCCESS
)
720 if ((status
= get_res_nameW( name
, &nameW
)) != STATUS_SUCCESS
)
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
)
727 et
= (const IMAGE_RESOURCE_DIRECTORY_ENTRY
*)(resdir
+ 1);
730 for (i
= 0; i
< resdir
->NumberOfNamedEntries
+ resdir
->NumberOfIdEntries
; i
++)
732 ret
= func( module
, type
, name
, et
[i
].u
.Id
, param
);
739 status
= STATUS_ACCESS_VIOLATION
;
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
) );
750 /**********************************************************************
751 * EnumResourceNamesExA (kernelbase.@)
753 BOOL WINAPI DECLSPEC_HOTPATCH
EnumResourceNamesExA( HMODULE module
, LPCSTR type
, ENUMRESNAMEPROCA func
,
754 LONG_PTR param
, DWORD flags
, LANGID lang
)
758 DWORD len
= 0, newlen
;
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 );
777 if ((status
= LdrFindResourceDirectory_U( module
, NULL
, 0, &basedir
)) != STATUS_SUCCESS
)
779 if ((status
= get_res_nameA( type
, &typeW
)) != STATUS_SUCCESS
)
781 info
.Type
= (ULONG_PTR
)typeW
.Buffer
;
782 if ((status
= LdrFindResourceDirectory_U( module
, &info
, 1, &resdir
)) != STATUS_SUCCESS
)
785 et
= (const IMAGE_RESOURCE_DIRECTORY_ENTRY
*)(resdir
+ 1);
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
)
797 HeapFree( GetProcessHeap(), 0, name
);
798 if (!(name
= HeapAlloc( GetProcessHeap(), 0, len
+ 1 )))
804 WideCharToMultiByte( CP_ACP
, 0, str
->NameString
, str
->Length
, name
, len
, NULL
, NULL
);
806 ret
= func( module
, type
, name
, param
);
810 ret
= func( module
, type
, UIntToPtr(et
[i
].u
.Id
), param
);
818 status
= STATUS_ACCESS_VIOLATION
;
823 HeapFree( GetProcessHeap(), 0, name
);
824 if (!IS_INTRESOURCE(typeW
.Buffer
)) HeapFree( GetProcessHeap(), 0, typeW
.Buffer
);
825 if (status
!= STATUS_SUCCESS
) SetLastError( RtlNtStatusToDosError(status
) );
830 /**********************************************************************
831 * EnumResourceNamesExW (kernelbase.@)
833 BOOL WINAPI DECLSPEC_HOTPATCH
EnumResourceNamesExW( HMODULE module
, LPCWSTR type
, ENUMRESNAMEPROCW func
,
834 LONG_PTR param
, DWORD flags
, LANGID lang
)
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 );
856 if ((status
= LdrFindResourceDirectory_U( module
, NULL
, 0, &basedir
)) != STATUS_SUCCESS
)
858 if ((status
= get_res_nameW( type
, &typeW
)) != STATUS_SUCCESS
)
860 info
.Type
= (ULONG_PTR
)typeW
.Buffer
;
861 if ((status
= LdrFindResourceDirectory_U( module
, &info
, 1, &resdir
)) != STATUS_SUCCESS
)
864 et
= (const IMAGE_RESOURCE_DIRECTORY_ENTRY
*)(resdir
+ 1);
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
) )))
882 memcpy(name
, str
->NameString
, str
->Length
* sizeof (WCHAR
));
883 name
[str
->Length
] = 0;
884 ret
= func( module
, type
, name
, param
);
888 ret
= func( module
, type
, UIntToPtr(et
[i
].u
.Id
), param
);
896 status
= STATUS_ACCESS_VIOLATION
;
900 HeapFree( GetProcessHeap(), 0, name
);
901 if (!IS_INTRESOURCE(typeW
.Buffer
)) HeapFree( GetProcessHeap(), 0, typeW
.Buffer
);
902 if (status
!= STATUS_SUCCESS
) SetLastError( RtlNtStatusToDosError(status
) );
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
)
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
)
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
);
958 ret
= func( module
, type
, param
);
962 ret
= func( module
, UIntToPtr(et
[i
].u
.Id
), param
);
966 HeapFree( GetProcessHeap(), 0, type
);
971 /**********************************************************************
972 * EnumResourceTypesExW (kernelbase.@)
974 BOOL WINAPI DECLSPEC_HOTPATCH
EnumResourceTypesExW( HMODULE module
, ENUMRESTYPEPROCW func
, LONG_PTR param
,
975 DWORD flags
, LANGID lang
)
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
);
1011 ret
= func( module
, UIntToPtr(et
[i
].u
.Id
), param
);
1015 HeapFree( GetProcessHeap(), 0, type
);
1020 /**********************************************************************
1021 * FindResourceExW (kernelbase.@)
1023 HRSRC WINAPI DECLSPEC_HOTPATCH
FindResourceExW( HMODULE module
, LPCWSTR type
, LPCWSTR name
, WORD lang
)
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
;
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
);
1044 if (status
!= STATUS_SUCCESS
) SetLastError( RtlNtStatusToDosError(status
) );
1048 SetLastError( ERROR_INVALID_PARAMETER
);
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
)
1076 /**********************************************************************
1077 * LoadResource (kernelbase.@)
1079 HGLOBAL WINAPI DECLSPEC_HOTPATCH
LoadResource( HINSTANCE module
, HRSRC rsrc
)
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
)))
1093 /**********************************************************************
1094 * LockResource (kernelbase.@)
1096 LPVOID WINAPI DECLSPEC_HOTPATCH
LockResource( HGLOBAL 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
)
1142 TRACE( "%p %08x\n", ctx
, ctx
? ctx
->dwFlags
: 0 );
1144 if (!set_ntstatus( RtlCreateActivationContext( &context
, ctx
))) return INVALID_HANDLE_VALUE
;
1149 /***********************************************************************
1150 * DeactivateActCtx (kernelbase.@)
1152 BOOL WINAPI DECLSPEC_HOTPATCH
DeactivateActCtx( DWORD flags
, ULONG_PTR cookie
)
1154 RtlDeactivateActivationContext( flags
, cookie
);
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
)
1179 SetLastError( ERROR_INVALID_PARAMETER
);
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
,
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
));