00052                    :
00053 
00054     This function initializes 
the machine dependent context of a thread object.
00055 
00056     N.B. This function does not check 
the accessibility of 
the context record.
00057          It 
is assumed 
the the caller of 
this routine 
is either prepared to
00058          handle access violations or has probed and copied 
the context record
00059          as appropriate.
00060 
00061 Arguments:
00062 
00063     Thread - Supplies a pointer to a dispatcher object of 
type thread.
00064 
00065     SystemRoutine - Supplies a pointer to 
the system function that 
is to be
00066         called when 
the thread 
is first scheduled 
for execution.
00067 
00068     StartRoutine - Supplies an optional pointer to a function that 
is to be
00069         called after 
the system has finished initializing 
the thread. This
00070         parameter 
is specified 
if the thread 
is a system thread and will
00071         execute totally in kernel mode.
00072 
00073     StartContext - Supplies an optional pointer to an arbitrary data structure
00074         which will be passed to 
the StartRoutine as a parameter. This
00075         parameter 
is specified 
if the thread 
is a system thread and will
00076         execute totally in kernel mode.
00077 
00078     ContextRecord - Supplies an optional pointer a context frame which contains
00079         
the initial user mode state of 
the thread. This parameter 
is specified
00080         
if the thread 
is a user thread and will execute in user mode. If 
this
00081         parameter 
is not specified, then 
the Teb parameter 
is ignored.
00082 
00083 Return Value:
00084 
00085     None.
00086 
00087 --*/
00088 
00089 {
00090 
00091     PKEXCEPTION_FRAME CxFrame;
00092     PKEXCEPTION_FRAME ExFrame;
00093     ULONG InitialStack;
00094     PKTRAP_FRAME TrFrame;
00095 
00096     
00097     
00098     
00099     
00100 
00101     InitialStack = (LONG)Thread->InitialStack;
00102     
if (ARGUMENT_PRESENT(ContextRecord)) {
00103         TrFrame = (PKTRAP_FRAME)(InitialStack - 
sizeof(KTRAP_FRAME));
00104         ExFrame = (PKEXCEPTION_FRAME)((ULONG)TrFrame - 
sizeof(KEXCEPTION_FRAME));
00105         CxFrame = (PKEXCEPTION_FRAME)((ULONG)ExFrame - 
sizeof(KEXCEPTION_FRAME));
00106 
00107         
00108         
00109         
00110         
00111 
00112         RtlZeroMemory((PVOID)ExFrame, 
sizeof(KEXCEPTION_FRAME));
00113         RtlZeroMemory((PVOID)TrFrame, 
sizeof(KTRAP_FRAME));
00114         
KeContextToKframes(TrFrame,
00115                            ExFrame,
00116                            ContextRecord,
00117                            ContextRecord->ContextFlags | CONTEXT_CONTROL,
00118                            UserMode);
00119 
00120         
00121         
00122         
00123         
00124 
00125         TrFrame->PreviousMode = 
UserMode;
00126         Thread->PreviousMode = 
UserMode;
00127 
00128         
00129         
00130         
00131 
00132         ExFrame->IntRa = 0;
00133 
00134     } 
else {
00135         ExFrame = 
NULL;
00136         CxFrame = (PKEXCEPTION_FRAME)(InitialStack - 
sizeof(KEXCEPTION_FRAME));
00137 
00138         
00139         
00140         
00141 
00142         Thread->PreviousMode = 
KernelMode;
00143     }
00144 
00145     
00146     
00147     
00148 
00149     CxFrame->SwapReturn = (ULONG)
KiThreadStartup;
00150     
if (ExFrame == 
NULL) {
00151         CxFrame->IntS8 = (ULONG)ExFrame;
00152 
00153     } 
else {
00154         CxFrame->IntS8 = (ULONG)TrFrame;
00155     }
00156 
00157     CxFrame->IntS0 = (ULONG)ContextRecord;
00158     CxFrame->IntS1 = (ULONG)StartContext;
00159     CxFrame->IntS2 = (ULONG)StartRoutine;
00160     CxFrame->IntS3 = (ULONG)SystemRoutine;
00161     Thread->KernelStack = (PVOID)CxFrame;
00162     
return;
00163 }