Alexandre Julliard : ntdll: Load the apiset schema at startup.
Alexandre Julliard
julliard at winehq.org
Mon Feb 21 16:15:14 CST 2022
Module: wine
Branch: master
Commit: e3c9d73cd1d092542d846a368196e26cd5c44972
URL: https://source.winehq.org/git/wine.git/?a=commit;h=e3c9d73cd1d092542d846a368196e26cd5c44972
Author: Alexandre Julliard <julliard at winehq.org>
Date: Mon Feb 21 22:23:03 2022 +0100
ntdll: Load the apiset schema at startup.
Signed-off-by: Alexandre Julliard <julliard at 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)
More information about the wine-cvs
mailing list