ReactOS 0.4.15-dev-7842-g558ab78
exp.c File Reference
#include <ntoskrnl.h>
#include <debug.h>
Include dependency graph for exp.c:

Go to the source code of this file.

Macros

#define NDEBUG
 

Functions

VOID NTAPI KeInitExceptions (VOID)
 
ULONG FASTCALL KiUpdateDr7 (IN ULONG Dr7)
 
BOOLEAN FASTCALL KiRecordDr7 (OUT PULONG Dr7Ptr, OUT PULONG DrMask)
 
ULONG NTAPI KiEspFromTrapFrame (IN PKTRAP_FRAME TrapFrame)
 
VOID NTAPI KiEspToTrapFrame (IN PKTRAP_FRAME TrapFrame, IN ULONG Esp)
 
ULONG NTAPI KiSsFromTrapFrame (IN PKTRAP_FRAME TrapFrame)
 
VOID NTAPI KiSsToTrapFrame (IN PKTRAP_FRAME TrapFrame, IN ULONG Ss)
 
USHORT NTAPI KiTagWordFnsaveToFxsave (USHORT TagWord)
 
VOID NTAPI Ki386AdjustEsp0 (IN PKTRAP_FRAME TrapFrame)
 
VOID NTAPI KeContextToTrapFrame (IN PCONTEXT Context, IN OUT PKEXCEPTION_FRAME ExceptionFrame, IN OUT PKTRAP_FRAME TrapFrame, IN ULONG ContextFlags, IN KPROCESSOR_MODE PreviousMode)
 
VOID NTAPI KeTrapFrameToContext (IN PKTRAP_FRAME TrapFrame, IN PKEXCEPTION_FRAME ExceptionFrame, IN OUT PCONTEXT Context)
 
BOOLEAN FASTCALL KeInvalidAccessAllowed (IN PVOID TrapInformation OPTIONAL)
 
VOID NTAPI KiDispatchException (IN PEXCEPTION_RECORD ExceptionRecord, IN PKEXCEPTION_FRAME ExceptionFrame, IN PKTRAP_FRAME TrapFrame, IN KPROCESSOR_MODE PreviousMode, IN BOOLEAN FirstChance)
 
DECLSPEC_NORETURN VOID NTAPI KiDispatchExceptionFromTrapFrame (IN NTSTATUS Code, IN ULONG Flags, IN ULONG_PTR Address, IN ULONG ParameterCount, IN ULONG_PTR Parameter1, IN ULONG_PTR Parameter2, IN ULONG_PTR Parameter3, IN PKTRAP_FRAME TrapFrame)
 
DECLSPEC_NORETURN VOID FASTCALL KiSystemFatalException (IN ULONG ExceptionCode, IN PKTRAP_FRAME TrapFrame)
 
NTSTATUS NTAPI KeRaiseUserException (IN NTSTATUS ExceptionCode)
 

Macro Definition Documentation

◆ NDEBUG

#define NDEBUG

Definition at line 14 of file exp.c.

Function Documentation

◆ KeContextToTrapFrame()

VOID NTAPI KeContextToTrapFrame ( IN PCONTEXT  Context,
IN OUT PKEXCEPTION_FRAME  ExceptionFrame,
IN OUT PKTRAP_FRAME  TrapFrame,
IN ULONG  ContextFlags,
IN KPROCESSOR_MODE  PreviousMode 
)

Definition at line 314 of file exp.c.

319{
320 PFX_SAVE_AREA FxSaveArea;
321 ULONG i;
322 BOOLEAN V86Switch = FALSE;
324 ULONG DrMask = 0;
325
326 /* Do this at APC_LEVEL */
329
330 /* Start with the basic Registers */
331 if ((ContextFlags & CONTEXT_CONTROL) == CONTEXT_CONTROL)
332 {
333 /* Check if we went through a V86 switch */
334 if ((Context->EFlags & EFLAGS_V86_MASK) !=
335 (TrapFrame->EFlags & EFLAGS_V86_MASK))
336 {
337 /* We did, remember this for later */
338 V86Switch = TRUE;
339 }
340
341 /* Copy EFLAGS and sanitize them*/
342 TrapFrame->EFlags = Ke386SanitizeFlags(Context->EFlags, PreviousMode);
343
344 /* Copy EBP and EIP */
345 TrapFrame->Ebp = Context->Ebp;
346 TrapFrame->Eip = Context->Eip;
347
348 /* Check if we were in V86 Mode */
349 if (TrapFrame->EFlags & EFLAGS_V86_MASK)
350 {
351 /* Simply copy the CS value */
352 TrapFrame->SegCs = Context->SegCs;
353 }
354 else
355 {
356 /* We weren't in V86, so sanitize the CS */
357 TrapFrame->SegCs = Ke386SanitizeSeg(Context->SegCs, PreviousMode);
358
359 /* Don't let it under 8, that's invalid */
360 if ((PreviousMode != KernelMode) && (TrapFrame->SegCs < 8))
361 {
362 /* Force it to User CS */
363 TrapFrame->SegCs = KGDT_R3_CODE | RPL_MASK;
364 }
365 }
366
367 /* Handle SS Specially for validation */
368 KiSsToTrapFrame(TrapFrame, Context->SegSs);
369
370 /* Write ESP back; take into account Edited Trap Frames */
371 KiEspToTrapFrame(TrapFrame, Context->Esp);
372
373 /* Handle our V86 Bias if we went through a switch */
374 if (V86Switch) Ki386AdjustEsp0(TrapFrame);
375 }
376
377 /* Process the Integer Registers */
378 if ((ContextFlags & CONTEXT_INTEGER) == CONTEXT_INTEGER)
379 {
380 /* Copy them manually */
381 TrapFrame->Eax = Context->Eax;
382 TrapFrame->Ebx = Context->Ebx;
383 TrapFrame->Ecx = Context->Ecx;
384 TrapFrame->Edx = Context->Edx;
385 TrapFrame->Esi = Context->Esi;
386 TrapFrame->Edi = Context->Edi;
387 }
388
389 /* Process the Context Segments */
390 if ((ContextFlags & CONTEXT_SEGMENTS) == CONTEXT_SEGMENTS)
391 {
392 /* Check if we were in V86 Mode */
393 if (TrapFrame->EFlags & EFLAGS_V86_MASK)
394 {
395 /* Copy the V86 Segments directly */
396 TrapFrame->V86Ds = Context->SegDs;
397 TrapFrame->V86Es = Context->SegEs;
398 TrapFrame->V86Fs = Context->SegFs;
399 TrapFrame->V86Gs = Context->SegGs;
400 }
401 else if (!KiUserTrap(TrapFrame))
402 {
403 /* For kernel mode, write the standard values */
404 TrapFrame->SegDs = KGDT_R3_DATA | RPL_MASK;
405 TrapFrame->SegEs = KGDT_R3_DATA | RPL_MASK;
406 TrapFrame->SegFs = Ke386SanitizeSeg(Context->SegFs, PreviousMode);
407 TrapFrame->SegGs = 0;
408 }
409 else
410 {
411 /* For user mode, return the values directly */
412 TrapFrame->SegDs = Context->SegDs;
413 TrapFrame->SegEs = Context->SegEs;
414 TrapFrame->SegFs = Context->SegFs;
415
416 /* Handle GS specially */
417 if (TrapFrame->SegCs == (KGDT_R3_CODE | RPL_MASK))
418 {
419 /* Don't use it, if user */
420 TrapFrame->SegGs = 0;
421 }
422 else
423 {
424 /* Copy it if kernel */
425 TrapFrame->SegGs = Context->SegGs;
426 }
427 }
428 }
429
430 /* Handle the extended registers */
431 if (((ContextFlags & CONTEXT_EXTENDED_REGISTERS) ==
433 {
434 /* Get the FX Area */
435 FxSaveArea = (PFX_SAVE_AREA)(TrapFrame + 1);
436
437 /* Flush the NPX State */
439
440 /* Copy the FX State */
441 RtlCopyMemory(&FxSaveArea->U.FxArea,
442 &Context->ExtendedRegisters[0],
444
445 /* Remove reserved bits from MXCSR */
446 FxSaveArea->U.FxArea.MXCsr &= KiMXCsrMask;
447
448 /* Mask out any invalid flags */
449 FxSaveArea->Cr0NpxState &= ~(CR0_EM | CR0_MP | CR0_TS);
450
451 /* Check if this is a VDM app */
452 if (PsGetCurrentProcess()->VdmObjects)
453 {
454 /* Allow the EM flag */
455 FxSaveArea->Cr0NpxState |= Context->FloatSave.Cr0NpxState & (CR0_EM | CR0_MP);
456 }
457 }
458
459 /* Handle the floating point state */
460 if (((ContextFlags & CONTEXT_FLOATING_POINT) ==
461 CONTEXT_FLOATING_POINT) && KiUserTrap(TrapFrame))
462 {
463 /* Get the FX Area */
464 FxSaveArea = (PFX_SAVE_AREA)(TrapFrame + 1);
465
466 /* Flush the NPX State */
468
469 /* Check if we have Fxsr support */
471 {
472 /* Convert the Fn Floating Point state to Fx */
473 FxSaveArea->U.FxArea.ControlWord = (USHORT)Context->FloatSave.ControlWord;
474 FxSaveArea->U.FxArea.StatusWord = (USHORT)Context->FloatSave.StatusWord;
475 FxSaveArea->U.FxArea.TagWord =
476 KiTagWordFnsaveToFxsave((USHORT)Context->FloatSave.TagWord);
477 FxSaveArea->U.FxArea.ErrorOpcode =
478 (USHORT)((Context->FloatSave.ErrorSelector >> 16) & 0xFFFF);
479 FxSaveArea->U.FxArea.ErrorOffset = Context->FloatSave.ErrorOffset;
480 FxSaveArea->U.FxArea.ErrorSelector = Context->FloatSave.ErrorSelector & 0xFFFF;
481 FxSaveArea->U.FxArea.DataOffset = Context->FloatSave.DataOffset;
482 FxSaveArea->U.FxArea.DataSelector = Context->FloatSave.DataSelector;
483
484 /* Clear out the Register Area */
486
487 /* Loop the 8 floating point registers */
488 for (i = 0; i < 8; i++)
489 {
490 /* Copy from Fn to Fx */
491 RtlCopyMemory(FxSaveArea->U.FxArea.RegisterArea + (i * 16),
492 Context->FloatSave.RegisterArea + (i * 10),
493 10);
494 }
495 }
496 else
497 {
498 /* Copy the structure */
499 FxSaveArea->U.FnArea.ControlWord = Context->FloatSave.ControlWord;
500 FxSaveArea->U.FnArea.StatusWord = Context->FloatSave.StatusWord;
501 FxSaveArea->U.FnArea.TagWord = Context->FloatSave.TagWord;
502 FxSaveArea->U.FnArea.ErrorOffset = Context->FloatSave.ErrorOffset;
503 FxSaveArea->U.FnArea.ErrorSelector = Context->FloatSave.ErrorSelector;
504 FxSaveArea->U.FnArea.DataOffset = Context->FloatSave.DataOffset;
505 FxSaveArea->U.FnArea.DataSelector = Context->FloatSave.DataSelector;
506
507 /* Loop registers */
508 for (i = 0; i < SIZE_OF_80387_REGISTERS; i++)
509 {
510 /* Copy registers */
511 FxSaveArea->U.FnArea.RegisterArea[i] = Context->FloatSave.RegisterArea[i];
512 }
513 }
514
515 /* Mask out any invalid flags */
516 FxSaveArea->Cr0NpxState &= ~(CR0_EM | CR0_MP | CR0_TS);
517
518 /* Check if this is a VDM app */
519 if (PsGetCurrentProcess()->VdmObjects)
520 {
521 /* Allow the EM flag */
522 FxSaveArea->Cr0NpxState |= Context->FloatSave.Cr0NpxState & (CR0_EM | CR0_MP);
523 }
524 }
525
526 /* Handle the Debug Registers */
527 if ((ContextFlags & CONTEXT_DEBUG_REGISTERS) == CONTEXT_DEBUG_REGISTERS)
528 {
529 /* Copy Dr0 - Dr4 */
530 TrapFrame->Dr0 = Context->Dr0;
531 TrapFrame->Dr1 = Context->Dr1;
532 TrapFrame->Dr2 = Context->Dr2;
533 TrapFrame->Dr3 = Context->Dr3;
534
535 /* If we're in user-mode */
537 {
538 /* Make sure, no Dr address is above user space */
539 if (Context->Dr0 > (ULONG)MmHighestUserAddress) TrapFrame->Dr0 = 0;
540 if (Context->Dr1 > (ULONG)MmHighestUserAddress) TrapFrame->Dr1 = 0;
541 if (Context->Dr2 > (ULONG)MmHighestUserAddress) TrapFrame->Dr2 = 0;
542 if (Context->Dr3 > (ULONG)MmHighestUserAddress) TrapFrame->Dr3 = 0;
543 }
544
545 /* Now sanitize and save DR6 */
546 TrapFrame->Dr6 = Context->Dr6 & DR6_LEGAL;
547
548 /* Update the Dr active mask */
549 if (TrapFrame->Dr0) DrMask |= DR_MASK(0);
550 if (TrapFrame->Dr1) DrMask |= DR_MASK(1);
551 if (TrapFrame->Dr2) DrMask |= DR_MASK(2);
552 if (TrapFrame->Dr3) DrMask |= DR_MASK(3);
553 if (TrapFrame->Dr6) DrMask |= DR_MASK(6);
554
555 /* Sanitize and save DR7 */
556 TrapFrame->Dr7 = Context->Dr7 & DR7_LEGAL;
557 KiRecordDr7(&TrapFrame->Dr7, &DrMask);
558
559 /* If we're in user-mode */
561 {
562 /* Save the mask */
563 KeGetCurrentThread()->Header.DebugActive = (UCHAR)DrMask;
564 }
565 }
566
567 /* Check if thread has IOPL and force it enabled if so */
568 if (KeGetCurrentThread()->Iopl) TrapFrame->EFlags |= EFLAGS_IOPL;
569
570 /* Restore IRQL */
572}
unsigned char BOOLEAN
#define NULL
Definition: types.h:112
#define TRUE
Definition: types.h:120
#define FALSE
Definition: types.h:117
UCHAR KIRQL
Definition: env_spec_w32.h:591
#define KeRaiseIrql(irql, oldIrql)
Definition: env_spec_w32.h:597
#define APC_LEVEL
Definition: env_spec_w32.h:695
#define KeLowerIrql(oldIrql)
Definition: env_spec_w32.h:602
#define KeGetCurrentIrql()
Definition: env_spec_w32.h:706
GLsizei GLenum const GLvoid GLsizei GLenum GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLint GLint GLint GLshort GLshort GLshort GLubyte GLubyte GLubyte GLuint GLuint GLuint GLushort GLushort GLushort GLbyte GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLfloat GLint GLint GLint GLint GLshort GLshort GLshort GLshort GLubyte GLubyte GLubyte GLubyte GLuint GLuint GLuint GLuint GLushort GLushort GLushort GLushort GLboolean const GLdouble const GLfloat const GLint const GLshort const GLbyte const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLdouble const GLfloat const GLfloat const GLint const GLint const GLshort const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort GLenum GLenum GLenum GLfloat GLenum GLint GLenum GLenum GLenum GLfloat GLenum GLenum GLint GLenum GLfloat GLenum GLint GLint GLushort GLenum GLenum GLfloat GLenum GLenum GLint GLfloat const GLubyte GLenum GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLint GLint GLsizei GLsizei GLint GLenum GLenum const GLvoid GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLenum const GLdouble GLenum GLenum const GLfloat GLenum GLenum const GLint GLsizei GLuint GLfloat GLuint GLbitfield GLfloat GLint GLuint GLboolean GLenum GLfloat GLenum GLbitfield GLenum GLfloat GLfloat GLint GLint const GLfloat GLenum GLfloat GLfloat GLint GLint GLfloat GLfloat GLint GLint const GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat const GLdouble const GLfloat const GLdouble const GLfloat GLint i
Definition: glfuncs.h:248
#define KeGetCurrentThread
Definition: hal.h:55
VOID NTAPI KiEspToTrapFrame(IN PKTRAP_FRAME TrapFrame, IN ULONG Esp)
Definition: exp.c:164
USHORT NTAPI KiTagWordFnsaveToFxsave(USHORT TagWord)
Definition: exp.c:263
VOID NTAPI KiSsToTrapFrame(IN PKTRAP_FRAME TrapFrame, IN ULONG Ss)
Definition: exp.c:242
VOID NTAPI Ki386AdjustEsp0(IN PKTRAP_FRAME TrapFrame)
Definition: exp.c:280
BOOLEAN FASTCALL KiRecordDr7(OUT PULONG Dr7Ptr, OUT PULONG DrMask)
Definition: exp.c:61
if(dx< 0)
Definition: linetemp.h:194
#define KernelMode
Definition: asm.h:34
#define CR0_MP
Definition: asm.h:246
#define CR0_EM
Definition: asm.h:247
#define CR0_TS
Definition: asm.h:248
#define EFLAGS_V86_MASK
Definition: ketypes.h:193
#define DR7_LEGAL
Definition: ketypes.h:161
#define RPL_MASK
Definition: ketypes.h:130
#define EFLAGS_IOPL
Definition: ketypes.h:189
#define DR6_LEGAL
Definition: asm.h:511
#define KGDT_R3_DATA
Definition: ketypes.h:126
#define KGDT_R3_CODE
Definition: ketypes.h:125
struct _FX_SAVE_AREA * PFX_SAVE_AREA
#define SIZE_OF_FX_REGISTERS
Definition: ketypes.h:245
#define CONTEXT_DEBUG_REGISTERS
Definition: nt_native.h:1373
#define CONTEXT_CONTROL
Definition: nt_native.h:1369
#define CONTEXT_INTEGER
Definition: nt_native.h:1370
#define CONTEXT_FLOATING_POINT
Definition: nt_native.h:1372
#define CONTEXT_SEGMENTS
Definition: nt_native.h:1371
#define SIZE_OF_80387_REGISTERS
Definition: nt_native.h:1356
ULONG KeI386FxsrPresent
Definition: cpu.c:33
FORCEINLINE BOOLEAN KiUserTrap(IN PKTRAP_FRAME TrapFrame)
Definition: ke.h:364
#define DR_MASK(x)
Definition: ke.h:15
FORCEINLINE ULONG Ke386SanitizeFlags(IN ULONG Eflags, IN KPROCESSOR_MODE Mode)
Definition: ke.h:740
VOID NTAPI KiFlushNPXState(IN FLOATING_SAVE_AREA *SaveArea)
ULONG KiMXCsrMask
Definition: cpu.c:30
FORCEINLINE ULONG Ke386SanitizeSeg(IN ULONG Cs, IN KPROCESSOR_MODE Mode)
Definition: ke.h:723
unsigned short USHORT
Definition: pedump.c:61
PVOID MmHighestUserAddress
Definition: rtlcompat.c:29
#define CONTEXT_EXTENDED_REGISTERS
ULONG TagWord
Definition: ketypes.h:471
ULONG StatusWord
Definition: ketypes.h:470
ULONG ControlWord
Definition: ketypes.h:469
ULONG DataOffset
Definition: ketypes.h:474
UCHAR RegisterArea[80]
Definition: ketypes.h:476
ULONG DataSelector
Definition: ketypes.h:475
ULONG ErrorSelector
Definition: ketypes.h:473
ULONG ErrorOffset
Definition: ketypes.h:472
ULONG DataSelector
Definition: ketypes.h:488
UCHAR RegisterArea[SIZE_OF_FX_REGISTERS]
Definition: ketypes.h:491
ULONG ErrorOffset
Definition: ketypes.h:485
ULONG MXCsr
Definition: ketypes.h:489
USHORT ControlWord
Definition: ketypes.h:481
USHORT TagWord
Definition: ketypes.h:483
USHORT ErrorOpcode
Definition: ketypes.h:484
ULONG DataOffset
Definition: ketypes.h:487
USHORT StatusWord
Definition: ketypes.h:482
ULONG ErrorSelector
Definition: ketypes.h:486
FNSAVE_FORMAT FnArea
Definition: ketypes.h:501
union _FX_SAVE_AREA::@2449 U
ULONG Cr0NpxState
Definition: ketypes.h:505
FXSAVE_FORMAT FxArea
Definition: ketypes.h:502
#define RtlCopyMemory(Destination, Source, Length)
Definition: typedefs.h:263
#define RtlZeroMemory(Destination, Length)
Definition: typedefs.h:262
uint32_t ULONG
Definition: typedefs.h:59
#define MAXIMUM_SUPPORTED_EXTENSION
Definition: x86context.h:35
_Requires_lock_held_ Interrupt _Releases_lock_ Interrupt _In_ _IRQL_restores_ KIRQL OldIrql
Definition: kefuncs.h:778
#define PsGetCurrentProcess
Definition: psfuncs.h:17
_In_ KPROCESSOR_MODE PreviousMode
Definition: sefuncs.h:103
unsigned char UCHAR
Definition: xmlstorage.h:181

◆ KeInitExceptions()

VOID NTAPI KeInitExceptions ( VOID  )

Definition at line 23 of file exp.c.

24{
25 ULONG i;
26 USHORT FlippedSelector;
27
28 /* Loop the IDT */
29 for (i = 0; i <= MAXIMUM_IDTVECTOR; i++)
30 {
31 /* Save the current Selector */
32 FlippedSelector = KiIdt[i].Selector;
33
34 /* Flip Selector and Extended Offset */
36 KiIdt[i].ExtendedOffset = FlippedSelector;
37 }
38}
#define MAXIMUM_IDTVECTOR
Definition: asm.h:280
KIDTENTRY KiIdt[MAXIMUM_IDTVECTOR+1]
Definition: except.c:50
USHORT Selector
Definition: ketypes.h:441
USHORT ExtendedOffset
Definition: ketypes.h:443

Referenced by KiSystemStartup().

◆ KeInvalidAccessAllowed()

BOOLEAN FASTCALL KeInvalidAccessAllowed ( IN PVOID TrapInformation  OPTIONAL)

Definition at line 756 of file exp.c.

757{
758 ULONG Eip;
759 PKTRAP_FRAME TrapFrame = TrapInformation;
761
762 /* Don't do anything if we didn't get a trap frame */
763 if (!TrapInformation) return FALSE;
764
765 /* Check where we came from */
766 switch (TrapFrame->SegCs)
767 {
768 /* Kernel mode */
769 case KGDT_R0_CODE:
770
771 /* Allow S-LIST Routine to fail */
773 break;
774
775 /* User code */
776 case KGDT_R3_CODE | RPL_MASK:
777
778 /* Allow S-LIST Routine to fail */
779 //Eip = (ULONG)KeUserPopEntrySListFault;
780 Eip = 0;
781 break;
782
783 default:
784
785 /* Anything else gets a bugcheck */
786 Eip = 0;
787 }
788
789 /* Return TRUE if we want to keep the system up */
790 return (TrapFrame->Eip == Eip) ? TRUE : FALSE;
791}
#define KGDT_R0_CODE
Definition: ketypes.h:123
VOID NTAPI ExpInterlockedPopEntrySListFault(VOID)
ULONG Eip
Definition: ketypes.h:321
USHORT SegCs
Definition: ketypes.h:450
#define NTAPI
Definition: typedefs.h:36

◆ KeRaiseUserException()

NTSTATUS NTAPI KeRaiseUserException ( IN NTSTATUS  ExceptionCode)

Definition at line 1114 of file exp.c.

1115{
1116 ULONG OldEip;
1117 PTEB Teb = KeGetCurrentThread()->Teb;
1118 PKTRAP_FRAME TrapFrame = KeGetCurrentThread()->TrapFrame;
1119
1120 /* Make sure we can access the TEB */
1121 _SEH2_TRY
1122 {
1123 /* Set the exception code */
1125 }
1127 {
1128 /* Return the exception code */
1130 }
1131 _SEH2_END;
1132
1133 /* Get the old EIP */
1134 OldEip = TrapFrame->Eip;
1135
1136 /* Change it to the user-mode dispatcher */
1138
1139 /* Return the old EIP */
1140 return (NTSTATUS)OldEip;
1141}
LONG NTSTATUS
Definition: precomp.h:26
_Inout_ PIRP _In_ NTSTATUS ExceptionCode
Definition: cdprocs.h:1774
#define ULONG_PTR
Definition: config.h:101
#define _SEH2_END
Definition: filesup.c:22
#define _SEH2_TRY
Definition: filesup.c:19
#define EXCEPTION_EXECUTE_HANDLER
Definition: excpt.h:85
PVOID KeRaiseUserExceptionDispatcher
Definition: ke.h:144
#define _SEH2_GetExceptionCode()
Definition: pseh2_64.h:159
#define _SEH2_EXCEPT(...)
Definition: pseh2_64.h:34
#define _SEH2_YIELD(__stmt)
Definition: pseh2_64.h:162
Definition: compat.h:836
LONG ExceptionCode
Definition: compat.h:853

◆ KeTrapFrameToContext()

VOID NTAPI KeTrapFrameToContext ( IN PKTRAP_FRAME  TrapFrame,
IN PKEXCEPTION_FRAME  ExceptionFrame,
IN OUT PCONTEXT  Context 
)

Definition at line 576 of file exp.c.

579{
580 PFX_SAVE_AREA FxSaveArea;
581 struct _AlignHack
582 {
583 UCHAR Hack[15];
584 FLOATING_SAVE_AREA UnalignedArea;
585 } FloatSaveBuffer;
586 FLOATING_SAVE_AREA *FloatSaveArea;
588 ULONG i;
589
590 /* Do this at APC_LEVEL */
593
594 /* Start with the Control flags */
595 if ((Context->ContextFlags & CONTEXT_CONTROL) == CONTEXT_CONTROL)
596 {
597 /* EBP, EIP and EFLAGS */
598 Context->Ebp = TrapFrame->Ebp;
599 Context->Eip = TrapFrame->Eip;
600 Context->EFlags = TrapFrame->EFlags;
601
602 /* Return the correct CS */
603 if (!(TrapFrame->SegCs & FRAME_EDITED) &&
604 !(TrapFrame->EFlags & EFLAGS_V86_MASK))
605 {
606 /* Get it from the Temp location */
607 Context->SegCs = TrapFrame->TempSegCs & 0xFFFF;
608 }
609 else
610 {
611 /* Return it directly */
612 Context->SegCs = TrapFrame->SegCs & 0xFFFF;
613 }
614
615 /* Get the Ss and ESP */
616 Context->SegSs = KiSsFromTrapFrame(TrapFrame);
617 Context->Esp = KiEspFromTrapFrame(TrapFrame);
618 }
619
620 /* Handle the Segments */
621 if ((Context->ContextFlags & CONTEXT_SEGMENTS) == CONTEXT_SEGMENTS)
622 {
623 /* Do V86 Mode first */
624 if (TrapFrame->EFlags & EFLAGS_V86_MASK)
625 {
626 /* Return from the V86 location */
627 Context->SegGs = TrapFrame->V86Gs & 0xFFFF;
628 Context->SegFs = TrapFrame->V86Fs & 0xFFFF;
629 Context->SegEs = TrapFrame->V86Es & 0xFFFF;
630 Context->SegDs = TrapFrame->V86Ds & 0xFFFF;
631 }
632 else
633 {
634 /* Check if this was a Kernel Trap */
635 if (TrapFrame->SegCs == KGDT_R0_CODE)
636 {
637 /* Set valid selectors */
638 TrapFrame->SegGs = 0;
639 TrapFrame->SegFs = KGDT_R0_PCR;
640 TrapFrame->SegEs = KGDT_R3_DATA | RPL_MASK;
641 TrapFrame->SegDs = KGDT_R3_DATA | RPL_MASK;
642 }
643
644 /* Return the segments */
645 Context->SegGs = TrapFrame->SegGs & 0xFFFF;
646 Context->SegFs = TrapFrame->SegFs & 0xFFFF;
647 Context->SegEs = TrapFrame->SegEs & 0xFFFF;
648 Context->SegDs = TrapFrame->SegDs & 0xFFFF;
649 }
650 }
651
652 /* Handle the simple registers */
653 if ((Context->ContextFlags & CONTEXT_INTEGER) == CONTEXT_INTEGER)
654 {
655 /* Return them directly */
656 Context->Eax = TrapFrame->Eax;
657 Context->Ebx = TrapFrame->Ebx;
658 Context->Ecx = TrapFrame->Ecx;
659 Context->Edx = TrapFrame->Edx;
660 Context->Esi = TrapFrame->Esi;
661 Context->Edi = TrapFrame->Edi;
662 }
663
664 /* Handle extended registers */
665 if (((Context->ContextFlags & CONTEXT_EXTENDED_REGISTERS) ==
667 {
668 /* Get the FX Save Area */
669 FxSaveArea = (PFX_SAVE_AREA)(TrapFrame + 1);
670
671 /* Flush the NPX State */
673
674 /* Copy the registers */
675 RtlCopyMemory(&Context->ExtendedRegisters[0],
676 &FxSaveArea->U.FxArea,
678 }
679
680 /* Handle Floating Point */
681 if (((Context->ContextFlags & CONTEXT_FLOATING_POINT) ==
682 CONTEXT_FLOATING_POINT) && KiUserTrap(TrapFrame))
683 {
684 /* Get the FX Save Area */
685 FxSaveArea = (PFX_SAVE_AREA)(TrapFrame + 1);
686
687 /* Check if we have Fxsr support */
689 {
690 /* Align the floating area to 16-bytes */
691 FloatSaveArea = (FLOATING_SAVE_AREA*)((ULONG_PTR)&FloatSaveBuffer.UnalignedArea &~ 0xF);
692
693 /* Get the State */
694 KiFlushNPXState(FloatSaveArea);
695 }
696 else
697 {
698 /* We don't, use the FN area and flush the NPX State */
699 FloatSaveArea = (FLOATING_SAVE_AREA*)&FxSaveArea->U.FnArea;
701 }
702
703 /* Copy structure */
704 Context->FloatSave.ControlWord = FloatSaveArea->ControlWord;
705 Context->FloatSave.StatusWord = FloatSaveArea->StatusWord;
706 Context->FloatSave.TagWord = FloatSaveArea->TagWord;
707 Context->FloatSave.ErrorOffset = FloatSaveArea->ErrorOffset;
708 Context->FloatSave.ErrorSelector = FloatSaveArea->ErrorSelector;
709 Context->FloatSave.DataOffset = FloatSaveArea->DataOffset;
710 Context->FloatSave.DataSelector = FloatSaveArea->DataSelector;
711 Context->FloatSave.Cr0NpxState = FxSaveArea->Cr0NpxState;
712
713 /* Loop registers */
714 for (i = 0; i < SIZE_OF_80387_REGISTERS; i++)
715 {
716 /* Copy them */
717 Context->FloatSave.RegisterArea[i] = FloatSaveArea->RegisterArea[i];
718 }
719 }
720
721 /* Handle debug registers */
722 if ((Context->ContextFlags & CONTEXT_DEBUG_REGISTERS) ==
724 {
725 /* Make sure DR7 is valid */
726 if (TrapFrame->Dr7 & ~DR7_RESERVED_MASK)
727 {
728 /* Copy the debug registers */
729 Context->Dr0 = TrapFrame->Dr0;
730 Context->Dr1 = TrapFrame->Dr1;
731 Context->Dr2 = TrapFrame->Dr2;
732 Context->Dr3 = TrapFrame->Dr3;
733 Context->Dr6 = TrapFrame->Dr6;
734
735 /* Update DR7 */
736 Context->Dr7 = KiUpdateDr7(TrapFrame->Dr7);
737 }
738 else
739 {
740 /* Otherwise clear DR registers */
741 Context->Dr0 =
742 Context->Dr1 =
743 Context->Dr2 =
744 Context->Dr3 =
745 Context->Dr6 =
746 Context->Dr7 = 0;
747 }
748 }
749
750 /* Restore IRQL */
752}
ULONG NTAPI KiEspFromTrapFrame(IN PKTRAP_FRAME TrapFrame)
Definition: exp.c:137
ULONG FASTCALL KiUpdateDr7(IN ULONG Dr7)
Definition: exp.c:42
ULONG NTAPI KiSsFromTrapFrame(IN PKTRAP_FRAME TrapFrame)
Definition: exp.c:220
#define DR7_RESERVED_MASK
Definition: asm.h:515
#define KGDT_R0_PCR
Definition: ketypes.h:128
#define FRAME_EDITED
Definition: ke.h:68
UCHAR RegisterArea[SIZE_OF_80387_REGISTERS]
Definition: nt_native.h:1390
uint32_t ULONG_PTR
Definition: typedefs.h:65

Referenced by _IRQL_requires_(), Ke386SetIOPL(), KiDispatchException(), KiInitializeUserApc(), KiSaveProcessorState(), and PspGetContext().

◆ Ki386AdjustEsp0()

VOID NTAPI Ki386AdjustEsp0 ( IN PKTRAP_FRAME  TrapFrame)

Definition at line 280 of file exp.c.

281{
284 ULONG EFlags;
285
286 /* Get the current thread's stack */
288 Stack = (ULONG_PTR)Thread->InitialStack;
289
290 /* Check if we are in V8086 mode */
291 if (!(TrapFrame->EFlags & EFLAGS_V86_MASK))
292 {
293 /* Bias the stack for the V86 segments */
294 Stack -= sizeof(KTRAP_FRAME) -
296 }
297
298 /* Bias the stack for the FPU area */
299 Stack -= sizeof(FX_SAVE_AREA);
300
301 /* Disable interrupts */
302 EFlags = __readeflags();
303 _disable();
304
305 /* Set new ESP0 value in the TSS */
306 KeGetPcr()->TSS->Esp0 = Stack;
307
308 /* Restore old interrupt state */
309 __writeeflags(EFlags);
310}
_In_opt_ PFILE_OBJECT _In_opt_ PETHREAD Thread
Definition: fltkernel.h:2653
void __cdecl _disable(void)
Definition: intrin_arm.h:365
__INTRIN_INLINE void __writeeflags(uintptr_t Value)
Definition: intrin_x86.h:1669
__INTRIN_INLINE uintptr_t __readeflags(void)
Definition: intrin_x86.h:1674
struct _KTRAP_FRAME KTRAP_FRAME
#define KeGetPcr()
Definition: ketypes.h:81
struct _FX_SAVE_AREA FX_SAVE_AREA
#define FIELD_OFFSET(t, f)
Definition: typedefs.h:255
_In_ WDFREQUEST _In_ PIO_STACK_LOCATION Stack
Definition: wdfrequest.h:639

Referenced by KeContextToTrapFrame(), KiVdmOpcodeIRET(), KiVdmOpcodePOPF(), and VdmSwapContext().

◆ KiDispatchException()

VOID NTAPI KiDispatchException ( IN PEXCEPTION_RECORD  ExceptionRecord,
IN PKEXCEPTION_FRAME  ExceptionFrame,
IN PKTRAP_FRAME  TrapFrame,
IN KPROCESSOR_MODE  PreviousMode,
IN BOOLEAN  FirstChance 
)

Definition at line 795 of file exp.c.

800{
802 EXCEPTION_RECORD LocalExceptRecord;
803
804 /* Increase number of Exception Dispatches */
805 KeGetCurrentPrcb()->KeExceptionDispatchCount++;
806
807 /* Set the context flags */
809
810 /* Check if User Mode or if the kernel debugger is enabled */
812 {
813 /* Add the FPU Flag */
814 Context.ContextFlags |= CONTEXT_FLOATING_POINT;
815
816 /* Check for NPX Support */
818 {
819 /* Save those too */
820 Context.ContextFlags |= CONTEXT_EXTENDED_REGISTERS;
821 }
822 }
823
824 /* Get a Context */
825 KeTrapFrameToContext(TrapFrame, ExceptionFrame, &Context);
826
827 /* Look at our exception code */
828 switch (ExceptionRecord->ExceptionCode)
829 {
830 /* Breakpoint */
832
833 /* Decrement EIP by one */
834 Context.Eip--;
835 break;
836
837 /* Internal exception */
839
840 /* Set correct code */
841 ExceptionRecord->ExceptionCode = STATUS_ACCESS_VIOLATION;
842 if (PreviousMode == UserMode)
843 {
844 /* FIXME: Handle no execute */
845 }
846 break;
847 }
848
849 /* Sanity check */
851 (Context.EFlags & EFLAGS_V86_MASK)));
852
853 /* Handle kernel-mode first, it's simpler */
855 {
856 /* Check if this is a first-chance exception */
857 if (FirstChance != FALSE)
858 {
859 /* Break into the debugger for the first time */
860 if (KiDebugRoutine(TrapFrame,
861 ExceptionFrame,
862 ExceptionRecord,
863 &Context,
865 FALSE))
866 {
867 /* Exception was handled */
868 goto Handled;
869 }
870
871 /* If the Debugger couldn't handle it, dispatch the exception */
872 if (RtlDispatchException(ExceptionRecord, &Context)) goto Handled;
873 }
874
875 /* This is a second-chance exception, only for the debugger */
876 if (KiDebugRoutine(TrapFrame,
877 ExceptionFrame,
878 ExceptionRecord,
879 &Context,
881 TRUE))
882 {
883 /* Exception was handled */
884 goto Handled;
885 }
886
887 /* Third strike; you're out */
888 KeBugCheckEx(KMODE_EXCEPTION_NOT_HANDLED,
889 ExceptionRecord->ExceptionCode,
890 (ULONG_PTR)ExceptionRecord->ExceptionAddress,
891 (ULONG_PTR)TrapFrame,
892 0);
893 }
894 else
895 {
896 /* User mode exception, was it first-chance? */
897 if (FirstChance)
898 {
899 /*
900 * Break into the kernel debugger unless a user mode debugger
901 * is present or user mode exceptions are ignored, except if this
902 * is a debug service which we must always pass to KD
903 */
904 if ((!(PsGetCurrentProcess()->DebugPort) &&
906 (KdIsThisAKdTrap(ExceptionRecord,
907 &Context,
908 PreviousMode)))
909 {
910 /* Call the kernel debugger */
911 if (KiDebugRoutine(TrapFrame,
912 ExceptionFrame,
913 ExceptionRecord,
914 &Context,
916 FALSE))
917 {
918 /* Exception was handled */
919 goto Handled;
920 }
921 }
922
923 /* Forward exception to user mode debugger */
924 if (DbgkForwardException(ExceptionRecord, TRUE, FALSE)) return;
925
926 /* Set up the user-stack */
927DispatchToUser:
929 {
930 ULONG Size;
931 ULONG_PTR Stack, NewStack;
932
933 /* Make sure we have a valid SS and that this isn't V86 mode */
934 if ((TrapFrame->HardwareSegSs != (KGDT_R3_DATA | RPL_MASK)) ||
935 (TrapFrame->EFlags & EFLAGS_V86_MASK))
936 {
937 /* Raise an exception instead */
938 LocalExceptRecord.ExceptionCode = STATUS_ACCESS_VIOLATION;
939 LocalExceptRecord.ExceptionFlags = 0;
940 LocalExceptRecord.NumberParameters = 0;
941 RtlRaiseException(&LocalExceptRecord);
942 }
943
944 /* Align context size and get stack pointer */
945 Size = (sizeof(CONTEXT) + 3) & ~3;
946 Stack = (Context.Esp & ~3) - Size;
947
948 /* Probe stack and copy Context */
949 ProbeForWrite((PVOID)Stack, Size, sizeof(ULONG));
951
952 /* Align exception record size and get stack pointer */
953 Size = (sizeof(EXCEPTION_RECORD) -
955 ExceptionRecord->NumberParameters) *
956 sizeof(ULONG) + 3) & ~3;
957 NewStack = Stack - Size;
958
959 /* Probe stack and copy exception record */
960 ProbeForWrite((PVOID)(NewStack - 2 * sizeof(ULONG_PTR)),
961 Size + 2 * sizeof(ULONG_PTR),
962 sizeof(ULONG));
963 RtlCopyMemory((PVOID)NewStack, ExceptionRecord, Size);
964
965 /* Now write the two params for the user-mode dispatcher */
966 *(PULONG_PTR)(NewStack - 1 * sizeof(ULONG_PTR)) = Stack;
967 *(PULONG_PTR)(NewStack - 2 * sizeof(ULONG_PTR)) = NewStack;
968
969 /* Set new Stack Pointer */
970 KiSsToTrapFrame(TrapFrame, KGDT_R3_DATA);
971 KiEspToTrapFrame(TrapFrame, NewStack - 2 * sizeof(ULONG_PTR));
972
973 /* Force correct segments */
974 TrapFrame->SegCs = Ke386SanitizeSeg(KGDT_R3_CODE, PreviousMode);
975 TrapFrame->SegDs = Ke386SanitizeSeg(KGDT_R3_DATA, PreviousMode);
976 TrapFrame->SegEs = Ke386SanitizeSeg(KGDT_R3_DATA, PreviousMode);
977 TrapFrame->SegFs = Ke386SanitizeSeg(KGDT_R3_TEB, PreviousMode);
978 TrapFrame->SegGs = 0;
979
980 /* Set EIP to the User-mode Dispatcher */
981 TrapFrame->Eip = (ULONG)KeUserExceptionDispatcher;
982
983 /* Dispatch exception to user-mode */
984 _SEH2_YIELD(return);
985 }
987 {
988 /* Check if we got a stack overflow and raise that instead */
989 if ((NTSTATUS)LocalExceptRecord.ExceptionCode ==
991 {
992 /* Copy the exception address and record */
993 LocalExceptRecord.ExceptionAddress =
994 ExceptionRecord->ExceptionAddress;
995 RtlCopyMemory(ExceptionRecord,
996 (PVOID)&LocalExceptRecord,
997 sizeof(EXCEPTION_RECORD));
998
999 /* Do the exception again */
1000 _SEH2_YIELD(goto DispatchToUser);
1001 }
1002 }
1003 _SEH2_END;
1004
1005 DPRINT("First chance exception in %.16s, ExceptionCode: %lx, ExceptionAddress: %p, P0: %lx, P1: %lx\n",
1006 PsGetCurrentProcess()->ImageFileName,
1007 ExceptionRecord->ExceptionCode,
1008 ExceptionRecord->ExceptionAddress,
1009 ExceptionRecord->ExceptionInformation[0],
1010 ExceptionRecord->ExceptionInformation[1]);
1011 }
1012
1013 /* Try second chance */
1014 if (DbgkForwardException(ExceptionRecord, TRUE, TRUE))
1015 {
1016 /* Handled, get out */
1017 return;
1018 }
1019 else if (DbgkForwardException(ExceptionRecord, FALSE, TRUE))
1020 {
1021 /* Handled, get out */
1022 return;
1023 }
1024
1025 /* 3rd strike, kill the process */
1026 DPRINT1("Kill %.16s, ExceptionCode: %lx, ExceptionAddress: %p, BaseAddress: %p, P0: %lx, P1: %lx\n",
1027 PsGetCurrentProcess()->ImageFileName,
1028 ExceptionRecord->ExceptionCode,
1029 ExceptionRecord->ExceptionAddress,
1030 PsGetCurrentProcess()->SectionBaseAddress,
1031 ExceptionRecord->ExceptionInformation[0],
1032 ExceptionRecord->ExceptionInformation[1]);
1033
1034 ZwTerminateProcess(NtCurrentProcess(), ExceptionRecord->ExceptionCode);
1035 KeBugCheckEx(KMODE_EXCEPTION_NOT_HANDLED,
1036 ExceptionRecord->ExceptionCode,
1037 (ULONG_PTR)ExceptionRecord->ExceptionAddress,
1038 (ULONG_PTR)TrapFrame,
1039 0);
1040 }
1041
1042Handled:
1043 /* Convert the context back into Trap/Exception Frames */
1045 ExceptionFrame,
1046 TrapFrame,
1047 Context.ContextFlags,
1048 PreviousMode);
1049 return;
1050}
VOID NTAPI KeTrapFrameToContext(IN PKTRAP_FRAME TrapFrame, IN PKEXCEPTION_FRAME ExceptionFrame, IN OUT PCONTEXT Context)
Definition: exp.c:86
VOID NTAPI KeContextToTrapFrame(IN PCONTEXT Context, IN OUT PKEXCEPTION_FRAME ExceptionFrame, IN OUT PKTRAP_FRAME TrapFrame, IN ULONG ContextFlags, IN KPROCESSOR_MODE PreviousMode)
Definition: exp.c:19
#define DPRINT1
Definition: precomp.h:8
BOOLEAN NTAPI DbgkForwardException(IN PEXCEPTION_RECORD ExceptionRecord, IN BOOLEAN DebugPort, IN BOOLEAN SecondChance)
Definition: dbgkobj.c:317
#define EXCEPTION_MAXIMUM_PARAMETERS
Definition: compat.h:206
struct _EXCEPTION_RECORD EXCEPTION_RECORD
VOID NTAPI ProbeForWrite(IN PVOID Address, IN SIZE_T Length, IN ULONG Alignment)
Definition: exintrin.c:143
DBGKD_GET_VERSION64 KdVersionBlock
Definition: kddata.c:496
BOOLEAN KdIgnoreUmExceptions
Definition: kddata.c:86
PKDEBUG_ROUTINE KiDebugRoutine
Definition: kddata.c:74
BOOLEAN NTAPI KdIsThisAKdTrap(IN PEXCEPTION_RECORD ExceptionRecord, IN PCONTEXT Context, IN KPROCESSOR_MODE PreviousMode)
Definition: kdtrap.c:317
#define ASSERT(a)
Definition: mode.c:44
#define UserMode
Definition: asm.h:35
FORCEINLINE struct _KPRCB * KeGetCurrentPrcb(VOID)
Definition: ketypes.h:1148
#define KGDT_R3_TEB
Definition: ketypes.h:129
#define KI_EXCEPTION_ACCESS_VIOLATION
Definition: ketypes.h:144
NTSYSAPI BOOLEAN NTAPI RtlDispatchException(_In_ PEXCEPTION_RECORD ExceptionRecord, _In_ PCONTEXT Context)
Definition: except.c:87
NTSYSAPI VOID NTAPI RtlRaiseException(_In_ PEXCEPTION_RECORD ExceptionRecord)
struct _CONTEXT CONTEXT
#define NtCurrentProcess()
Definition: nt_native.h:1657
#define CONTEXT_FULL
Definition: nt_native.h:1375
PVOID KeUserExceptionDispatcher
Definition: ke.h:143
#define STATUS_STACK_OVERFLOW
Definition: ntstatus.h:489
#define STATUS_BREAKPOINT
Definition: ntstatus.h:184
#define STATUS_ACCESS_VIOLATION
Definition: ntstatus.h:242
#define _SEH2_GetExceptionInformation()
Definition: pseh2_64.h:158
VOID NTAPI KeBugCheckEx(_In_ ULONG BugCheckCode, _In_ ULONG_PTR BugCheckParameter1, _In_ ULONG_PTR BugCheckParameter2, _In_ ULONG_PTR BugCheckParameter3, _In_ ULONG_PTR BugCheckParameter4)
Definition: rtlcompat.c:108
#define DPRINT
Definition: sndvol32.h:71
DWORD ExceptionCode
Definition: compat.h:208
DWORD NumberParameters
Definition: compat.h:212
DWORD ExceptionFlags
Definition: compat.h:209
PVOID ExceptionAddress
Definition: compat.h:211
uint32_t * PULONG_PTR
Definition: typedefs.h:65
_Must_inspect_result_ _In_ WDFDEVICE _In_ PWDF_DEVICE_PROPERTY_DATA _In_ DEVPROPTYPE _In_ ULONG Size
Definition: wdfdevice.h:4533
_In_ BOOLEAN Handled
Definition: ketypes.h:349

◆ KiDispatchExceptionFromTrapFrame()

DECLSPEC_NORETURN VOID NTAPI KiDispatchExceptionFromTrapFrame ( IN NTSTATUS  Code,
IN ULONG  Flags,
IN ULONG_PTR  Address,
IN ULONG  ParameterCount,
IN ULONG_PTR  Parameter1,
IN ULONG_PTR  Parameter2,
IN ULONG_PTR  Parameter3,
IN PKTRAP_FRAME  TrapFrame 
)

Definition at line 1055 of file exp.c.

1063{
1064 EXCEPTION_RECORD ExceptionRecord;
1065
1066 /* Build the exception record */
1067 ExceptionRecord.ExceptionCode = Code;
1068 ExceptionRecord.ExceptionFlags = Flags;
1069 ExceptionRecord.ExceptionRecord = NULL;
1070 ExceptionRecord.ExceptionAddress = (PVOID)Address;
1071 ExceptionRecord.NumberParameters = ParameterCount;
1072 if (ParameterCount)
1073 {
1074 /* Copy extra parameters */
1075 ExceptionRecord.ExceptionInformation[0] = Parameter1;
1076 ExceptionRecord.ExceptionInformation[1] = Parameter2;
1077 ExceptionRecord.ExceptionInformation[2] = Parameter3;
1078 }
1079
1080 /* Now go dispatch the exception */
1081 KiDispatchException(&ExceptionRecord,
1082 NULL,
1083 TrapFrame,
1084 TrapFrame->EFlags & EFLAGS_V86_MASK ?
1085 -1 : KiUserTrap(TrapFrame),
1086 TRUE);
1087
1088 /* Return from this trap */
1089 KiEoiHelper(TrapFrame);
1090}
#define Code
Definition: deflate.h:80
VOID NTAPI KiDispatchException(IN PEXCEPTION_RECORD ExceptionRecord, IN PKEXCEPTION_FRAME ExceptionFrame, IN PKTRAP_FRAME TrapFrame, IN KPROCESSOR_MODE PreviousMode, IN BOOLEAN FirstChance)
Definition: exp.c:795
DECLSPEC_NORETURN VOID FASTCALL KiEoiHelper(IN PKTRAP_FRAME TrapFrame)
Definition: traphdlr.c:126
static WCHAR Address[46]
Definition: ping.c:68
struct _EXCEPTION_RECORD * ExceptionRecord
Definition: compat.h:210
ULONG_PTR ExceptionInformation[EXCEPTION_MAXIMUM_PARAMETERS]
Definition: compat.h:213
void * PVOID
Definition: typedefs.h:50
_Must_inspect_result_ _In_ ULONG Flags
Definition: wsk.h:170

Referenced by KiDebugHandler(), KiDispatchException0Args(), KiDispatchException1Args(), KiDispatchException2Args(), KiRaiseSecurityCheckFailureHandler(), and KiTrap0EHandler().

◆ KiEspFromTrapFrame()

ULONG NTAPI KiEspFromTrapFrame ( IN PKTRAP_FRAME  TrapFrame)

Definition at line 137 of file exp.c.

138{
139 /* Check if this is user-mode or V86 */
140 if (KiUserTrap(TrapFrame) ||
141 (TrapFrame->EFlags & EFLAGS_V86_MASK))
142 {
143 /* Return it directly */
144 return TrapFrame->HardwareEsp;
145 }
146 else
147 {
148 /* Edited frame */
149 if (!(TrapFrame->SegCs & FRAME_EDITED))
150 {
151 /* Return edited value */
152 return TrapFrame->TempEsp;
153 }
154 else
155 {
156 /* Virgin frame, calculate */
157 return (ULONG)&TrapFrame->HardwareEsp;
158 }
159 }
160}

Referenced by KeTrapFrameToContext(), and KiEspToTrapFrame().

◆ KiEspToTrapFrame()

VOID NTAPI KiEspToTrapFrame ( IN PKTRAP_FRAME  TrapFrame,
IN ULONG  Esp 
)

Definition at line 164 of file exp.c.

166{
168 ULONG Previous;
169
170 /* Raise to APC_LEVEL if needed */
173
174 /* Get the old ESP */
175 Previous = KiEspFromTrapFrame(TrapFrame);
176
177 /* Check if this is user-mode or V86 */
178 if (KiUserTrap(TrapFrame) ||
179 (TrapFrame->EFlags & EFLAGS_V86_MASK))
180 {
181 /* Write it directly */
182 TrapFrame->HardwareEsp = Esp;
183 }
184 else
185 {
186 /* Don't allow ESP to be lowered, this is illegal */
187 if (Esp < Previous) KeBugCheckEx(SET_OF_INVALID_CONTEXT,
188 Esp,
189 Previous,
190 (ULONG_PTR)TrapFrame,
191 0);
192
193 /* Create an edit frame, check if it was alrady */
194 if (!(TrapFrame->SegCs & FRAME_EDITED))
195 {
196 /* Update the value */
197 TrapFrame->TempEsp = Esp;
198 }
199 else
200 {
201 /* Check if ESP changed */
202 if (Previous != Esp)
203 {
204 /* Save CS */
205 TrapFrame->TempSegCs = TrapFrame->SegCs;
206 TrapFrame->SegCs &= ~FRAME_EDITED;
207
208 /* Save ESP */
209 TrapFrame->TempEsp = Esp;
210 }
211 }
212 }
213
214 /* Restore IRQL */
216}

Referenced by KeContextToTrapFrame(), and KiDispatchException().

◆ KiRecordDr7()

BOOLEAN FASTCALL KiRecordDr7 ( OUT PULONG  Dr7Ptr,
OUT PULONG  DrMask 
)

Definition at line 61 of file exp.c.

63{
64 ULONG NewMask, Mask;
66
67 /* Check if the caller gave us a mask */
68 if (!DrMask)
69 {
70 /* He didn't, use the one from the thread */
71 Mask = KeGetCurrentThread()->Header.DebugActive;
72 }
73 else
74 {
75 /* He did, read it */
76 Mask = *DrMask;
77 }
78
79 /* Sanity check */
80 ASSERT((*Dr7Ptr & DR7_RESERVED_MASK) == 0);
81
82 /* Check if DR7 is empty */
83 NewMask = Mask;
84 if (!(*Dr7Ptr))
85 {
86 /* Assume failure */
87 Result = FALSE;
88
89 /* Check the DR mask */
90 NewMask &= ~(DR_MASK(7));
91 if (NewMask & DR_REG_MASK)
92 {
93 /* Set the active mask */
94 NewMask |= DR_MASK(DR7_OVERRIDE_V);
95
96 /* Set DR7 override */
97 *Dr7Ptr |= DR7_OVERRIDE_MASK;
98 }
99 else
100 {
101 /* Sanity check */
102 ASSERT(NewMask == 0);
103 }
104 }
105 else
106 {
107 /* Check if we have a mask or not */
108 Result = NewMask ? TRUE: FALSE;
109
110 /* Update the mask to disable debugging */
111 NewMask &= ~(DR_MASK(DR7_OVERRIDE_V));
112 NewMask |= DR_MASK(7);
113 }
114
115 /* Check if caller wants the new mask */
116 if (DrMask)
117 {
118 /* Update it */
119 *DrMask = NewMask;
120 }
121 else
122 {
123 /* Check if the mask changed */
124 if (Mask != NewMask)
125 {
126 /* Update it */
127 KeGetCurrentThread()->Header.DebugActive = (UCHAR)NewMask;
128 }
129 }
130
131 /* Return the result */
132 return Result;
133}
unsigned int Mask
Definition: fpcontrol.c:82
#define DR7_OVERRIDE_V
Definition: asm.h:514
#define DR7_OVERRIDE_MASK
Definition: asm.h:516
#define DR_REG_MASK
Definition: ke.h:16
_At_(*)(_In_ PWSK_CLIENT Client, _In_opt_ PUNICODE_STRING NodeName, _In_opt_ PUNICODE_STRING ServiceName, _In_opt_ ULONG NameSpace, _In_opt_ GUID *Provider, _In_opt_ PADDRINFOEXW Hints, _Outptr_ PADDRINFOEXW *Result, _In_opt_ PEPROCESS OwningProcess, _In_opt_ PETHREAD OwningThread, _Inout_ PIRP Irp Result)(Mem)) NTSTATUS(WSKAPI *PFN_WSK_GET_ADDRESS_INFO
Definition: wsk.h:409

Referenced by KeContextToTrapFrame().

◆ KiSsFromTrapFrame()

ULONG NTAPI KiSsFromTrapFrame ( IN PKTRAP_FRAME  TrapFrame)

Definition at line 220 of file exp.c.

221{
222 /* Check if this was V86 Mode */
223 if (TrapFrame->EFlags & EFLAGS_V86_MASK)
224 {
225 /* Just return it */
226 return TrapFrame->HardwareSegSs;
227 }
228 else if (KiUserTrap(TrapFrame))
229 {
230 /* User mode, return the User SS */
231 return TrapFrame->HardwareSegSs | RPL_MASK;
232 }
233 else
234 {
235 /* Kernel mode */
236 return KGDT_R0_DATA;
237 }
238}
#define KGDT_R0_DATA
Definition: ketypes.h:124

Referenced by KeTrapFrameToContext().

◆ KiSsToTrapFrame()

VOID NTAPI KiSsToTrapFrame ( IN PKTRAP_FRAME  TrapFrame,
IN ULONG  Ss 
)

Definition at line 242 of file exp.c.

244{
245 /* Remove the high-bits */
246 Ss &= 0xFFFF;
247
248 /* If this was V86 Mode */
249 if (TrapFrame->EFlags & EFLAGS_V86_MASK)
250 {
251 /* Just write it */
252 TrapFrame->HardwareSegSs = Ss;
253 }
254 else if (KiUserTrap(TrapFrame))
255 {
256 /* Usermode, save the User SS */
257 TrapFrame->HardwareSegSs = Ss | RPL_MASK;
258 }
259}

Referenced by KeContextToTrapFrame(), and KiDispatchException().

◆ KiSystemFatalException()

DECLSPEC_NORETURN VOID FASTCALL KiSystemFatalException ( IN ULONG  ExceptionCode,
IN PKTRAP_FRAME  TrapFrame 
)

Definition at line 1095 of file exp.c.

1097{
1098 /* Bugcheck the system */
1099 KeBugCheckWithTf(UNEXPECTED_KERNEL_MODE_TRAP,
1101 0,
1102 0,
1103 0,
1104 TrapFrame);
1105}
DECLSPEC_NORETURN VOID NTAPI KeBugCheckWithTf(ULONG BugCheckCode, ULONG_PTR BugCheckParameter1, ULONG_PTR BugCheckParameter2, ULONG_PTR BugCheckParameter3, ULONG_PTR BugCheckParameter4, PKTRAP_FRAME Tf)

Referenced by KiTrap02Handler(), KiTrap05Handler(), KiTrap09Handler(), KiTrap0AHandler(), KiTrap0BHandler(), KiTrap0CHandler(), KiTrap0DHandler(), KiTrap0FHandler(), and KiTrap11Handler().

◆ KiTagWordFnsaveToFxsave()

USHORT NTAPI KiTagWordFnsaveToFxsave ( USHORT  TagWord)

Definition at line 263 of file exp.c.

264{
265 INT FxTagWord = ~TagWord;
266
267 /*
268 * Empty is now 00, any 2 bits containing 1 mean valid
269 * Now convert the rest (11->0 and the rest to 1)
270 */
271 FxTagWord = (FxTagWord | (FxTagWord >> 1)) & 0x5555; /* 0V0V0V0V0V0V0V0V */
272 FxTagWord = (FxTagWord | (FxTagWord >> 1)) & 0x3333; /* 00VV00VV00VV00VV */
273 FxTagWord = (FxTagWord | (FxTagWord >> 2)) & 0x0f0f; /* 0000VVVV0000VVVV */
274 FxTagWord = (FxTagWord | (FxTagWord >> 4)) & 0x00ff; /* 00000000VVVVVVVV */
275 return FxTagWord;
276}
int32_t INT
Definition: typedefs.h:58

Referenced by KeContextToTrapFrame().

◆ KiUpdateDr7()

ULONG FASTCALL KiUpdateDr7 ( IN ULONG  Dr7)

Definition at line 42 of file exp.c.

43{
44 ULONG DebugMask = KeGetCurrentThread()->Header.DebugActive;
45
46 /* Check if debugging is enabled */
47 if (DebugMask & DR_MASK(DR7_OVERRIDE_V))
48 {
49 /* Sanity checks */
50 ASSERT((DebugMask & DR_REG_MASK) != 0);
52 return 0;
53 }
54
55 /* Return DR7 itself */
56 return Dr7;
57}

Referenced by KeTrapFrameToContext().