windows-nt/Source/XPSP1/NT/base/mvdm/dpmi32/int2f.c

249 lines
4.7 KiB
C
Raw Normal View History

2020-09-26 03:20:57 -05:00
/*++
Copyright (c) 1992 Microsoft Corporation
Module Name:
Int2f.c
Abstract:
This module provides the int 2f API for dpmi
Author:
Neil Sandlin (neilsa) 23-Nov-1996
Revision History:
--*/
#include "precomp.h"
#pragma hdrstop
#include <softpc.h>
#include "xlathlp.h"
//
// Local constants
//
#define MSCDEX_FUNC 0x15
#define WIN386_FUNC 0x16
#define WIN386_IDLE 0x80
#define WIN386_Get_Device_API 0x84
#define WIN386_INT31 0x86
#define WIN386_GETLDT 0x88
#define WIN386_KRNLIDLE 0x89
#define DPMI_MSDOS_EXT 0x8A
#define SEL_LDT 0x137
#define DISPCRIT_FUNC 0x40
#define DISPCRIT_ENTER 0x03
#define DISPCRIT_EXIT 0x04
#define XMS_ID 0x43
#define XMS_INS_CHK 0x00
#define XMS_CTRL_FUNC 0x10
typedef BOOL (WINAPI *PFNMSCDEXVDDDISPATCH)(VOID);
PFNMSCDEXVDDDISPATCH
LoadMscdexAndGetVDDDispatchAddr(
VOID
);
BOOL
PMInt2fHandler(
VOID
)
/*++
Routine Description:
This routine is called at the end of the protect mode PM int chain
for int 2fh. It is provided for compatibility with win31.
Arguments:
Client registers are the arguments to int2f
Return Value:
TRUE if the interrupt was handled, FALSE otherwise
--*/
{
DECLARE_LocalVdmContext;
BOOL bHandled = FALSE;
static char szMSDOS[] = "MS-DOS";
PCHAR VdmData;
static PFNMSCDEXVDDDISPATCH pfnMscdexVDDDispatch = NULL;
switch(getAH()) {
//
// Int2f Func 15xx - MSCDEX
//
case MSCDEX_FUNC:
if (!pfnMscdexVDDDispatch) {
pfnMscdexVDDDispatch = LoadMscdexAndGetVDDDispatchAddr();
}
if (pfnMscdexVDDDispatch) {
bHandled = pfnMscdexVDDDispatch();
}
break;
//
// Int2f Func 16
//
case WIN386_FUNC:
switch(getAL()) {
case WIN386_KRNLIDLE:
case WIN386_IDLE:
bHandled = TRUE;
break;
case WIN386_GETLDT:
if (getBX() == 0xbad) {
setAX(0);
setBX(SEL_LDT);
bHandled = TRUE;
}
break;
case WIN386_INT31:
setAX(0);
bHandled = TRUE;
break;
case WIN386_Get_Device_API:
GetVxDApiHandler(getBX());
bHandled = TRUE;
break;
case DPMI_MSDOS_EXT:
VdmData = VdmMapFlat(getDS(), (*GetSIRegister)(), VDM_PM);
if (!strcmp(VdmData, szMSDOS)) {
setES(HIWORD(DosxMsDosApi));
(*SetDIRegister)((ULONG)LOWORD(DosxMsDosApi));
setAX(0);
bHandled = TRUE;
}
break;
}
break;
//
// Int2f Func 40
//
case DISPCRIT_FUNC:
if ((getAL() == DISPCRIT_ENTER) ||
(getAL() == DISPCRIT_ENTER)) {
bHandled = TRUE;
}
break;
//
// Int2f Func 43
//
case XMS_ID:
if (getAL() == XMS_INS_CHK) {
setAL(0x80);
bHandled = TRUE;
} else if (getAL() == XMS_CTRL_FUNC) {
setES(HIWORD(DosxXmsControl));
setBX(LOWORD(DosxXmsControl));
bHandled = TRUE;
}
break;
}
return bHandled;
}
PFNMSCDEXVDDDISPATCH
LoadMscdexAndGetVDDDispatchAddr(
VOID
)
/*++
Routine Description:
This routine is called when we want the VCDEX VDD to handle
a protected-mode Int2f AH=15, but we don't yet have a
pointer to the VCDEX VDDDispatch entrypoint.
Arguments:
None
Return Value:
Pointer to VCDEX VDDDispatch or NULL if the VDD couldn't
be loaded or the entrypoint couldn't be found.
--*/
{
static const char szVCDEX[] = "VCDEX";
DECLARE_LocalVdmContext;
HANDLE hmodMscdexVdd;
WORD saveAX, saveBX, saveCX;
DWORD saveCF;
//
// The VDD may already have been loaded by the MSCDEX TSR.
//
hmodMscdexVdd = GetModuleHandle(szVCDEX);
if (!hmodMscdexVdd) {
//
// Synthesize an Int2f 1500 to get the VDD loaded.
// This can fail if the user has removed mscdex
// from config.nt.
//
DpmiSwitchToRealMode();
saveAX = getAX();
saveBX = getBX();
saveCX = getCX();
saveCF = getCF();
setAX(0x1500);
setBX(0);
DPMI_EXEC_INT(0x2f);
setCF(saveCF);
setCX(saveCX);
setBX(saveBX);
setAX(saveAX);
DpmiSwitchToProtectedMode();
//
// Try again. If this fails, so will GetProcAddress below
// and we'll pass it down to v86 mode handlers.
//
hmodMscdexVdd = GetModuleHandle(szVCDEX);
}
return (PFNMSCDEXVDDDISPATCH) GetProcAddress(hmodMscdexVdd, "VDDDispatch");
}