CORE-6639 #resolve #time 1d #comment Guard pages now work ;-)
[reactos.git] / reactos / lib / rtl / thread.c
index 3213b33..93e6fe0 100644 (file)
@@ -46,6 +46,7 @@ RtlpCreateUserStack(IN HANDLE hProcess,
     {
         /* Get the Image Headers */
         Headers = RtlImageNtHeader(NtCurrentPeb()->ImageBaseAddress);
+        if (!Headers) return STATUS_INVALID_IMAGE_FORMAT;
 
         /* If we didn't get the parameters, find them ourselves */
         if (!StackReserve) StackReserve = Headers->OptionalHeader.
@@ -60,15 +61,17 @@ RtlpCreateUserStack(IN HANDLE hProcess,
         if (!StackCommit) StackCommit = SystemBasicInfo.PageSize;
     }
 
+    /* Check if the commit is higher than the reserve*/
+    if (StackCommit >= StackReserve)
+    {
+        /* Grow the reserve beyond the commit, up to 1MB alignment */
+        StackReserve = ROUND_UP(StackCommit, 1024 * 1024);
+    }
+
     /* Align everything to Page Size */
     StackReserve = ROUND_UP(StackReserve, SystemBasicInfo.AllocationGranularity);
     StackCommit = ROUND_UP(StackCommit, SystemBasicInfo.PageSize);
 
-    // FIXME: Remove once Guard Page support is here
-    #if 1
-    StackCommit = StackReserve;
-    #endif
-
     /* Reserve memory for the stack */
     Status = ZwAllocateVirtualMemory(hProcess,
                                      (PVOID*)&Stack,
@@ -121,7 +124,7 @@ RtlpCreateUserStack(IN HANDLE hProcess,
         if (!NT_SUCCESS(Status)) return Status;
 
         /* Update the Stack Limit keeping in mind the Guard Page */
-        InitialTeb->StackLimit = (PVOID)((ULONG_PTR)InitialTeb->StackLimit -
+        InitialTeb->StackLimit = (PVOID)((ULONG_PTR)InitialTeb->StackLimit +
                                          GuardPageSize);
     }
 
@@ -150,6 +153,48 @@ RtlpFreeUserStack(IN HANDLE Process,
 
 /* FUNCTIONS ***************************************************************/
 
+
+/*
+ * @implemented
+ */
+NTSTATUS
+NTAPI
+RtlSetThreadIsCritical(IN BOOLEAN NewValue,
+                       OUT PBOOLEAN OldValue OPTIONAL,
+                       IN BOOLEAN NeedBreaks)
+{
+    ULONG BreakOnTermination;
+
+    /* Initialize to FALSE */
+    if (OldValue) *OldValue = FALSE;
+
+    /* Fail, if the critical breaks flag is required but is not set */
+    if ((NeedBreaks) &&
+        !(NtCurrentPeb()->NtGlobalFlag & FLG_ENABLE_SYSTEM_CRIT_BREAKS))
+    {
+        return STATUS_UNSUCCESSFUL;
+    }
+
+    /* Check if the caller wants the old value */
+    if (OldValue)
+    {
+        /* Query and return the old break on termination flag for the process */
+        ZwQueryInformationThread(NtCurrentThread(),
+                                 ThreadBreakOnTermination,
+                                 &BreakOnTermination,
+                                 sizeof(ULONG),
+                                 NULL);
+        *OldValue = (BOOLEAN)BreakOnTermination;
+    }
+
+    /* Set the break on termination flag for the process */
+    BreakOnTermination = NewValue;
+    return ZwSetInformationThread(NtCurrentThread(),
+                                  ThreadBreakOnTermination,
+                                  &BreakOnTermination,
+                                  sizeof(ULONG));
+}
+
 /*
  @implemented
 */