Module: wine Branch: master Commit: e3c9d73cd1d092542d846a368196e26cd5c44972 URL: https://source.winehq.org/git/wine.git/?a=commit;h=e3c9d73cd1d092542d846a368...
Author: Alexandre Julliard julliard@winehq.org Date: Mon Feb 21 22:23:03 2022 +0100
ntdll: Load the apiset schema at startup.
Signed-off-by: Alexandre Julliard julliard@winehq.org
---
dlls/ntdll/unix/loader.c | 77 ++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 77 insertions(+)
diff --git a/dlls/ntdll/unix/loader.c b/dlls/ntdll/unix/loader.c index 96301b1654e..98a5c933215 100644 --- a/dlls/ntdll/unix/loader.c +++ b/dlls/ntdll/unix/loader.c @@ -1992,6 +1992,82 @@ static void load_ntdll(void) }
+/*********************************************************************** + * load_apiset_dll + */ +static void load_apiset_dll(void) +{ + static WCHAR path[] = {'\','?','?','\','C',':','\','w','i','n','d','o','w','s','\', + 's','y','s','t','e','m','3','2','\', + 'a','p','i','s','e','t','s','c','h','e','m','a','.','d','l','l',0}; + const char *pe_dir = get_pe_dir( current_machine ); + const IMAGE_NT_HEADERS *nt; + const IMAGE_SECTION_HEADER *sec; + API_SET_NAMESPACE *map; + OBJECT_ATTRIBUTES attr; + UNICODE_STRING str; + NTSTATUS status; + HANDLE handle, mapping; + SIZE_T size; + char *name; + void *ptr; + UINT i; + + init_unicode_string( &str, path ); + InitializeObjectAttributes( &attr, &str, 0, 0, NULL ); + + name = malloc( strlen( ntdll_dir ) + strlen( pe_dir ) + sizeof("/apisetschema.dll") ); + if (build_dir) sprintf( name, "%s/dlls/apisetschema/apisetschema.dll", build_dir ); + else sprintf( name, "%s%s/apisetschema.dll", dll_dir, pe_dir ); + status = open_unix_file( &handle, name, GENERIC_READ | SYNCHRONIZE, &attr, 0, + FILE_SHARE_READ | FILE_SHARE_DELETE, FILE_OPEN, + FILE_SYNCHRONOUS_IO_NONALERT | FILE_NON_DIRECTORY_FILE, NULL, 0 ); + free( name ); + + if (!status) + { + status = NtCreateSection( &mapping, STANDARD_RIGHTS_REQUIRED | SECTION_QUERY | SECTION_MAP_READ, + NULL, NULL, PAGE_READONLY, SEC_COMMIT, handle ); + NtClose( handle ); + } + if (!status) + { + ptr = NULL; + size = 0; + status = NtMapViewOfSection( mapping, NtCurrentProcess(), &ptr, + is_win64 && wow_peb ? 0x7fffffff : 0, 0, NULL, + &size, ViewShare, 0, PAGE_READONLY ); + NtClose( mapping ); + } + if (!status) + { + nt = get_rva( ptr, ((IMAGE_DOS_HEADER *)ptr)->e_lfanew ); + sec = (IMAGE_SECTION_HEADER *)((char *)&nt->OptionalHeader + nt->FileHeader.SizeOfOptionalHeader); + + for (i = 0; i < nt->FileHeader.NumberOfSections; i++, sec++) + { + if (memcmp( (char *)sec->Name, ".apiset", 8 )) continue; + map = (API_SET_NAMESPACE *)((char *)ptr + sec->PointerToRawData); + if (sec->PointerToRawData < size && + size - sec->PointerToRawData >= sec->Misc.VirtualSize && + map->Version == 6 && + map->Size <= sec->Misc.VirtualSize) + { + NtCurrentTeb()->Peb->ApiSetMap = map; + if (wow_peb) wow_peb->ApiSetMap = PtrToUlong(map); + NtUnmapViewOfSection( NtCurrentProcess(), ptr ); + TRACE( "loaded %s apiset at %p\n", debugstr_w(path), map ); + return; + } + break; + } + NtUnmapViewOfSection( NtCurrentProcess(), ptr ); + status = STATUS_APISET_NOT_PRESENT; + } + ERR( "failed to load apiset: %x\n", status ); +} + + /*********************************************************************** * load_wow64_ntdll */ @@ -2098,6 +2174,7 @@ static void start_main_thread(void) NtCreateKeyedEvent( &keyed_event, GENERIC_READ | GENERIC_WRITE, NULL, 0 ); load_ntdll(); if (main_image_info.Machine != current_machine) load_wow64_ntdll( main_image_info.Machine ); + load_apiset_dll(); ntdll_init_syscalls( 0, &syscall_table, p__wine_syscall_dispatcher ); status = p__wine_set_unix_funcs( NTDLL_UNIXLIB_VERSION, &unix_funcs ); if (status == STATUS_REVISION_MISMATCH)