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
);
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 /***********************************************************************
62 ***********************************************************************/
65 /******************************************************************
68 FARPROC WINAPI
get_proc_address( HMODULE module
, LPCSTR function
)
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
)))
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
;
95 DWORD protect
= PAGE_READONLY
;
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
);
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
);
138 else *mod_ret
= (HMODULE
)((char *)module
+ 2); /* set bit 1 for image resource module */
144 if (module
) UnmapViewOfFile( module
);
150 /******************************************************************
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
;
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
);
172 status
= LdrLoadDll( load_path
, flags
, libname
, &module
);
173 if (!set_ntstatus( status
))
176 if (status
== STATUS_DLL_NOT_FOUND
&& (GetVersion() & 0x80000000))
177 SetLastError( ERROR_DLL_NOT_FOUND
);
181 RtlReleasePath( load_path
);
186 /****************************************************************************
187 * AddDllDirectory (kernelbase.@)
189 DLL_DIRECTORY_COOKIE WINAPI DECLSPEC_HOTPATCH
AddDllDirectory( const WCHAR
*dir
)
194 RtlInitUnicodeString( &str
, dir
);
195 if (!set_ntstatus( LdrAddDllDirectory( &str
, &cookie
))) return NULL
;
200 /***********************************************************************
201 * DelayLoadFailureHook (kernelbase.@)
203 FARPROC WINAPI DECLSPEC_HOTPATCH
DelayLoadFailureHook( LPCSTR name
, LPCSTR function
)
207 if ((ULONG_PTR
)function
>> 16)
208 ERR( "failed to delay load %s.%s\n", name
, function
);
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
);
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
)
234 SetLastError( ERROR_INVALID_HANDLE
);
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
);
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
);
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
) );
279 SetLastError( ERROR_NOT_ENOUGH_MEMORY
);
282 if ((len
= GetModuleFileNameW( module
, filenameW
, size
)))
284 len
= file_name_WtoA( filenameW
, len
, filename
, size
);
288 SetLastError( ERROR_INSUFFICIENT_BUFFER
);
290 HeapFree( GetProcessHeap(), 0, filenameW
);
295 /***********************************************************************
296 * GetModuleFileNameW (kernelbase.@)
298 DWORD WINAPI DECLSPEC_HOTPATCH
GetModuleFileNameW( HMODULE module
, LPWSTR filename
, DWORD size
)
301 WIN16_SUBSYSTEM_TIB
*win16_tib
;
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;
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
));
319 TRACE( "%s\n", debugstr_wn(filename
, len
) );
324 /***********************************************************************
325 * GetModuleHandleA (kernelbase.@)
327 HMODULE WINAPI DECLSPEC_HOTPATCH
GetModuleHandleA( LPCSTR module
)
331 GetModuleHandleExA( GET_MODULE_HANDLE_EX_FLAG_UNCHANGED_REFCOUNT
, module
, &ret
);
336 /***********************************************************************
337 * GetModuleHandleW (kernelbase.@)
339 HMODULE WINAPI DECLSPEC_HOTPATCH
GetModuleHandleW( LPCWSTR module
)
343 GetModuleHandleExW( GET_MODULE_HANDLE_EX_FLAG_UNCHANGED_REFCOUNT
, module
, &ret
);
348 /***********************************************************************
349 * GetModuleHandleExA (kernelbase.@)
351 BOOL WINAPI DECLSPEC_HOTPATCH
GetModuleHandleExA( DWORD flags
, LPCSTR name
, HMODULE
*module
)
357 SetLastError( ERROR_INVALID_PARAMETER
);
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
)))
367 SetLastError( ERROR_MOD_NOT_FOUND
);
370 return GetModuleHandleExW( flags
, nameW
, module
);
374 /***********************************************************************
375 * GetModuleHandleExW (kernelbase.@)
377 BOOL WINAPI DECLSPEC_HOTPATCH
GetModuleHandleExW( DWORD flags
, LPCWSTR name
, HMODULE
*module
)
385 SetLastError( ERROR_INVALID_PARAMETER
);
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
))
395 SetLastError( ERROR_INVALID_PARAMETER
);
399 if (name
&& !(flags
& GET_MODULE_HANDLE_EX_FLAG_FROM_ADDRESS
))
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
);
414 ret
= name
? RtlPcToFileHeader( (void *)name
, &dummy
) : NtCurrentTeb()->Peb
->ImageBaseAddress
;
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
);
421 status
= STATUS_SUCCESS
;
422 } else status
= STATUS_DLL_NOT_FOUND
;
426 return set_ntstatus( status
);
430 /***********************************************************************
431 * GetProcAddress (kernelbase.@)
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 */
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")
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"
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")
468 __ASM_CFI(".cfi_adjust_cfa_offset -8\n\t")
469 __ASM_CFI(".cfi_same_value %rbp\n\t")
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
)
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
)
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
)
537 SetLastError( ERROR_INVALID_PARAMETER
);
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
);
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
);
566 /***********************************************************************
567 * LoadAppInitDlls (kernelbase.@)
569 void WINAPI
LoadAppInitDlls(void)
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 /***********************************************************************
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
;
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
;
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
)
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
)
672 if ((status
= get_res_nameA( type
, &typeW
)) != STATUS_SUCCESS
)
674 if ((status
= get_res_nameA( name
, &nameW
)) != STATUS_SUCCESS
)
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
)
681 et
= (const IMAGE_RESOURCE_DIRECTORY_ENTRY
*)(resdir
+ 1);
684 for (i
= 0; i
< resdir
->NumberOfNamedEntries
+ resdir
->NumberOfIdEntries
; i
++)
686 ret
= func( module
, type
, name
, et
[i
].u
.Id
, param
);
693 status
= STATUS_ACCESS_VIOLATION
;
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
) );
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
)
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
)
732 if ((status
= get_res_nameW( type
, &typeW
)) != STATUS_SUCCESS
)
734 if ((status
= get_res_nameW( name
, &nameW
)) != STATUS_SUCCESS
)
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
)
741 et
= (const IMAGE_RESOURCE_DIRECTORY_ENTRY
*)(resdir
+ 1);
744 for (i
= 0; i
< resdir
->NumberOfNamedEntries
+ resdir
->NumberOfIdEntries
; i
++)
746 ret
= func( module
, type
, name
, et
[i
].u
.Id
, param
);
753 status
= STATUS_ACCESS_VIOLATION
;
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
) );
764 /**********************************************************************
765 * EnumResourceNamesExA (kernelbase.@)
767 BOOL WINAPI DECLSPEC_HOTPATCH
EnumResourceNamesExA( HMODULE module
, LPCSTR type
, ENUMRESNAMEPROCA func
,
768 LONG_PTR param
, DWORD flags
, LANGID lang
)
772 DWORD len
= 0, newlen
;
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 );
791 if ((status
= LdrFindResourceDirectory_U( module
, NULL
, 0, &basedir
)) != STATUS_SUCCESS
)
793 if ((status
= get_res_nameA( type
, &typeW
)) != STATUS_SUCCESS
)
795 info
.Type
= (ULONG_PTR
)typeW
.Buffer
;
796 if ((status
= LdrFindResourceDirectory_U( module
, &info
, 1, &resdir
)) != STATUS_SUCCESS
)
799 et
= (const IMAGE_RESOURCE_DIRECTORY_ENTRY
*)(resdir
+ 1);
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
)
811 HeapFree( GetProcessHeap(), 0, name
);
812 if (!(name
= HeapAlloc( GetProcessHeap(), 0, len
+ 1 )))
818 WideCharToMultiByte( CP_ACP
, 0, str
->NameString
, str
->Length
, name
, len
, NULL
, NULL
);
820 ret
= func( module
, type
, name
, param
);
824 ret
= func( module
, type
, UIntToPtr(et
[i
].u
.Id
), param
);
832 status
= STATUS_ACCESS_VIOLATION
;
837 HeapFree( GetProcessHeap(), 0, name
);
838 if (!IS_INTRESOURCE(typeW
.Buffer
)) HeapFree( GetProcessHeap(), 0, typeW
.Buffer
);
839 if (status
!= STATUS_SUCCESS
) SetLastError( RtlNtStatusToDosError(status
) );
844 /**********************************************************************
845 * EnumResourceNamesExW (kernelbase.@)
847 BOOL WINAPI DECLSPEC_HOTPATCH
EnumResourceNamesExW( HMODULE module
, LPCWSTR type
, ENUMRESNAMEPROCW func
,
848 LONG_PTR param
, DWORD flags
, LANGID lang
)
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 );
870 if ((status
= LdrFindResourceDirectory_U( module
, NULL
, 0, &basedir
)) != STATUS_SUCCESS
)
872 if ((status
= get_res_nameW( type
, &typeW
)) != STATUS_SUCCESS
)
874 info
.Type
= (ULONG_PTR
)typeW
.Buffer
;
875 if ((status
= LdrFindResourceDirectory_U( module
, &info
, 1, &resdir
)) != STATUS_SUCCESS
)
878 et
= (const IMAGE_RESOURCE_DIRECTORY_ENTRY
*)(resdir
+ 1);
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
) )))
896 memcpy(name
, str
->NameString
, str
->Length
* sizeof (WCHAR
));
897 name
[str
->Length
] = 0;
898 ret
= func( module
, type
, name
, param
);
902 ret
= func( module
, type
, UIntToPtr(et
[i
].u
.Id
), param
);
910 status
= STATUS_ACCESS_VIOLATION
;
914 HeapFree( GetProcessHeap(), 0, name
);
915 if (!IS_INTRESOURCE(typeW
.Buffer
)) HeapFree( GetProcessHeap(), 0, typeW
.Buffer
);
916 if (status
!= STATUS_SUCCESS
) SetLastError( RtlNtStatusToDosError(status
) );
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
)
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
)
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
);
972 ret
= func( module
, type
, param
);
976 ret
= func( module
, UIntToPtr(et
[i
].u
.Id
), param
);
980 HeapFree( GetProcessHeap(), 0, type
);
985 /**********************************************************************
986 * EnumResourceTypesExW (kernelbase.@)
988 BOOL WINAPI DECLSPEC_HOTPATCH
EnumResourceTypesExW( HMODULE module
, ENUMRESTYPEPROCW func
, LONG_PTR param
,
989 DWORD flags
, LANGID lang
)
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
);
1025 ret
= func( module
, UIntToPtr(et
[i
].u
.Id
), param
);
1029 HeapFree( GetProcessHeap(), 0, type
);
1034 /**********************************************************************
1035 * FindResourceExW (kernelbase.@)
1037 HRSRC WINAPI DECLSPEC_HOTPATCH
FindResourceExW( HMODULE module
, LPCWSTR type
, LPCWSTR name
, WORD lang
)
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
;
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
);
1058 if (status
!= STATUS_SUCCESS
) SetLastError( RtlNtStatusToDosError(status
) );
1062 SetLastError( ERROR_INVALID_PARAMETER
);
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
)
1090 /**********************************************************************
1091 * LoadResource (kernelbase.@)
1093 HGLOBAL WINAPI DECLSPEC_HOTPATCH
LoadResource( HINSTANCE module
, HRSRC rsrc
)
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
)))
1107 /**********************************************************************
1108 * LockResource (kernelbase.@)
1110 LPVOID WINAPI DECLSPEC_HOTPATCH
LockResource( HGLOBAL 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
)
1156 TRACE( "%p %08lx\n", ctx
, ctx
? ctx
->dwFlags
: 0 );
1158 if (!set_ntstatus( RtlCreateActivationContext( &context
, ctx
))) return INVALID_HANDLE_VALUE
;
1163 /***********************************************************************
1164 * DeactivateActCtx (kernelbase.@)
1166 BOOL WINAPI DECLSPEC_HOTPATCH
DeactivateActCtx( DWORD flags
, ULONG_PTR cookie
)
1168 RtlDeactivateActivationContext( flags
, cookie
);
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
)
1193 SetLastError( ERROR_INVALID_PARAMETER
);
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
,
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
));