ntdll: Implement RtlGetNtGlobalFlags(), add related defines to winternl.h.
diff --git a/dlls/ntdll/ntdll.spec b/dlls/ntdll/ntdll.spec
index 382feb3..e7f298d 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 ba51df5..aaf8315 100644
--- a/dlls/ntdll/process.c
+++ b/dlls/ntdll/process.c
@@ -73,6 +73,15 @@
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 b9529bd..c370651 100644
--- a/dlls/ntdll/thread.c
+++ b/dlls/ntdll/thread.c
@@ -216,6 +216,53 @@
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 @@
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 6f21ad0..9625d88 100644
--- a/include/winternl.h
+++ b/include/winternl.h
@@ -1732,6 +1732,10 @@
#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 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*);