branch update for HEAD-2003091401
[reactos.git] / ntoskrnl / ps / create.c
index 3eacb29..f406976 100644 (file)
@@ -8,6 +8,7 @@
  * REVISION HISTORY: 
  *               23/06/98: Created
  *               12/10/99: Phillip Susi:  Thread priorities, and APC work
+ *               09/08/03: Skywing:       ThreadEventPair support (delete)
  */
 
 /*
 
 /* INCLUDES ****************************************************************/
 
-#include <ddk/ntddk.h>
+#define NTOS_MODE_KERNEL
+#include <ntos.h>
 #include <internal/ke.h>
 #include <internal/ob.h>
 #include <internal/ps.h>
+#include <internal/ex.h>
 #include <internal/se.h>
 #include <internal/id.h>
 #include <internal/dbg.h>
@@ -93,6 +96,9 @@ PsAssignImpersonationToken(PETHREAD Thread,
    return(STATUS_SUCCESS);
 }
 
+/*
+ * @implemented
+ */
 VOID STDCALL
 PsRevertToSelf(VOID)
 {
@@ -107,6 +113,9 @@ PsRevertToSelf(VOID)
      }
 }
 
+/*
+ * @implemented
+ */
 VOID STDCALL
 PsImpersonateClient(PETHREAD Thread,
                    PACCESS_TOKEN Token,
@@ -251,6 +260,9 @@ NtOpenThreadToken(IN        HANDLE          ThreadHandle,
 
 #endif /* LIBCAPTIVE */
 
+/*
+ * @implemented
+ */
 PACCESS_TOKEN STDCALL 
 PsReferenceImpersonationToken(PETHREAD Thread,
                              PULONG Unknown1,
@@ -292,24 +304,38 @@ PiDeleteThread(PVOID ObjectBody)
   KIRQL oldIrql;
   PETHREAD Thread;
   ULONG i;
+  PCREATE_THREAD_NOTIFY_ROUTINE NotifyRoutine[MAX_THREAD_NOTIFY_ROUTINE_COUNT];
+  ULONG NotifyRoutineCount;
+
   Thread = (PETHREAD)ObjectBody;
 
   DPRINT("PiDeleteThread(ObjectBody %x)\n",ObjectBody);
 
+  /* Terminate Win32 thread */
+  PsTerminateWin32Thread (Thread);
+
   ObDereferenceObject(Thread->ThreadsProcess);
   Thread->ThreadsProcess = NULL;
 
   KeAcquireSpinLock(&PiThreadListLock, &oldIrql);
-  
   for (i = 0; i < PiThreadNotifyRoutineCount; i++)
-    {
-      PiThreadNotifyRoutine[i](Thread->Cid.UniqueProcess,
-                              Thread->Cid.UniqueThread,
-                              FALSE);
-    }    
+  {
+     NotifyRoutine[i] = PiThreadNotifyRoutine[i];
+  }
+  NotifyRoutineCount = PiThreadNotifyRoutineCount;
   PiNrThreads--;
   RemoveEntryList(&Thread->Tcb.ThreadListEntry);
   KeReleaseSpinLock(&PiThreadListLock, oldIrql);
+  ExpSwapThreadEventPair(Thread, NULL); /* Release the associated eventpair object, if there was one */
+
+  for (i = 0; i < NotifyRoutineCount; i++)
+  {
+     //must be called below DISPATCH_LVL
+     NotifyRoutine[i](Thread->Cid.UniqueProcess,
+                      Thread->Cid.UniqueThread,
+                      FALSE);
+  }
+
   KeReleaseThread(Thread);
   DPRINT("PiDeleteThread() finished\n");
 }
@@ -330,8 +356,10 @@ PsInitializeThread(HANDLE ProcessHandle,
    PEPROCESS Process;
 #ifndef LIBCAPTIVE
    ULONG i;
+   ULONG NotifyRoutineCount;
+   PCREATE_THREAD_NOTIFY_ROUTINE NotifyRoutine[MAX_THREAD_NOTIFY_ROUTINE_COUNT];
 #endif /* LIBCAPTIVE */
-   
+
    /*
     * Reference process
     */
@@ -362,7 +390,7 @@ PsInitializeThread(HANDLE ProcessHandle,
    /*
     * Create and initialize thread
     */
-   Status = ObCreateObject(ThreadHandle,
+   Status = ObRosCreateObject(ThreadHandle,
                           DesiredAccess,
                           ThreadAttributes,
                           PsThreadType,
@@ -397,18 +425,26 @@ PsInitializeThread(HANDLE ProcessHandle,
    
    KeAcquireSpinLock(&PiThreadListLock, &oldIrql);
    InsertTailList(&PiThreadListHead, &Thread->Tcb.ThreadListEntry);
+#ifndef LIBCAPTIVE
+   for (i = 0; i < PiThreadNotifyRoutineCount; i++)
+   {
+      NotifyRoutine[i] = PiThreadNotifyRoutine[i];
+   }
+   NotifyRoutineCount = PiThreadNotifyRoutineCount;
+#endif /* LIBCAPTIVE */
    KeReleaseSpinLock(&PiThreadListLock, oldIrql);
 
    Thread->Tcb.BasePriority = Thread->ThreadsProcess->Pcb.BasePriority;
    Thread->Tcb.Priority = Thread->Tcb.BasePriority;
 
 #ifndef LIBCAPTIVE
-  for (i = 0; i < PiThreadNotifyRoutineCount; i++)
-    {
-      PiThreadNotifyRoutine[i](Thread->Cid.UniqueProcess,
+  for (i = 0; i < NotifyRoutineCount; i++)
+  {
+      //must be called below DISPATCH_LVL
+      NotifyRoutine[i](Thread->Cid.UniqueProcess,
                               Thread->Cid.UniqueThread,
                               TRUE);
-    }
+  }
 #endif /* LIBCAPTIVE */
 
   return(STATUS_SUCCESS);
@@ -445,7 +481,7 @@ PsCreateTeb(HANDLE ProcessHandle,
        if (!NT_SUCCESS(Status))
          {
             CPRINT("NtQueryVirtualMemory (Status %x)\n", Status);
-            KeBugCheck(0);
+            KEBUGCHECK(0);
          }
        /* FIXME: Race between this and the above check */
        if (Info.State == MEM_FREE)
@@ -629,10 +665,10 @@ NtCreateThread(PHANDLE ThreadHandle,
    * routine.
    */
   LdrInitApc = ExAllocatePool(NonPagedPool, sizeof(KAPC));
-  KeInitializeApc(LdrInitApc, &Thread->Tcb, 0, LdrInitApcKernelRoutine,
+  KeInitializeApc(LdrInitApc, &Thread->Tcb, OriginalApcEnvironment, LdrInitApcKernelRoutine,
                  LdrInitApcRundownRoutine, LdrpGetSystemDllEntryPoint(), 
                  UserMode, NULL);
-  KeInsertQueueApc(LdrInitApc, NULL, NULL, UserMode);
+  KeInsertQueueApc(LdrInitApc, NULL, NULL, IO_NO_INCREMENT);
 
   /*
    * Start the thread running and force it to execute the APC(s) we just
@@ -646,6 +682,9 @@ NtCreateThread(PHANDLE ThreadHandle,
 }
 
 
+/*
+ * @implemented
+ */
 NTSTATUS STDCALL
 PsCreateSystemThread(PHANDLE ThreadHandle,
                     ACCESS_MASK DesiredAccess,
@@ -706,14 +745,24 @@ PsCreateSystemThread(PHANDLE ThreadHandle,
 }
 
 
+/*
+ * @implemented
+ */
 NTSTATUS STDCALL
 PsSetCreateThreadNotifyRoutine(IN PCREATE_THREAD_NOTIFY_ROUTINE NotifyRoutine)
 {
+  KIRQL oldIrql;
+
+  KeAcquireSpinLock(&PiThreadListLock, &oldIrql);
   if (PiThreadNotifyRoutineCount >= MAX_THREAD_NOTIFY_ROUTINE_COUNT)
+  {
+    KeReleaseSpinLock(&PiThreadListLock, oldIrql);
     return(STATUS_INSUFFICIENT_RESOURCES);
+  }
 
   PiThreadNotifyRoutine[PiThreadNotifyRoutineCount] = NotifyRoutine;
   PiThreadNotifyRoutineCount++;
+  KeReleaseSpinLock(&PiThreadListLock, oldIrql);
 
   return(STATUS_SUCCESS);
 }