[BROWSEUI] SHExplorerParseCmdLine: Fix parsing of /root (#6752)
[reactos.git] / ntoskrnl / ke / amd64 / thrdini.c
index b55daf8..3185de2 100644 (file)
@@ -1,7 +1,7 @@
 /*
  * COPYRIGHT:       See COPYING in the top level directory
  * PROJECT:         ReactOS kernel
- * FILE:            ntoskrnl/ke/i386/thread.c
+ * FILE:            ntoskrnl/ke/amd64/thrdini.c
  * PURPOSE:         amd64 Thread Context Creation
  * PROGRAMMER:      Timo Kreuzer (timo.kreuzer@reactos.org)
  *                  Alex Ionescu (alex@relsoft.net)
 #define NDEBUG
 #include <debug.h>
 
+extern void KiInvalidSystemThreadStartupExit(void);
+extern void KiUserThreadStartupExit(void);
+extern void KiServiceExit3(void);
+
 typedef struct _KUINIT_FRAME
 {
     KSWITCH_FRAME CtxSwitchFrame;
@@ -77,10 +81,11 @@ KiInitializeContextThread(IN PKTHREAD Thread,
 
         /* Zero out the trap frame */
         RtlZeroMemory(TrapFrame, sizeof(KTRAP_FRAME));
+        RtlZeroMemory(&InitFrame->ExceptionFrame, sizeof(KEXCEPTION_FRAME));
 
         /* Set up a trap frame from the context. */
         KeContextToTrapFrame(Context,
-                             NULL,
+                             &InitFrame->ExceptionFrame,
                              TrapFrame,
                              CONTEXT_AMD64 | ContextFlags,
                              UserMode);
@@ -97,8 +102,11 @@ KiInitializeContextThread(IN PKTHREAD Thread,
         /* Terminate the Exception Handler List */
         TrapFrame->ExceptionFrame = 0;
 
-        /* We return to ... */
-        StartFrame->Return = (ULONG64)KiServiceExit2;
+        /* KiThreadStartup returns to KiUserThreadStartupExit */
+        StartFrame->Return = (ULONG64)KiUserThreadStartupExit;
+
+        /* KiUserThreadStartupExit returns to KiServiceExit3 */
+        InitFrame->ExceptionFrame.Return = (ULONG64)KiServiceExit3;
     }
     else
     {
@@ -120,27 +128,26 @@ KiInitializeContextThread(IN PKTHREAD Thread,
         /* No NPX State */
         Thread->NpxState = 0xA;
 
-        /* We have no return address! */
-        StartFrame->Return = 0;
+        /* This must never return! */
+        StartFrame->Return = (ULONG64)KiInvalidSystemThreadStartupExit;
     }
 
     /* Set up the Context Switch Frame */
     CtxSwitchFrame->Return = (ULONG64)KiThreadStartup;
-    CtxSwitchFrame->ApcBypass = FALSE;
+    CtxSwitchFrame->ApcBypass = TRUE;
 
     StartFrame->P1Home = (ULONG64)StartRoutine;
     StartFrame->P2Home = (ULONG64)StartContext;
     StartFrame->P3Home = 0;
     StartFrame->P4Home = (ULONG64)SystemRoutine;
-    StartFrame->P5Home = 0;
-
+    StartFrame->Reserved = 0;
 }
 
 BOOLEAN
 KiSwapContextResume(
-    IN PKTHREAD NewThread,
-    IN PKTHREAD OldThread,
-    IN BOOLEAN ApcBypass)
+    _In_ BOOLEAN ApcBypass,
+    _In_ PKTHREAD OldThread,
+    _In_ PKTHREAD NewThread)
 {
     PKIPCR Pcr = (PKIPCR)KeGetPcr();
     PKPROCESS OldProcess, NewProcess;
@@ -184,18 +191,22 @@ KiSwapContextResume(
                      0);
     }
 
+    /* Old thread os no longer busy */
+    OldThread->SwapBusy = FALSE;
+
     /* Kernel APCs may be pending */
     if (NewThread->ApcState.KernelApcPending)
     {
         /* Are APCs enabled? */
-        if (!NewThread->SpecialApcDisable)
+        if ((NewThread->SpecialApcDisable == 0) &&
+            (ApcBypass == 0))
         {
-            /* Request APC delivery */
-            if (!ApcBypass)
-                HalRequestSoftwareInterrupt(APC_LEVEL);
-            else
-                return TRUE;
+            /* Return TRUE to indicate that we want APCs to be delivered */
+            return TRUE;
         }
+
+        /* Request an APC interrupt to be delivered later */
+        HalRequestSoftwareInterrupt(APC_LEVEL);
     }
 
     /* Return stating that no kernel APCs are pending*/