- Added constants for all the ETHREAD flags so when we use Interlocked operations to edit them, a nice symbolic name is there isntead of a magic hex value.

- Fixed a bug in PspUserThreadStartup which was causing us to notify the debugger for system threads or hidden threads, instead of vice-versa.
- Documented cookie generation for Thomas.
- Threads were incorrectly created with KernelMode access instead of PreviousMode.
- Initialize the thread's rundown protection and use the process's.
- Handle failure when TEB = NULL.
- The LPC Semaphore has a limit of 1, not 0x7FFF.

svn path=/trunk/; revision=23085
This commit is contained in:
Alex Ionescu 2006-07-16 17:19:21 +00:00
parent 72185bb72b
commit 03d4c9af39
2 changed files with 67 additions and 17 deletions

View file

@ -97,9 +97,9 @@ extern NTSYSAPI POBJECT_TYPE PsProcessType;
#define PS_INHERIT_HANDLES 4
#define PS_UNKNOWN_VALUE 8
#define PS_ALL_FLAGS (PS_REQUEST_BREAKAWAY | \
PS_NO_DEBUG_INHERIT | \
PS_INHERIT_HANDLES | \
PS_UNKNOWN_VALUE)
PS_NO_DEBUG_INHERIT | \
PS_INHERIT_HANDLES | \
PS_UNKNOWN_VALUE)
//
// Process base priorities
@ -139,7 +139,6 @@ extern NTSYSAPI POBJECT_TYPE PsProcessType;
0xFFF)
#endif
//
// Job Access Types
//
@ -151,6 +150,34 @@ extern NTSYSAPI POBJECT_TYPE PsProcessType;
#define JOB_OBJECT_ALL_ACCESS (STANDARD_RIGHTS_REQUIRED | \
SYNCHRONIZE | \
31)
//
// Cross Thread Flags
//
#define CT_TERMINATED_BIT 0x1
#define CT_DEAD_THREAD_BIT 0x2
#define CT_HIDE_FROM_DEBUGGER_BIT 0x4
#define CT_ACTIVE_IMPERSTIONATION_INFO_BIT 0x8
#define CT_SYSTEM_THREAD_BIT 0x10
#define CT_HARD_ERRORS_ARE_DISABLED_BIT 0x20
#define CT_BREAK_ON_TERMINATION_BIT 0x40
#define CT_SKIP_CREATION_MSG_BIT 0x80
#define CT_SKIP_TERMINATION_MSG_BIT 0x100
//
// Same Thread Passive Flags
//
#define STP_ACTIVE_EX_WORKER_BIT 0x1
#define STP_EX_WORKER_CAN_WAIT_USER_BIT 0x2
#define STP_MEMORY_MAKER_BIT 0x4
#define STP_KEYED_EVENT_IN_USE_BIT 0x8
//
// Same Thread APC Flags
//
#define STA_LPC_RECEIVED_MSG_ID_VALID_BIT 0x1
#define STA_LPC_EXIT_THREAD_CALLED_BIT 0x2
#define STA_ADDRESS_SPACE_OWNER_BIT 0x4
#endif
#ifdef NTOS_MODE_USER

View file

@ -4,7 +4,7 @@
* FILE: ntoskrnl/ps/thread.c
* PURPOSE: Process Manager: Thread Management
* PROGRAMMERS: Alex Ionescu (alex.ionescu@reactos.org)
* Thomas Weidenmueller (w3seek@reactos.org
* Thomas Weidenmueller (w3seek@reactos.org)
*/
/*
@ -66,9 +66,9 @@ PspUserThreadStartup(PKSTART_ROUTINE StartRoutine,
}
/* Check if this is a system thread, or if we're hiding */
if ((Thread->SystemThread) || (Thread->HideFromDebugger))
{
/* Notify the debugger */
if (!(Thread->SystemThread) && !(Thread->HideFromDebugger))
{
/* We're not, so notify the debugger */
DbgkCreateThread(StartContext);
}
@ -90,9 +90,9 @@ PspUserThreadStartup(PKSTART_ROUTINE StartRoutine,
sizeof(KTRAP_FRAME) -
sizeof(FX_SAVE_AREA)),
PspSystemDllEntryPoint,
NULL,
NULL,
PspSystemDllBase,
NULL);
NULL);
/* Lower it back to passive */
KeLowerIrql(PASSIVE_LEVEL);
@ -100,13 +100,21 @@ PspUserThreadStartup(PKSTART_ROUTINE StartRoutine,
else
{
/* We're dead, kill us now */
PspTerminateThreadByPointer(Thread, STATUS_THREAD_IS_TERMINATING, TRUE);
PspTerminateThreadByPointer(Thread,
STATUS_THREAD_IS_TERMINATING,
TRUE);
}
/* Do we have a cookie set yet? */
if (!SharedUserData->Cookie)
{
/* FIXME: Generate cookie */
/*
* FIXME: Generate cookie
* Formula (roughly): Per-CPU Page Fault ^ Per-CPU Interrupt Time ^
* Global System Time ^ Stack Address of where
* the LARGE_INTEGER containing the Global System
* Time is.
*/
}
}
@ -202,7 +210,7 @@ PspCreateThread(OUT PHANDLE ThreadHandle,
Status = ObCreateObject(PreviousMode,
PsThreadType,
ObjectAttributes,
KernelMode,
PreviousMode,
NULL,
sizeof(ETHREAD),
0,
@ -218,6 +226,9 @@ PspCreateThread(OUT PHANDLE ThreadHandle,
/* Zero the Object entirely */
RtlZeroMemory(Thread, sizeof(ETHREAD));
/* Initialize rundown protection */
ExInitializeRundownProtection(&Thread->RundownProtect);
/* Set the Process CID */
Thread->ThreadsProcess = Process;
Thread->Cid.UniqueProcess = Process->UniqueProcessId;
@ -228,8 +239,7 @@ PspCreateThread(OUT PHANDLE ThreadHandle,
Thread->Cid.UniqueThread = ExCreateHandle(PspCidTable, &CidEntry);
if (!Thread->Cid.UniqueThread)
{
/* We couldn't create the CID, dereference everything and fail */
ObDereferenceObject(Process);
/* We couldn't create the CID, dereference the thread and fail */
ObDereferenceObject(Thread);
return STATUS_INSUFFICIENT_RESOURCES;
}
@ -238,7 +248,7 @@ PspCreateThread(OUT PHANDLE ThreadHandle,
Thread->ReadClusterSize = MmReadClusterSize;
/* Initialize the LPC Reply Semaphore */
KeInitializeSemaphore(&Thread->LpcReplySemaphore, 0, MAXLONG);
KeInitializeSemaphore(&Thread->LpcReplySemaphore, 0, 1);
/* Initialize the list heads and locks */
InitializeListHead(&Thread->LpcReplyChain);
@ -247,6 +257,9 @@ PspCreateThread(OUT PHANDLE ThreadHandle,
InitializeListHead(&Thread->ActiveTimerListHead);
KeInitializeSpinLock(&Thread->ActiveTimerListLock);
/* Acquire rundown protection */
ExAcquireRundownProtection(&Process->RundownProtect);
/* Allocate Stack for non-GUI Thread */
KernelStack = (ULONG_PTR)MmCreateKernelStack(FALSE) + KERNEL_STACK_SIZE;
@ -255,6 +268,13 @@ PspCreateThread(OUT PHANDLE ThreadHandle,
{
/* User-mode Thread, create Teb */
TebBase = MmCreateTeb(Process, &Thread->Cid, InitialTeb);
if (!TebBase)
{
/* Failed to create the TEB. Release rundown and dereference */
ExReleaseRundownProtection(&Process->RundownProtect);
ObDereferenceObject(Thread);
return STATUS_INSUFFICIENT_RESOURCES;
}
/* Set the Start Addresses */
Thread->StartAddress = (PVOID)ThreadContext->Eip;
@ -274,7 +294,7 @@ PspCreateThread(OUT PHANDLE ThreadHandle,
{
/* System Thread */
Thread->StartAddress = StartRoutine;
InterlockedOr((PLONG)&Thread->CrossThreadFlags, 0x10);
InterlockedOr((PLONG)&Thread->CrossThreadFlags, CT_SYSTEM_THREAD_BIT);
/* Let the kernel intialize the Thread */
KeInitializeThread(&Process->Pcb,
@ -295,6 +315,9 @@ PspCreateThread(OUT PHANDLE ThreadHandle,
InsertTailList(&Process->ThreadListHead, &Thread->ThreadListEntry);
Process->ActiveThreads++;
/* Release rundown */
ExReleaseRundownProtection(&Process->RundownProtect);
/* Notify WMI */
//WmiTraceProcess(Process, TRUE);
//WmiTraceThread(Thread, InitialTeb, TRUE);