Implement KiServiceExit2 which restores debug registers and exits with IRET, used during user-mode return without a syscall Modified: trunk/reactos/ntoskrnl/ke/i386/ctxswitch.S Modified: trunk/reactos/ntoskrnl/ke/i386/syscall.S _____
Modified: trunk/reactos/ntoskrnl/ke/i386/ctxswitch.S --- trunk/reactos/ntoskrnl/ke/i386/ctxswitch.S 2005-04-23 04:31:11 UTC (rev 14757) +++ trunk/reactos/ntoskrnl/ke/i386/ctxswitch.S 2005-04-23 05:00:10 UTC (rev 14758) @@ -88,7 +88,7 @@
mov ebp, esp
/* Exit back to user-mode */ - jmp _KiServiceExit + jmp _KiServiceExit2
BadThread:
_____
Modified: trunk/reactos/ntoskrnl/ke/i386/syscall.S --- trunk/reactos/ntoskrnl/ke/i386/syscall.S 2005-04-23 04:31:11 UTC (rev 14757) +++ trunk/reactos/ntoskrnl/ke/i386/syscall.S 2005-04-23 05:00:10 UTC (rev 14758) @@ -22,6 +22,7 @@
.globl KeReturnFromSystemCallWithHook .globl _KiServiceExit +.globl _KiServiceExit2 .globl _KiFastCallEntry .globl _KiSystemService
@@ -317,3 +318,82 @@ movl $STATUS_INVALID_SYSTEM_SERVICE, %eax movl %eax, KTRAP_FRAME_EAX(%ebp) jmp _KiServiceExit + +_KiServiceExit2: + + /* Get the Current Thread */ + cli + movl %fs:KPCR_CURRENT_THREAD, %esi + + /* Deliver APCs only if we were called from user mode */ + testb $1, KTRAP_FRAME_CS(%esp) + je KiRosTrapReturn + + /* And only if any are actually pending */ + cmpb $0, KTHREAD_PENDING_USER_APC(%esi) + je KiRosTrapReturn + + /* Save pointer to Trap Frame */ + movl %esp, %ebx + + /* Raise IRQL to APC_LEVEL */ + movl $1, %ecx + call @KfRaiseIrql@4 + + /* Save old IRQL */ + pushl %eax + + /* Deliver APCs */ + sti + pushl %ebx + pushl $0 + pushl $UserMode + call _KiDeliverApc@12 + cli + + /* Return to old IRQL */ + popl %ecx + call @KfLowerIrql@4 + + /* Skip useless Debug Data */ + addl $0x18, %esp // + 0x74 + + /* Restore Debug Registers */ + popl %eax // + 0x5C + movl %eax, %dr0 + popl %eax // + 0x58 + movl %eax, %dr1 + popl %eax // + 0x54 + movl %eax, %dr2 + popl %eax // + 0x50 + movl %eax, %dr3 + popl %eax // + 0x4C + movl %eax, %dr6 + popl %eax // + 0x48 + movl %eax, %dr7 + + /* Restore Registers */ + popl %gs // + 0x44 + popl %es // + 0x40 + popl %ds // + 0x3C + popl %edx // + 0x38 + popl %ecx // + 0x34 + popl %eax // + 0x30 + + /* Restore the old previous mode */ + popl %ebx // + 0x2C + movb %bl, %ss:KTHREAD_PREVIOUS_MODE(%esi) + + /* Restore the old exception handler list */ + popl %fs:KPCR_EXCEPTION_LIST // + 0x28 + + /* Restore final registers from trap frame */ + popl %fs // + 0x24 + popl %edi // + 0x20 + popl %esi // + 0x1C + popl %ebx // + 0x18 + popl %ebp // + 0x14 + add $4, %esp // + 0x10 + + /* Return to user-mode */ + iret