initialize the handle tables before creating them
Modified: trunk/reactos/ntoskrnl/ex/handle.c
Modified: trunk/reactos/ntoskrnl/ex/init.c
Modified: trunk/reactos/ntoskrnl/ps/process.c
Modified: trunk/reactos/ntoskrnl/ps/psmgr.c
Modified: trunk/reactos/ntoskrnl/ps/thread.c

Modified: trunk/reactos/ntoskrnl/ex/handle.c
--- trunk/reactos/ntoskrnl/ex/handle.c	2005-03-13 22:33:13 UTC (rev 14039)
+++ trunk/reactos/ntoskrnl/ex/handle.c	2005-03-13 23:03:31 UTC (rev 14040)
@@ -77,6 +77,8 @@
 #define IS_VALID_EX_HANDLE(index)                                              \
   (((index) & ~VALID_HANDLE_MASK) == 0)
 
+static BOOLEAN ExpInitialized = FALSE;
+
 /******************************************************************************/
 
 VOID
@@ -85,6 +87,8 @@
   ExpHandleShortWait.QuadPart = -50000;
   InitializeListHead(&ExpHandleTableHead);
   ExInitializeFastMutex(&ExpHandleTableListLock);
+
+  ExpInitialized = TRUE;
 }
 
 PHANDLE_TABLE
@@ -94,6 +98,11 @@
   
   PAGED_CODE();
   
+  if(!ExpInitialized)
+  {
+    KEBUGCHECK(0);
+  }
+  
   if(QuotaProcess != NULL)
   {
     /* FIXME - Charge process quota before allocating the handle table! */

Modified: trunk/reactos/ntoskrnl/ex/init.c
--- trunk/reactos/ntoskrnl/ex/init.c	2005-03-13 22:33:13 UTC (rev 14039)
+++ trunk/reactos/ntoskrnl/ex/init.c	2005-03-13 23:03:31 UTC (rev 14040)
@@ -33,6 +33,8 @@
 extern KSPIN_LOCK KiProfileLock;
 #endif
 
+VOID PspPostInitSystemProcess(VOID);
+
 /* FUNCTIONS ****************************************************************/
 
 static 
@@ -479,6 +481,18 @@
     /* Initialize Basic System Objects and Worker Threads */
     ExInit3();
     
+    /* Create the system handle table, assign it to the system process, create
+       the client id table and assign a PID for the system process. This needs
+       to be done before the worker threads are initialized so the system
+       process gets the first PID (4) */
+    PspPostInitSystemProcess();
+
+    /* initialize the worker threads */
+    ExInitializeWorkerThreads();
+    
+    /* initialize callbacks */
+    ExpInitializeCallbacks();
+    
     /* Initialize the GDB Stub and break */
     KdInit1();
   
@@ -656,18 +670,16 @@
 VOID INIT_FUNCTION
 ExInit3 (VOID)
 {
-  ExInitializeWorkerThreads();
   ExpInitializeEventImplementation();
   ExpInitializeEventPairImplementation();
   ExpInitializeMutantImplementation();
   ExpInitializeSemaphoreImplementation();
   ExpInitializeTimerImplementation();
-  ExpInitializeHandleTables();
   LpcpInitSystem();
   ExpInitializeProfileImplementation();
   ExpWin32kInit();
   ExpInitUuids();
-  ExpInitializeCallbacks();
+  ExpInitializeHandleTables();
 }
 
 /* EOF */

Modified: trunk/reactos/ntoskrnl/ps/process.c
--- trunk/reactos/ntoskrnl/ps/process.c	2005-03-13 22:33:13 UTC (rev 14039)
+++ trunk/reactos/ntoskrnl/ps/process.c	2005-03-13 23:03:31 UTC (rev 14040)
@@ -16,6 +16,8 @@
 
 /* GLOBALS ******************************************************************/
 
+VOID INIT_FUNCTION PsInitClientIDManagment(VOID);
+
 PEPROCESS EXPORTED PsInitialSystemProcess = NULL;
 
 POBJECT_TYPE EXPORTED PsProcessType = NULL;
@@ -393,7 +395,6 @@
    
    MmInitializeAddressSpace(PsInitialSystemProcess,
 			    &PsInitialSystemProcess->AddressSpace);
-   ObCreateHandleTable(NULL,FALSE,PsInitialSystemProcess);
    
    KeInitializeEvent(&PsInitialSystemProcess->LockEvent, SynchronizationEvent, FALSE);
    PsInitialSystemProcess->LockCount = 0;
@@ -421,6 +422,28 @@
    SepCreateSystemProcessToken(PsInitialSystemProcess);
 }
 
+VOID
+PspPostInitSystemProcess(VOID)
+{
+  NTSTATUS Status;
+  
+  /* this routine is called directly after the exectuive handle tables were
+     initialized. We'll set up the Client ID handle table and assign the system
+     process a PID */
+  PsInitClientIDManagment();
+  
+  ObCreateHandleTable(NULL, FALSE, PsInitialSystemProcess);
+  
+  Status = PsCreateCidHandle(PsInitialSystemProcess,
+                             PsProcessType,
+                             &PsInitialSystemProcess->UniqueProcessId);
+  if(!NT_SUCCESS(Status))
+  {
+    DPRINT1("Failed to create CID handle (unique process id) for the system process!\n");
+    KEBUGCHECK(0);
+  }
+}
+
 VOID STDCALL
 PiDeleteProcessWorker(PVOID pContext)
 {

Modified: trunk/reactos/ntoskrnl/ps/psmgr.c
--- trunk/reactos/ntoskrnl/ps/psmgr.c	2005-03-13 22:33:13 UTC (rev 14039)
+++ trunk/reactos/ntoskrnl/ps/psmgr.c	2005-03-13 23:03:31 UTC (rev 14040)
@@ -14,8 +14,6 @@
 #define NDEBUG
 #include <internal/debug.h>
 
-VOID INIT_FUNCTION PsInitClientIDManagment(VOID);
-
 /* FUNCTIONS ***************************************************************/
 
 VOID PiShutdownProcessManager(VOID)
@@ -28,23 +26,10 @@
 VOID INIT_FUNCTION
 PiInitProcessManager(VOID)
 {
-   NTSTATUS Status;
-   
-   PsInitClientIDManagment();
    PsInitJobManagment();
    PsInitProcessManagment();
    PsInitThreadManagment();
    PsInitIdleThread();
-   
-   Status = PsCreateCidHandle(PsInitialSystemProcess,
-                              PsProcessType,
-                              &PsInitialSystemProcess->UniqueProcessId);
-   if(!NT_SUCCESS(Status))
-   {
-     DPRINT1("Failed to create CID handle (unique process id) for the system process!\n");
-     KEBUGCHECK(0);
-   }
-   
    PsInitialiseSuspendImplementation();
    PsInitialiseW32Call();
 }

Modified: trunk/reactos/ntoskrnl/ps/thread.c
--- trunk/reactos/ntoskrnl/ps/thread.c	2005-03-13 22:33:13 UTC (rev 14039)
+++ trunk/reactos/ntoskrnl/ps/thread.c	2005-03-13 23:03:31 UTC (rev 14040)
@@ -731,9 +731,9 @@
  * FUNCTION: Initialize thread managment
  */
 {
-   HANDLE PiReaperThreadHandle;
-   PETHREAD FirstThread;
+   PETHREAD FirstThread, ReaperThread;
    ULONG i;
+   KIRQL oldIrql;
    NTSTATUS Status;
 
    for (i=0; i < MAXIMUM_PRIORITY; i++)
@@ -782,20 +782,27 @@
     */
    PsInitializeThreadReaper();
    KeInitializeEvent(&PiReaperThreadEvent, SynchronizationEvent, FALSE);
-   Status = PsCreateSystemThread(&PiReaperThreadHandle,
-				 THREAD_ALL_ACCESS,
-				 NULL,
-				 NULL,
-				 NULL,
-				 PiReaperThreadMain,
-				 NULL);
+   Status = PsInitializeThread(NULL,
+			       &ReaperThread,
+			       NULL,
+			       FALSE);
    if (!NT_SUCCESS(Status))
      {
        DPRINT1("PS: Failed to create reaper thread.\n");
        KEBUGCHECK(0);
      }
 
-   NtClose(PiReaperThreadHandle);
+   ReaperThread->StartAddress = PiReaperThreadMain;
+   Status = KiArchInitThread(&ReaperThread->Tcb, PiReaperThreadMain, NULL);
+   if (!NT_SUCCESS(Status))
+     {
+       DPRINT1("PS: Failed to initialize reaper thread.\n");
+       KEBUGCHECK(0);
+     }
+
+   oldIrql = KeAcquireDispatcherDatabaseLock ();
+   PsUnblockThread(ReaperThread, NULL, 0);
+   KeReleaseDispatcherDatabaseLock(oldIrql);
 }
 
 /*