diff --git a/reactos/ntoskrnl/ke/i386/ctxswitch.S b/reactos/ntoskrnl/ke/i386/ctxswitch.S index 2d23bef0906..67840f04007 100644 --- a/reactos/ntoskrnl/ke/i386/ctxswitch.S +++ b/reactos/ntoskrnl/ke/i386/ctxswitch.S @@ -115,14 +115,11 @@ BadThread: .globl @KiSwapContextInternal@0 @KiSwapContextInternal@0: - /* Save WaitIrql APC-bypass in EFLAGS */ - or cl, cl - /* Set the Thread to running */ mov byte ptr [esi+KTHREAD_STATE], Running - /* Save the flags */ - pushf + /* Save the IRQL */ + push ecx /* Save the Exception list */ push [ebx+KPCR_EXCEPTION_LIST] @@ -224,13 +221,36 @@ SameProcess: /* Restore exception list */ pop [ebx+KPCR_EXCEPTION_LIST] - /* Retore EFLAGS */ - popf + /* Restore IRQL */ + pop ecx - /* Return no APC pending */ + /* Check if kernel APCs are pending */ + cmp byte ptr [esi+KTHREAD_PENDING_KERNEL_APC], 0 + jnz CheckApc + + /* No APCs, return */ xor eax, eax ret +CheckApc: + + /* Check if they're disabled */ + cmp word ptr [esi+KTHREAD_SPECIAL_APC_DISABLE], 0 + jnz ApcReturn + test cl, cl + jz ApcReturn + + /* Request APC Delivery */ + mov cl, APC_LEVEL + call @HalRequestSoftwareInterrupt@4 + or eax, esp + +ApcReturn: + + /* Return with APC pending */ + setz al + ret + LdtStuff: /* Write the LDT Selector */ @@ -240,6 +260,13 @@ LdtStuff: mov eax, [edi+KPROCESS_LDT_DESCRIPTOR1] mov [ecx+KGDT_LDT+4], eax + /* Write the INT21 handler */ + mov ecx, [ebx+KPCR_IDT] + mov eax, [ebp+KPROCESS_INT21_DESCRIPTOR0] + mov [ecx+0x108], eax + mov eax, [ebp+KPROCESS_INT21_DESCRIPTOR1] + mov [ecx+0x10C], eax + /* Save LDT Selector */ mov eax, KGDT_LDT jmp LoadLdt diff --git a/reactos/ntoskrnl/ke/i386/thread.c b/reactos/ntoskrnl/ke/i386/thread.c index 466db3c63ba..b7469485525 100644 --- a/reactos/ntoskrnl/ke/i386/thread.c +++ b/reactos/ntoskrnl/ke/i386/thread.c @@ -15,7 +15,7 @@ typedef struct _KSHARED_CTXSWITCH_FRAME { PVOID ExceptionList; - ULONG Flags; + KIRQL WaitIrql; PVOID RetEip; } KSHARED_CTXSWITCH_FRAME, *PKSHARED_CTXSWITCH_FRAME; @@ -231,7 +231,7 @@ Ke386InitThreadWithContext(PKTHREAD Thread, /* And set up the Context Switch Frame */ CtxSwitchFrame->RetEip = KiThreadStartup; - CtxSwitchFrame->Flags = EFLAGS_INTERRUPT_MASK; + CtxSwitchFrame->WaitIrql = APC_LEVEL; CtxSwitchFrame->ExceptionList = (PVOID)0xFFFFFFFF; /* Save back the new value of the kernel stack. */