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

strtexec.c

Go to the documentation of this file.
00001 /*++ 00002 00003 Copyright (c) 1992 Microsoft Corporation 00004 00005 Module Name: 00006 00007 Startexec.c 00008 00009 Abstract: 00010 00011 This module contains routines for switching to and from application 00012 mode in a vdm 00013 00014 Author: 00015 00016 Dave Hastings (daveh) 24-Apr-1992 00017 00018 Notes: 00019 00020 This code started out in ke\i386\vdm.c 00021 00022 Revision History: 00023 00024 23-Sep-1992 sudeepb Formed W_VDMEndExecution from VDMEndExecution 00025 for performance. 00026 00027 18-Dec-1992 sudeepb Tuned all the routines for performance 00028 00029 12-Oct-1993 Jonle , removed unneeded endexecution worker functions 00030 00031 --*/ 00032 #include "vdmp.h" 00033 00034 #ifdef ALLOC_PRAGMA 00035 #pragma alloc_text(PAGE, VdmpStartExecution) 00036 #pragma alloc_text(PAGE, VdmEndExecution) 00037 #endif 00038 00039 NTSTATUS 00040 VdmpStartExecution( 00041 VOID 00042 ) 00043 /*++ 00044 00045 Routine Description: 00046 00047 This routine causes execution of dos application code to begin. The 00048 Dos application executes on the thread. The Vdms context is loaded 00049 from the VDM_TIB for the thread. The 32 bit context is stored into 00050 the MonitorContext. Execution in the VDM context will continue until 00051 an event occurs that the monitor needs to service. At that point, 00052 the information will be put into the VDM_TIB, and the call will 00053 return. 00054 00055 Arguments: 00056 00057 Return Value: 00058 00059 TrapFrame->Eax for application mode, required for system sevices 00060 exit. 00061 00062 00063 --*/ 00064 { 00065 PVDM_TIB VdmTib; 00066 PKTRAP_FRAME TrapFrame; 00067 PETHREAD Thread; 00068 KIRQL OldIrql; 00069 BOOLEAN IntsEnabled; 00070 PVDM_PROCESS_OBJECTS pProcessObjects; 00071 NTSTATUS Status; 00072 CONTEXT VdmContext; 00073 00074 PAGED_CODE(); 00075 00076 00077 KeRaiseIrql(APC_LEVEL, &OldIrql); 00078 00079 // 00080 // Form a pointer to the trap frame for the current thread 00081 // 00082 Thread = PsGetCurrentThread(); 00083 TrapFrame = VdmGetTrapFrame(&Thread->Tcb); 00084 00085 00086 // 00087 // Get the VdmTib 00088 // 00089 00090 Status = VdmpGetVdmTib(&VdmTib, VDMTIB_KMODE); 00091 if (!NT_SUCCESS(Status)) { 00092 KeLowerIrql(OldIrql); 00093 return(STATUS_INVALID_SYSTEM_SERVICE); 00094 } 00095 00096 try { 00097 00098 // 00099 // Determine if interrupts are on or off 00100 // 00101 IntsEnabled = VdmTib->VdmContext.EFlags & EFLAGS_INTERRUPT_MASK 00102 ? TRUE : FALSE; 00103 00104 // 00105 // check for timer ints to dispatch, However if interrupts are disabled 00106 // or there are hardware ints pending we postpone dispatching the timer 00107 // interrupt until interrupts are enabled. 00108 // 00109 if (*pNtVDMState & VDM_INT_TIMER && 00110 IntsEnabled && !(*pNtVDMState & VDM_INT_HARDWARE)) 00111 { 00112 VdmTib->EventInfo.Event = VdmIntAck; 00113 VdmTib->EventInfo.InstructionSize = 0; 00114 VdmTib->EventInfo.IntAckInfo = 0; 00115 KeLowerIrql(OldIrql); 00116 return STATUS_SUCCESS; 00117 } 00118 00119 // 00120 // Perform IF to VIF translation 00121 // 00122 00123 // 00124 // If the processor supports IF virtualization 00125 // 00126 if (((KeI386VirtualIntExtensions & V86_VIRTUAL_INT_EXTENSIONS) && 00127 (VdmTib->VdmContext.EFlags & EFLAGS_V86_MASK)) || 00128 ((KeI386VirtualIntExtensions & PM_VIRTUAL_INT_EXTENSIONS) && 00129 !(VdmTib->VdmContext.EFlags & EFLAGS_V86_MASK))) 00130 { 00131 // 00132 // Translate IF to VIF 00133 // 00134 00135 if (IntsEnabled) { 00136 VdmTib->VdmContext.EFlags |= EFLAGS_VIF; 00137 00138 } else { 00139 VdmTib->VdmContext.EFlags &= ~EFLAGS_VIF; 00140 VdmTib->VdmContext.EFlags |= EFLAGS_INTERRUPT_MASK; 00141 } 00142 00143 if (*pNtVDMState & VDM_INT_HARDWARE) 00144 VdmTib->VdmContext.EFlags |= EFLAGS_VIP; 00145 else 00146 VdmTib->VdmContext.EFlags &= ~EFLAGS_VIP; 00147 00148 00149 // 00150 // Else if we are not running in v86 mode, or not using IOPL in 00151 // v86 mode 00152 // 00153 } else if (!(KeI386VdmIoplAllowed) || 00154 !(VdmTib->VdmContext.EFlags & EFLAGS_V86_MASK)) 00155 { 00156 // 00157 // Translate the real interrupt flag in the VdmContext to the virtual 00158 // interrupt flag in the VdmTib, and force real interrupts enabled. 00159 // 00160 00161 ASSERT(VDM_VIRTUAL_INTERRUPTS == EFLAGS_INTERRUPT_MASK); 00162 00163 if (VdmTib->VdmContext.EFlags & EFLAGS_INTERRUPT_MASK) { 00164 _asm { 00165 00166 mov eax,VdmFixedStateLinear ; get pointer to VDM State 00167 lock or dword ptr [eax], dword ptr VDM_VIRTUAL_INTERRUPTS 00168 } 00169 } else { 00170 _asm { 00171 00172 mov eax,VdmFixedStateLinear ; get pointer to VDM State 00173 lock and dword ptr [eax], NOT VDM_VIRTUAL_INTERRUPTS 00174 } 00175 } 00176 00177 // 00178 // Insure that real interrupts are always enabled. 00179 // 00180 VdmTib->VdmContext.EFlags |= EFLAGS_INTERRUPT_MASK; 00181 } 00182 00183 // before working on a trap frame, make sure that it's our own structure 00184 // 00185 00186 VdmContext = VdmTib->VdmContext; 00187 if (!(VdmContext.SegCs & FRAME_EDITED)) { 00188 // we will crash in KiServiceExit 00189 KeLowerIrql(OldIrql); 00190 return(STATUS_INVALID_SYSTEM_SERVICE); 00191 } 00192 00193 // 00194 // Switch from MonitorContext to VdmContext 00195 // 00196 00197 VdmSwapContexts( 00198 TrapFrame, 00199 &(VdmTib->MonitorContext), 00200 &VdmContext 00201 ); 00202 00203 00204 // 00205 // Check for pending interrupts 00206 // 00207 if (IntsEnabled && (*pNtVDMState & VDM_INT_HARDWARE)) { 00208 VdmDispatchInterrupts(TrapFrame, VdmTib); 00209 } 00210 00211 } 00212 except(EXCEPTION_EXECUTE_HANDLER) { 00213 Status = GetExceptionCode(); 00214 KeLowerIrql(OldIrql); 00215 return(Status); 00216 } 00217 00218 KeLowerIrql(OldIrql); 00219 00220 return (NTSTATUS) TrapFrame->Eax; 00221 } 00222 00223 VOID 00224 VdmEndExecution( 00225 PKTRAP_FRAME TrapFrame, 00226 PVDM_TIB VdmTib 00227 ) 00228 /*++ 00229 00230 Routine Description: 00231 00232 This routine does the core work to end the execution 00233 00234 Arguments: 00235 00236 None 00237 00238 Return Value: 00239 00240 --*/ 00241 { 00242 PAGED_CODE(); 00243 00244 ASSERT((TrapFrame->EFlags & EFLAGS_V86_MASK) || 00245 (TrapFrame->SegCs != (KGDT_R3_CODE | RPL_MASK)) ); 00246 00247 00248 // Sudeepb 01-Dec-1992 - There was a try except here which i have 00249 // taken out, because we come here with a top level exception frame, 00250 // so no one can blow NT even if we take a fault here becuase user 00251 // memory was'nt allocated. 00252 00253 00254 // The return value must be put into the Monitorcontext, and set, 00255 // since we are probably returning to user mode via EXIT_ALL, and 00256 // the volatile registers will be restored. 00257 VdmTib->MonitorContext.Eax = STATUS_SUCCESS; 00258 00259 // 00260 // Switch from MonitorContext to VdmContext 00261 // 00262 VdmSwapContexts( 00263 TrapFrame, 00264 &(VdmTib->VdmContext), 00265 &(VdmTib->MonitorContext) 00266 ); 00267 00268 // 00269 // Perform IF to VIF translation 00270 // 00271 00272 // 00273 // If the processor supports IF virtualization 00274 // 00275 if (((KeI386VirtualIntExtensions & V86_VIRTUAL_INT_EXTENSIONS) && 00276 (VdmTib->VdmContext.EFlags & EFLAGS_V86_MASK)) || 00277 ((KeI386VirtualIntExtensions & PM_VIRTUAL_INT_EXTENSIONS) && 00278 !(VdmTib->VdmContext.EFlags & EFLAGS_V86_MASK))) 00279 { 00280 // 00281 // Translate VIF to IF 00282 // 00283 if (VdmTib->VdmContext.EFlags & EFLAGS_VIF) { 00284 VdmTib->VdmContext.EFlags |= EFLAGS_INTERRUPT_MASK; 00285 } else { 00286 VdmTib->VdmContext.EFlags &= ~EFLAGS_INTERRUPT_MASK; 00287 } 00288 00289 // 00290 // Turn off VIP and VIF to insure that nothing strange happens 00291 // 00292 TrapFrame->EFlags &= ~(EFLAGS_VIP | EFLAGS_VIF); 00293 // 00294 // Else if we are not running in v86 mode, or not using IOPL in 00295 // v86 mode 00296 // 00297 } else if (!(KeI386VdmIoplAllowed) || 00298 !(VdmTib->VdmContext.EFlags & EFLAGS_V86_MASK)) 00299 { 00300 // 00301 // Translate the virtual interrupt flag from the VdmTib back to the 00302 // real interrupt flag in the VdmContext 00303 // 00304 00305 VdmTib->VdmContext.EFlags = 00306 (VdmTib->VdmContext.EFlags & ~EFLAGS_INTERRUPT_MASK) 00307 | (*(PULONG)pNtVDMState & VDM_VIRTUAL_INTERRUPTS); 00308 } 00309 00310 return; 00311 }

Generated on Sat May 15 19:41:53 2004 for test by doxygen 1.3.7