00001 
00002 
00003 
00004 
00005 
00006 
00007 
00008 
00009 
00010 
00011 
00012 
00013 
00014 
00015 
00016 
00017 
00018 
00019 
00020 
00021 
00022 
00023 
00024 
00025 
00026 
00027 
00028 
#include "ki.h"
00029 
00030 
VOID
00031 
KeContextToKframesSpecial (
00032     IN 
PKTHREAD Thread,
00033     IN OUT PKTRAP_FRAME TrapFrame,
00034     IN OUT PKEXCEPTION_FRAME ExceptionFrame,
00035     IN PCONTEXT ContextFrame,
00036     IN ULONG ContextFlags
00037     );
00038 
00039 
00040 
00041 
00042 
00043 
00044 #define ASSERT_PROCESS(E) {                    \
00045 
    ASSERT((E)->Header.Type == ProcessObject); \
00046 
}
00047 
00048 #define ASSERT_THREAD(E) {                    \
00049 
    ASSERT((E)->Header.Type == ThreadObject); \
00050 
}
00051 
00052 
00053 
00054 
VOID
00055 KiInitializeContextThread (
00056     IN 
PKTHREAD Thread,
00057     IN PKSYSTEM_ROUTINE SystemRoutine,
00058     IN PKSTART_ROUTINE StartRoutine OPTIONAL,
00059     IN PVOID StartContext OPTIONAL,
00060     IN PCONTEXT ContextRecord OPTIONAL
00061     )
00062 
00063 
00064 
00065 
00066 
00067 
00068 
00069 
00070 
00071 
00072 
00073 
00074 
00075 
00076 
00077 
00078 
00079 
00080 
00081 
00082 
00083 
00084 
00085 
00086 
00087 
00088 
00089 
00090 
00091 
00092 
00093 
00094 
00095 
00096 
00097 
00098 
00099 
00100 
00101 
00102 
00103 
00104 
00105 
00106 
00107 
00108 
00109 
00110 
00111 
00112 
00113 
00114 
00115 
00116 {
00117 
00118     PKSWITCH_FRAME SwFrame;
00119     PKEXCEPTION_FRAME ExFrame;
00120     ULONG_PTR InitialStack;
00121     PKTRAP_FRAME TrFrame;
00122 
00123     
00124     
00125     
00126 
00127     InitialStack = (ULONG_PTR)Thread->InitialStack;
00128     Thread->InitialBStore = (PVOID)InitialStack;
00129     Thread->BStoreLimit = (PVOID)(InitialStack + KERNEL_BSTORE_SIZE);
00130 
00131     
00132     
00133     
00134     
00135     
00136 
00137     
if (ARGUMENT_PRESENT(ContextRecord)) {
00138 
00139         TrFrame = (PKTRAP_FRAME)((InitialStack) 
00140                       - KTHREAD_STATE_SAVEAREA_LENGTH
00141                       - KTRAP_FRAME_LENGTH);
00142 
00143         ExFrame = (PKEXCEPTION_FRAME)(((ULONG_PTR)TrFrame + 
00144                       STACK_SCRATCH_AREA - 
00145                       
sizeof(KEXCEPTION_FRAME)) & ~((ULONG_PTR)15));
00146 
00147         SwFrame = (PKSWITCH_FRAME)(((ULONG_PTR)ExFrame -
00148                       
sizeof(KSWITCH_FRAME)) & ~((ULONG_PTR)15));
00149 
00150         
KeContextToKframesSpecial(Thread, TrFrame, ExFrame,
00151                            ContextRecord,
00152                            ContextRecord->ContextFlags | 
CONTEXT_CONTROL);
00153 
00154         
00155         
00156         
00157         
00158 
00159         TrFrame->PreviousMode = 
UserMode;
00160         Thread->PreviousMode = 
UserMode;
00161 
00162         
00163         
00164         
00165 
00166         TrFrame->StFPSR = USER_FPSR_INITIAL;
00167 
00168         
00169         
00170         
00171 
00172         TrFrame->IntTeb = (ULONGLONG)Thread->Teb;
00173 
00174     } 
else {
00175 
00176         SwFrame = (PKSWITCH_FRAME)((InitialStack) - 
sizeof(KSWITCH_FRAME));
00177 
00178         
00179         
00180         
00181 
00182         Thread->PreviousMode = 
KernelMode;
00183     }
00184 
00185     
00186     
00187     
00188     
00189 
00190     RtlZeroMemory((PVOID)SwFrame, 
sizeof(KSWITCH_FRAME));   
00191 
00192     SwFrame->SwitchRp = ((PPLABEL_DESCRIPTOR)
KiThreadStartup)->EntryPoint;
00193     SwFrame->SwitchExceptionFrame.IntS0 = (ULONGLONG)ContextRecord;
00194     SwFrame->SwitchExceptionFrame.IntS1 = (ULONGLONG)StartContext;
00195     SwFrame->SwitchExceptionFrame.IntS2 = (ULONGLONG)StartRoutine;
00196     SwFrame->SwitchExceptionFrame.IntS3 = 
00197         ((PPLABEL_DESCRIPTOR)SystemRoutine)->EntryPoint;
00198     SwFrame->SwitchFPSR = FPSR_FOR_KERNEL;
00199     SwFrame->SwitchBsp = (ULONGLONG)Thread->InitialBStore;
00200 
00201     Thread->KernelBStore = Thread->InitialBStore;
00202     Thread->KernelStack = (PVOID)((ULONG_PTR)SwFrame-STACK_SCRATCH_AREA);
00203 
00204     
if (Thread->Teb) {
00205         PKAPPLICATION_REGISTERS AppRegs;
00206 
00207         AppRegs = GET_APPLICATION_REGISTER_SAVEAREA(Thread->StackBase);
00208 
00209         AppRegs->Ar21 = 0; 
00210         AppRegs->Ar24 = SANITIZE_FLAGS((ULONG) ContextRecord->Eflag, 
UserMode);
00211         AppRegs->Ar25 = USER_CODE_DESCRIPTOR;
00212         AppRegs->Ar26 = USER_DATA_DESCRIPTOR;
00213         AppRegs->Ar27 = (ULONGLONG)((CR4_VME << 32) | CR0_PE | CFLG_II);
00214         AppRegs->Ar28 = ContextRecord->StFSR;
00215         AppRegs->Ar29 = ContextRecord->StFIR;
00216         AppRegs->Ar30 = ContextRecord->StFDR;
00217         
00218     }
00219 
00220     
return;
00221 }
00222 
00223 BOOLEAN
00224 KeSetAutoAlignmentProcess (
00225     IN 
PRKPROCESS Process,
00226     IN BOOLEAN Enable
00227     )
00228 
00229 
00230 
00231 
00232 
00233 
00234 
00235 
00236 
00237 
00238 
00239 
00240 
00241 
00242 
00243 
00244 
00245 
00246 
00247 
00248 
00249 
00250 
00251 
00252 
00253 
00254 {
00255 
00256     KIRQL OldIrql;
00257     BOOLEAN Previous;
00258 
00259     
ASSERT_PROCESS(Process);
00260 
00261     
00262     
00263     
00264 
00265     
KiLockDispatcherDatabase(&OldIrql);
00266 
00267     
00268     
00269     
00270     
00271 
00272     Previous = Process->AutoAlignment;
00273     Process->AutoAlignment = Enable;
00274 
00275     
00276     
00277     
00278     
00279 
00280     
KiUnlockDispatcherDatabase(OldIrql);
00281     
return Previous;
00282 }
00283 
00284 BOOLEAN
00285 KeSetAutoAlignmentThread (
00286     IN 
PKTHREAD Thread,
00287     IN BOOLEAN Enable
00288     )
00289 
00290 
00291 
00292 
00293 
00294 
00295 
00296 
00297 
00298 
00299 
00300 
00301 
00302 
00303 
00304 
00305 
00306 
00307 
00308 
00309 
00310 
00311 
00312 
00313 
00314 
00315 {
00316 
00317     KIRQL OldIrql;
00318     BOOLEAN Previous;
00319 
00320     
ASSERT_THREAD(Thread);
00321 
00322     
00323     
00324     
00325 
00326     
KiLockDispatcherDatabase(&OldIrql);
00327 
00328     
00329     
00330     
00331     
00332 
00333     Previous = Thread->AutoAlignment;
00334     Thread->AutoAlignment = Enable;
00335 
00336     
00337     
00338     
00339     
00340 
00341     
KiUnlockDispatcherDatabase(OldIrql);
00342     
return Previous;
00343 }