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

apcuser.c File Reference

#include "ki.h"
#include "kxppc.h"

Go to the source code of this file.

Defines

#define _KXPPC_C_HEADER_

Functions

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


Define Documentation

#define _KXPPC_C_HEADER_
 

Definition at line 30 of file ppc/apcuser.c.


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 34 of file ppc/apcuser.c.

References CONTEXT_FULL, KeContextFromKframes(), KeUserApcDispatcher, KiCopyInformation(), KiDispatchException(), ProbeForWrite(), STK_MIN_FRAME, TRUE, and UserMode.

Referenced by KiDeliverApc().

00045 : 00046 00047 This function is called to initialize the context for a user mode APC. 00048 00049 Arguments: 00050 00051 ExceptionFrame - Supplies a pointer to an exception frame. 00052 00053 TrapFrame - Supplies a pointer to a trap frame. 00054 00055 NormalRoutine - Supplies a pointer to the user mode APC routine. 00056 00057 NormalContext - Supplies a pointer to the user context for the APC 00058 routine. 00059 00060 SystemArgument1 - Supplies the first system supplied value. 00061 00062 SystemArgument2 - Supplies the second system supplied value. 00063 00064 Return Value: 00065 00066 None. 00067 00068 --*/ 00069 00070 { 00071 00072 CONTEXT ContextRecord; 00073 EXCEPTION_RECORD ExceptionRecord; 00074 LONG Length; 00075 ULONG UserStack; 00076 PULONG PUserStack; 00077 00078 // 00079 // Move the user mode state from the trap and exception frames to the 00080 // context frame. 00081 // 00082 00083 ContextRecord.ContextFlags = CONTEXT_FULL; 00084 KeContextFromKframes(TrapFrame, ExceptionFrame, &ContextRecord); 00085 00086 // 00087 // Transfer the context information to the user stack, initialize the 00088 // APC routine parameters, and modify the trap frame so execution will 00089 // continue in user mode at the user mode APC dispatch routine. 00090 // 00091 // We build the following structure on the user stack: 00092 // 00093 // | | 00094 // |-------------------------------| 00095 // | Stack frame header | 00096 // | Back chain points to | 00097 // | user's stack frame | 00098 // | - - - - - - - - - - - - - - - | 00099 // | Context Frame | 00100 // | Filled in with state | 00101 // | of interrupted user | 00102 // | program | 00103 // | - - - - - - - - - - - - - - - | 00104 // | Trap Frame | 00105 // | Empty; for use by | 00106 // | NtContinue eventually | 00107 // | - - - - - - - - - - - - - - - | 00108 // | Save word for TOC ptr | 00109 // | - - - - - - - - - - - - - - - | 00110 // | Canonical slack space | 00111 // |-------------------------------| 00112 // | | 00113 // | Interrupted user's | 00114 // | stack frame | 00115 // | | 00116 // | | 00117 // |-------------------------------| 00118 // | | 00119 00120 try { 00121 00122 // 00123 // Set pointer to KeUserApcDispatcher\'s function descriptor 00124 // First word = address of entry point 00125 // Second word = address of TOC 00126 // 00127 00128 PULONG FnDesc = (PULONG) KeUserApcDispatcher; 00129 00130 // 00131 // Compute length of context record and new aligned user stack pointer. 00132 // 00133 00134 Length = (STK_MIN_FRAME + CONTEXT_LENGTH + KTRAP_FRAME_LENGTH + 00135 sizeof(ULONG) + STK_SLACK_SPACE + 7) & (-8); 00136 UserStack = (ContextRecord.Gpr1 & (~7)) - Length; 00137 00138 // 00139 // Probe user stack area for writeability and then transfer the 00140 // context record to the user stack. 00141 // 00142 00143 ProbeForWrite((PCHAR)UserStack, Length, sizeof(QUAD)); 00144 RtlCopyMemory((PULONG)(UserStack + STK_MIN_FRAME), &ContextRecord, sizeof(CONTEXT)); 00145 00146 // 00147 // Set the back chain in the new stack frame, store the resume 00148 // address as if it were the LR value (for stack trace/unwind), 00149 // and fill in TOC value as if it had been saved by prologue. 00150 // 00151 00152 PUserStack = (PULONG) UserStack; 00153 PUserStack[0] = ContextRecord.Gpr1; 00154 PUserStack[(STK_MIN_FRAME + CONTEXT_LENGTH + 00155 KTRAP_FRAME_LENGTH) / sizeof(ULONG)] = FnDesc[1]; 00156 00157 // 00158 // Set the address of the user APC routine, the APC parameters, the 00159 // new frame pointer, and the new stack pointer in the current trap 00160 // frame. Set the continuation address so control will be transfered 00161 // to the user APC dispatcher. 00162 // 00163 00164 TrapFrame->Gpr1 = UserStack; // stack pointer 00165 TrapFrame->Gpr2 = FnDesc[1]; // TOC address from descriptor 00166 TrapFrame->Gpr3 = (ULONG)NormalContext; // 1st parameter 00167 TrapFrame->Gpr4 = (ULONG)SystemArgument1; // 2nd parameter 00168 TrapFrame->Gpr5 = (ULONG)SystemArgument2; // 3rd parameter 00169 TrapFrame->Gpr6 = (ULONG)NormalRoutine; // 4th parameter 00170 TrapFrame->Iar = FnDesc[0]; // entry point from descriptor 00171 00172 // 00173 // If an exception occurs, then copy the exception information to an 00174 // exception record and handle the exception. 00175 // 00176 00177 } except (KiCopyInformation(&ExceptionRecord, 00178 (GetExceptionInformation())->ExceptionRecord)) { 00179 00180 // 00181 // Set the address of the exception to the current program address 00182 // and raise the exception by calling the exception dispatcher. 00183 // 00184 00185 ExceptionRecord.ExceptionAddress = (PVOID)(TrapFrame->Iar); 00186 KiDispatchException(&ExceptionRecord, 00187 ExceptionFrame, 00188 TrapFrame, 00189 UserMode, 00190 TRUE); 00191 } 00192 00193 return; 00194 } }


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