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 
#include "ki.h"
00030 
#include "ia32def.h"
00031 
#include "vdmntos.h"
00032 
00033 
#if DEVL
00034 
ULONG ExVdmOpcodeDispatchCounts[MAX_VDM_INDEX];
00035 ULONG ExVdmSegmentNotPresent;
00036 
#endif
00037 
00038 extern ULONG 
KeIA32EFlagsAndMaskV86;
00039 extern ULONG 
KeIA32EFlagsOrMaskV86;
00040 extern BOOLEAN 
KeIA32VdmIoplAllowed;
00041 extern ULONG 
KeIA32VirtualIntExtensions;
00042 
00043 
#if defined(WX86) && defined(TRY_NTVDM)
00044 
00045 
00046 
00047 
00048 BOOLEAN
00049 KiIA32VdmDispatchIo(
00050     IN ULONG PortNumber,
00051     IN ULONG Size,
00052     IN BOOLEAN Read,
00053     IN UCHAR InstructionSize,
00054     IN PKIA32_FRAME TrapFrame
00055     );
00056 
00057 BOOLEAN
00058 KiIA32VdmDispatchStringIo(
00059     IN ULONG PortNumber,
00060     IN ULONG Size,
00061     IN BOOLEAN Rep,
00062     IN BOOLEAN Read,
00063     IN ULONG Count,
00064     IN ULONG Address,
00065     IN UCHAR InstructionSize,
00066     IN PKIA32_FRAME TrapFrame
00067     );
00068 
00069 
00070 
00071 
00072 
00073 BOOLEAN
00074 PushInt(
00075     IN ULONG InterruptNumber,
00076     IN OUT PREGINFO Regs
00077     );
00078 
00079 BOOLEAN
00080 PushException(
00081     IN ULONG ExceptionNumber,
00082     IN OUT PREGINFO Regs
00083     );
00084 
00085 BOOLEAN
00086 CsToLinear(
00087     IN OUT PREGINFO Regs,
00088     IN BOOLEAN IsV86
00089     );
00090 
00091 BOOLEAN
00092 SsToLinear(
00093     IN OUT PREGINFO Regs,
00094     IN BOOLEAN IsV86
00095     );
00096 
00097 BOOLEAN
00098 CheckEip(
00099     IN PREGINFO Regs
00100     );
00101 
00102 BOOLEAN
00103 CheckEsp(
00104     IN PREGINFO Regs,
00105     IN ULONG StackNeeded
00106     );
00107 
00108 
VOID
00109 GetVirtualBits(
00110     IN OUT PULONG PFlags,
00111     IN PKIA32_FRAME Frame
00112     );
00113 
00114 
VOID
00115 SetVirtualBits(
00116     IN ULONG Flags,
00117     IN PREGINFO PRegs
00118     );
00119 
00120 
VOID
00121 VdmDispatchIntAck(
00122     IN PKIA32_FRAME Frame
00123     );
00124 
00125 
VOID
00126 CheckVdmFlags(
00127     IN OUT PREGINFO Regs
00128     );
00129 
00130 
VOID
00131 KeIA32AndOrVdmLock(
00132     IN ULONG AndMask,
00133     IN ULONG OrMask
00134     );
00135 
00136 BOOLEAN
00137 KeIA32UnscrambleLdtEntry(
00138     IN ULONG Selector,
00139     OUT PKXDESCRIPTOR XDescriptor
00140     );
00141 
00142 ULONGLONG
00143 KeIA32Unscramble(
00144     IN PLDT_ENTRY Descriptor
00145     );
00146 
00147 
NTSTATUS
00148 
PspQueryDescriptorThread (
00149     
PETHREAD Thread,
00150     PVOID ThreadInformation,
00151     ULONG ThreadInformationLength,
00152     PULONG ReturnLength
00153     );
00154 
00155 
00156 
00157 
00158 BOOLEAN
00159 
KiIA32DispatchOpcode(
00160     IN PKIA32_FRAME Frame
00161     )
00162 
00163 
00164 
00165 
00166 
00167 
00168 
00169 
00170 
00171 
00172 
00173 
00174 
00175 
00176 
00177 
00178 
00179 
00180 
00181 
00182 {
00183     REGINFO Regs;
00184     ULONG IOPort;
00185     ULONG IOCount;
00186     ULONG IOAddress;
00187     ULONG flags;
00188     KXDESCRIPTOR NewXDescriptor;
00189 
00190     
00191     
00192     
00193     
00194     PULONG longPtr;
00195     
PUSHORT shortPtr;
00196     PUCHAR charPtr;
00197 
00198     
00199     
00200     
00201     Regs.RiInstLength = 1;
00202     Regs.RiPrefixFlags = 0;
00203     Regs.RiTrapFrame = Frame;
00204     Regs.RiSegCs = Frame->SegCs;
00205     Regs.RiEip = Frame->Eip;
00206 
00207     
00208     
00209     
00210     
if (! CsToLinear(&Regs, VM86USER(Frame))) {
00211         
return FALSE;
00212     }
00213 
00214     
00215     
00216     
00217     
00218     
while (Regs.RiInstLength <= 
MAX_INSTRUCTION_LENGTH) {
00219 
00220         
00221         Regs.RiOpcode = *Regs.RiLinearAddr;
00222 
00223         
switch(Regs.RiOpcode) {
00224             
case 0x0f:
00225                 
00226 
#if DEVL
00227 
                ExVdmOpcodeDispatchCounts[VDM_INDEX_0F]++;
00228 
#endif
00229 
#if VDMDBG
00230 
                DbgPrintf(
"Saw 0x0f opcode (0x%02x) at linear address 0x%08lx\n", (
int) Regs.RiOpcode, (
long) Regs.RiLinearAddr);
00231 
#endif
00232 
                return(VdmOpcode0F(&Regs));
00233 
00234             
case 0x26:
00235 
#if DEVL
00236 
                ExVdmOpcodeDispatchCounts[VDM_INDEX_ESPrefix]++;
00237 
#endif
00238 
#if VDMDBG
00239 
                DbgPrintf(
"Saw ES Prefix opcode (0x%02x) at linear address 0x%08lx\n", (
int) Regs.RiOpcode, (
long) Regs.RiLinearAddr);
00240 
#endif
00241 
                Regs.RiPrefixFlags |= PREFIX_ES;
00242                 
break;
00243 
00244             
case 0x2e:
00245 
#if DEVL
00246 
                ExVdmOpcodeDispatchCounts[VDM_INDEX_CSPrefix]++;
00247 
#endif
00248 
#if VDMDBG
00249 
                DbgPrintf(
"Saw CS Prefix opcode (0x%02x) at linear address 0x%08lx\n", (
int) Regs.RiOpcode, (
long) Regs.RiLinearAddr);
00250 
#endif
00251 
                Regs.RiPrefixFlags |= PREFIX_CS;
00252                 
break;
00253 
00254             
case 0x36:
00255 
#if DEVL
00256 
                ExVdmOpcodeDispatchCounts[VDM_INDEX_SSPrefix]++;
00257 
#endif
00258 
#if VDMDBG
00259 
                DbgPrintf(
"Saw SS Prefix opcode (0x%02x) at linear address 0x%08lx\n", (
int) Regs.RiOpcode, (
long) Regs.RiLinearAddr);
00260 
#endif
00261 
                Regs.RiPrefixFlags |= PREFIX_SS;
00262                 
break;
00263 
00264             
case 0x3e:
00265 
#if DEVL
00266 
                ExVdmOpcodeDispatchCounts[VDM_INDEX_DSPrefix]++;
00267 
#endif
00268 
#if VDMDBG
00269 
                DbgPrintf(
"Saw DS Prefix opcode (0x%02x) at linear address 0x%08lx\n", (
int) Regs.RiOpcode, (
long) Regs.RiLinearAddr);
00270 
#endif
00271 
                Regs.RiPrefixFlags |= PREFIX_DS;
00272                 
break;
00273 
00274             
case 0x64:
00275 
#if DEVL
00276 
                ExVdmOpcodeDispatchCounts[VDM_INDEX_FSPrefix]++;
00277 
#endif
00278 
#if VDMDBG
00279 
                DbgPrintf(
"Saw FS Prefix opcode (0x%02x) at linear address 0x%08lx\n", (
int) Regs.RiOpcode, (
long) Regs.RiLinearAddr);
00280 
#endif
00281 
                Regs.RiPrefixFlags |= PREFIX_FS;
00282                 
break;
00283 
00284             
case 0x65:
00285 
#if DEVL
00286 
                ExVdmOpcodeDispatchCounts[VDM_INDEX_GSPrefix]++;
00287 
#endif
00288 
#if VDMDBG
00289 
                DbgPrintf(
"Saw GS Prefix opcode (0x%02x) at linear address 0x%08lx\n", (
int) Regs.RiOpcode, (
long) Regs.RiLinearAddr);
00290 
#endif
00291 
                Regs.RiPrefixFlags |= PREFIX_GS;
00292                 
break;
00293 
00294             
case 0x66:
00295 
#if DEVL
00296 
                ExVdmOpcodeDispatchCounts[VDM_INDEX_OPER32Prefix]++;
00297 
#endif
00298 
#if VDMDBG
00299 
                DbgPrintf(
"Saw Operand 32 Prefix opcode (0x%02x) at linear address 0x%08lx\n", (
int) Regs.RiOpcode, (
long) Regs.RiLinearAddr);
00300 
#endif
00301 
                Regs.RiPrefixFlags |= PREFIX_OPER32;
00302                 
break;
00303 
00304             
case 0x67:
00305 
#if DEVL
00306 
                ExVdmOpcodeDispatchCounts[VDM_INDEX_ADDR32Prefix]++;
00307 
#endif
00308 
#if VDMDBG
00309 
                DbgPrintf(
"Saw Address 32 Prefix opcode (0x%02x) at linear address 0x%08lx\n", (
int) Regs.RiOpcode, (
long) Regs.RiLinearAddr);
00310 
#endif
00311 
                Regs.RiPrefixFlags |= PREFIX_ADDR32;
00312                 
break;
00313 
00314             
00315             
00316             
00317             
00318             
00319             
00320             
00321             
00322             
case 0x6c:
00323                 
00324 
#if DEVL
00325 
                ExVdmOpcodeDispatchCounts[VDM_INDEX_INSB]++;
00326 
#endif
00327 
#if VDMDBG
00328 
                DbgPrintf(
"Saw INSB opcode (0x%02x) at linear address 0x%08lx\n", (
int) Regs.RiOpcode, (
long) Regs.RiLinearAddr);
00329 
#endif
00330 
                IOAddress = ( Frame->SegEs << 16 ) + Frame->Edi;
00331 
00332                 
if (Regs.RiPrefixFlags & PREFIX_REP) {
00333                     IOCount = Frame->Ecx;
00334                 }
00335                 
else {
00336                     IOCount = 1;
00337                 }
00338                 IOPort = Frame->Edx;
00339 
00340                 
return(KiIA32VdmDispatchStringIo(IOPort, 1, Regs.RiPrefixFlags & PREFIX_REP, TRUE, IOCount, IOAddress, Regs.RiInstLength, Frame));
00341 
00342             
case 0x6d:
00343                 
00344 
#if DEVL
00345 
                ExVdmOpcodeDispatchCounts[VDM_INDEX_INSW]++;
00346 
#endif
00347 
#if VDMDBG
00348 
                DbgPrintf(
"Saw INSW opcode (0x%02x) at linear address 0x%08lx\n", (
int) Regs.RiOpcode, (
long) Regs.RiLinearAddr);
00349 
#endif
00350 
                IOAddress = ( Frame->SegEs << 16 ) + Frame->Edi;
00351 
00352                 
if (Regs.RiPrefixFlags & PREFIX_REP) {
00353                     IOCount = Frame->Ecx;
00354                 }
00355                 
else {
00356                     IOCount = 1;
00357                 }
00358                 IOPort = Frame->Edx;
00359 
00360                 
return(KiIA32VdmDispatchStringIo(IOPort, 2, Regs.RiPrefixFlags & PREFIX_REP, TRUE, IOCount, IOAddress, Regs.RiInstLength, Frame));
00361 
00362             
case 0x6e:
00363                 
00364 
#if DEVL
00365 
                ExVdmOpcodeDispatchCounts[VDM_INDEX_OUTSB]++;
00366 
#endif
00367 
#if VDMDBG
00368 
                DbgPrintf(
"Saw OUTSB opcode (0x%02x) at linear address 0x%08lx\n", (
int) Regs.RiOpcode, (
long) Regs.RiLinearAddr);
00369 
#endif
00370 
                IOAddress = ( Frame->SegEs << 16 ) + Frame->Edi;
00371 
00372                 
if (Regs.RiPrefixFlags & PREFIX_REP) {
00373                     IOCount = Frame->Ecx;
00374                 }
00375                 
else {
00376                     IOCount = 1;
00377                 }
00378                 IOPort = Frame->Edx;
00379 
00380                 
return(KiIA32VdmDispatchStringIo(IOPort, 1, Regs.RiPrefixFlags & PREFIX_REP, FALSE, IOCount, IOAddress, Regs.RiInstLength, Frame));
00381 
00382             
case 0x6f:
00383                 
00384 
#if DEVL
00385 
                ExVdmOpcodeDispatchCounts[VDM_INDEX_OUTSW]++;
00386 
#endif
00387 
#if VDMDBG
00388 
                DbgPrintf(
"Saw OUTSW opcode (0x%02x) at linear address 0x%08lx\n", (
int) Regs.RiOpcode, (
long) Regs.RiLinearAddr);
00389 
#endif
00390 
                IOAddress = ( Frame->SegEs << 16 ) + Frame->Edi;
00391 
00392                 
if (Regs.RiPrefixFlags & PREFIX_REP) {
00393                     IOCount = Frame->Ecx;
00394                 }
00395                 
else {
00396                     IOCount = 1;
00397                 }
00398                 IOPort = Frame->Edx;
00399 
00400                 
return(KiIA32VdmDispatchStringIo(IOPort, 2, Regs.RiPrefixFlags & PREFIX_REP, FALSE, IOCount, IOAddress, Regs.RiInstLength, Frame));
00401 
00402             
case 0x9b:
00403             
case 0x0d8:
00404             
case 0x0d9:
00405             
case 0x0da:
00406             
case 0x0db:
00407             
case 0x0dc:
00408             
case 0x0dd:
00409             
case 0x0de:
00410             
case 0x0df:
00411 
#if DEVL
00412 
                ExVdmOpcodeDispatchCounts[VDM_INDEX_NPX]++;
00413 
#endif
00414 
#if VDMDBG
00415 
                DbgPrintf(
"Saw NPX opcode (0x%02x) at linear address 0x%08lx\n", (
int) Regs.RiOpcode, (
long) Regs.RiLinearAddr);
00416 
#endif
00417 
                break;
00418 
00419             
case 0x09c:
00420 
#if DEVL
00421 
                ExVdmOpcodeDispatchCounts[VDM_INDEX_PUSHF]++;
00422 
#endif
00423 
#if VDMDBG
00424 
                DbgPrintf(
"Saw PUSHF opcode (0x%02x) at linear address 0x%08lx\n", (
int) Regs.RiOpcode, (
long) Regs.RiLinearAddr);
00425 
#endif
00426 
                
00427                 
if (! VM86USER(Frame)) {
00428                     
return FALSE;
00429                 }
00430 
00431                 flags = Frame->EFlags & (~EFLAGS_INTERRUPT_MASK);
00432                 flags |= EFLAGS_IOPL_MASK;
00433                 flags |= (*
VdmFixedStateLinear & (
VDM_VIRTUAL_INTERRUPTS | EFLAGS_ALIGN_CHECK | EFLAGS_NT_MASK));
00434 
00435                 
if (Regs.RiPrefixFlags & PREFIX_OPER32) {
00436                     Frame->HardwareEsp = (Frame->HardwareEsp - 4) & 0xffff;
00437                     longPtr = (PULONG) (Frame->SegSs << 4) + Frame->HardwareEsp;
00438                     *longPtr = flags;
00439                 }
00440                 
else {
00441                     Frame->HardwareEsp = (Frame->HardwareEsp - 2) & 0xffff;
00442                     shortPtr = (
PUSHORT) (Frame->SegSs << 4) + Frame->HardwareEsp;
00443                     *shortPtr = flags & 0xffff;
00444                 }
00445 
00446                 Frame->Eip += Regs.RiInstLength;
00447 
00448                 
return TRUE;
00449 
00450             
case 0x9d:
00451 
#if DEVL
00452 
                ExVdmOpcodeDispatchCounts[VDM_INDEX_POPF]++;
00453 
#endif
00454 
#if VDMDBG
00455 
                DbgPrintf(
"Saw POPF opcode (0x%02x) at linear address 0x%08lx\n", (
int) Regs.RiOpcode, (
long) Regs.RiLinearAddr);
00456 
#endif
00457 
                
00458                 
if (! VM86USER(Frame)) {
00459                     
return FALSE;
00460                 }
00461 
00462                 
if (Regs.RiPrefixFlags & PREFIX_OPER32) {
00463                     longPtr = (PULONG) ((Frame->SegSs << 4) + Frame->HardwareEsp);
00464                     flags = *longPtr;
00465                     Frame->HardwareEsp = (Frame->HardwareEsp + 4) & 0xffff;
00466                 }
00467                 
else {
00468                     shortPtr = (
PUSHORT) ((Frame->SegSs << 4) + Frame->HardwareEsp);
00469                     flags = *shortPtr;
00470                     Frame->HardwareEsp = (Frame->HardwareEsp + 2) & 0xffff;
00471                 }
00472 
00473                 flags &= ~EFLAGS_IOPL_MASK;
00474 
00475                 KeIA32AndOrVdmLock(~(EFLAGS_INTERRUPT_MASK | EFLAGS_ALIGN_CHECK | EFLAGS_NT_MASK), (flags & (EFLAGS_INTERRUPT_MASK | EFLAGS_ALIGN_CHECK | EFLAGS_NT_MASK)));
00476 
00477                 flags &= ~EFLAGS_NT_MASK;
00478 
00479                 
00480                 
00481                 
00482                 
00483                 
if (
KeIA32VirtualIntExtensions & V86_VIRTUAL_INT_EXTENSIONS) {
00484                     flags |= EFLAGS_VIF;
00485                     
if (! (flags & EFLAGS_INTERRUPT_MASK)) {
00486                         flags &= ~EFLAGS_VIF;
00487                     }
00488                 }
00489                 flags |= (EFLAGS_INTERRUPT_MASK | EFLAGS_V86_MASK);
00490                 Frame->EFlags = flags;
00491 
00492                 Frame->Eip += Regs.RiInstLength;
00493 
00494                 
return TRUE;
00495 
00496             
case 0x0cd:
00497 
#if DEVL
00498 
                ExVdmOpcodeDispatchCounts[VDM_INDEX_INTnn]++;
00499 
#endif
00500 
#if VDMDBG
00501 
                DbgPrintf(
"Saw INTnn opcode (0x%02x) at linear address 0x%08lx\n", (
int) Regs.RiOpcode, (
long) Regs.RiLinearAddr);
00502 
#endif
00503 
                if (VM86USER(Frame)) {
00504                     
00505                     
00506                     
00507 
00508                     
00509                     
00510                     
00511                     
00512                     
00513 
00514                     Frame->HardwareEsp = (Frame->HardwareEsp - 2) & 0xffff;
00515                     shortPtr = (
PUSHORT) ((Frame->SegSs << 4) + Frame->HardwareEsp);
00516                     flags = Frame->EFlags;
00517 
00518                     
if (! 
KeIA32VdmIoplAllowed) {
00519                         flags = (flags & ~EFLAGS_INTERRUPT_MASK) | (*
VdmFixedStateLinear & (
VDM_INTERRUPT_PENDING | EFLAGS_ALIGN_CHECK));
00520                     }
00521 
00522                     flags |= EFLAGS_IOPL_MASK;
00523                     *shortPtr = flags;
00524 
00525                     
00526                     
00527                     
00528                     flags = Frame->EFlags;
00529 
00530                     
if (
KeIA32VdmIoplAllowed) {
00531                         flags &= ~EFLAGS_INTERRUPT_MASK;
00532                     }
00533                     
else {
00534                         KeIA32AndOrVdmLock(~VDM_VIRTUAL_INTERRUPTS, 0);
00535                         flags |= EFLAGS_INTERRUPT_MASK;
00536                     }
00537 
00538                     flags &= ~(EFLAGS_NT_MASK | EFLAGS_TF_MASK);
00539                     Frame->EFlags = flags;
00540 
00541                     
00542                     Frame->HardwareEsp = (Frame->HardwareEsp - 2) & 0xffff;
00543                     shortPtr = (
PUSHORT) ((Frame->SegSs << 4) + Frame->HardwareEsp);
00544                     *shortPtr = Frame->SegCs;
00545 
00546                     
00547                     Frame->HardwareEsp = (Frame->HardwareEsp - 2) & 0xffff;
00548                     shortPtr = (
PUSHORT) ((Frame->SegSs << 4) + Frame->HardwareEsp);
00549                     *shortPtr = Frame->Eip;
00550 
00551                     
00552                     
00553                     
00554                     
00555                     Regs.RiLinearAddr++;
00556                     longPtr = (PULONG) (*(Regs.RiLinearAddr) * 4);
00557 
00558                     
00559                     
00560                     
00561                     
00562                     Frame->Eip = *longPtr & 0xffff;
00563                     Frame->SegCs = *longPtr >> 16;
00564                 }
00565                 
else {
00566                     
00567                     
00568                     
00569 
00570                     
00571                     
00572                     
00573                     flags = Frame->EFlags;
00574                     GetVirtualBits(&flags, Frame);
00575                     Regs.RiEFlags = flags;
00576 
00577                     
00578                     
00579                     
00580                     Regs.RiSegSs = Frame->SegSs;
00581                     Regs.RiEsp = Frame->HardwareEsp;
00582                     
if (! SsToLinear(&Regs, VM86USER(Frame))) { 
00583                         
return FALSE;
00584                     }
00585 
00586                     
00587                     
00588                     
00589                     
00590                     Regs.RiEip++;
00591                     Regs.RiLinearAddr++;
00592                     
if (! CheckEip(&Regs)) {
00593                         
return FALSE;
00594                     }
00595 
00596                     
00597                     
00598                     
00599                     Regs.RiEip++;
00600                     Regs.RiLinearAddr++;
00601 
00602 
00603                     
00604                     
00605                     
00606                     
if (! PushInt(*(Regs.RiLinearAddr - 1), &Regs)) {
00607                         
return FALSE;
00608                     }
00609 
00610                     
00611                     
00612                     
00613 
00614                     
if (! KeIA32UnscrambleLdtEntry(Regs.RiSegCs, &NewXDescriptor)) {
00615                         
return FALSE;
00616                     }
00617 
00618                     Frame->HardwareEsp = Regs.RiEsp;
00619                     Frame->EFlags = Regs.RiEFlags;
00620                     Frame->SegCs = Regs.RiSegCs;
00621                     Frame->Eip = Regs.RiEip;
00622                 }
00623 
00624                 
return TRUE;
00625 
00626             
case 0x0ce:
00627 
#if DEVL
00628 
                ExVdmOpcodeDispatchCounts[VDM_INDEX_INTO]++;
00629 
#endif
00630 
#if VDMDBG
00631 
                DbgPrintf(
"Saw INTO opcode (0x%02x) at linear address 0x%08lx\n", (
int) Regs.RiOpcode, (
long) Regs.RiLinearAddr);
00632 
#endif
00633 
00634                 
00635                 
00636                 
00637                 
00638                 
return FALSE;
00639                 
00640                 
break;
00641 
00642             
case 0x0cf:
00643 
#if DEVL
00644 
                ExVdmOpcodeDispatchCounts[VDM_INDEX_IRET]++;
00645 
#endif
00646 
#if VDMDBG
00647 
                DbgPrintf(
"Saw IRET opcode (0x%02x) at linear address 0x%08lx\n", (
int) Regs.RiOpcode, (
long) Regs.RiLinearAddr);
00648 
#endif
00649 
                
00650                 
00651                 
00652 
00653                 
if (! VM86USER(Frame)) {
00654                     
return FALSE;
00655                 }
00656 
00657 
00658                 
00659                 
00660                 
00661                 
00662                 
if (Regs.RiPrefixFlags & PREFIX_OPER32) {
00663                     longPtr = (PULONG) ((Frame->SegSs << 4) + Frame->HardwareEsp);
00664 
00665                     Frame->Eip = *longPtr++;
00666                     Frame->SegCs = *longPtr++;
00667                     flags = *longPtr;
00668 
00669                     Frame->HardwareEsp = (Frame->HardwareEsp + 12) & 0xffff;
00670                 }
00671                 
else {
00672                     shortPtr = (
PUSHORT) ((Frame->SegSs << 4) + Frame->HardwareEsp);
00673 
00674                     Frame->Eip  = *shortPtr++ & 0xffff;
00675                     Frame->SegCs = *shortPtr++ & 0xffff;
00676                     flags = *shortPtr & 0xffff;
00677 
00678                     Frame->HardwareEsp = (Frame->HardwareEsp + 6) & 0xffff;
00679                 }
00680 
00681                 flags &= ~(EFLAGS_IOPL_MASK | EFLAGS_NT_MASK);
00682 
00683                 KeIA32AndOrVdmLock(~VDM_VIRTUAL_INTERRUPTS, flags & EFLAGS_INTERRUPT_MASK );
00684 
00685                 
00686                 
00687                 
00688                 
00689                 
if (
KeIA32VirtualIntExtensions & V86_VIRTUAL_INT_EXTENSIONS) {
00690                     
if (flags & EFLAGS_INTERRUPT_MASK) {
00691                         flags |= EFLAGS_VIF;
00692                     }
00693                     
else {
00694                         flags &= ~EFLAGS_VIF;
00695                     }
00696                 }
00697 
00698                 flags |= (EFLAGS_INTERRUPT_MASK | EFLAGS_V86_MASK);
00699                 Frame->EFlags = flags;
00700 
00701                 
00702                 shortPtr = (Frame->SegCs << 4) + Frame->Eip;
00703 
00704                 
if ((*shortPtr & 0xffff) == BOP_OPCODE) {
00705                     VdmDispatchBop(Frame);
00706                 }
00707                 
else if ((*
VdmFixedStateLinear & 
VDM_INTERRUPT_PENDING) &&
00708                                 (*
VdmFixedStateLinear & 
VDM_VIRTUAL_INTERRUPTS)) {
00709                     VdmDispatchIntAck(Frame);
00710                 }
00711 
00712                 
return TRUE;
00713 
00714             
case 0x0e4:
00715 
#if DEVL
00716 
                ExVdmOpcodeDispatchCounts[VDM_INDEX_INBimm]++;
00717 
#endif
00718 
#if VDMDBG
00719 
                DbgPrintf(
"Saw INB immediate opcode (0x%02x) at linear address 0x%08lx\n", (
int) Regs.RiOpcode, (
long) Regs.RiLinearAddr);
00720 
#endif
00721 
                
00722                 Regs.RiInstLength++;
00723 
00724                 
00725                 charPtr = Regs.RiLinearAddr + 1;
00726                 
if ((charPtr - Regs.RiCsBase) > Regs.RiCsLimit) {
00727                     
return FALSE;
00728                 }
00729 
00730                 IOPort = *charPtr;
00731 
00732                 
return(KiIA32VdmDispatchIo(IOPort, 1, TRUE, Regs.RiInstLength, Frame));
00733 
00734             
case 0x0e5:
00735 
#if DEVL
00736 
                ExVdmOpcodeDispatchCounts[VDM_INDEX_INWimm]++;
00737 
#endif
00738 
#if VDMDBG
00739 
                DbgPrintf(
"Saw INW immediate opcode (0x%02x) at linear address 0x%08lx\n", (
int) Regs.RiOpcode, (
long) Regs.RiLinearAddr);
00740 
#endif
00741 
                
00742                 Regs.RiInstLength++;
00743 
00744                 
00745                 charPtr = Regs.RiLinearAddr + 1;
00746                 
if ((charPtr - Regs.RiCsBase) > Regs.RiCsLimit) {
00747                     
return FALSE;
00748                 }
00749 
00750                 IOPort = *charPtr;
00751 
00752                 
return(KiIA32VdmDispatchIo(IOPort, 2, TRUE, Regs.RiInstLength, Frame));
00753             
case 0x0e6:
00754 
#if DEVL
00755 
                ExVdmOpcodeDispatchCounts[VDM_INDEX_OUTBimm]++;
00756 
#endif
00757 
#if VDMDBG
00758 
                DbgPrintf(
"Saw OUTB immediate opcode (0x%02x) at linear address 0x%08lx\n", (
int) Regs.RiOpcode, (
long) Regs.RiLinearAddr);
00759 
#endif
00760 
                
00761                 Regs.RiInstLength++;
00762 
00763                 
00764                 charPtr = Regs.RiLinearAddr + 1;
00765                 
if ((charPtr - Regs.RiCsBase) > Regs.RiCsLimit) {
00766                     
return FALSE;
00767                 }
00768 
00769                 IOPort = *charPtr;
00770 
00771                 
return(KiIA32VdmDispatchIo(IOPort, 1, FALSE, Regs.RiInstLength, Frame));
00772             
case 0x0e7:
00773 
#if DEVL
00774 
                ExVdmOpcodeDispatchCounts[VDM_INDEX_OUTWimm]++;
00775 
#endif
00776 
#if VDMDBG
00777 
                DbgPrintf(
"Saw OUTW immediate opcode (0x%02x) at linear address 0x%08lx\n", (
int) Regs.RiOpcode, (
long) Regs.RiLinearAddr);
00778 
#endif
00779 
                
00780                 Regs.RiInstLength++;
00781 
00782                 
00783                 charPtr = Regs.RiLinearAddr + 1;
00784                 
if ((charPtr - Regs.RiCsBase) > Regs.RiCsLimit) {
00785                     
return FALSE;
00786                 }
00787 
00788                 IOPort = *charPtr;
00789 
00790                 
return(KiIA32VdmDispatchIo(IOPort, 2, FALSE, Regs.RiInstLength, Frame));
00791 
00792             
case 0x0ec:
00793 
#if DEVL
00794 
                ExVdmOpcodeDispatchCounts[VDM_INDEX_INB]++;
00795 
#endif
00796 
#if VDMDBG
00797 
                DbgPrintf(
"Saw INB opcode (0x%02x) at linear address 0x%08lx\n", (
int) Regs.RiOpcode, (
long) Regs.RiLinearAddr);
00798 
#endif
00799 
                IOPort = Frame->Edx;
00800 
00801                 
00802                 
00803                 
00804 
#ifdef NON_PCAT
00805 
                if (VM86USER(Frame)) {
00806                     
if (KeIA32MachineType & MACHINE_TYPE_MASK) {
00807                         
return(KiIA32VdmDispatchIo(IOPort, 1, TRUE, Regs.RiInstLength, Frame));
00808                     }
00809                 }
00810 
#endif
00811 
                
00812                 
switch (IOPort) {
00813                     
case 0x03bd:
00814                     
case 0x0379:
00815                     
case 0x0279:
00816                     
if (
VdmPrinterStatus(IOPort, Regs.RiInstLength, Frame)) {
00817                         
return TRUE;
00818                     }
00819                     
00820                     
default:
00821                         
return(KiIA32VdmDispatchIo(IOPort, 1, TRUE, Regs.RiInstLength, Frame));
00822                 }
00823                 
00824                 
return FALSE;
00825 
00826             
case 0x0ed:
00827 
#if DEVL
00828 
                ExVdmOpcodeDispatchCounts[VDM_INDEX_INW]++;
00829 
#endif
00830 
#if VDMDBG
00831 
                DbgPrintf(
"Saw INW opcode (0x%02x) at linear address 0x%08lx\n", (
int) Regs.RiOpcode, (
long) Regs.RiLinearAddr);
00832 
#endif
00833 
                IOPort = Frame->Edx;
00834                 
return(KiIA32VdmDispatchIo(IOPort, 2, TRUE, Regs.RiInstLength, Frame));
00835 
00836             
case 0x0ee:
00837 
#if DEVL
00838 
                ExVdmOpcodeDispatchCounts[VDM_INDEX_OUTB]++;
00839 
#endif
00840 
#if VDMDBG
00841 
                DbgPrintf(
"Saw OUTB opcode (0x%02x) at linear address 0x%08lx\n", (
int) Regs.RiOpcode, (
long) Regs.RiLinearAddr);
00842 
#endif
00843 
                IOPort = Frame->Edx;
00844 
00845                 
00846                 
switch (IOPort) {
00847                     
case 0x03bc:
00848                     
case 0x0378:
00849                     
case 0x0278:
00850                         
if (
VdmPrinterWriteData(IOPort, Regs.RiInstLength, Frame)) {
00851                             
return TRUE;
00852                         }
00853                         
00854                         
00855                         
00856                     
default:
00857                         
return(KiIA32VdmDispatchIo(IOPort, 1, FALSE, Regs.RiInstLength, Frame));
00858                 }
00859                 
00860                 
return FALSE;
00861 
00862             
case 0x0ef:
00863 
#if DEVL
00864 
                ExVdmOpcodeDispatchCounts[VDM_INDEX_OUTW]++;
00865 
#endif
00866 
#if VDMDBG
00867 
                DbgPrintf(
"Saw OUTW opcode (0x%02x) at linear address 0x%08lx\n", (
int) Regs.RiOpcode, (
long) Regs.RiLinearAddr);
00868 
#endif
00869 
                IOPort = Frame->Edx;
00870                 
return(KiIA32VdmDispatchIo(IOPort, 2, FALSE, Regs.RiInstLength, Frame));
00871 
00872             
case 0x0f0:
00873 
#if DEVL
00874 
                ExVdmOpcodeDispatchCounts[VDM_INDEX_LOCKPrefix]++;
00875 
#endif
00876 
#if VDMDBG
00877 
                DbgPrintf(
"Saw LOCK Prefix (0x%02x) at linear address 0x%08lx\n", (
int) Regs.RiOpcode, (
long) Regs.RiLinearAddr);
00878 
#endif
00879 
                Regs.RiPrefixFlags |= PREFIX_LOCK;
00880                 
break;
00881 
00882             
case 0x0f2:
00883 
#if DEVL
00884 
                ExVdmOpcodeDispatchCounts[VDM_INDEX_REPNEPrefix]++;
00885 
#endif
00886 
#if VDMDBG
00887 
                DbgPrintf(
"Saw REPNE Prefix (0x%02x) at linear address 0x%08lx\n", (
int) Regs.RiOpcode, (
long) Regs.RiLinearAddr);
00888 
#endif
00889 
                Regs.RiPrefixFlags |= PREFIX_REPNE;
00890                 
break;
00891 
00892             
case 0x0f3:
00893 
#if DEVL
00894 
                ExVdmOpcodeDispatchCounts[VDM_INDEX_REPPrefix]++;
00895 
#endif
00896 
#if VDMDBG
00897 
                DbgPrintf(
"Saw REP Prefix (0x%02x) at linear address 0x%08lx\n", (
int) Regs.RiOpcode, (
long) Regs.RiLinearAddr);
00898 
#endif
00899 
                Regs.RiPrefixFlags |= PREFIX_REP;
00900                 
break;
00901 
00902             
case 0x0f4:
00903 
#if DEVL
00904 
                ExVdmOpcodeDispatchCounts[VDM_INDEX_HLT]++;
00905 
#endif
00906 
#if VDMDBG
00907 
                DbgPrintf(
"Saw HLT opcode (0x%02x) at linear address 0x%08lx\n", (
int) Regs.RiOpcode, (
long) Regs.RiLinearAddr);
00908 
#endif
00909 
                
00910 
00911                 
if (! VM86USER(Frame)) {
00912                     
return FALSE;
00913                 }
00914 
00915                 
00916 
00917                 
00918                 
00919                 
00920 
00921                 Frame->Eip = (Frame->Eip + Regs.RiInstLength) & 0xffff;
00922 
00923                 
return TRUE;
00924 
00925                 
break;
00926 
00927             
case 0x0fa:
00928 
#if DEVL
00929 
                ExVdmOpcodeDispatchCounts[VDM_INDEX_CLI]++;
00930 
#endif
00931 
#if VDMDBG
00932 
                DbgPrintf(
"Saw CLI opcode (0x%02x) at linear address 0x%08lx\n", (
int) Regs.RiOpcode, (
long) Regs.RiLinearAddr);
00933 
#endif
00934 
                if (! VM86USER(Frame)) {
00935                     flags = Frame->EFlags & ~EFLAGS_INTERRUPT_MASK;
00936                     SetVirtualBits(flags, &Regs);
00937                 }
00938                 
else {
00939                     KeIA32AndOrVdmLock(~VDM_VIRTUAL_INTERRUPTS, 0);
00940                 }
00941                 
00942                 
00943                 Frame->Eip += Regs.RiInstLength;
00944 
00945                 
return TRUE;
00946 
00947             
case 0x0fb:
00948 
#if DEVL
00949 
                ExVdmOpcodeDispatchCounts[VDM_INDEX_STI]++;
00950 
#endif
00951 
#if VDMDBG
00952 
                DbgPrintf(
"Saw STI opcode (0x%02x) at linear address 0x%08lx\n", (
int) Regs.RiOpcode, (
long) Regs.RiLinearAddr);
00953 
#endif
00954 
                if (! VM86USER(Frame)) {
00955                     flags = Frame->EFlags | EFLAGS_INTERRUPT_MASK;
00956                     SetVirtualBits(flags, &Regs);
00957                 }
00958                 
else {
00959                     
00960                     
00961                     
if (
KeIA32VirtualIntExtensions & V86_VIRTUAL_INT_EXTENSIONS) {
00962                         Frame->EFlags |= EFLAGS_VIF;
00963                     }
00964                         
00965                     KeIA32AndOrVdmLock(0xffffffff, EFLAGS_INTERRUPT_MASK);
00966                 }
00967 
00968                 
00969                 Frame->Eip += Regs.RiInstLength;
00970 
00971                 
00972                 
00973                 
if (*
VdmFixedStateLinear & 
VDM_INTERRUPT_PENDING) {
00974                     VdmDispatchIntAck(Frame);
00975                 }
00976                 
return TRUE;
00977 
00978             
default:
00979                 
00980 
#if VDMDBG
00981 
                DbgPrintf(
"Saw unexpected opcode (0x%02x) at linear address 0x%08lx\n", (
int) Regs.RiOpcode, (
long) Regs.RiLinearAddr);
00982 
#endif
00983 
                return FALSE;
00984 
00985         }
00986 
00987         
00988 
00989         Regs.RiLinearAddr++;
00990         Regs.RiInstLength++;
00991     }
00992 
00993     
00994 
00995     
return (
FALSE);
00996 }
00997 
00998 
00999 
VOID
01000 VdmDispatchIntAck(
01001     IN PKIA32_FRAME Frame
01002     )
01003 
01004 
01005 
01006 
01007 
01008 
01009 
01010 
01011 
01012 
01013 
01014 
01015 
01016 
01017 
01018 
01019 
01020 
01021 
01022 {
01023     
PVDM_TIB VdmTib;
01024 
01025     VdmTib = (
PsGetCurrentThread()->Tcb.Teb)->Vdm;
01026     
01027     
if (*
VdmFixedStateLinear & VDM_INT_HARDWARE) {
01028         
01029 
01030         
VdmDispatchInterrupts(Frame, VdmTib);
01031     }
01032     
else {
01033         
01034 
01035         VdmTib->
EventInfo.
Event = 
VdmIntAck;
01036         VdmTib->
EventInfo.
Size = 0;
01037         VdmTib->
EventInfo.IntAckInfo = 0;
01038         
VdmEndExecution(Frame, VdmTib);
01039     }
01040 }
01041 
01042 
01043 
01044 
01045 
#define _VDM_EXTOFF_FUNC(x) (x = (x & ~EFLAGS_INTERRUPT_MASK) | (*VdmFixedStateLinear & (VDM_VIRTUAL_INTERRUPTS | EFLAGS_ALIGN_CHECK)) | EFLAGS_IOPL_MASK)
01046 
#define _VDM_EXTON_FUNC(x)  (x = (x & ~EFLAGS_INTERRUPT_MASK) | (*VdmFixedStateLinear & (VDM_VIRTUAL_INTERRUPTS | EFLAGS_ALIGN_CHECK)) | EFLAGS_IOPL_MASK)
01047 
#define _VDM_IOPL_FUNC(x)   (x = (x & ~EFLAGS_ALIGN_CHECK) | (*VdmFixedStateLinear & EFLAGS_ALIGN_CHECK) | EFLAGS_IOPL_MASK)
01048 
01049 
01050 
VOID
01051 GetVirtualBits(
01052     IN OUT PULONG PFlags,
01053     IN PKIA32_FRAME Frame
01054     )
01055 
01056 
01057 
01058 
01059 
01060 
01061 
01062 
01063 
01064 
01065 
01066 
01067 
01068 
01069 
01070 
01071 
01072 
01073 {
01074     
01075     
if (
KeIA32VdmIoplAllowed) {
01076         
if (*PFlags & EFLAGS_V86_MASK) {
01077             _VDM_IOPL_FUNC(*PFlags);
01078         }
01079         
else {
01080             _VDM_EXTOFF_FUNC(*PFlags);
01081         }
01082     }
01083     
else {
01084 
01085         
01086         
01087         
01088         
01089 
01090         
if (
KeIA32VirtualIntExtensions & (V86_VIRTUAL_INT_EXTENSIONS | PM_VIRTUAL_INT_EXTENSIONS)) {
01091             
if (*PFlags & EFLAGS_V86_MASK) {
01092                 
if (
KeIA32VirtualIntExtensions & V86_VIRTUAL_INT_EXTENSIONS) {
01093                     _VDM_EXTON_FUNC(*PFlags);
01094                 }
01095                 
else {
01096                     _VDM_EXTOFF_FUNC(*PFlags);
01097                 }
01098             }
01099             
else {
01100                 
if (
KeIA32VirtualIntExtensions & PM_VIRTUAL_INT_EXTENSIONS) {
01101                     _VDM_EXTON_FUNC(*PFlags);
01102                 }
01103                 
else {
01104                     _VDM_EXTOFF_FUNC(*PFlags);
01105                 }
01106             }
01107         }
01108         
else {
01109             _VDM_EXTOFF_FUNC(*PFlags);
01110         }
01111     }
01112 }
01113 
01114 
VOID
01115 SetVirtualBits(
01116     IN ULONG Flags,
01117     IN PREGINFO PRegs
01118     )
01119 
01120 
01121 
01122 
01123 
01124 
01125 
01126 
01127 
01128 
01129 
01130 
01131 
01132 
01133 
01134 
01135 
01136 {
01137     KeIA32AndOrVdmLock(~VDM_VIRTUAL_INTERRUPTS, Flags & EFLAGS_INTERRUPT_MASK);
01138 
01139     
01140     
01141     
01142     
01143     
01144     
01145     
01146     
01147   
01148 
#if 0
01149 
    if (
KeIA32VirtualIntExtensions & (V86_VIRTUAL_INT_EXTENSIONS | PM_VIRTUAL_INT_EXTENSIONS)) {
01150         
if (Flags & EFLAGS_V86_MASK) {
01151             
if (
KeIA32VirtualIntExtensions & V86_VIRTUAL_INT_EXTENSIONS) {
01152             }
01153             
else {
01154             }
01155         }
01156         
else {
01157             
if (
KeIA32VirtualIntExtensions & PM_VIRTUAL_INT_EXTENSIONS) {
01158             }
01159             
else {
01160             }
01161         }
01162     }
01163     
else {
01164     }
01165 
#endif
01166 
01167     
if (PRegs->RiPrefixFlags & PREFIX_OPER32) {
01168         KeIA32AndOrVdmLock(~EFLAGS_ALIGN_CHECK, Flags & EFLAGS_ALIGN_CHECK);
01169     }
01170 }
01171 
01172 
01173 BOOLEAN
01174 
KiIA32VdmReflectException(
01175     IN OUT PKIA32_FRAME Frame,
01176     IN ULONG Code
01177     )
01178 
01179 
01180 
01181 
01182 
01183 
01184 
01185 
01186 
01187 
01188 
01189 
01190 
01191 
01192 
01193 
01194 
01195 
01196 
01197 
01198 
01199 
01200 {
01201     REGINFO Regs;
01202     KXDESCRIPTOR NewXCsDescriptor, NewXSsDescriptor;
01203 
01204     
01205     
01206     
01207     
if ((Code == 
EXCEPTION_GP_FAULT) && (*
VdmFixedStateLinear & VDM_BREAK_EXCEPTIONS)) {
01208         VdmDispatchException(Frame, STATUS_ACCESS_VIOLATION, Frame->Eip, 2, 0, -1,  0);
01209         
return TRUE;
01210     }
01211 
01212     
01213     
01214     
01215     
if (*
VdmFixedStateLinear & VDM_BREAK_DEBUGGER) {
01216         
if (Code == 
EXCEPTION_DEBUG) {
01217             
01218             
01219             
01220             
01221             Frame->EFlags &= ~EFLAGS_TF_MASK;
01222             VdmDispatchException(Frame, STATUS_SINGLE_STEP, Frame->Eip, 0, 0, 0,  0);
01223             
return TRUE;
01224         }
01225         
if (Code == 
EXCEPTION_INT3) {
01226             VdmDispatchException(Frame, STATUS_BREAKPOINT, Frame->Eip - 1, 3, USER_BREAKPOINT, 0,  0);
01227 
01228             
return TRUE;
01229         }
01230     }
01231 
01232     
01233     
01234     
01235     
if (FLATUSER(Frame)) {
01236         
return TRUE;
01237     }
01238 
01239 
01240 
#if DEVL
01241 
    if (Code == 
EXCEPTION_SEGMENT_NOT_PRESENT) {
01242         ExVdmSegmentNotPresent++;
01243     }
01244 
#endif
01245 
01246     
01247     
01248     
01249 
01250     Regs.RiTrapFrame = Frame;
01251     Regs.RiSegSs = Frame->SegSs;
01252     Regs.RiEsp = Frame->HardwareEsp;
01253     Regs.RiEFlags = Frame->EFlags;
01254     Regs.RiEip = Frame->Eip;
01255     Regs.RiSegCs = Frame->SegCs;
01256 
01257     
if (! CsToLinear(&Regs, VM86USER(Frame))) {
01258         
return FALSE;
01259     }
01260 
01261     
if (! SsToLinear(&Regs, VM86USER(Frame))) {
01262         
return FALSE;
01263     }
01264 
01265     
if (! PushException(Code, &Regs)) {
01266         
return FALSE;
01267     }
01268 
01269     
01270     
01271     
01272     
01273     
01274     
if (Regs.RiEFlags & EFLAGS_V86_MASK) {
01275 
01276         NewXCsDescriptor.DescriptorWords = (ULONGLONG) (Regs.RiSegCs << 4);
01277         NewXSsDescriptor.DescriptorWords = (ULONGLONG) (Regs.RiSegSs << 4);
01278     }
01279     
else {
01280         
if (! KeIA32UnscrambleLdtEntry(Regs.RiSegCs, &NewXCsDescriptor)) {
01281             
return FALSE;
01282         }
01283 
01284         
if (! KeIA32UnscrambleLdtEntry(Regs.RiSegSs, &NewXSsDescriptor)) {
01285             
return FALSE;
01286         }
01287     }
01288 
01289     Frame->HardwareEsp = Regs.RiEsp;
01290 
01291     
01292     
01293     
01294     Frame->SegSs = Regs.RiSegSs;
01295     Frame->EFlags = Regs.RiEFlags;
01296 
01297     
01298     
01299     
01300     Frame->SegCs = Regs.RiSegCs;
01301     Frame->Eip = Regs.RiEip;
01302 
01303     
if (Code == 
EXCEPTION_DEBUG) {
01304         
01305         
01306         
01307         
01308         Frame->EFlags &= ~EFLAGS_TF_MASK;
01309     }
01310 
01311     
return TRUE;
01312 }
01313 
01314 
01315 BOOLEAN
01316 
KiIA32VdmSegmentNotPresent(
01317     IN OUT PKIA32_FRAME Frame
01318     )
01319 
01320 
01321 
01322 
01323 
01324 
01325 
01326 
01327 
01328 
01329 
01330 
01331 
01332 
01333 
01334 
01335 
01336 
01337 
01338 {
01339     
PVDM_TIB VdmTib;
01340     PVDM_FAULTHANDLER NoSegFault;
01341     ULONG Flags;
01342     KXDESCRIPTOR NewXCsDescriptor;
01343     KXDESCRIPTOR NewXSsDescriptor;
01344     ULONG 
Offset;
01345 
01346     
01347     
01348     
01349     VdmTib = (
PVDM_TIB) (
PsGetCurrentThread()->Tcb.Teb)->Vdm;
01350 
01351     
01352     
01353     
01354     
if (VdmTib->PmStackInfo.LockCount != 0) {
01355         
return(
KiIA32VdmReflectException(Frame, EXCEPTION_SEGMENT_NOT_PRESENT));
01356     }
01357 
01358     NoSegFault = &(VdmTib->VdmFaultHandlers[
EXCEPTION_SEGMENT_NOT_PRESENT]);
01359 
01360 
#if DEVL
01361 
    ExVdmSegmentNotPresent++;
01362 
#endif
01363 
01364     
01365     
01366     
01367     VdmTib->PmStackInfo.LockCount++;
01368     VdmTib->PmStackInfo.SaveEip = Frame->Eip;
01369     VdmTib->PmStackInfo.SaveEsp = Frame->HardwareEsp;
01370     VdmTib->PmStackInfo.SaveSsSelector = Frame->SegSs;
01371 
01372     
01373     
01374     
01375     
01376     
if (! KeIA32UnscrambleLdtEntry(NoSegFault->CsSelector, &NewXCsDescriptor)) {
01377         
return FALSE;
01378     }
01379 
01380     
if (! KeIA32UnscrambleLdtEntry(VdmTib->PmStackInfo.SsSelector, &NewXSsDescriptor)) {
01381         
return FALSE;
01382     }
01383 
01384     
01385     
01386     
01387     Flags = Frame->EFlags;
01388     GetVirtualBits(&Flags, Frame);
01389 
01390     
01391     
01392     
01393     
if (VdmTib->PmStackInfo.
Flags & 1) {
01394         PULONG ExcptStack32;
01395 
01396         
01397         
01398         
01399         ExcptStack32 = (PULONG) (NewXSsDescriptor.Words.Bits.Base + DPMISTACK_OFFSET);
01400 
01401         
01402         
01403         
01404 
01405         *--ExcptStack32 = Frame->SegSs;
01406         *--ExcptStack32 = Frame->HardwareEsp;
01407         *--ExcptStack32 = Flags;
01408 
01409         *--ExcptStack32 = Frame->SegCs;
01410         *--ExcptStack32 = Frame->Eip;
01411         *--ExcptStack32 = Frame->ISRCode;
01412 
01413         
01414         
01415         
01416         *--ExcptStack32 = VdmTib->PmStackInfo.DosxFaultIretD >> 16;
01417         *--ExcptStack32 = VdmTib->PmStackInfo.DosxFaultIretD &  0x0ffff;
01418 
01419         
Offset = ((PUCHAR) ExcptStack32) - NewXSsDescriptor.Words.Bits.Base;
01420     }
01421     
else {
01422         
PUSHORT ExcptStack16;
01423 
01424         
01425         
01426         
01427         ExcptStack16 = NewXSsDescriptor.Words.Bits.Base + DPMISTACK_OFFSET;
01428 
01429         
01430         
01431         
01432         *--ExcptStack16 = Frame->SegSs;
01433         *--ExcptStack16 = Frame->HardwareEsp;
01434         *--ExcptStack16 = Flags;
01435 
01436         *--ExcptStack16 = Frame->SegCs;
01437         *--ExcptStack16 = Frame->Eip;
01438         *--ExcptStack16 = Frame->ISRCode;
01439 
01440         
01441         
01442         
01443         *--ExcptStack16 = VdmTib->PmStackInfo.DosxFaultIretD >> 16;
01444         *--ExcptStack16 = VdmTib->PmStackInfo.DosxFaultIretD &  0x0ffff;
01445         
Offset = ((PUCHAR) ExcptStack16) - NewXSsDescriptor.Words.Bits.Base;
01446     }
01447 
01448     
if (NoSegFault->Flags & VDM_INT_INT_GATE) {
01449         KeIA32AndOrVdmLock(~VDM_VIRTUAL_INTERRUPTS, 0);
01450         Frame->EFlags &= ~EFLAGS_VIF;
01451     }
01452 
01453     Frame->SegCs = NoSegFault->CsSelector;
01454     Frame->Eip = NoSegFault->Eip;
01455     Frame->SegSs = VdmTib->PmStackInfo.SsSelector;
01456     Frame->HardwareEsp = 
Offset;
01457 
01458     
return TRUE;
01459 }
01460 
01461 
01462 
VOID
01463 VdmDispatchException(
01464     IN PKIA32_FRAME Frame,
01465     IN NTSTATUS ExcepCode,
01466     IN PVOID ExcepAddr,
01467     IN ULONG NumParms,
01468     IN ULONG Parm1,
01469     IN ULONG Parm2,
01470     IN ULONG Parm3
01471     )
01472 
01473 
01474 
01475 
01476 
01477 
01478 
01479 
01480 
01481 
01482 
01483 
01484 
01485 
01486 
01487 
01488 
01489 {
01490     
01491     
01492     
01493 
01494     
KeLowerIrql(0);
01495 
01496     
01497         
01498     
01499     
ASSERT(NumParms <= 3);
01500 
01501     
01502     
01503     
01504     
01505     KiIA32ExceptionDispatch(Frame, ExcepCode, ExcepAddr, NumParms, Parm1, Parm2, Parm3);
01506 
01507         
01508     
01509         
01510 }
01511 
01512 
01513 BOOLEAN
01514 PushInt(IN ULONG InterruptNumber,
01515         IN OUT PREGINFO Regs
01516         )
01517 
01518 
01519 
01520 
01521 
01522 
01523 
01524 
01525 
01526 
01527 
01528 
01529 
01530 
01531 
01532 
01533 
01534 
01535 
01536 {
01537     
PVDM_TIB VdmTib;
01538     
PVDM_INTERRUPTHANDLER IntHandler;
01539     PULONG ExcptStack32;
01540     
PUSHORT ExcptStack16;
01541     ULONG Flags;
01542 
01543     
ASSERT(InterruptNumber < 256);
01544 
01545     VdmTib = (
PVDM_TIB) (
PsGetCurrentThread()->Tcb.Teb)->Vdm;
01546 
01547     IntHandler = &(VdmTib->
VdmInterruptHandlers[InterruptNumber]);
01548 
01549         
01550         
01551         
01552         
if (! Regs->RiSsDescriptor.Words.Bits.Default_Big) {
01553                 Regs->RiEsp &= 0xffff;
01554         }
01555 
01556         
01557         
01558         
01559         
if (IntHandler->Flags & VDM_INT_32) {
01560                 
if (Regs->RiEsp <= (3 * 
sizeof(PVOID))) {
01561                         
return FALSE;
01562                 }
01563 
01564                 Regs->RiEsp -= 3 * 
sizeof(PVOID);
01565         }
01566         
else {
01567                 
if (Regs->RiEsp <= (3 * 
sizeof(
SHORT))) {
01568                         
return FALSE;
01569                 }
01570 
01571                 Regs->RiEsp -= 3 * 
sizeof(
SHORT);
01572         }
01573 
01574         
01575         
01576         
01577         
if (Regs->RiSsDescriptor.Words.Bits.Type & DESCRIPTOR_EXPAND_DOWN) {
01578                 
if (Regs->RiEsp <= Regs->RiSsLimit) {
01579                         
return FALSE;
01580                 }
01581         }
01582         
else {
01583                 
if (Regs->RiEsp >= Regs->RiSsLimit) {
01584                         
return FALSE;
01585                 }
01586         }
01587 
01588         
01589         
01590         
01591 
01592         
01593         
01594         
01595         Flags = Regs->RiEFlags;
01596         GetVirtualBits(&Flags, Regs->RiTrapFrame);
01597 
01598         
if (IntHandler->Flags & VDM_INT_32) {
01599                 ExcptStack32 = Regs->RiSsBase + Regs->RiEsp;
01600 
01601                 
01602                 
01603                 
01604                 *ExcptStack32++ = Regs->RiEip;
01605                 *ExcptStack32++ = Regs->RiSegCs;
01606                 *ExcptStack32 = Flags;
01607         }
01608         
else {
01609                 ExcptStack16 = Regs->RiSsBase + Regs->RiEsp;
01610 
01611                 
01612                 
01613                 
01614                 *ExcptStack16++ = Regs->RiEip;
01615                 *ExcptStack16++ = Regs->RiSegCs;
01616                 *ExcptStack16 = Flags;
01617         }
01618 
01619         
01620         
01621         
01622         Regs.RiSegCs = IntHandler->
CsSelector;
01623         Regs.RiEip = IntHandler->
Eip;
01624 
01625         
if (CsToLinear(&Regs, ! (IntHandler->Flags & VDM_INT_32))) {
01626                 
if (! Regs->RiCsDescriptor.Words.Bits.Pres) {
01627                         
return FALSE;
01628                 }
01629         }
01630         
else {
01631                 
01632                 
01633                 
01634                 
01635                 
01636 
01637                 
if (Regs.RiEip >= Regs.RiCsLimit) {
01638                         
return FALSE;
01639                 }
01640         }
01641 
01642         Regs.RiEFlags &= ~EFLAGS_TF_MASK;
01643 
01644         
if (IntHandler->Flags & VDM_INT_INT_GATE) {
01645                 
if (
KeIA32VirtualIntExtensions & PM_VIRTUAL_INT_EXTENSIONS) {
01646                         Regs->RiEFlags &= ~EFLAGS_VIF;
01647                 }
01648                 KeIA32AndOrVdmLock(~EFLAGS_INTERRUPT_MASK, 0);
01649         }
01650 
01651         Regs.RiEFlags &= ~(EFLAGS_IOPL_MASK | EFLAGS_NT_MASK | EFLAGS_V86_MASK);
01652         Regs.RiEFlags |= EFLAGS_INTERRUPT_MASK;
01653 
01654         
return TRUE;
01655 }
01656 
01657 
01658 BOOLEAN
01659 PushException(
01660         IN ULONG ExceptionNumber,
01661         IN OUT PREGINFO Regs
01662         )
01663 
01664 
01665 
01666 
01667 
01668 
01669 
01670 
01671 
01672 
01673 
01674 
01675 
01676 
01677 
01678 
01679 
01680 
01681 
01682 {
01683     
PVDM_TIB VdmTib;
01684     PVDM_FAULTHANDLER ExceptHandler;
01685     ULONG Flags;
01686 
01687     
ASSERT(ExceptionNumber < 32);
01688 
01689     VdmTib = (
PVDM_TIB) (
PsGetCurrentThread()->Tcb.Teb)->Vdm;
01690     ExceptHandler = &(VdmTib->VdmFaultHandlers[ExceptionNumber]);
01691 
01692     
if (Regs->RiEFlags & EFLAGS_V86_MASK) {
01693         
PUSHORT ExcptStack16;
01694 
01695         
01696 
01697         
01698         
01699         
01700         
01701         
if (ExceptionNumber > 7) {
01702             
return FALSE;
01703         }
01704 
01705         
01706         
01707         
01708         
01709         Regs->RiEsp = ((Regs->RiEsp - 2) & 0xffff);
01710         ExcptStack16 = Regs->RiSsBase + Regs->RiEsp;
01711         Flags = Regs->RiEFlags;
01712         GetVirtualBits(&Flags, Regs->RiTrapFrame);
01713         *ExcptStack16 = Flags;
01714 
01715         Regs->RiEsp = ((Regs->RiEsp - 2) & 0xffff);
01716         ExcptStack16 = Regs->RiSsBase + Regs->RiEsp;
01717         *ExcptStack16 = Regs->RiSegCs;
01718 
01719         Regs->RiEsp = ((Regs->RiEsp - 2) & 0xffff);
01720         ExcptStack16 = Regs->RiSsBase + Regs->RiEsp;
01721         *ExcptStack16 = Regs->RiEip;
01722     }
01723     
else {
01724         
01725 
01726         
01727         
01728         
01729         
01730         
01731 
01732         
01733         
01734         
01735         
if (VdmTib->PmStackInfo.LockCount == 0) {
01736             VdmTib->PmStackInfo.SaveEip = Regs.RiEip;
01737             VdmTib->PmStackInfo.SaveEsp = Regs.RiEsp;
01738             VdmTib->PmStackInfo.SaveSsSelector = Regs.RiSegSs;
01739 
01740             Regs->RiSegSs = VdmTib->PmStackInfo.SsSelector;
01741             Regs->RiEsp = DPMISTACK_EXCEPTION_OFFSET;
01742 
01743             
01744             
01745             
01746             
if (! SsToLinear(Regs, FALSE)) {
01747                 
return FALSE;
01748             }
01749 
01750             VdmTib->PmStackInfo.LockCount++;
01751         }
01752 
01753         
01754         
01755         
01756         Regs->RiEsp -= 0x20;
01757 
01758         
if (! Regs->RiSsDescriptor.Words.Bits.Default_Big) {
01759             
01760             
01761             
01762             Regs->RiEsp &= 0xffff;
01763         }
01764 
01765         Flags = Regs->RiEFlags;
01766         GetVirtualBits(&Flags, Regs->RiTrapFrame);
01767 
01768         
if (VdmTib->PmStackInfo.
Flags) {
01769             PULONG ExcptStack32;
01770 
01771             
01772             
01773             
01774 
01775             
if (! CheckEsp(Regs, 32)) {
01776                 
return FALSE;
01777             }
01778 
01779             ExcptStack32 = Regs.RiSsBase + Regs.RiEsp;
01780             *--ExcptStack32 = VdmTib->PmStackInfo.SaveSsSelector;
01781             *--ExcptStack32 = VdmTib->PmStackInfo.SaveEsp;
01782             *--ExcptStack32 = Flags;
01783             *--ExcptStack32 = Regs->RiSegCs;
01784             *--ExcptStack32 = VdmTib->PmStackInfo.SaveEip;
01785             *--ExcptStack32 = Regs->RiTrapFrame->ISRCode;
01786 
01787             
01788             
01789             
01790             *--ExcptStack32 = VdmTib->PmStackInfo.DosxFaultIretD >> 16;
01791             *--ExcptStack32 = VdmTib->PmStackInfo.DosxFaultIretD &  0x0ffff;
01792 
01793 
01794             Regs.RiEsp = ExcptStack32 - Regs.RiSsBase;
01795 
01796         }
01797         
else {
01798             
PUSHORT ExcptStack16;
01799 
01800             
01801             
01802             
01803 
01804             
if (! CheckEsp(Regs, 16)) {
01805                 
return FALSE;
01806             }
01807 
01808             ExcptStack16 = Regs.RiSsBase + Regs.RiEsp;
01809             *--ExcptStack16 = VdmTib->PmStackInfo.SaveSsSelector;
01810             *--ExcptStack16 = VdmTib->PmStackInfo.SaveEsp;
01811             *--ExcptStack16 = Flags;
01812             *--ExcptStack16 = Regs->RiSegCs;
01813             *--ExcptStack16 = VdmTib->PmStackInfo.SaveEip;
01814             *--ExcptStack16 = Regs->RiTrapFrame->ISRCode;
01815 
01816             
01817             
01818             
01819             *--ExcptStack16 = VdmTib->PmStackInfo.DosxFaultIretD >> 16;
01820             *--ExcptStack16 = VdmTib->PmStackInfo.DosxFaultIretD &  0x0ffff;
01821 
01822             Regs->RiEsp = ExcptStack16 - Regs.RiSsBase;
01823         }
01824     }
01825 
01826     
01827     
01828     
01829     Regs.RiSegCs = ExceptHandler->CsSelector;
01830     Regs.RiEip = ExceptHandler->Eip;
01831 
01832     
if (! CsToLinear(&Regs, Regs->RiEFlags & EFLAGS_V86_MASK)) {
01833         
return FALSE;
01834     }
01835 
01836     
01837     
01838     
01839     
01840     
01841     
01842 
01843     
if (ExceptHandler->Flags & VDM_INT_INT_GATE) {
01844         SetVirtualBits(Regs->RiEFlags & ~(EFLAGS_INTERRUPT_MASK | EFLAGS_TF_MASK), &Regs);
01845     }
01846 
01847     CheckVdmFlags(&Regs);
01848 
01849     Regs.RiEFlags &= ~EFLAGS_TF_MASK;
01850 
01851     
return TRUE;
01852 }
01853 
01854 
01855 BOOLEAN
01856 CsToLinear(
01857         IN OUT PREGINFO Regs,
01858         IN BOOLEAN IsV86
01859         )
01860 
01861 
01862 
01863 
01864 
01865 
01866 
01867 
01868 
01869 
01870 
01871 
01872 
01873 
01874 
01875 
01876 
01877 
01878 
01879 
01880 {
01881     
if (IsV86) {
01882         
01883         
01884         
01885         Regs->RiCsBase = Regs->RiSegCs << 4;
01886 
01887         Regs->RiCsDescriptor.DescriptorWords = (ULONGLONG) Regs->RiCsBase;
01888         Regs->RiCsLimit = 0xffff;
01889     }
01890     
else {
01891 
01892         
if (! KeIA32UnscrambleLdtEntry(Regs->RiSegCs, &Regs->RiCsDescriptor)) {
01893             
return FALSE;
01894         }
01895 
01896         
01897         
01898         
01899         
01900         Regs->RiCsBase = (ULONG) Regs->RiCsDescriptor.Words.Bits.Base;
01901         Regs->RiCsLimit = (ULONG) Regs->RiCsDescriptor.Words.Bits.Limit;
01902 
01903         
01904         
01905         
01906         
if (Regs->RiCsDescriptor.Words.Bits.Granularity) {
01907                 Regs->RiCsLimit <<= 12;
01908                 Regs->RiCsLimit |= 0xfff;
01909         }
01910 
01911         
01912         
01913         
01914         
01915         
01916         
01917         
01918         
if ((Regs->RiCsDescriptor.Words.Bits.Type & TYPE_CODE_USER ) != 
01919              TYPE_CODE_USER) {
01920              
return FALSE;
01921         }
01922     }
01923 
01924     
01925     
01926     
01927     
if (Regs->RiEip > Regs->RiCsLimit) {
01928         
return FALSE;
01929     }
01930 
01931     
01932     
01933     
01934     Regs->RiLinearAddr = Regs->RiEip + Regs->RiCsBase;
01935 
01936     
return TRUE;
01937 }
01938 
01939 
01940 BOOLEAN
01941 CheckEip(
01942         IN PREGINFO Regs
01943         )
01944 
01945 
01946 
01947 
01948 
01949 
01950 
01951 
01952 
01953 
01954 
01955 
01956 
01957 
01958 
01959 
01960 
01961 
01962 {
01963     
if (Regs->RiEFlags & EFLAGS_V86_MASK) {
01964         Regs->RiEip &= Regs->RiCsLimit;
01965     }
01966     
else {
01967         
if (Regs->RiEip > Regs->RiCsLimit) {
01968             
return FALSE;
01969         }
01970     }
01971 
01972     
return TRUE;
01973 }
01974 
01975 
01976 BOOLEAN
01977 SsToLinear(
01978         IN OUT PREGINFO Regs,
01979         IN BOOLEAN IsV86
01980         )
01981 
01982 
01983 
01984 
01985 
01986 
01987 
01988 
01989 
01990 
01991 
01992 
01993 
01994 
01995 
01996 
01997 
01998 
01999 
02000 
02001 
02002 
02003 {
02004     
if (IsV86) {
02005         
02006         
02007         
02008         Regs->RiSsBase = Regs->RiSegSs << 4;
02009         Regs->RiSsDescriptor.DescriptorWords = (ULONGLONG) Regs->RiSsBase;
02010         Regs->RiSsLimit = 0xffff;
02011     }
02012     
else {
02013         
if (! KeIA32UnscrambleLdtEntry(Regs->RiSegSs, &Regs->RiSsDescriptor)) {
02014             
return FALSE;
02015         }
02016 
02017         
02018         
02019         
02020         
02021         
if ((Regs->RiSsDescriptor.Words.Bits.Type & DESCRIPTOR_DATA_READWRITE) !=
02022             DESCRIPTOR_DATA_READWRITE ) {
02023             
return FALSE;
02024         }
02025 
02026         
02027         
02028         
02029         Regs->RiSsBase = (ULONG) (Regs->RiSsDescriptor.Words.Bits.Base);
02030         Regs->RiSsLimit = (ULONG) (Regs->RiSsDescriptor.Words.Bits.Limit);
02031 
02032         
02033         
02034         
02035         
if (Regs->RiSsDescriptor.Words.Bits.Default_Big) {
02036                 Regs->RiSsLimit <<= 12;
02037                 Regs->RiSsLimit |= 0xfff;
02038         }
02039     }
02040 
02041     
return TRUE;
02042 }
02043 
02044 
02045 BOOLEAN
02046 CheckEsp(
02047         IN PREGINFO Regs,
02048         IN ULONG StackNeeded
02049         )
02050 
02051 
02052 
02053 
02054 
02055 
02056 
02057 
02058 
02059 
02060 
02061 
02062 
02063 
02064 
02065 
02066 
02067 
02068 
02069 
02070 {
02071     
if (Regs->RiEFlags & EFLAGS_V86_MASK) {
02072         Regs->RiEsp &= Regs->RiSsLimit;
02073     }
02074     
else {
02075         
if (! Regs->RiSsDescriptor.Words.Bits.Default_Big) {
02076             
02077             
02078             
02079             Regs->RiEsp &= 0xffff;
02080         }
02081 
02082         
02083         
02084         
02085         
if (StackNeeded > Regs->RiEsp) {
02086             
return FALSE;
02087         }
02088 
02089         
if ((Regs->RiSsDescriptor.Words.Bits.Type & DESCRIPTOR_EXPAND_DOWN) ==
02090             DESCRIPTOR_EXPAND_DOWN ) {
02091             
if (Regs->RiEsp - StackNeeded - 1 < Regs->RiSsLimit) {
02092                 
return FALSE;
02093             }
02094         }
02095         
else { 
02096             
if (Regs->RiEsp >= Regs->RiSsLimit) {
02097                 
return FALSE;
02098             }
02099         }
02100     }
02101 
02102     
return TRUE;
02103 }
02104 
02105 
02106 BOOLEAN
02107 KeIA32UnscrambleLdtEntry(
02108         IN ULONG Selector,
02109         OUT PKXDESCRIPTOR XDescriptor
02110         )
02111 
02112 
02113 
02114 
02115 
02116 
02117 
02118 
02119 
02120 
02121 
02122 
02123 
02124 
02125 
02126 
02127 
02128 
02129 
02130 {
02131     
PETHREAD Thread;
02132     DESCRIPTOR_TABLE_ENTRY DescriptorEntry;
02133     
NTSTATUS Status;
02134 
02135     
02136     
02137     
02138     
if ((Selector & (SELECTOR_TABLE_INDEX | DPL_USER)) != (SELECTOR_TABLE_INDEX | DPL_USER)) {
02139     
02140         
return FALSE;
02141     }
02142 
02143     Thread = 
KeGetCurrentThread();
02144     DescriptorEntry.Selector = Selector;
02145 
02146     
Status = 
PspQueryDescriptorThread(Thread, &DescriptorEntry, 
sizeof(DescriptorEntry), NULL);
02147     
if (!
NT_SUCCESS(Status)) {
02148         
return FALSE;
02149     }
02150 
02151     XDescriptor->Words.DescriptorWords = KeIA32Unscramble(&DescriptorEntry.Descriptor);
02152 
02153     
return TRUE;
02154 }
02155 
02156 
02157 ULONGLONG
02158 KeIA32Unscramble(
02159         IN PLDT_ENTRY Descriptor
02160         )
02161 
02162 
02163 
02164 
02165 
02166 
02167 
02168 
02169 
02170 
02171 
02172 
02173 
02174 
02175 
02176 
02177 
02178 
02179 
02180 
02181 
02182 
02183 {
02184     KXDESCRIPTOR Result;
02185 
02186     
02187     
02188     
02189     Result.Words.Bits.Base = Descriptor->BaseLow | (Descriptor->HighWord.Bytes.BaseMid << 16) | (Descriptor->HighWord.Bytes.BaseHi << 24);
02190 
02191     
02192     
02193     
02194     Result.Words.Bits.Limit = (Descriptor->LimitLow | (Descriptor->HighWord.Bits.LimitHi << 16)) << UNSCRAM_LIMIT_OFFSET;
02195 
02196     
02197     
02198     
02199     
02200     
02201     Result.Words.Bits.Type = Descriptor->HighWord.Bits.Type;
02202     Result.Words.Bits.Dpl = Descriptor->HighWord.Bits.Dpl;
02203     Result.Words.Bits.Pres = Descriptor->HighWord.Bits.Pres;
02204     Result.Words.Bits.Sys = Descriptor->HighWord.Bits.Sys;
02205     Result.Words.Bits.Reserved_0 = Descriptor->HighWord.Bits.Reserved_0;
02206     Result.Words.Bits.Default_Big = Descriptor->HighWord.Bits.Default_Big;
02207     Result.Words.Bits.Granularity = Descriptor->HighWord.Bits.Granularity;
02208 
02209     
return Result.Words.DescriptorWords;
02210 }
02211 
02212 
02213 
02214 
02215 
02216 
#define _VDM_CHECK_OR_FUNC(x) ((x) |= EFLAGS_INTERRUPT_MASK)
02217 
#define _VDM_CHECK_AND_FUNC(x) ((x) &= ~(EFLAGS_IOPL_MASK | EFLAGS_NT_MASK | EFLAGS_VIF | EFLAGS_VIP))
02218 
02219 
02220 
VOID
02221 CheckVdmFlags(
02222     IN OUT PREGINFO Regs
02223     )
02224 
02225 
02226 
02227 
02228 
02229 
02230 
02231 
02232 
02233 
02234 
02235 
02236 
02237 
02238 
02239 
02240 
02241 {
02242     
if (
KeIA32VdmIoplAllowed) {
02243         
if (! (Regs->RiEFlags & EFLAGS_V86_MASK)) {
02244             _VDM_CHECK_OR_FUNC(Regs->RiEFlags);
02245         }
02246         _VDM_CHECK_AND_FUNC(Regs->RiEFlags);
02247         
return;
02248     }
02249 
02250     
02251     
02252     
02253     
02254     
02255     
02256     
02257     
02258 
02259 
#if 0
02260 
    if (
KeIA32VirtualIntExtensions & (V86_VIRTUAL_INT_EXTENSIONS | PM_VIRTUAL_INT_EXTENSIONS)) {
02261         
if (Regs->RiEflags & EFLAGS_V86_MASK) {
02262             
if (
KeIA32VirtualIntExtensions & V86_VIRTUAL_INT_EXTENSIONS) {
02263             }
02264             
else {
02265             }
02266         }
02267         
else {
02268             
if (
KeIA32VirtualIntExtensions & PM_VIRTUAL_INT_EXTENSIONS) {
02269             }
02270             
else {
02271             }
02272         }
02273     }
02274 
#endif
02275 
02276     _VDM_CHECK_OR_FUNC(Regs->RiEFlags);
02277     _VDM_CHECK_AND_FUNC(Regs->RiEFlags);
02278 }
02279 
02280 
02281 
VOID
02282 KeIA32AndOrVdmLock(
02283     IN ULONG AndMask,
02284     IN ULONG OrMask
02285     )
02286 
02287 
02288 
02289 
02290 
02291 
02292 
02293 
02294 
02295 
02296 
02297 
02298 
02299 
02300 
02301 
02302 
02303 
02304 {
02305 
#ifdef NT_UP
02306 
    *
VdmFixedStateLinear = (*
VdmFixedStateLinear & AndMask) | OrMask;
02307 
#else
02308 
    VdmGenericAndOrLock(VdmFixedStateLinear, AndMask, OrMask);
02309 
#endif
02310 
}
02311 
02312 
#else   // defined(WX86) && defined(TRY_NTVDM)
02313 
02314 
02315 BOOLEAN
02316 KiIA32VdmReflectException(
02317     IN OUT PKIA32_FRAME Frame,
02318     IN ULONG Code
02319     )
02320 
02321 
02322 
02323 
02324 
02325 
02326 
02327 
02328 
02329 
02330 
02331 
02332 
02333 
02334 
02335 
02336 
02337 
02338 
02339 
02340 
02341 
02342 {
02343     
02344     
02345     
02346     
return(
FALSE);
02347 }
02348 
02349 
02350 BOOLEAN
02351 KiIA32DispatchOpcode(
02352     IN PKIA32_FRAME Frame
02353     )
02354 
02355 
02356 
02357 
02358 
02359 
02360 
02361 
02362 
02363 
02364 
02365 
02366 
02367 
02368 
02369 
02370 
02371 
02372 
02373 
02374 {
02375     
02376     
02377     
02378 
02379     
return(
FALSE);
02380 }
02381 
02382 
02383 BOOLEAN
02384 KiIA32VdmSegmentNotPresent(
02385     IN OUT PKIA32_FRAME Frame
02386     )
02387 
02388 
02389 
02390 
02391 
02392 
02393 
02394 
02395 
02396 
02397 
02398 
02399 
02400 
02401 
02402 
02403 
02404 
02405 
02406 {
02407     
02408     
02409     
02410 
02411     
return(
FALSE);
02412 }
02413 
02414 
#endif  // defined(WX86) && defined(TRY_NTVDM)