-/* $Id: create.c,v 1.35 2001/07/12 17:21:05 ekohl Exp $
+/* $Id: create.c,v 1.46 2002/03/05 00:20:54 ekohl Exp $
*
* COPYRIGHT: See COPYING in the top level directory
* PROJECT: ReactOS kernel
#include <internal/ke.h>
#include <internal/ob.h>
#include <internal/ps.h>
-#include <internal/ob.h>
+#include <internal/se.h>
#include <internal/id.h>
#include <internal/dbg.h>
extern LIST_ENTRY PiThreadListHead;
+#define MAX_THREAD_NOTIFY_ROUTINE_COUNT 8
+
+static ULONG PiThreadNotifyRoutineCount = 0;
+static PCREATE_THREAD_NOTIFY_ROUTINE
+PiThreadNotifyRoutine[MAX_THREAD_NOTIFY_ROUTINE_COUNT];
+
/* FUNCTIONS ***************************************************************/
NTSTATUS STDCALL
{
Status = ObReferenceObjectByHandle(TokenHandle,
0,
- SeTokenType,
+ SepTokenObjectType,
UserMode,
(PVOID*)&Token,
NULL);
return(STATUS_SUCCESS);
}
-VOID STDCALL
-PsRevertToSelf(PETHREAD Thread)
+VOID STDCALL
+PsRevertToSelf(VOID)
{
+ PETHREAD Thread;
+
+ Thread = PsGetCurrentThread();
+
if (Thread->ActiveImpersonationInfo != 0)
{
- Thread->ActiveImpersonationInfo = 0;
ObDereferenceObject(Thread->ImpersonationInfo->Token);
+ Thread->ActiveImpersonationInfo = 0;
}
}
-VOID STDCALL
+VOID STDCALL
PsImpersonateClient(PETHREAD Thread,
PACCESS_TOKEN Token,
UCHAR b,
Thread->ImpersonationInfo->Token = Token;
ObReferenceObjectByPointer(Token,
0,
- SeTokenType,
+ SepTokenObjectType,
KernelMode);
Thread->ActiveImpersonationInfo = 1;
}
-PACCESS_TOKEN
+PACCESS_TOKEN
PsReferenceEffectiveToken(PETHREAD Thread,
PTOKEN_TYPE TokenType,
PUCHAR b,
return(Token);
}
-NTSTATUS STDCALL
-NtImpersonateThread (IN HANDLE ThreadHandle,
- IN HANDLE ThreadToImpersonateHandle,
- IN PSECURITY_QUALITY_OF_SERVICE
- SecurityQualityOfService)
+NTSTATUS STDCALL
+NtImpersonateThread(IN HANDLE ThreadHandle,
+ IN HANDLE ThreadToImpersonateHandle,
+ IN PSECURITY_QUALITY_OF_SERVICE SecurityQualityOfService)
{
PETHREAD Thread;
PETHREAD ThreadToImpersonate;
NTSTATUS Status;
- SE_SOME_STRUCT2 b;
+ SECURITY_CLIENT_CONTEXT ClientContext;
Status = ObReferenceObjectByHandle(ThreadHandle,
0,
Status = SeCreateClientSecurity(ThreadToImpersonate,
SecurityQualityOfService,
0,
- &b);
+ &ClientContext);
if (!NT_SUCCESS(Status))
{
ObDereferenceObject(Thread);
return(Status);
}
- SeImpersonateClient(&b, Thread);
- if (b.Token != NULL)
+ SeImpersonateClient(&ClientContext, Thread);
+ if (ClientContext.Token != NULL)
{
- ObDereferenceObject(b.Token);
+ ObDereferenceObject(ClientContext.Token);
}
return(STATUS_SUCCESS);
}
-NTSTATUS STDCALL
+NTSTATUS STDCALL
NtOpenThreadToken(IN HANDLE ThreadHandle,
IN ACCESS_MASK DesiredAccess,
IN BOOLEAN OpenAsSelf,
*Unknown2 = Thread->ImpersonationInfo->Unknown2;
ObReferenceObjectByPointer(Thread->ImpersonationInfo->Token,
TOKEN_ALL_ACCESS,
- SeTokenType,
+ SepTokenObjectType,
KernelMode);
return(Thread->ImpersonationInfo->Token);
}
-VOID
-PiTimeoutThread(struct _KDPC *dpc,
- PVOID Context,
- PVOID arg1,
+VOID STDCALL
+PiTimeoutThread(struct _KDPC *dpc,
+ PVOID Context,
+ PVOID arg1,
PVOID arg2)
{
// wake up the thread, and tell it it timed out
KeRemoveAllWaitsThread((PETHREAD)Context, Status);
}
-VOID
+VOID
PiBeforeBeginThread(CONTEXT c)
{
DPRINT("PiBeforeBeginThread(Eip %x)\n", c.Eip);
}
#endif
-VOID PiDeleteThread(PVOID ObjectBody)
+VOID STDCALL
+PiDeleteThread(PVOID ObjectBody)
{
- KIRQL oldIrql;
-
- DPRINT("PiDeleteThread(ObjectBody %x)\n",ObjectBody);
-
- KeAcquireSpinLock(&PiThreadListLock, &oldIrql);
- DPRINT("Process %x(%d)\n", ((PETHREAD)ObjectBody)->ThreadsProcess,
- ObGetReferenceCount(((PETHREAD)ObjectBody)->ThreadsProcess));
- ObDereferenceObject(((PETHREAD)ObjectBody)->ThreadsProcess);
- ((PETHREAD)ObjectBody)->ThreadsProcess = NULL;
- PiNrThreads--;
- RemoveEntryList(&((PETHREAD)ObjectBody)->Tcb.ThreadListEntry);
- HalReleaseTask((PETHREAD)ObjectBody);
- KeReleaseSpinLock(&PiThreadListLock, oldIrql);
- DPRINT("PiDeleteThread() finished\n");
+ KIRQL oldIrql;
+ PETHREAD Thread;
+ ULONG i;
+
+ DPRINT("PiDeleteThread(ObjectBody %x)\n",ObjectBody);
+
+ KeAcquireSpinLock(&PiThreadListLock, &oldIrql);
+ Thread = (PETHREAD)ObjectBody;
+
+ for (i = 0; i < PiThreadNotifyRoutineCount; i++)
+ {
+ PiThreadNotifyRoutine[i](Thread->Cid.UniqueProcess,
+ Thread->Cid.UniqueThread,
+ FALSE);
+ }
+
+ DPRINT("Process %x(%d)\n",
+ Thread->ThreadsProcess,
+ ObGetObjectPointerCount(Thread->ThreadsProcess));
+ ObDereferenceObject(Thread->ThreadsProcess);
+ Thread->ThreadsProcess = NULL;
+ PiNrThreads--;
+ RemoveEntryList(&Thread->Tcb.ThreadListEntry);
+ KeReleaseThread(Thread);
+ KeReleaseSpinLock(&PiThreadListLock, oldIrql);
+ DPRINT("PiDeleteThread() finished\n");
}
-VOID PiCloseThread(PVOID ObjectBody, ULONG HandleCount)
+VOID STDCALL
+PiCloseThread(PVOID ObjectBody,
+ ULONG HandleCount)
{
DPRINT("PiCloseThread(ObjectBody %x)\n", ObjectBody);
- DPRINT("ObGetReferenceCount(ObjectBody) %d "
- "ObGetHandleCount(ObjectBody) %d\n",
- ObGetReferenceCount(ObjectBody),
- ObGetHandleCount(ObjectBody));
+ DPRINT("ObGetObjectPointerCount(ObjectBody) %d "
+ "ObGetObjectHandleCount(ObjectBody) %d\n",
+ ObGetObjectPointerCount(ObjectBody),
+ ObGetObjectHandleCount(ObjectBody));
}
NTSTATUS
NTSTATUS Status;
KIRQL oldIrql;
PEPROCESS Process;
+ ULONG i;
/*
* Reference process
Thread->Tcb.BasePriority = Thread->ThreadsProcess->Pcb.BasePriority;
Thread->Tcb.Priority = Thread->Tcb.BasePriority;
-
- return(STATUS_SUCCESS);
+
+ for (i = 0; i < PiThreadNotifyRoutineCount; i++)
+ {
+ PiThreadNotifyRoutine[i](Thread->Cid.UniqueProcess,
+ Thread->Cid.UniqueThread,
+ TRUE);
+ }
+
+ return(STATUS_SUCCESS);
}
static NTSTATUS
PsCreateTeb(HANDLE ProcessHandle,
- PNT_TEB *TebPtr,
+ PTEB *TebPtr,
PETHREAD Thread,
PINITIAL_TEB InitialTeb)
{
ULONG RegionSize;
ULONG TebSize;
PVOID TebBase;
- NT_TEB Teb;
+ TEB Teb;
ULONG ResultLength;
TebBase = (PVOID)0x7FFDE000;
&ResultLength);
if (!NT_SUCCESS(Status))
{
- DbgPrint("NtQueryVirtualMemory (Status %x)\n", Status);
+ CPRINT("NtQueryVirtualMemory (Status %x)\n", Status);
KeBugCheck(0);
}
/* FIXME: Race between this and the above check */
&TebBase,
0,
&TebSize,
- MEM_COMMIT,
+ MEM_RESERVE | MEM_COMMIT,
PAGE_READWRITE);
if (NT_SUCCESS(Status))
{
{
Teb.Tib.StackBase = InitialTeb->StackBase;
Teb.Tib.StackLimit = InitialTeb->StackLimit;
-
- /*
- * I don't know if this is really stored in a WNT-TEB,
- * but it's needed to free the thread stack. (Eric Kohl)
- */
- Teb.StackCommit = InitialTeb->StackCommit;
- Teb.StackCommitMax = InitialTeb->StackCommitMax;
- Teb.StackReserve = InitialTeb->StackReserve;
+ Teb.DeallocationStack = InitialTeb->StackAllocate;
}
-
/* more initialization */
Teb.Cid.UniqueThread = Thread->Cid.UniqueThread;
Teb.Cid.UniqueProcess = Thread->Cid.UniqueProcess;
Teb.CurrentLocale = PsDefaultThreadLocaleId;
- DPRINT("sizeof(NT_TEB) %x\n", sizeof(NT_TEB));
+ DPRINT("sizeof(TEB) %x\n", sizeof(TEB));
/* write TEB data into teb page */
Status = NtWriteVirtualMemory(ProcessHandle,
TebBase,
&Teb,
- sizeof(NT_TEB),
+ sizeof(TEB),
&ByteCount);
if (!NT_SUCCESS(Status))
if (TebPtr != NULL)
{
- *TebPtr = (PNT_TEB)TebBase;
+ *TebPtr = (PTEB)TebBase;
}
DPRINT("TEB allocated at %p\n", TebBase);
}
-NTSTATUS STDCALL
+NTSTATUS STDCALL
NtCreateThread (PHANDLE ThreadHandle,
ACCESS_MASK DesiredAccess,
POBJECT_ATTRIBUTES ObjectAttributes,
BOOLEAN CreateSuspended)
{
PETHREAD Thread;
- PNT_TEB TebBase;
+ PTEB TebBase;
NTSTATUS Status;
DPRINT("NtCreateThread(ThreadHandle %x, PCONTEXT %x)\n",
ThreadHandle,ThreadContext);
- Status = PsInitializeThread(ProcessHandle,&Thread,ThreadHandle,
- DesiredAccess,ObjectAttributes, FALSE);
+ Status = PsInitializeThread(ProcessHandle,
+ &Thread,
+ ThreadHandle,
+ DesiredAccess,
+ ObjectAttributes,
+ FALSE);
if (!NT_SUCCESS(Status))
{
return(Status);
}
-
-#if 0
- Status = NtWriteVirtualMemory(ProcessHandle,
- (PVOID)(((ULONG)ThreadContext->Esp) - 8),
- &ThreadContext->Eip,
- sizeof(ULONG),
- &Length);
- if (!NT_SUCCESS(Status))
- {
- DPRINT1("NtWriteVirtualMemory failed\n");
- KeBugCheck(0);
- }
- ThreadContext->Eip = LdrpGetSystemDllEntryPoint;
-#endif
- Status = Ke386InitThreadWithContext(&Thread->Tcb, ThreadContext);
+ Status = Ke386InitThreadWithContext(&Thread->Tcb,
+ ThreadContext);
if (!NT_SUCCESS(Status))
{
return(Status);
}
-
- Status = PsCreateTeb (ProcessHandle,
- &TebBase,
- Thread,
- InitialTeb);
+
+ Status = PsCreateTeb(ProcessHandle,
+ &TebBase,
+ Thread,
+ InitialTeb);
if (!NT_SUCCESS(Status))
{
return(Status);
}
-
+
/* Attention: TebBase is in user memory space */
Thread->Tcb.Teb = TebBase;
if (Client != NULL)
{
*Client=Thread->Cid;
- }
+ }
/*
* Maybe send a message to the process's debugger
}
-NTSTATUS STDCALL
+NTSTATUS STDCALL
PsCreateSystemThread(PHANDLE ThreadHandle,
ACCESS_MASK DesiredAccess,
POBJECT_ATTRIBUTES ObjectAttributes,
DPRINT("PsCreateSystemThread(ThreadHandle %x, ProcessHandle %x)\n",
ThreadHandle,ProcessHandle);
- Status = PsInitializeThread(ProcessHandle,&Thread,ThreadHandle,
- DesiredAccess,ObjectAttributes, FALSE);
+ Status = PsInitializeThread(ProcessHandle,
+ &Thread,
+ ThreadHandle,
+ DesiredAccess,
+ ObjectAttributes,
+ FALSE);
if (!NT_SUCCESS(Status))
{
return(Status);
}
Thread->StartAddress=StartRoutine;
- Status = Ke386InitThread(&Thread->Tcb, StartRoutine, StartContext);
+ Status = Ke386InitThread(&Thread->Tcb,
+ StartRoutine,
+ StartContext);
if (!NT_SUCCESS(Status))
{
return(Status);
if (ClientId!=NULL)
{
*ClientId=Thread->Cid;
- }
+ }
PsUnblockThread(Thread, NULL);
return(STATUS_SUCCESS);
}
+
+NTSTATUS STDCALL
+PsSetCreateThreadNotifyRoutine(IN PCREATE_THREAD_NOTIFY_ROUTINE NotifyRoutine)
+{
+ if (PiThreadNotifyRoutineCount >= MAX_THREAD_NOTIFY_ROUTINE_COUNT)
+ return(STATUS_INSUFFICIENT_RESOURCES);
+
+ PiThreadNotifyRoutine[PiThreadNotifyRoutineCount] = NotifyRoutine;
+ PiThreadNotifyRoutineCount++;
+
+ return(STATUS_SUCCESS);
+}
+
/* EOF */