00041                    :
00042 
00043     This function 
is called to initialize 
the context 
for a user mode APC.
00044 
00045 Arguments:
00046 
00047     ExceptionFrame - Supplies a pointer to an exception frame.
00048 
00049     TrapFrame - Supplies a pointer to a trap frame.
00050 
00051     NormalRoutine - Supplies a pointer to 
the user mode APC routine.
00052 
00053     NormalContext - Supplies a pointer to 
the user context 
for the APC
00054         routine.
00055 
00056     SystemArgument1 - Supplies 
the first system supplied value.
00057 
00058     SystemArgument2 - Supplies 
the second system supplied value.
00059 
00060 Return Value:
00061 
00062     None.
00063 
00064 --*/
00065 
00066 {
00067 
00068     CONTEXT ContextRecord;
00069     EXCEPTION_RECORD ExceptionRecord;
00070     LONG Length;
00071     ULONGLONG UserStack;
00072     ULONGLONG OriginalBSP;
00073     PULONGLONG Arguments;
00074 
00075     
00076     
00077     
00078     
00079 
00080     ContextRecord.ContextFlags = 
CONTEXT_FULL;
00081     OriginalBSP = TrapFrame->RsBSP;
00082 
00083     
if (TRAP_FRAME_TYPE(TrapFrame) == SYSCALL_FRAME) {
00084 
00085         
00086         
00087         
00088         
00089 
00090         
SHORT RNatSaveIndex, Temp;
00091         
SHORT OutputFrameSize;
00092 
00093         OutputFrameSize = (
SHORT)((TrapFrame->StIFS & PFS_SIZE_MASK) - ((TrapFrame->StIFS >> PFS_SIZE_SHIFT) & PFS_SIZE_MASK));
00094         RNatSaveIndex = (
SHORT)((TrapFrame->RsBSP>>3) & NAT_BITS_PER_RNAT_REG);
00095 
00096         Temp = RNatSaveIndex + OutputFrameSize - NAT_BITS_PER_RNAT_REG;
00097         
while (Temp >= 0) {
00098             OutputFrameSize++;
00099             Temp -= NAT_BITS_PER_RNAT_REG;
00100         }
00101         TrapFrame->RsBSP += OutputFrameSize * 
sizeof(ULONGLONG);
00102 
00103     }
00104 
00105     
KeContextFromKframes(TrapFrame, ExceptionFrame, &ContextRecord);
00106     TrapFrame->RsBSP = OriginalBSP;
00107 
00108     
00109     
00110     
00111     
00112     
00113     
00114     
00115     
00116     
00117     
00118     
00119     
00120     
00121     
00122     
00123     
00124     
00125     
00126     
00127     
00128     
00129     
00130     
00131     
00132     
00133     
00134     
00135     
00136     
00137     
00138     
00139 
00140     
try {
00141 
00142     
USHORT LocalFrameSize;
00143     PPLABEL_DESCRIPTOR Plabel = (PPLABEL_DESCRIPTOR) 
KeUserApcDispatcher;
00144 
00145     
00146     
00147     
00148     
00149     
00150     
00151 
00152     Length = (4 * 
sizeof(ULONGLONG) + CONTEXT_LENGTH +
00153               STACK_SCRATCH_AREA + 15) & (~15);
00154     UserStack = (ContextRecord.IntSp & (~15)) - Length;
00155     Arguments = (PULONGLONG)(UserStack + STACK_SCRATCH_AREA + CONTEXT_LENGTH);
00156 
00157     
00158     
00159     
00160     
00161 
00162     
ProbeForWrite((PCHAR)UserStack, Length, 
sizeof(QUAD));
00163     RtlCopyMemory((PVOID)(UserStack+STACK_SCRATCH_AREA), 
00164                   &ContextRecord, 
sizeof(CONTEXT));
00165 
00166     
00167     
00168     
00169     
00170     
00171     
00172     
00173     
00174 
00175     *Arguments++ = (ULONGLONG)NormalContext;     
00176     *Arguments++ = (ULONGLONG)SystemArgument1;   
00177     *Arguments++ = (ULONGLONG)SystemArgument2;   
00178     *Arguments++ = (ULONGLONG)NormalRoutine;     
00179     *(PULONGLONG)UserStack = Plabel->GlobalPointer;  
00180 
00181     TrapFrame->IntNats = 0;                      
00182     TrapFrame->IntSp = UserStack;                
00183 
00184     TrapFrame->StIIP = Plabel->EntryPoint;       
00185     TrapFrame->StIPSR &= ~(0x3ULL << PSR_RI);    
00186     TrapFrame->StIFS &= 0xffffffc000000000;      
00187                                                  
00188                                                  
00189 
00190     
00191     
00192     
00193     
00194 
00195     } except (
KiCopyInformation(&ExceptionRecord,
00196                                 (GetExceptionInformation())->ExceptionRecord)) {
00197 
00198         
00199         
00200         
00201         
00202 
00203         ExceptionRecord.ExceptionAddress = (PVOID)(TrapFrame->StIIP);
00204         
KiDispatchException(&ExceptionRecord,
00205                             ExceptionFrame,
00206                             TrapFrame,
00207                             UserMode,
00208                             TRUE);
00209     }
00210 
00211     
return;
00212 }
}