diff --git a/dlls/ntdll/ntdll.spec b/dlls/ntdll/ntdll.spec index 382feb324a5..e7f298da014 100644 --- a/dlls/ntdll/ntdll.spec +++ b/dlls/ntdll/ntdll.spec @@ -632,7 +632,7 @@ @ stdcall RtlGetLongestNtPathLength() # @ stub RtlGetNativeSystemInformation # @ stub RtlGetNextRange -@ stub RtlGetNtGlobalFlags +@ stdcall RtlGetNtGlobalFlags() @ stdcall RtlGetNtProductType(ptr) @ stdcall RtlGetNtVersionNumbers(ptr ptr ptr) @ stdcall RtlGetOwnerSecurityDescriptor(ptr ptr ptr) diff --git a/dlls/ntdll/process.c b/dlls/ntdll/process.c index ba51df56445..aaf8315513d 100644 --- a/dlls/ntdll/process.c +++ b/dlls/ntdll/process.c @@ -73,6 +73,15 @@ PEB * WINAPI RtlGetCurrentPeb(void) return NtCurrentTeb()->Peb; } +/****************************************************************************** + * RtlGetNtGlobalFlags [NTDLL.@] + * + */ +ULONG WINAPI RtlGetNtGlobalFlags(void) +{ + return NtCurrentTeb()->Peb->NtGlobalFlag; +} + /*********************************************************************** * __wine_make_process_system (NTDLL.@) * diff --git a/dlls/ntdll/thread.c b/dlls/ntdll/thread.c index b9529bdfb44..c3706512f10 100644 --- a/dlls/ntdll/thread.c +++ b/dlls/ntdll/thread.c @@ -216,6 +216,53 @@ done: return status; } +/*********************************************************************** + * get_global_flag + * + * This is called before the process heap is created, + * but after the connection to the server is established. + * No windows heap allocation is permitted. + */ +static DWORD get_global_flag(void) +{ + static const WCHAR sessionman_keyW[] = {'M','a','c','h','i','n','e','\\', + 'S','y','s','t','e','m','\\', + 'C','u','r','r','e','n','t','C','o','n','t','r','o','l','S','e','t','\\', + 'C','o','n','t','r','o','l','\\', + 'S','e','s','s','i','o','n',' ','M','a','n','a','g','e','r',0}; + static const WCHAR global_flagW[] = {'G','l','o','b','a','l','F','l','a','g',0}; + OBJECT_ATTRIBUTES attr; + UNICODE_STRING nameW, valueW; + HANDLE hkey; + char tmp[32]; + DWORD count; + KEY_VALUE_PARTIAL_INFORMATION *info = (KEY_VALUE_PARTIAL_INFORMATION *)tmp; + NTSTATUS status; + + attr.Length = sizeof(attr); + attr.RootDirectory = 0; + attr.ObjectName = &nameW; + attr.Attributes = 0; + attr.SecurityDescriptor = NULL; + attr.SecurityQualityOfService = NULL; + RtlInitUnicodeString( &nameW, sessionman_keyW ); + + status = NtOpenKey( &hkey, KEY_ALL_ACCESS, &attr ); + if (status != STATUS_SUCCESS) + return 0; + + RtlInitUnicodeString( &valueW, global_flagW ); + status = NtQueryValueKey( hkey, &valueW, KeyValuePartialInformation, tmp, sizeof(tmp)-1, &count ); + if (status != STATUS_SUCCESS) + return 0; + + /* Some documents say this can be a string, so handle either type */ + if (info->Type == REG_DWORD) + return *(DWORD *)info->Data; + if (info->Type == REG_SZ) + return strtol((char *)info->Data, NULL, 16); + return 0; +} /*********************************************************************** * thread_init @@ -297,6 +344,9 @@ HANDLE thread_init(void) server_init_process(); info_size = server_init_thread( peb ); + /* retrieve the global flags settings from the registry */ + peb->NtGlobalFlag = get_global_flag(); + /* create the process heap */ if (!(peb->ProcessHeap = RtlCreateHeap( HEAP_GROWABLE, NULL, 0, 0, NULL, NULL ))) { diff --git a/include/winternl.h b/include/winternl.h index 6f21ad0c36b..9625d883d84 100644 --- a/include/winternl.h +++ b/include/winternl.h @@ -1732,6 +1732,10 @@ typedef void (NTAPI *RTL_WAITORTIMERCALLBACKFUNC)(PVOID,BOOLEAN); /* FIXME: not #define SE_CREATE_GLOBAL_PRIVILEGE 30L #define SE_MAX_WELL_KNOWN_PRIVILEGE SE_CREATE_GLOBAL_PRIVILEGE +/* NtGlobalFlag bits */ +#define FLG_HEAP_ENABLE_TAIL_CHECK 0x00000010 +#define FLG_HEAP_ENABLE_FREE_CHECK 0x00000020 +#define FLG_HEAP_DISABLE_COALESCING 0x00200000 /* Rtl*Registry* functions structs and defines */ #define RTL_REGISTRY_ABSOLUTE 0 @@ -2404,6 +2408,7 @@ NTSYSAPI NTSTATUS WINAPI RtlGetGroupSecurityDescriptor(PSECURITY_DESCRIPTOR,PSI NTSYSAPI NTSTATUS WINAPI RtlGetLastNtStatus(void); NTSYSAPI DWORD WINAPI RtlGetLastWin32Error(void); NTSYSAPI DWORD WINAPI RtlGetLongestNtPathLength(void); +NTSYSAPI ULONG WINAPI RtlGetNtGlobalFlags(void); NTSYSAPI BOOLEAN WINAPI RtlGetNtProductType(LPDWORD); NTSYSAPI NTSTATUS WINAPI RtlGetOwnerSecurityDescriptor(PSECURITY_DESCRIPTOR,PSID *,PBOOLEAN); NTSYSAPI ULONG WINAPI RtlGetProcessHeaps(ULONG,HANDLE*);