implement user mode catchable exceptions, refactor system status codes to use NTLSTATUS_ prefix, update build scripts to use shared literal macros for linker arguments, update named queue lifetime cleanup to include KeNamedQueueUnpublishHandle.
This commit is contained in:
1 parent
1f5477cf66
commit
b7fcfce6f7
140 files changed
+7649
-3943
No files matched your search
+41
-33
@@ -41,7 +41,7 @@ static void KiThreadDestroy(OBJECT* obj) {
|
||||
// A wait that uses auxiliary stack wait blocks must be removed before the
|
||||
// kernel stack is released. A terminated thread may never return to the
|
||||
// wait syscall to run normal cleanup.
|
||||
KeRundownThreadWait(thread, STATUS_ALERTED);
|
||||
KeRundownThreadWait(thread, NTLSTATUS_ALERTED);
|
||||
|
||||
KiRundownApcState(thread);
|
||||
|
||||
@@ -94,11 +94,11 @@ static void KiThreadDestroy(OBJECT* obj) {
|
||||
|
||||
__declspec(dllexport) KSTATUS KeCreateThread(PROCESS* owner, uintptr_t entry, uintptr_t arg,
|
||||
THREAD_PRIORITY priority, THREAD** out) {
|
||||
if (!owner || !out) return STATUS_INVALID_PARAMETER;
|
||||
if (priority >= PriorityCount) return STATUS_INVALID_PARAMETER;
|
||||
if (!owner || !out) return NTLSTATUS_INVALID_PARAMETER;
|
||||
if (priority >= PriorityCount) return NTLSTATUS_INVALID_PARAMETER;
|
||||
|
||||
THREAD* thread = (THREAD *)ObAllocateObject(ObjectTypeThread, sizeof(THREAD));
|
||||
if (!thread) return STATUS_NO_MEMORY;
|
||||
if (!thread) return NTLSTATUS_NO_MEMORY;
|
||||
|
||||
thread->Header.Destroy = KiThreadDestroy;
|
||||
thread->ThreadId = _InterlockedExchangeAdd((volatile long *)&gNextThreadId, 1);
|
||||
@@ -118,19 +118,23 @@ __declspec(dllexport) KSTATUS KeCreateThread(PROCESS* owner, uintptr_t entry, ui
|
||||
LIST_INIT(&thread->ProcessLink);
|
||||
LIST_INIT(&thread->SchedulerLink);
|
||||
thread->WaitObject = (OBJECT *)0;
|
||||
thread->WaitStatus = STATUS_SUCCESS;
|
||||
thread->WaitStatus = NTLSTATUS_SUCCESS;
|
||||
thread->WaitListHead = (LIST_ENTRY*)0;
|
||||
thread->AlertableWait = 0;
|
||||
thread->SleepUntilTick = 0;
|
||||
thread->TimeoutStatus = STATUS_SUCCESS;
|
||||
thread->TimeoutStatus = NTLSTATUS_SUCCESS;
|
||||
thread->SwitchLockCookie = 0x202ULL;
|
||||
KiInitializeApcState(thread);
|
||||
thread->TrapFrame = (KTRAP_FRAME*)0;
|
||||
thread->UserExceptionDepth = 0;
|
||||
thread->UserExceptionNoncontinuableMask = 0;
|
||||
thread->UserExceptionFrameUserAddress = 0;
|
||||
memset(thread->UserExceptionExitStatus, 0, sizeof(thread->UserExceptionExitStatus));
|
||||
|
||||
void* kstack = MmAllocatePoolTag(KSTACK_SIZE, MM_POOL_TAG('k', 's', 't', 'k'));
|
||||
if (!kstack) {
|
||||
ObDereferenceObject(&thread->Header);
|
||||
return STATUS_NO_MEMORY;
|
||||
return NTLSTATUS_NO_MEMORY;
|
||||
}
|
||||
memset(kstack, 0, KSTACK_SIZE);
|
||||
thread->KernelStackBase = kstack;
|
||||
@@ -148,7 +152,7 @@ __declspec(dllexport) KSTATUS KeCreateThread(PROCESS* owner, uintptr_t entry, ui
|
||||
MmFreePool(kstack);
|
||||
thread->KernelStackBase = (void*)0;
|
||||
ObDereferenceObject(&thread->Header);
|
||||
return STATUS_NO_MEMORY;
|
||||
return NTLSTATUS_NO_MEMORY;
|
||||
}
|
||||
thread->UserStackBase = ustack;
|
||||
// Ring-3 starts at the image entry via IRET, not CALL. The MS x64 ABI
|
||||
@@ -172,7 +176,7 @@ __declspec(dllexport) KSTATUS KeCreateThread(PROCESS* owner, uintptr_t entry, ui
|
||||
MmFreePool(kstack);
|
||||
thread->KernelStackBase = (void*)0;
|
||||
ObDereferenceObject(&thread->Header);
|
||||
return STATUS_NO_MEMORY;
|
||||
return NTLSTATUS_NO_MEMORY;
|
||||
}
|
||||
memset(teb, 0, sizeof(SYS_TEB));
|
||||
teb->Peb = (SYS_PEB*)owner->UserPebBase;
|
||||
@@ -241,7 +245,7 @@ __declspec(dllexport) KSTATUS KeCreateThread(PROCESS* owner, uintptr_t entry, ui
|
||||
*out = thread;
|
||||
|
||||
KeReadyThread(thread);
|
||||
return STATUS_SUCCESS;
|
||||
return NTLSTATUS_SUCCESS;
|
||||
}
|
||||
|
||||
// Implements the exit Thread operation.
|
||||
@@ -284,11 +288,11 @@ static KSTATUS KiCreateKernelThreadWithAffinity(uintptr_t fn, uintptr_t arg,
|
||||
THREAD* currentThread = KeGetCurrentThread();
|
||||
owner = currentThread ? currentThread->Owner : (PROCESS*)0;
|
||||
}
|
||||
if (!owner) return STATUS_INVALID_PARAMETER;
|
||||
if (priority >= PriorityCount) return STATUS_INVALID_PARAMETER;
|
||||
if (!owner) return NTLSTATUS_INVALID_PARAMETER;
|
||||
if (priority >= PriorityCount) return NTLSTATUS_INVALID_PARAMETER;
|
||||
|
||||
THREAD* thread = (THREAD*)ObAllocateObject(ObjectTypeThread, sizeof(THREAD));
|
||||
if (!thread) return STATUS_NO_MEMORY;
|
||||
if (!thread) return NTLSTATUS_NO_MEMORY;
|
||||
|
||||
thread->Header.Destroy = KiThreadDestroy;
|
||||
thread->ThreadId = _InterlockedExchangeAdd((volatile long*)&gNextThreadId, 1);
|
||||
@@ -308,14 +312,18 @@ static KSTATUS KiCreateKernelThreadWithAffinity(uintptr_t fn, uintptr_t arg,
|
||||
LIST_INIT(&thread->ProcessLink);
|
||||
LIST_INIT(&thread->SchedulerLink);
|
||||
thread->WaitObject = (OBJECT*)0;
|
||||
thread->WaitStatus = STATUS_SUCCESS;
|
||||
thread->WaitStatus = NTLSTATUS_SUCCESS;
|
||||
thread->WaitListHead = (LIST_ENTRY*)0;
|
||||
thread->AlertableWait = 0;
|
||||
thread->SleepUntilTick = 0;
|
||||
thread->TimeoutStatus = STATUS_SUCCESS;
|
||||
thread->TimeoutStatus = NTLSTATUS_SUCCESS;
|
||||
thread->SwitchLockCookie = 0x202ULL;
|
||||
KiInitializeApcState(thread);
|
||||
thread->TrapFrame = (KTRAP_FRAME*)0;
|
||||
thread->UserExceptionDepth = 0;
|
||||
thread->UserExceptionNoncontinuableMask = 0;
|
||||
thread->UserExceptionFrameUserAddress = 0;
|
||||
memset(thread->UserExceptionExitStatus, 0, sizeof(thread->UserExceptionExitStatus));
|
||||
thread->UserStackBase = (void*)0; // no user stack
|
||||
thread->Teb = (void*)0; // no TEB; GS_BASE will be 0 in kernel ctx
|
||||
thread->TebSize = 0;
|
||||
@@ -323,7 +331,7 @@ static KSTATUS KiCreateKernelThreadWithAffinity(uintptr_t fn, uintptr_t arg,
|
||||
void* kstack = MmAllocatePoolTag(KSTACK_SIZE, MM_POOL_TAG('k', 's', 't', 'k'));
|
||||
if (!kstack) {
|
||||
ObDereferenceObject(&thread->Header);
|
||||
return STATUS_NO_MEMORY;
|
||||
return NTLSTATUS_NO_MEMORY;
|
||||
}
|
||||
memset(kstack, 0, KSTACK_SIZE);
|
||||
thread->KernelStackBase = kstack;
|
||||
@@ -363,7 +371,7 @@ static KSTATUS KiCreateKernelThreadWithAffinity(uintptr_t fn, uintptr_t arg,
|
||||
|
||||
KeInitThreadFpuContext(thread);
|
||||
KeReadyThread(thread);
|
||||
return STATUS_SUCCESS;
|
||||
return NTLSTATUS_SUCCESS;
|
||||
}
|
||||
|
||||
__declspec(dllexport) KSTATUS KeCreateKernelThread(uintptr_t fn, uintptr_t arg,
|
||||
@@ -388,7 +396,7 @@ void KePrepareBlockThread(THREAD* thread, OBJECT* waitObject, uint8_t alertable)
|
||||
KiSchedulerMarkThreadWaiting(thread);
|
||||
|
||||
thread->WaitObject = waitObject;
|
||||
thread->WaitStatus = STATUS_PENDING;
|
||||
thread->WaitStatus = NTLSTATUS_PENDING;
|
||||
thread->WaitListHead = (LIST_ENTRY*)0;
|
||||
thread->AlertableWait = alertable ? 1 : 0;
|
||||
thread->WaitRundownRoutine = (KE_WAIT_RUNDOWN_ROUTINE)0;
|
||||
@@ -436,13 +444,13 @@ static void KiFinishWait(THREAD* thread, KSTATUS status) {
|
||||
thread->WaitListHead = (LIST_ENTRY*)0;
|
||||
thread->AlertableWait = 0;
|
||||
thread->SleepUntilTick = 0;
|
||||
thread->TimeoutStatus = STATUS_SUCCESS;
|
||||
thread->TimeoutStatus = NTLSTATUS_SUCCESS;
|
||||
}
|
||||
|
||||
// Implements the commit Block Thread operation.
|
||||
KSTATUS KeCommitBlockThread(THREAD* thread, uint8_t alertable) {
|
||||
KeAssertIrql(PASSIVE_LEVEL);
|
||||
if (!thread) return STATUS_INVALID_PARAMETER;
|
||||
if (!thread) return NTLSTATUS_INVALID_PARAMETER;
|
||||
|
||||
if (alertable)
|
||||
thread->AlertableWait = 1;
|
||||
@@ -455,7 +463,7 @@ KSTATUS KeCommitBlockThread(THREAD* thread, uint8_t alertable) {
|
||||
KSTATUS status = thread->WaitStatus;
|
||||
thread->AlertableWait = 0;
|
||||
thread->SleepUntilTick = 0;
|
||||
thread->TimeoutStatus = STATUS_SUCCESS;
|
||||
thread->TimeoutStatus = NTLSTATUS_SUCCESS;
|
||||
return status;
|
||||
}
|
||||
|
||||
@@ -464,21 +472,21 @@ KSTATUS KeCommitBlockThread(THREAD* thread, uint8_t alertable) {
|
||||
if (alertable && thread->UserApcPending && thread->UserApcDispatcher) {
|
||||
if (thread->WaitListHead)
|
||||
ListRemove(&thread->SchedulerLink);
|
||||
KiFinishWait(thread, STATUS_USER_APC);
|
||||
KiFinishWait(thread, NTLSTATUS_USER_APC);
|
||||
thread->State = ThreadRunning;
|
||||
return STATUS_USER_APC;
|
||||
return NTLSTATUS_USER_APC;
|
||||
}
|
||||
|
||||
KiSchedulerNoteVoluntaryBlock(thread);
|
||||
KeYield();
|
||||
|
||||
// Kernel APCs are delivered before an alertable wait returns
|
||||
// STATUS_KERNEL_APC to its caller.
|
||||
// NTLSTATUS_KERNEL_APC to its caller.
|
||||
KiDeliverKernelApcs();
|
||||
|
||||
thread->AlertableWait = 0;
|
||||
thread->SleepUntilTick = 0;
|
||||
thread->TimeoutStatus = STATUS_SUCCESS;
|
||||
thread->TimeoutStatus = NTLSTATUS_SUCCESS;
|
||||
return thread->WaitStatus;
|
||||
}
|
||||
|
||||
@@ -517,7 +525,7 @@ static int KiRemoveThreadFromObjectWaitListLocked(THREAD* thread, LIST_ENTRY* wa
|
||||
ListRemove(&thread->SchedulerLink);
|
||||
thread->WaitListHead = (LIST_ENTRY*)0;
|
||||
thread->SleepUntilTick = 0;
|
||||
thread->TimeoutStatus = STATUS_SUCCESS;
|
||||
thread->TimeoutStatus = NTLSTATUS_SUCCESS;
|
||||
return 1;
|
||||
}
|
||||
|
||||
@@ -582,36 +590,36 @@ void KeAbortThreadWait(THREAD* thread, KSTATUS status) {
|
||||
|
||||
// Implements the unblock Thread operation.
|
||||
void KeUnblockThread(THREAD* thread) {
|
||||
KeUnblockThreadWithStatus(thread, STATUS_SUCCESS);
|
||||
KeUnblockThreadWithStatus(thread, NTLSTATUS_SUCCESS);
|
||||
}
|
||||
|
||||
// Implements the alert Thread With Status operation.
|
||||
static KSTATUS KiAlertThreadWithStatus(THREAD* thread, KSTATUS status) {
|
||||
if (!thread) return STATUS_INVALID_PARAMETER;
|
||||
if (!thread) return NTLSTATUS_INVALID_PARAMETER;
|
||||
|
||||
if (thread->State != ThreadWaiting || !thread->AlertableWait)
|
||||
return STATUS_PENDING;
|
||||
return NTLSTATUS_PENDING;
|
||||
|
||||
if (thread->WaitListHead)
|
||||
ListRemove(&thread->SchedulerLink);
|
||||
|
||||
KeUnblockThreadWithStatus(thread, status);
|
||||
return STATUS_SUCCESS;
|
||||
return NTLSTATUS_SUCCESS;
|
||||
}
|
||||
|
||||
// Implements the alert Thread operation.
|
||||
KSTATUS KeAlertThread(THREAD* thread) {
|
||||
return KiAlertThreadWithStatus(thread, STATUS_ALERTED);
|
||||
return KiAlertThreadWithStatus(thread, NTLSTATUS_ALERTED);
|
||||
}
|
||||
|
||||
// Implements the wake Thread For Kernel Apc operation.
|
||||
void KiWakeThreadForKernelApc(THREAD* thread) {
|
||||
(void)KiAlertThreadWithStatus(thread, STATUS_KERNEL_APC);
|
||||
(void)KiAlertThreadWithStatus(thread, NTLSTATUS_KERNEL_APC);
|
||||
}
|
||||
|
||||
// Implements the wake Thread For User Apc operation.
|
||||
void KiWakeThreadForUserApc(THREAD* thread) {
|
||||
(void)KiAlertThreadWithStatus(thread, STATUS_USER_APC);
|
||||
(void)KiAlertThreadWithStatus(thread, NTLSTATUS_USER_APC);
|
||||
}
|
||||
|
||||
void KeInitThreadFpuContext(THREAD* thread)
|
||||
|
||||
Reference in new issue
Block a user