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 CONTEXT ContextRecord;
00068 EXCEPTION_RECORD ExceptionRecord;
00069 LONG Length;
00070 ULONG UserStack;
00071
00072
00073
00074
00075
00076
00077 ContextRecord.ContextFlags =
CONTEXT_FULL;
00078
KeContextFromKframes(TrapFrame, ExceptionFrame, &ContextRecord);
00079
00080
00081
00082
00083
00084
00085
00086
try {
00087
00088
00089
00090
00091
00092 Length =
sizeof(CONTEXT);
00093 UserStack = (ULONG)(ContextRecord.XIntSp & (~7)) - Length;
00094
00095
00096
00097
00098
00099
00100
ProbeForWrite((PCHAR)UserStack, Length,
sizeof(QUAD));
00101 RtlMoveMemory((PULONG)UserStack, &ContextRecord,
sizeof(CONTEXT));
00102
00103
00104
00105
00106
00107
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
00120
00121
00122
00123 } except (
KiCopyInformation(&ExceptionRecord,
00124 (GetExceptionInformation())->ExceptionRecord)) {
00125
00126
00127
00128
00129
00130
00131 ExceptionRecord.ExceptionAddress = (PVOID)(TrapFrame->Fir);
00132
KiDispatchException(&ExceptionRecord,
00133 ExceptionFrame,
00134 TrapFrame,
00135 UserMode,
00136 TRUE);
00137 }
00138
00139
return;
00140 }
}