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

apcuser.c File Reference

#include "ki.h"

Go to the source code of this file.

Functions

VOID KiInitializeUserApc (IN PKEXCEPTION_FRAME ExceptionFrame, IN PKTRAP_FRAME TrapFrame, IN PKNORMAL_ROUTINE NormalRoutine, IN PVOID NormalContext, IN PVOID SystemArgument1, IN PVOID SystemArgument2)


Function Documentation

VOID KiInitializeUserApc IN PKEXCEPTION_FRAME  ExceptionFrame,
IN PKTRAP_FRAME  TrapFrame,
IN PKNORMAL_ROUTINE  NormalRoutine,
IN PVOID  NormalContext,
IN PVOID  SystemArgument1,
IN PVOID  SystemArgument2
 

Definition at line 29 of file i386/apcuser.c.

References ASSERT, CONTEXT_FULL, KAPC_RECORD, KeContextFromKframes(), KeGetCurrentThread, KernelMode, KeUserApcDispatcher, KiCopyInformation(), KiDispatchException(), ProbeForWrite(), TRUE, and UserMode.

00040 : 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 EXCEPTION_RECORD ExceptionRecord; 00068 CONTEXT ContextFrame; 00069 LONG Length; 00070 ULONG UserStack; 00071 00072 00073 // 00074 // APCs are not defined for V86 mode; however, it is possible a 00075 // thread is trying to set it's context to V86 mode - this isn't 00076 // going to work, but we don't want to crash the system so we 00077 // check for the possibility before hand. 00078 // 00079 00080 if (TrapFrame->EFlags & EFLAGS_V86_MASK) { 00081 return ; 00082 } 00083 00084 // 00085 // Move machine state from trap and exception frames to the context frame. 00086 // 00087 00088 ContextFrame.ContextFlags = CONTEXT_FULL | CONTEXT_DEBUG_REGISTERS; 00089 KeContextFromKframes(TrapFrame, ExceptionFrame, &ContextFrame); 00090 00091 // 00092 // Transfer the context information to the user stack, initialize the 00093 // APC routine parameters, and modify the trap frame so execution will 00094 // continue in user mode at the user mode APC dispatch routine. 00095 // 00096 00097 00098 try { 00099 ASSERT((TrapFrame->SegCs & MODE_MASK) != KernelMode); // Assert usermode frame 00100 00101 // 00102 // Compute length of context record and new aligned user stack pointer. 00103 // 00104 00105 Length = ((sizeof(CONTEXT) + CONTEXT_ROUND) & 00106 ~CONTEXT_ROUND) + sizeof(KAPC_RECORD); 00107 UserStack = (ContextFrame.Esp & ~CONTEXT_ROUND) - Length; 00108 00109 // 00110 // Probe user stack area for writeability and then transfer the 00111 // context record to the user stack. 00112 // 00113 00114 ProbeForWrite((PCHAR)UserStack, Length, CONTEXT_ALIGN); 00115 RtlMoveMemory((PULONG)(UserStack + (sizeof(KAPC_RECORD))), 00116 &ContextFrame, sizeof(CONTEXT)); 00117 00118 // 00119 // Force correct R3 selectors into TrapFrame. 00120 // 00121 00122 TrapFrame->SegCs = SANITIZE_SEG(KGDT_R3_CODE, UserMode); 00123 TrapFrame->HardwareSegSs = SANITIZE_SEG(KGDT_R3_DATA, UserMode); 00124 TrapFrame->SegDs = SANITIZE_SEG(KGDT_R3_DATA, UserMode); 00125 TrapFrame->SegEs = SANITIZE_SEG(KGDT_R3_DATA, UserMode); 00126 TrapFrame->SegFs = SANITIZE_SEG(KGDT_R3_TEB, UserMode); 00127 TrapFrame->SegGs = 0; 00128 TrapFrame->EFlags = SANITIZE_FLAGS( ContextFrame.EFlags, UserMode ); 00129 00130 // 00131 // If thread is supposed to have IOPL, then force it on in eflags 00132 // 00133 00134 if (KeGetCurrentThread()->Iopl) { 00135 TrapFrame->EFlags |= (EFLAGS_IOPL_MASK & -1); // IOPL = 3 00136 } 00137 00138 // 00139 // Set the address of the user APC routine, the APC parameters, the 00140 // new frame pointer, and the new stack pointer in the current trap 00141 // frame. Set the continuation address so control will be transfered 00142 // to the user APC dispatcher. 00143 // 00144 00145 TrapFrame->HardwareEsp = UserStack; 00146 TrapFrame->Eip = (ULONG)KeUserApcDispatcher; 00147 TrapFrame->ErrCode = 0; 00148 *((PULONG)UserStack)++ = (ULONG)NormalRoutine; 00149 *((PULONG)UserStack)++ = (ULONG)NormalContext; 00150 *((PULONG)UserStack)++ = (ULONG)SystemArgument1; 00151 *((PULONG)UserStack)++ = (ULONG)SystemArgument2; 00152 } except (KiCopyInformation(&ExceptionRecord, 00153 (GetExceptionInformation())->ExceptionRecord)) { 00154 00155 // 00156 // Set the address of the exception to the current program address 00157 // and raise the exception by calling the exception dispatcher. 00158 // 00159 00160 ExceptionRecord.ExceptionAddress = (PVOID)(TrapFrame->Eip); 00161 KiDispatchException(&ExceptionRecord, 00162 ExceptionFrame, 00163 TrapFrame, 00164 UserMode, 00165 TRUE); 00166 } 00167 return; 00168 } }


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