Geoff Chappell - Software Analyst
This function tests whether the caller executes with protected-mode addressing as a client of the DOS Protected Mode Interface (DPMI). Among the implications of success is protected-mode interrupt handling and the availability of at least some of the DPMI’s int 31h functions. Testing for these may be most of the reason that int 2Fh function 1686h exists. See especially that the subfunction number, 86h, is defined symbolically as W386_Test_Int31_Avail in a header named INT2FAPI.INC which Microsoft distributed with the Device Driver Kit at least as early as for Windows 3.1.
Among Microsoft’s DPMI hosts, int 2Fh function 1686h is implemented by both DOSX and the Virtual Machine Manager (VMM) from Windows 3.0 and higher.
The function uses registers for both input and output.
ax | 1686h |
ax | 0000h |
Success means not only that the calling program is a DPMI client in some general sense but that this int 2Fh in particular was executed with protected-mode addressing and interrupt handling. If int 2Fh function 1686h is instead executed with real-mode addressing, e.g., before the DPMI client has stepped up to protected mode with the help of int 2Fh function 1687h or during the real-mode or virtual-8086 handling of a DPMI client’s software interrupt, then the function fails.
DOSX distinguishes the cases by having separate int 2Fh handling for protected mode and real mode. Executed in protected mode, int 2Fh goes through the Interrupt Descriptor Table (IDT). DOSX’s protected-mode handler recognises function 1686h and clears ax. When executed in real mode, the processor diverts the interrupt through the Interrupt Vector Table. DOSX’s real-mode hook passes function 1686h along as unhandled.
The VMM has common handling of int 2Fh function 1686h in a V86 Interrupt Chain or as a PM Fault. This handling distinguishes the interrupt’s origin according to the VMSTAT_PM_EXEC flag in the CB_VM_Status member of the Virtual Machine Control Block (VMCB but formally a cb_s) for the current VM. If the flag is set, the VMM returns the interrupt with ax cleared. Otherwise, the interrupt is returned with no registers changed.
Microsoft’s only known caller of int 2Fh function 1686h is SETUP.EXE from Windows 3.1 (explicitly not 3.0). What use SETUP makes of the function has not yet been studied.
The DOSX from WIndows 3.0 has its own program loader for its child process and starts this child’s execution in protected mode. The child is necessarily KRNL286.EXE. The Windows 3.0 version of KRNL286 assumes it starts in protected mode and has immediate use of int 31h functions. If instead it is executed as any ordinary DOS program, whether for mischief or by accident but either way independently of DOSX, it crashes (with all the usual potential for undefined behaviour from crashing DOS, all the way to hanging the machine so that even Ctrl-Alt-Del does not reboot). Had Microsoft wanted to defend against this, a check with int 2Fh function 1686h would have done nicely.