From 03d4c9af396d80454d7b794d7df61773a00b2b67 Mon Sep 17 00:00:00 2001 From: Alex Ionescu Date: Sun, 16 Jul 2006 17:19:21 +0000 Subject: [PATCH] - 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 --- reactos/include/ndk/pstypes.h | 35 ++++++++++++++++++++++--- reactos/ntoskrnl/ps/thread.c | 49 +++++++++++++++++++++++++---------- 2 files changed, 67 insertions(+), 17 deletions(-) diff --git a/reactos/include/ndk/pstypes.h b/reactos/include/ndk/pstypes.h index 954e1c5ad2a..7b0e2fcfcf1 100644 --- a/reactos/include/ndk/pstypes.h +++ b/reactos/include/ndk/pstypes.h @@ -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 diff --git a/reactos/ntoskrnl/ps/thread.c b/reactos/ntoskrnl/ps/thread.c index 06484df7681..66ead43b86d 100644 --- a/reactos/ntoskrnl/ps/thread.c +++ b/reactos/ntoskrnl/ps/thread.c @@ -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);