Commit e3c9d73c authored by Alexandre Julliard's avatar Alexandre Julliard

ntdll: Load the apiset schema at startup.

parent a31f3374
......@@ -1993,6 +1993,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
*/
static void load_wow64_ntdll( USHORT machine )
......@@ -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)
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment