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:
maksw committed 2026-06-27 20:38:43 +02:00
1 parent 1f5477cf66
commit b7fcfce6f7
140 files changed
+7649 -3943

No files matched your search

+20 -20
View File
@@ -38,12 +38,12 @@ static bool KiUserRflagsValid(uint64_t rflags) {
static KSTATUS KiValidateUserApcResumeState(uint64_t rip, uint64_t rsp, uint64_t rflags,
uint64_t cs, uint64_t ss) {
if (!KiUserAddressValid(rip) || !KiUserAddressValid(rsp))
return STATUS_ACCESS_DENIED;
return NTLSTATUS_ACCESS_DENIED;
if (cs != KI_USER_CS || ss != KI_USER_SS)
return STATUS_ACCESS_DENIED;
return NTLSTATUS_ACCESS_DENIED;
if (!KiUserRflagsValid(rflags))
return STATUS_ACCESS_DENIED;
return STATUS_SUCCESS;
return NTLSTATUS_ACCESS_DENIED;
return NTLSTATUS_SUCCESS;
}
// Allocates a nonzero token for one active user APC return frame.
@@ -128,7 +128,7 @@ __declspec(dllexport) bool KeInsertQueueApc(KAPC* apc,
// If the target opted into an alertable wait, make the APC itself the
// wait completion. The target thread will deliver the APC before
// KeWaitForEvent(..., true) returns STATUS_KERNEL_APC.
// KeWaitForEvent(..., true) returns NTLSTATUS_KERNEL_APC.
if (wakeAlertable)
KiWakeThreadForKernelApc(thread);
@@ -238,15 +238,15 @@ void KiDeliverKernelApcs(void) {
// Updates user Apc Dispatcher.
__declspec(dllexport) KSTATUS KeSetUserApcDispatcher(void* dispatcher) {
THREAD* thread = KeGetCurrentThread();
if (!thread) return STATUS_FAILURE;
if (!dispatcher) return STATUS_INVALID_PARAMETER;
if (!KiUserAddressValid((uint64_t)(uintptr_t)dispatcher)) return STATUS_ACCESS_DENIED;
if (!thread) return NTLSTATUS_FAILURE;
if (!dispatcher) return NTLSTATUS_INVALID_PARAMETER;
if (!KiUserAddressValid((uint64_t)(uintptr_t)dispatcher)) return NTLSTATUS_ACCESS_DENIED;
KSTATUS s = MmProbeUserRead(dispatcher, 1);
if (!KSUCCESS(s)) return s;
thread->UserApcDispatcher = (uintptr_t)dispatcher;
return STATUS_SUCCESS;
return NTLSTATUS_SUCCESS;
}
__declspec(dllexport) KSTATUS KeQueueUserApc(THREAD* thread,
@@ -255,15 +255,15 @@ __declspec(dllexport) KSTATUS KeQueueUserApc(THREAD* thread,
void* systemArgument1,
void* systemArgument2) {
if (!thread || !routine)
return STATUS_INVALID_PARAMETER;
return NTLSTATUS_INVALID_PARAMETER;
if (!KiUserAddressValid((uint64_t)(uintptr_t)routine))
return STATUS_ACCESS_DENIED;
return NTLSTATUS_ACCESS_DENIED;
if (thread->State == ThreadDead)
return STATUS_OBJECT_DEAD;
return NTLSTATUS_OBJECT_DEAD;
KUSER_APC* apc = (KUSER_APC*)MmAllocatePoolTag(sizeof(KUSER_APC), MM_POOL_TAG('a', 'p', 'c', ' '));
if (!apc)
return STATUS_NO_MEMORY;
return NTLSTATUS_NO_MEMORY;
memset(apc, 0, sizeof(*apc));
LIST_INIT(&apc->Link);
@@ -283,7 +283,7 @@ __declspec(dllexport) KSTATUS KeQueueUserApc(THREAD* thread,
if (wakeAlertable)
KiWakeThreadForUserApc(thread);
return STATUS_SUCCESS;
return NTLSTATUS_SUCCESS;
}
// Implements the pop User Apc operation.
@@ -359,11 +359,11 @@ void KiCheckForUserApcDelivery(KTRAP_FRAME* frame) {
thread->UserApcSavedRip = frame->Rip;
thread->UserApcSavedRsp = frame->Rsp;
thread->UserApcSavedRflags = frame->Rflags;
thread->UserApcSavedRax = STATUS_USER_APC;
thread->UserApcSavedRax = NTLSTATUS_USER_APC;
frame->Rip = thread->UserApcDispatcher;
frame->Rsp = newRsp;
frame->Rax = STATUS_USER_APC;
frame->Rax = NTLSTATUS_USER_APC;
thread->UserApcDeliverable = 0;
thread->UserApcDeliveryActive = 1;
@@ -416,10 +416,10 @@ void KiRundownApcState(THREAD* thread) {
__declspec(dllexport) uint64_t KeUserApcReturn(const SYS_USER_APC_FRAME_K* userFrame) {
THREAD* thread = KeGetCurrentThread();
if (!thread)
return STATUS_FAILURE;
return NTLSTATUS_FAILURE;
if (!thread->UserApcDeliveryActive || !userFrame)
return STATUS_INVALID_PARAMETER;
return NTLSTATUS_INVALID_PARAMETER;
SYS_USER_APC_FRAME_K frameCopy;
KSTATUS s = CopyFromUser(&frameCopy, userFrame, sizeof(frameCopy));
@@ -434,12 +434,12 @@ __declspec(dllexport) uint64_t KeUserApcReturn(const SYS_USER_APC_FRAME_K* userF
(uint64_t)thread->UserApcFrameUserAddress,
frameCopy.ReturnToken,
thread->UserApcReturnToken);
return STATUS_INVALID_PARAMETER;
return NTLSTATUS_INVALID_PARAMETER;
}
KTRAP_FRAME* frame = KeGetCurrentTrapFrame();
if (!frame || !KeTrapFrameFromUser(frame) || frame->Kind != KTRAP_KIND_SYSCALL)
return STATUS_FAILURE;
return NTLSTATUS_FAILURE;
s = KiValidateUserApcResumeState(thread->UserApcSavedRip,
thread->UserApcSavedRsp,