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
00029
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
00046
00047
00048
00049
00050
00051
00052
00053
00054
00055
00056
00057
00058
00059
00060
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
00081
00082 Thread =
PsGetCurrentThread();
00083 TrapFrame = VdmGetTrapFrame(&Thread->
Tcb);
00084
00085
00086
00087
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
00100
00101 IntsEnabled = VdmTib->
VdmContext.EFlags & EFLAGS_INTERRUPT_MASK
00102 ?
TRUE :
FALSE;
00103
00104
00105
00106
00107
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
00121
00122
00123
00124
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
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
00151
00152
00153 }
else if (!(
KeI386VdmIoplAllowed) ||
00154 !(VdmTib->
VdmContext.EFlags & EFLAGS_V86_MASK))
00155 {
00156
00157
00158
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
00179
00180 VdmTib->
VdmContext.EFlags |= EFLAGS_INTERRUPT_MASK;
00181 }
00182
00183
00184
00185
00186 VdmContext = VdmTib->
VdmContext;
00187
if (!(VdmContext.SegCs & FRAME_EDITED)) {
00188
00189
KeLowerIrql(OldIrql);
00190
return(STATUS_INVALID_SYSTEM_SERVICE);
00191 }
00192
00193
00194
00195
00196
00197
VdmSwapContexts(
00198 TrapFrame,
00199 &(VdmTib->
MonitorContext),
00200 &VdmContext
00201 );
00202
00203
00204
00205
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
00231
00232
00233
00234
00235
00236
00237
00238
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
00249
00250
00251
00252
00253
00254
00255
00256
00257 VdmTib->
MonitorContext.Eax = STATUS_SUCCESS;
00258
00259
00260
00261
00262
VdmSwapContexts(
00263 TrapFrame,
00264 &(VdmTib->
VdmContext),
00265 &(VdmTib->
MonitorContext)
00266 );
00267
00268
00269
00270
00271
00272
00273
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
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
00291
00292 TrapFrame->EFlags &= ~(EFLAGS_VIP | EFLAGS_VIF);
00293
00294
00295
00296
00297 }
else if (!(
KeI386VdmIoplAllowed) ||
00298 !(VdmTib->
VdmContext.EFlags & EFLAGS_V86_MASK))
00299 {
00300
00301
00302
00303
00304
00305 VdmTib->
VdmContext.EFlags =
00306 (VdmTib->
VdmContext.EFlags & ~EFLAGS_INTERRUPT_MASK)
00307 | (*(PULONG)pNtVDMState &
VDM_VIRTUAL_INTERRUPTS);
00308 }
00309
00310
return;
00311 }