Main Page | Class Hierarchy | Class List | File List | Class Members | File Members

apcuser.c

Go to the documentation of this file.
00001 /*++ 00002 00003 Copyright (c) 1990 Microsoft Corporation 00004 00005 Module Name: 00006 00007 apcuser.c 00008 00009 Abstract: 00010 00011 This module implements the machine dependent code necessary to initialize 00012 a user mode APC. 00013 00014 Author: 00015 00016 David N. Cutler (davec) 23-Apr-1990 00017 00018 Environment: 00019 00020 Kernel mode only, IRQL APC_LEVEL. 00021 00022 Revision History: 00023 00024 --*/ 00025 00026 #include "ki.h" 00027 00028 VOID 00029 KiInitializeUserApc ( 00030 IN PKEXCEPTION_FRAME ExceptionFrame, 00031 IN PKTRAP_FRAME TrapFrame, 00032 IN PKNORMAL_ROUTINE NormalRoutine, 00033 IN PVOID NormalContext, 00034 IN PVOID SystemArgument1, 00035 IN PVOID SystemArgument2 00036 ) 00037 00038 /*++ 00039 00040 Routine Description: 00041 00042 This function is called to initialize the context for a user mode APC. 00043 00044 Arguments: 00045 00046 ExceptionFrame - Supplies a pointer to an exception frame. 00047 00048 TrapFrame - Supplies a pointer to a trap frame. 00049 00050 NormalRoutine - Supplies a pointer to the user mode APC routine. 00051 00052 NormalContext - Supplies a pointer to the user context for the APC 00053 routine. 00054 00055 SystemArgument1 - Supplies the first system supplied value. 00056 00057 SystemArgument2 - Supplies the second system supplied value. 00058 00059 Return Value: 00060 00061 None. 00062 00063 --*/ 00064 00065 { 00066 00067 CONTEXT ContextRecord; 00068 EXCEPTION_RECORD ExceptionRecord; 00069 LONG Length; 00070 ULONG UserStack; 00071 00072 // 00073 // Move the user mode state from the trap and exception frames to the 00074 // context frame. 00075 // 00076 00077 ContextRecord.ContextFlags = CONTEXT_FULL; 00078 KeContextFromKframes(TrapFrame, ExceptionFrame, &ContextRecord); 00079 00080 // 00081 // Transfer the context information to the user stack, initialize the 00082 // APC routine parameters, and modify the trap frame so execution will 00083 // continue in user mode at the user mode APC dispatch routine. 00084 // 00085 00086 try { 00087 00088 // 00089 // Compute length of context record and new aligned user stack pointer. 00090 // 00091 00092 Length = sizeof(CONTEXT); 00093 UserStack = (ULONG)(ContextRecord.XIntSp & (~7)) - Length; 00094 00095 // 00096 // Probe user stack area for writeability and then transfer the 00097 // context record to the user stack. 00098 // 00099 00100 ProbeForWrite((PCHAR)UserStack, Length, sizeof(QUAD)); 00101 RtlMoveMemory((PULONG)UserStack, &ContextRecord, sizeof(CONTEXT)); 00102 00103 // 00104 // Set the address of the user APC routine, the APC parameters, the 00105 // new frame pointer, and the new stack pointer in the current trap 00106 // frame. Set the continuation address so control will be transfered 00107 // to the user APC dispatcher. 00108 // 00109 00110 TrapFrame->XIntSp = (LONG)UserStack; 00111 TrapFrame->XIntS8 = (LONG)UserStack; 00112 TrapFrame->XIntA0 = (LONG)NormalContext; 00113 TrapFrame->XIntA1 = (LONG)SystemArgument1; 00114 TrapFrame->XIntA2 = (LONG)SystemArgument2; 00115 TrapFrame->XIntA3 = (LONG)NormalRoutine; 00116 TrapFrame->Fir = KeUserApcDispatcher; 00117 00118 // 00119 // If an exception occurs, then copy the exception information to an 00120 // exception record and handle the exception. 00121 // 00122 00123 } except (KiCopyInformation(&ExceptionRecord, 00124 (GetExceptionInformation())->ExceptionRecord)) { 00125 00126 // 00127 // Set the address of the exception to the current program address 00128 // and raise the exception by calling the exception dispatcher. 00129 // 00130 00131 ExceptionRecord.ExceptionAddress = (PVOID)(TrapFrame->Fir); 00132 KiDispatchException(&ExceptionRecord, 00133 ExceptionFrame, 00134 TrapFrame, 00135 UserMode, 00136 TRUE); 00137 } 00138 00139 return; 00140 }

Generated on Sat May 15 19:39:15 2004 for test by doxygen 1.3.7