Initialize LPC-related fields in ETHREAD.
[reactos.git] / reactos / ntoskrnl / ps / create.c
index 846dc16..afca150 100644 (file)
@@ -1,4 +1,4 @@
-/* $Id: create.c,v 1.67 2003/09/25 20:08:36 ekohl Exp $
+/* $Id: create.c,v 1.73 2004/03/24 22:00:39 ea Exp $
  *
  * COPYRIGHT:              See COPYING in the top level directory
  * PROJECT:                ReactOS kernel
@@ -21,6 +21,8 @@
 
 /* INCLUDES ****************************************************************/
 
+#include <limits.h>
+
 #define NTOS_MODE_KERNEL
 #include <ntos.h>
 #include <internal/ke.h>
@@ -58,7 +60,7 @@ PsAssignImpersonationToken(PETHREAD Thread,
    PACCESS_TOKEN Token;
    SECURITY_IMPERSONATION_LEVEL ImpersonationLevel;
    NTSTATUS Status;
-   
+
    if (TokenHandle != NULL)
      {
        Status = ObReferenceObjectByHandle(TokenHandle,
@@ -78,7 +80,7 @@ PsAssignImpersonationToken(PETHREAD Thread,
        Token = NULL;
        ImpersonationLevel = 0;
      }
-   
+
    PsImpersonateClient(Thread,
                       Token,
                       0,
@@ -91,152 +93,162 @@ PsAssignImpersonationToken(PETHREAD Thread,
    return(STATUS_SUCCESS);
 }
 
+
 /*
  * @implemented
  */
 VOID STDCALL
-PsRevertToSelf(VOID)
+PsRevertToSelf (VOID)
 {
-   PETHREAD Thread;
+  PETHREAD Thread;
 
-   Thread = PsGetCurrentThread();
+  Thread = PsGetCurrentThread ();
 
-   if (Thread->ActiveImpersonationInfo != 0)
-     {
-       ObDereferenceObject(Thread->ImpersonationInfo->Token);
-       Thread->ActiveImpersonationInfo = 0;
-     }
+  if (Thread->ActiveImpersonationInfo == TRUE)
+    {
+      ObDereferenceObject (Thread->ImpersonationInfo->Token);
+      Thread->ActiveImpersonationInfo = FALSE;
+    }
 }
 
+
 /*
  * @implemented
  */
 VOID STDCALL
-PsImpersonateClient(PETHREAD Thread,
-                   PACCESS_TOKEN Token,
-                   UCHAR b,
-                   UCHAR c,
-                   SECURITY_IMPERSONATION_LEVEL Level)
+PsImpersonateClient (IN PETHREAD Thread,
+                    IN PACCESS_TOKEN Token,
+                    IN BOOLEAN CopyOnOpen,
+                    IN BOOLEAN EffectiveOnly,
+                    IN SECURITY_IMPERSONATION_LEVEL ImpersonationLevel)
 {
-   if (Token == 0)
-     {
-       if (Thread->ActiveImpersonationInfo != 0)
-         {
-            Thread->ActiveImpersonationInfo = 0;
-            if (Thread->ImpersonationInfo->Token != NULL)
-              {
-                 ObDereferenceObject(Thread->ImpersonationInfo->Token);
-              }
-         }
-       return;
-     }
-   if (Thread->ActiveImpersonationInfo == 0 ||
-       Thread->ImpersonationInfo == NULL)
-     {
-       Thread->ImpersonationInfo = ExAllocatePool(NonPagedPool,
-                                          sizeof(PS_IMPERSONATION_INFO));      
-     }
-   Thread->ImpersonationInfo->Level = Level;
-   Thread->ImpersonationInfo->Unknown2 = c;
-   Thread->ImpersonationInfo->Unknown1 = b;
-   Thread->ImpersonationInfo->Token = Token;
-   ObReferenceObjectByPointer(Token,
+  if (Token == NULL)
+    {
+      if (Thread->ActiveImpersonationInfo == TRUE)
+       {
+         Thread->ActiveImpersonationInfo = FALSE;
+         if (Thread->ImpersonationInfo->Token != NULL)
+           {
+             ObDereferenceObject (Thread->ImpersonationInfo->Token);
+           }
+       }
+      return;
+    }
+
+  if (Thread->ImpersonationInfo == NULL)
+    {
+      Thread->ImpersonationInfo = ExAllocatePool (NonPagedPool,
+                                                 sizeof(PS_IMPERSONATION_INFO));
+    }
+
+  Thread->ImpersonationInfo->Level = ImpersonationLevel;
+  Thread->ImpersonationInfo->CopyOnOpen = CopyOnOpen;
+  Thread->ImpersonationInfo->EffectiveOnly = EffectiveOnly;
+  Thread->ImpersonationInfo->Token = Token;
+  ObReferenceObjectByPointer (Token,
                              0,
                              SepTokenObjectType,
                              KernelMode);
-   Thread->ActiveImpersonationInfo = 1;
+  Thread->ActiveImpersonationInfo = TRUE;
 }
 
+
 PACCESS_TOKEN
 PsReferenceEffectiveToken(PETHREAD Thread,
                          PTOKEN_TYPE TokenType,
-                         PUCHAR b,
+                         PBOOLEAN EffectiveOnly,
                          PSECURITY_IMPERSONATION_LEVEL Level)
 {
    PEPROCESS Process;
    PACCESS_TOKEN Token;
    
-   if (Thread->ActiveImpersonationInfo == 0)
+   if (Thread->ActiveImpersonationInfo == FALSE)
      {
        Process = Thread->ThreadsProcess;
        *TokenType = TokenPrimary;
-       *b = 0;
+       *EffectiveOnly = FALSE;
        Token = Process->Token;
      }
    else
      {
        Token = Thread->ImpersonationInfo->Token;
        *TokenType = TokenImpersonation;
-       *b = Thread->ImpersonationInfo->Unknown2;
-       *Level = Thread->ImpersonationInfo->Level;      
+       *EffectiveOnly = Thread->ImpersonationInfo->EffectiveOnly;
+       *Level = Thread->ImpersonationInfo->Level;
      }
    return(Token);
 }
 
+
 NTSTATUS STDCALL
 NtImpersonateThread(IN HANDLE ThreadHandle,
                    IN HANDLE ThreadToImpersonateHandle,
                    IN PSECURITY_QUALITY_OF_SERVICE SecurityQualityOfService)
 {
-   PETHREAD Thread;
-   PETHREAD ThreadToImpersonate;
-   NTSTATUS Status;
-   SECURITY_CLIENT_CONTEXT ClientContext;
-   
-   Status = ObReferenceObjectByHandle(ThreadHandle,
+  SECURITY_CLIENT_CONTEXT ClientContext;
+  PETHREAD Thread;
+  PETHREAD ThreadToImpersonate;
+  NTSTATUS Status;
+
+  Status = ObReferenceObjectByHandle (ThreadHandle,
                                      0,
                                      PsThreadType,
                                      UserMode,
                                      (PVOID*)&Thread,
                                      NULL);
-   if (!NT_SUCCESS(Status))
-     {
-       return(Status);
-     }
-   
-   Status = ObReferenceObjectByHandle(ThreadToImpersonateHandle,
+  if (!NT_SUCCESS (Status))
+    {
+      return Status;
+    }
+
+  Status = ObReferenceObjectByHandle (ThreadToImpersonateHandle,
                                      0,
                                      PsThreadType,
                                      UserMode,
                                      (PVOID*)&ThreadToImpersonate,
                                      NULL);
-   if (!NT_SUCCESS(Status))
-     {
-       ObDereferenceObject(Thread);
-       return(Status);
-     }
-   
-   Status = SeCreateClientSecurity(ThreadToImpersonate,
+  if (!NT_SUCCESS(Status))
+    {
+      ObDereferenceObject (Thread);
+      return Status;
+    }
+
+  Status = SeCreateClientSecurity (ThreadToImpersonate,
                                   SecurityQualityOfService,
                                   0,
                                   &ClientContext);
-   if (!NT_SUCCESS(Status))
-     {
-       ObDereferenceObject(Thread);
-       ObDereferenceObject(ThreadToImpersonate);
-       return(Status);
-     }
-   
-   SeImpersonateClient(&ClientContext, Thread);
-   if (ClientContext.Token != NULL)
-     {
-       ObDereferenceObject(ClientContext.Token);
+  if (!NT_SUCCESS(Status))
+    {
+      ObDereferenceObject (ThreadToImpersonate);
+      ObDereferenceObject (Thread);
+      return Status;
      }
-   return(STATUS_SUCCESS);
+
+  SeImpersonateClient (&ClientContext,
+                      Thread);
+  if (ClientContext.Token != NULL)
+    {
+      ObDereferenceObject (ClientContext.Token);
+    }
+
+  ObDereferenceObject (ThreadToImpersonate);
+  ObDereferenceObject (Thread);
+
+  return STATUS_SUCCESS;
 }
 
+
 NTSTATUS STDCALL
-NtOpenThreadToken(IN   HANDLE          ThreadHandle,  
-                 IN    ACCESS_MASK     DesiredAccess,  
-                 IN    BOOLEAN         OpenAsSelf,     
-                 OUT   PHANDLE         TokenHandle)
+NtOpenThreadToken (IN HANDLE ThreadHandle,
+                  IN ACCESS_MASK DesiredAccess,
+                  IN BOOLEAN OpenAsSelf,
+                  OUT PHANDLE TokenHandle)
 {
-#if 0
-   PETHREAD Thread;
-   NTSTATUS Status;
-   PACCESS_TOKEN Token;
-   
-   Status = ObReferenceObjectByHandle(ThreadHandle,
+  PACCESS_TOKEN Token;
+  PETHREAD Thread;
+  NTSTATUS Status;
+
+  Status = ObReferenceObjectByHandle (ThreadHandle,
                                      0,
                                      PsThreadType,
                                      UserMode,
@@ -246,84 +258,96 @@ NtOpenThreadToken(IN      HANDLE          ThreadHandle,
      {
        return(Status);
      }
-   
-   Token = PsReferencePrimaryToken(Thread->ThreadsProcess);
-   SepCreateImpersonationTokenDacl(Token);
-#endif
-   return(STATUS_UNSUCCESSFUL);
+
+  if (OpenAsSelf)
+    {
+      if (Thread->ActiveImpersonationInfo == FALSE)
+       {
+         ObDereferenceObject (Thread);
+         return STATUS_NO_TOKEN;
+       }
+
+      Token = Thread->ImpersonationInfo->Token;
+    }
+  else
+    {
+      Token = Thread->ThreadsProcess->Token;
+    }
+
+  if (Token == NULL)
+    {
+      ObDereferenceObject (Thread);
+      return STATUS_NO_TOKEN;
+    }
+
+  Status = ObCreateHandle (PsGetCurrentProcess(),
+                          Token,
+                          DesiredAccess,
+                          FALSE,
+                          TokenHandle);
+
+  ObDereferenceObject (Thread);
+
+  return Status;
 }
 
+
 /*
  * @implemented
  */
-PACCESS_TOKEN STDCALL 
-PsReferenceImpersonationToken(PETHREAD Thread,
-                             PULONG Unknown1,
-                             PULONG Unknown2,
-                             SECURITY_IMPERSONATION_LEVEL* Level)
+PACCESS_TOKEN STDCALL
+PsReferenceImpersonationToken(IN PETHREAD Thread,
+                             OUT PBOOLEAN CopyOnOpen,
+                             OUT PBOOLEAN EffectiveOnly,
+                             OUT PSECURITY_IMPERSONATION_LEVEL ImpersonationLevel)
 {
-   if (Thread->ActiveImpersonationInfo == 0)
-     {
-       return(NULL);
-     }
-   
-   *Level = Thread->ImpersonationInfo->Level;
-   *Unknown1 = Thread->ImpersonationInfo->Unknown1;
-   *Unknown2 = Thread->ImpersonationInfo->Unknown2;
-   ObReferenceObjectByPointer(Thread->ImpersonationInfo->Token,
+  if (Thread->ActiveImpersonationInfo == FALSE)
+    {
+      return NULL;
+    }
+
+  *ImpersonationLevel = Thread->ImpersonationInfo->Level;
+  *CopyOnOpen = Thread->ImpersonationInfo->CopyOnOpen;
+  *EffectiveOnly = Thread->ImpersonationInfo->EffectiveOnly;
+  ObReferenceObjectByPointer (Thread->ImpersonationInfo->Token,
                              TOKEN_ALL_ACCESS,
                              SepTokenObjectType,
                              KernelMode);
-   return(Thread->ImpersonationInfo->Token);
+
+  return Thread->ImpersonationInfo->Token;
 }
 
+
 VOID
 PiBeforeBeginThread(CONTEXT c)
 {
    KeLowerIrql(PASSIVE_LEVEL);
 }
 
+
 VOID STDCALL
 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++)
-  {
-     NotifyRoutine[i] = PiThreadNotifyRoutine[i];
-  }
-  NotifyRoutineCount = PiThreadNotifyRoutineCount;
   PiNrThreads--;
   RemoveEntryList(&Thread->Tcb.ThreadListEntry);
   KeReleaseSpinLock(&PiThreadListLock, oldIrql);
 
-  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");
 }
 
+
 NTSTATUS
 PsInitializeThread(HANDLE ProcessHandle,
                   PETHREAD* ThreadPtr,
@@ -336,9 +360,6 @@ PsInitializeThread(HANDLE ProcessHandle,
    NTSTATUS Status;
    KIRQL oldIrql;
    PEPROCESS Process;
-   ULONG i;
-   ULONG NotifyRoutineCount;
-   PCREATE_THREAD_NOTIFY_ROUTINE NotifyRoutine[MAX_THREAD_NOTIFY_ROUTINE_COUNT];
 
    /*
     * Reference process
@@ -421,25 +442,22 @@ PsInitializeThread(HANDLE ProcessHandle,
    
    KeAcquireSpinLock(&PiThreadListLock, &oldIrql);
    InsertTailList(&PiThreadListHead, &Thread->Tcb.ThreadListEntry);
-   for (i = 0; i < PiThreadNotifyRoutineCount; i++)
-   {
-      NotifyRoutine[i] = PiThreadNotifyRoutine[i];
-   }
-   NotifyRoutineCount = PiThreadNotifyRoutineCount;
    KeReleaseSpinLock(&PiThreadListLock, oldIrql);
 
-   Thread->Tcb.BasePriority = Thread->ThreadsProcess->Pcb.BasePriority;
+   Thread->Tcb.BasePriority = (CHAR)Thread->ThreadsProcess->Pcb.BasePriority;
    Thread->Tcb.Priority = Thread->Tcb.BasePriority;
 
-  for (i = 0; i < NotifyRoutineCount; i++)
-  {
-      //must be called below DISPATCH_LVL
-      NotifyRoutine[i](Thread->Cid.UniqueProcess,
-                              Thread->Cid.UniqueThread,
-                              TRUE);
-  }
+   /*
+    * Local Procedure Call facility (LPC)
+    */
+   KeInitializeSemaphore  (& Thread->LpcReplySemaphore, 0, LONG_MAX);
+   Thread->LpcReplyMessage = NULL;
+   Thread->LpcReplyMessageId = 0; /* not valid */
+   /* Thread->LpcReceiveMessageId = 0; */
+   Thread->LpcExitThreadCalled = FALSE;
+   Thread->LpcReceivedMsgIdValid = FALSE;
 
-  return(STATUS_SUCCESS);
+   return(STATUS_SUCCESS);
 }
 
 
@@ -490,7 +508,7 @@ PsCreateTeb(HANDLE ProcessHandle,
               }
          }
             
-       TebBase = TebBase - TebSize;
+       TebBase = (char*)TebBase - TebSize;
      }
 
    DPRINT ("TebBase %p TebSize %lu\n", TebBase, TebSize);
@@ -564,12 +582,14 @@ PsCreateTeb(HANDLE ProcessHandle,
    return Status;
 }
 
+
 VOID STDCALL
 LdrInitApcRundownRoutine(PKAPC Apc)
 {
    ExFreePool(Apc);
 }
 
+
 VOID STDCALL
 LdrInitApcKernelRoutine(PKAPC Apc,
                        PKNORMAL_ROUTINE* NormalRoutine,
@@ -580,6 +600,7 @@ LdrInitApcKernelRoutine(PKAPC Apc,
   ExFreePool(Apc);
 }
 
+
 NTSTATUS STDCALL
 NtCreateThread(PHANDLE ThreadHandle,
               ACCESS_MASK DesiredAccess,
@@ -736,24 +757,33 @@ PsCreateSystemThread(PHANDLE ThreadHandle,
 }
 
 
+VOID STDCALL
+PspRunCreateThreadNotifyRoutines(PETHREAD CurrentThread,
+                                BOOLEAN Create)
+{
+  ULONG i;
+  CLIENT_ID Cid = CurrentThread->Cid;
+
+  for (i = 0; i < PiThreadNotifyRoutineCount; i++)
+    {
+      PiThreadNotifyRoutine[i](Cid.UniqueProcess, Cid.UniqueThread, Create);
+    }
+}
+
+
 /*
  * @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);
-  }
+    {
+      return(STATUS_INSUFFICIENT_RESOURCES);
+    }
 
   PiThreadNotifyRoutine[PiThreadNotifyRoutineCount] = NotifyRoutine;
   PiThreadNotifyRoutineCount++;
-  KeReleaseSpinLock(&PiThreadListLock, oldIrql);
 
   return(STATUS_SUCCESS);
 }