VOID KiUserApcDispatcher( __in PCONTEXT Context, __in PVOID ApcContext, __in PVOID Argument1, __in PVOID Argument2, __in PKNORMAL_ROUTINE ApcRoutine ) { NTSTATUS Status; try_again: // // A custom calling convention is used, the actual implementation is not C. // // // Call the user APC routine. Note that in Windows x64, the user APC routine // has a hidden additional (fourth) argument that does not strictly conform to // the standard KNORMAL_ROUTINE procedure type. This hidden argument is made // possible by virtue of the fact that the x64 calling convention passes // arguments in registers. // #if defined(_WIN64) ApcRoutine( ApcContext, Argument1, Argument2, Context ); #else ApcRoutine( ApcContext, Argument1, Argument2 ); #endif // // Continue execution. Note that the TestAlert parameter is set to TRUE. // This will invoke the next queued user mode APC, if any exists. Otherwise, // control is resumed at the specified machine register context. In either // case, NtContinue should never normally "return" to its caller; control is // hard transferred to either the desired context, or to KiUserApcDispatcher. // Status = NtContinue( Context, TRUE ); if (Status == STATUS_SUCCESS) goto try_again; RtlRaiseStatus( Status ); // // No return from RtlRaiseStatus. // }