// N.B. The size of this structure cannot change since it has been exported.
// N.B. The following two members MUST be together.
// N.B. The user APC pending field must be the last member of this structure.
// whether the APC was inserted.
;    any pending user mode APCs.
test    byte ptr [TFrame]+TsEflags+2, EFLAGS_V86_MASK/010000h ; is previous mode v86?
test    byte ptr [TFrame]+TsSegCs,MODE_MASK ; is previous mode user mode?
; call the APC delivery routine.
to this routine IRQL is set to APC_LEVEL.
to be valid if, and only if, the previous mode is user.
// then back up the PC to the start of the SLIST pop.
// exception from being raised within an APC routine.
// Restore the previous thread trap frame address.
// if any kernel mode APC's can be delivered.
// deliver a user APC.
// and determine the type of APC.
//      APC queue is found to be non-empty.
// First entry in the kernel APC queue is a special kernel APC.
// First entry in the kernel APC queue is a normal kernel APC.
// the APC queue, and clear kernel APC in progress.
// another user mode APC can be processed.
// a user mode APC.
// one or more entries, then release the APC lock and exit.
// continue in user mode at the user mode APC dispatch routine.
// has been bypassed and the context is already on the user stack.
// N.B. The context record has been probed for write access.
// context record, and probe user stack for writeability.
// record on the user stack.
// Fill in machine frame information.
// Initialize the user APC parameters.
//      to obtain the context of the current thread.
// Home address for the parameter registers.
// Page fault load/store indicator.
//    0 - interrupt frame.
//    1 - exception frame.
//    2 - service frame.
//      are not saved for system calls.
// Gsbase is only used if the previous mode was kernel.
// GsSwap is only used if the previous mode was user.
// Page fault address or context record address if user APC bypass.
// N.B. Either AMD64 or EM64T information is stored in the following locations.
// Previous trap frame address.
// saved in system service trap frames.
// pointer during trap processing and is saved in all trap frames.
// Information pushed by hardware.
// invalid opcode and general protection fault routines.
;             trapframe built by KiSystemService.
;    ContextRecord (ebp+8: after setup) = Supplies a pointer to a context rec.
;       whether alert should be tested for the previous processor mode.
;    status code is returned.
; is an atomic entity, so we don't need to allocate any other space here.
or      eax,eax                 ; return value 0?
; Check to determine if alert should be tested for the previous processor mode.
mov     al,byte ptr [ebx]+ThPreviousMode ; No need to xor eax, eax.
specified exception and trap frames for the continue system service.
ContextRecord - Supplies a pointer to a context record.
ExceptionFrame - Supplies a pointer to an exception frame.
TrapFrame - Supplies a pointer to a trap frame.
to the specified exception and trap frames.
// Synchronize with other context operations.
// If the current IRQL is less than APC_LEVEL, then raise IRQL to APC level.