-/* $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
/* INCLUDES ****************************************************************/
+#include <limits.h>
+
#define NTOS_MODE_KERNEL
#include <ntos.h>
#include <internal/ke.h>
PACCESS_TOKEN Token;
SECURITY_IMPERSONATION_LEVEL ImpersonationLevel;
NTSTATUS Status;
-
+
if (TokenHandle != NULL)
{
Status = ObReferenceObjectByHandle(TokenHandle,
Token = NULL;
ImpersonationLevel = 0;
}
-
+
PsImpersonateClient(Thread,
Token,
0,
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,
{
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,
NTSTATUS Status;
KIRQL oldIrql;
PEPROCESS Process;
- ULONG i;
- ULONG NotifyRoutineCount;
- PCREATE_THREAD_NOTIFY_ROUTINE NotifyRoutine[MAX_THREAD_NOTIFY_ROUTINE_COUNT];
/*
* Reference process
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);
}
}
}
- TebBase = TebBase - TebSize;
+ TebBase = (char*)TebBase - TebSize;
}
DPRINT ("TebBase %p TebSize %lu\n", TebBase, TebSize);
return Status;
}
+
VOID STDCALL
LdrInitApcRundownRoutine(PKAPC Apc)
{
ExFreePool(Apc);
}
+
VOID STDCALL
LdrInitApcKernelRoutine(PKAPC Apc,
PKNORMAL_ROUTINE* NormalRoutine,
ExFreePool(Apc);
}
+
NTSTATUS STDCALL
NtCreateThread(PHANDLE ThreadHandle,
ACCESS_MASK DesiredAccess,
}
+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);
}