#define NDEBUG
#include <debug.h>
-VOID KiFastCallEntry(VOID);
-VOID KiFastCallEntryWithSingleStep(VOID);
+VOID __cdecl KiFastCallEntry(VOID);
+VOID __cdecl KiFastCallEntryWithSingleStep(VOID);
extern PVOID FrRestore;
VOID FASTCALL Ke386LoadFpuState(IN PFX_SAVE_AREA SaveArea);
PKDBG_PRESERVICEHOOK KeWin32PreServiceHook = NULL;
PKDBG_POSTSERVICEHOOK KeWin32PostServiceHook = NULL;
#endif
-#if TRAP_DEBUG
+#if DBG
BOOLEAN StopChecking = FALSE;
#endif
{
/* We can use the sysexit handler */
KiFastCallExitHandler(TrapFrame);
+ UNREACHABLE;
}
}
}
}
- /* User or kernel trap -- get ready to issue an exception */
- if (Thread->NpxState == NPX_STATE_NOT_LOADED)
+ /* User or kernel trap -- check if we need to unload the current state */
+ if (Thread->NpxState == NPX_STATE_LOADED)
{
/* Update CR0 */
Cr0 = __readcr0();
}
/* Get legal exceptions that software should handle */
- /* We do this by first masking off from the Mask the bits we need, */
- /* This is done so we can keep the FSW_STACK_FAULT bit in Error. */
Mask &= (FSW_INVALID_OPERATION |
FSW_DENORMAL |
FSW_ZERO_DIVIDE |
/* Check for invalid operation */
if (Error & FSW_INVALID_OPERATION)
{
- /* NOTE: Stack fault is handled differently than any other case. */
- /* 1. It's only raised for invalid operation. */
- /* 2. It's only raised if invalid operation is not masked. */
+ /*
+ * Now check if this is actually a Stack Fault. This is needed because
+ * on x86 the Invalid Operation error is set for Stack Check faults as well.
+ */
if (Error & FSW_STACK_FAULT)
{
/* Issue stack check fault */
DataOffset,
TrapFrame);
}
-
- /* Issue fault */
- KiDispatchException1Args(STATUS_FLOAT_INVALID_OPERATION,
- ErrorOffset,
- 0,
- TrapFrame);
+ else
+ {
+ /* This is an invalid operation fault after all, so raise that instead */
+ KiDispatchException1Args(STATUS_FLOAT_INVALID_OPERATION,
+ ErrorOffset,
+ 0,
+ TrapFrame);
+ }
}
/* Check for divide by zero */
TrapFrame.Edi = Tss->Edi;
TrapFrame.SegFs = Tss->Fs;
TrapFrame.ExceptionList = PCR->NtTib.ExceptionList;
- TrapFrame.PreviousPreviousMode = -1;
+ TrapFrame.PreviousPreviousMode = (ULONG)-1;
TrapFrame.Eax = Tss->Eax;
TrapFrame.Ecx = Tss->Ecx;
TrapFrame.Edx = Tss->Edx;
}
/* Go to APC level */
- OldIrql = KfRaiseIrql(APC_LEVEL);
+ KeRaiseIrql(APC_LEVEL, &OldIrql);
_enable();
/* Check for BOP */
}
/* Bring IRQL back */
- KfLowerIrql(OldIrql);
+ KeLowerIrql(OldIrql);
_disable();
/* Do a quick V86 exit if possible */
}
/* Go to APC level */
- OldIrql = KfRaiseIrql(APC_LEVEL);
+ KeRaiseIrql(APC_LEVEL, &OldIrql);
_enable();
/* Handle the V86 opcode */
}
/* Bring IRQL back */
- KfLowerIrql(OldIrql);
+ KeLowerIrql(OldIrql);
_disable();
/* Do a quick V86 exit if possible */
KiTrap0EHandler(IN PKTRAP_FRAME TrapFrame)
{
PKTHREAD Thread;
+ BOOLEAN Present;
+ BOOLEAN StoreInstruction;
ULONG_PTR Cr2;
NTSTATUS Status;
/* Save CR2 */
Cr2 = __readcr2();
- /* Enable interupts */
+ /* Enable interrupts */
_enable();
+ /* Interpret the error code */
+ Present = (TrapFrame->ErrCode & 1) != 0;
+ StoreInstruction = (TrapFrame->ErrCode & 2) != 0;
+
/* Check if we came in with interrupts disabled */
if (!(TrapFrame->EFlags & EFLAGS_INTERRUPT_MASK))
{
/* This is completely illegal, bugcheck the system */
KeBugCheckWithTf(IRQL_NOT_LESS_OR_EQUAL,
Cr2,
- -1,
- TrapFrame->ErrCode & 2 ? TRUE : FALSE,
+ (ULONG_PTR)-1,
+ StoreInstruction,
TrapFrame->Eip,
TrapFrame);
}
/* Do what windows does and issue an invalid access violation */
KiDispatchException2Args(KI_EXCEPTION_ACCESS_VIOLATION,
TrapFrame->Eip,
- TrapFrame->ErrCode & 2 ? TRUE : FALSE,
+ StoreInstruction,
Cr2,
TrapFrame);
#endif
}
/* Call the access fault handler */
- Status = MmAccessFault(TrapFrame->ErrCode & 1,
+ Status = MmAccessFault(Present,
(PVOID)Cr2,
KiUserTrap(TrapFrame),
TrapFrame);
UNIMPLEMENTED_FATAL();
}
#endif
+
/* Check for VDM trap */
- ASSERT((KiVdmTrap(TrapFrame)) == FALSE);
+ if (KiVdmTrap(TrapFrame))
+ {
+ DPRINT1("VDM PAGE FAULT at %lx:%lx for address %lx\n",
+ TrapFrame->SegCs, TrapFrame->Eip, Cr2);
+ if (VdmDispatchPageFault(TrapFrame))
+ {
+ /* Return and end VDM execution */
+ DPRINT1("VDM page fault with status 0x%lx resolved\n", Status);
+ KiEoiHelper(TrapFrame);
+ }
+ DPRINT1("VDM page fault with status 0x%lx NOT resolved\n", Status);
+ }
/* Either kernel or user trap (non VDM) so dispatch exception */
if (Status == STATUS_ACCESS_VIOLATION)
/* This status code is repurposed so we can recognize it later */
KiDispatchException2Args(KI_EXCEPTION_ACCESS_VIOLATION,
TrapFrame->Eip,
- TrapFrame->ErrCode & 2 ? TRUE : FALSE,
+ StoreInstruction,
Cr2,
TrapFrame);
}
/* These faults only have two parameters */
KiDispatchException2Args(Status,
TrapFrame->Eip,
- TrapFrame->ErrCode & 2 ? TRUE : FALSE,
+ StoreInstruction,
Cr2,
TrapFrame);
}
0,
TrapFrame->Eip,
3,
- TrapFrame->ErrCode & 2 ? TRUE : FALSE,
+ StoreInstruction,
Cr2,
Status,
TrapFrame);
FASTCALL
KiGetTickCountHandler(IN PKTRAP_FRAME TrapFrame)
{
- UNIMPLEMENTED_DBGBREAK();
+ /* Save trap frame */
+ KiEnterTrap(TrapFrame);
+
+ /*
+ * Just fail the request
+ */
+ DbgPrint("INT 0x2A attempted, returning 0 tick count\n");
+ TrapFrame->Eax = 0;
+
+ /* Exit the trap */
+ KiEoiHelper(TrapFrame);
}
VOID
Thread = KeGetCurrentThread();
Thread->TrapFrame = TrapFrame;
Thread->PreviousMode = KiUserTrap(TrapFrame);
- NT_ASSERT(Thread->PreviousMode != KernelMode);
+ ASSERT(Thread->PreviousMode != KernelMode);
/* Pass the register parameters to NtCallbackReturn.
Result pointer is in ecx, result length in edx, status in eax */
{
PKTHREAD Thread;
PKSERVICE_TABLE_DESCRIPTOR DescriptorTable;
- ULONG Id, Offset, StackBytes, Result;
+ ULONG Id, Offset, StackBytes;
+ NTSTATUS Status;
PVOID Handler;
ULONG SystemCallNumber = TrapFrame->Eax;
if (!(Offset & SERVICE_TABLE_TEST))
{
/* Fail the call */
- Result = STATUS_INVALID_SYSTEM_SERVICE;
+ Status = STATUS_INVALID_SYSTEM_SERVICE;
goto ExitCall;
}
/* Convert us to a GUI thread -- must wrap in ASM to get new EBP */
- Result = KiConvertToGuiThread();
+ Status = KiConvertToGuiThread();
/* Reload trap frame and descriptor table pointer from new stack */
TrapFrame = *(volatile PVOID*)&Thread->TrapFrame;
DescriptorTable = (PVOID)(*(volatile ULONG_PTR*)&Thread->ServiceTable + Offset);
- if (!NT_SUCCESS(Result))
+ if (!NT_SUCCESS(Status))
{
/* Set the last error and fail */
goto ExitCall;
if (Id >= DescriptorTable->Limit)
{
/* Fail the call */
- Result = STATUS_INVALID_SYSTEM_SERVICE;
+ Status = STATUS_INVALID_SYSTEM_SERVICE;
goto ExitCall;
}
}
/* Get the handler and make the system call */
Handler = (PVOID)DescriptorTable->Base[Id];
- Result = KiSystemCallTrampoline(Handler, Arguments, StackBytes);
+ Status = KiSystemCallTrampoline(Handler, Arguments, StackBytes);
/* Call post-service debug hook */
- Result = KiDbgPostServiceHook(SystemCallNumber, Result);
+ Status = KiDbgPostServiceHook(SystemCallNumber, Status);
/* Make sure we're exiting correctly */
KiExitSystemCallDebugChecks(Id, TrapFrame);
Thread->TrapFrame = (PKTRAP_FRAME)TrapFrame->Edx;
/* Exit from system call */
- KiServiceExit(TrapFrame, Result);
+ KiServiceExit(TrapFrame, Status);
+}
+
+VOID
+FASTCALL
+KiCheckForSListAddress(IN PKTRAP_FRAME TrapFrame)
+{
+ UNIMPLEMENTED;
}
/*
Kei386EoiHelper(VOID)
{
/* We should never see this call happening */
- ERROR_FATAL("Mismatched NT/HAL version");
+ KeBugCheck(MISMATCHED_HAL);
}
/* EOF */