792 lines
23 KiB
Plaintext
792 lines
23 KiB
Plaintext
|
|
|
|
Installable Virtual Device Driver (VDD) Support For NTVDM
|
|
==========================================================
|
|
|
|
Problem:
|
|
--------
|
|
There is a class of DOS applications which run on their
|
|
own custom hardware. Generally these applications will
|
|
have a pluggable card and a 16bit device driver for their
|
|
card. As these cards are beyond the scope of normal PC
|
|
architecture, NTVDM cannot virtualize them in a secure
|
|
manner. So all such applications are not supported under
|
|
NTVDM.
|
|
|
|
Solution:
|
|
---------
|
|
|
|
If an ISV is writing an NT native device driver for such a
|
|
card, it is technically quite simple to provide the support
|
|
such that the DOS application runs unmodified and in a secure
|
|
fashion. The vendor has to write a Virtual Device Driver (VDD)
|
|
which will virtualize the card for the DOS application by calling
|
|
the native device driver.
|
|
|
|
|
|
-----------------------
|
|
| |
|
|
| DOS Application | V86 mode
|
|
| |
|
|
-----------------------
|
|
I/O-map | ^ |Mem-Map | DMA
|
|
IO | | |IO |
|
|
-------------|-----------------------------
|
|
| | | |
|
|
V | V V
|
|
-----------------------
|
|
| | DMA |
|
|
| NTVDM -------| NT User mode code
|
|
| |
|
|
-----------------------
|
|
^ |
|
|
| | Dispatches the event to VDD
|
|
| V
|
|
-----------------------
|
|
| |
|
|
| VDD | VDD is a DLL attached to NTVDM
|
|
| |
|
|
-----------------------
|
|
^ |
|
|
| | Call the real driver
|
|
-------------|-----------------------------
|
|
| |
|
|
| V
|
|
-----------------------
|
|
| |
|
|
| NT Device Driver | Kernel mode
|
|
| |
|
|
-----------------------
|
|
^ |
|
|
| | Carries out the operation with its card
|
|
| V
|
|
-----------------------
|
|
| |
|
|
| Plugged Card |
|
|
| |
|
|
-----------------------
|
|
|
|
Following are the main work items to achieve the above solution:
|
|
|
|
a. Loading the VDD
|
|
b. Support for I/O mapped I/O
|
|
c. Support for Memory mapped I/O
|
|
d. Support for DMA operations
|
|
e. Register manipulation services
|
|
f. Memory accessing services
|
|
g. Interrupt simulation services
|
|
h. Miscelleneous services
|
|
|
|
|
|
a. Loading the VDD:
|
|
|
|
The system administrator will add the command lines in the
|
|
\\HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\CONTROL\"VirtualDeviceDrivers"
|
|
section of the registry for all the VDDs to be loaded in the
|
|
VDM process. The command line format is REG_MULT_SZ (i.e. ASCIIZZ).
|
|
This key will laways be present and install program just need to
|
|
add their VDD name.
|
|
|
|
[VirtualDeviceDrivers]
|
|
VDD = <full-path of the VDD1.DLL>\0<full-path of the VDD2>\0\0
|
|
|
|
VDD ACTION :
|
|
|
|
NTVDM will load all these VDDs from the registry at the VDM process
|
|
initialization time and call their initialization routine. VDDs should
|
|
make sure at this time that their respective NT device driver is
|
|
present and make all the resource allocations. The VDD handle passed
|
|
in this initialization routine will be the Id of the VDD when calling
|
|
the VDD services as described below.
|
|
|
|
|
|
b. Support for I/O mapped I/O:
|
|
|
|
Following services will be provided for VDDs to deal with IO
|
|
ports:
|
|
|
|
BOOL VDDInstallIOHook (HANDLE, IO_PORT_RANGE, IO_PORT_HANDLERS);
|
|
BOOL VDDDeInstallIOHook (HANDLE, IO_PORT_RANGE);
|
|
|
|
The HANDLE is the one passed to the VDD in its DLLInit routine.
|
|
Only one IO hook may be installed for a given port, all subsequent
|
|
requests will fail. On DeInstalling, the default IO hook will be
|
|
placed, which means no one is hooked on those IO ports. IO_PORT_HANDLERS
|
|
should atleast provide a byte read and a byte write handler. In addition,
|
|
word and string handlers can also be provided. In the absense of word
|
|
or string handlers, these will be emulated using byte handlers.
|
|
A port has to be hooked for both read and write. VDDs should not hook
|
|
DMA ports as these are virtualized by NTVDM and services are provided
|
|
for VDDs to access DMA.
|
|
|
|
VDD Action: On an IO access (or on a series of IO accesses) the VDD
|
|
can check if it needs to start the DMA. If so it can call
|
|
the DMA services given in the following section. If it
|
|
does'nt require the DMA or if the DMA has transfered the
|
|
buffer, then the VDD can call its NT device driver to
|
|
complete the desired request. (Its also possible that the
|
|
VDD first requests the device driver and than using DMA
|
|
services copies the contents to the VDM buffer).
|
|
|
|
|
|
c. Support for Memory mapped I/O:
|
|
|
|
Following services will be provided for VDDs to deal with their
|
|
memory mapped addresses:
|
|
|
|
BOOL VDDInstallMemoryHooks (HANDLE, ADDR_RANGE, MEMORY_HANDLER);
|
|
BOOL VDDDeInstallMemoryHooks (HANDLE, ADDR_RANGE);
|
|
|
|
The addr_range should be a valid range i.e. above RMSIZE and below system
|
|
rom. Only one Memory hook may be installed for a given range, all subsequent
|
|
requests will fail. On deinstalling the range, VDD will no longer get page
|
|
fault on those ranges. Memory_handler will
|
|
tell on which address the fault occured and whether it was a
|
|
read or write fault. On its return from the memory handler it will be
|
|
assumed that the fault was handled.
|
|
|
|
|
|
A port-range will actually result in a whole page to be reserved. That
|
|
means the page will not remain available to EMM for EMM page frames and
|
|
UMBs.
|
|
|
|
VDD Action: It can map the normal memory and let the app write to it.
|
|
Later they can use the WIN32 API's or its device driver
|
|
as per the case to deal the whole memory range.
|
|
|
|
d. Support for DMA operations
|
|
|
|
Following DMA service will be provided for the VDD:
|
|
|
|
DWORD VDDRequestDMA (HANDLE, DMA_CHANNEL, BUFFER, TRANSFER_BYTES);
|
|
BOOL VDDQueryDMA (HANDLE, DMA_CHANNEL, DMA_INFO_BUFFER);
|
|
BOOL VDDSetDma (HANDLE, DMA_CHANNEL, INDEX, DMA_INFO_BUFFER);
|
|
|
|
NTVDM will control all the DMA ports and will maintain all the
|
|
information on per channel basis. There are two flavors in which
|
|
a VDD can carry-out the DMA operations. It can call VDDRequestDMA
|
|
and this service will interpret the DMA registers and do the
|
|
DMA transfer. It should be clear at this point that this will
|
|
involve two buffer copyings. For example, the VDD will ask the device
|
|
driver to trasnfer some data in a buffer (allocated by VDD) then it will
|
|
call this service to transfer this buffer to the address DOS application
|
|
has asked for (through DMA programming).
|
|
|
|
On the other hand, a VDD can collect all the DMA registers using
|
|
VDDQueryDMA and figure out where the DOS application has asked the
|
|
DMA to take place, in what mode and how much to transfer. Then it can
|
|
call the NT device driver with same address as asked by DOS app. In this
|
|
case there will be only one copying. VDD should use VDDSetDMA after
|
|
such an operation to update the DMA state.
|
|
|
|
e. Register manipulation services:
|
|
|
|
See the reference section for details. There is a get and a set service
|
|
for each V86 registers.
|
|
|
|
|
|
f: Memory Accessing services:
|
|
|
|
Following services are provided for Manipulating VDM's memory.
|
|
|
|
PVOID GetVDMPointer(ULONG Address, ULONG Size, BOOL ProtectedMode);
|
|
BOOL FreeVDMPointer(ULONG Address, ULONG Size, BOOL ProtectedMode);
|
|
BOOL FlushVDMPointer(ULONG Addr,
|
|
ULONG Size, PVOID Buffer, BOOL ProtectedMode);
|
|
|
|
g: Interrupt simulation services
|
|
|
|
Following services is provided for simulating an interrupt to the VDM.
|
|
|
|
VOID VDDSimulateInterrupt (BYTE ms, BYTE line, WORD count);
|
|
|
|
|
|
h. Miscellaneous Services
|
|
|
|
Following services will be provided for memory allocation/deallocation.
|
|
|
|
VDDAllocMem (HANDLE, ADDRESS, PAGES);
|
|
VDDFreeMem (HANDLE, ADDRESS, PAGES);
|
|
|
|
VDD will use VDDAllocMem when it gets a page fault on a page which
|
|
it has hooked using VDDInstallMemoryHook. Later it can free this memory
|
|
using VDDFreeMem. We are asking VDDs to use WIN32 API for all their needs
|
|
and here also a VDD could have used VirtualAlloc and VirtualFree. The
|
|
problem is that on a non-x86 machine this would'nt have worked because
|
|
on such a plateform the VDM memory is under the emulator's control and it
|
|
has to be told of such memory changes.
|
|
|
|
Following service will be provided for VDM termination.
|
|
|
|
VDDTerminateVDM (VOID);
|
|
|
|
VDD will use this service to terminate the VDM. For instance if a VDD
|
|
fails to allocate memory on a memory mapped IO, it may want to terminate
|
|
the VDM as its state is inconsistenet.
|
|
|
|
VDDs should always use these services to achieve plateform independence.
|
|
|
|
|
|
|
|
---------------- REFERENCE SECTION -------------------------
|
|
|
|
/** Basic typedefs of VDD IO hooks **/
|
|
|
|
typedef VOID (*PFNVDD_INB) (WORD iport,BYTE * data);
|
|
typedef VOID (*PFNVDD_INW) (WORD iport,WORD * data);
|
|
typedef VOID (*PFNVDD_INSB) (WORD iport,BYTE * data,WORD count);
|
|
typedef VOID (*PFNVDD_INSW) (WORD iport,WORD * data,WORD count);
|
|
typedef VOID (*PFNVDD_OUTB) (WORD iport,BYTE data);
|
|
typedef VOID (*PFNVDD_OUTW) (WORD iport,WORD data);
|
|
typedef VOID (*PFNVDD_OUTSB) (WORD iport,BYTE * data,WORD count);
|
|
typedef VOID (*PFNVDD_OUTSW) (WORD iport,WORD * data,WORD count);
|
|
|
|
/** Array of handlers for VDD IO hooks. **/
|
|
|
|
typedef struct _VDD_IO_HANDLERS {
|
|
PFNVDD_INB inb_handler;
|
|
PFNVDD_INW inw_handler;
|
|
PFNVDD_INSB insb_handler;
|
|
PFNVDD_INSW insw_handler;
|
|
PFNVDD_OUTB outb_handler;
|
|
PFNVDD_OUTW outw_handler;
|
|
PFNVDD_OUTSB outsb_handler;
|
|
PFNVDD_OUTSW outsw_handler;
|
|
} VDD_IO_HANDLERS, *PVDD_IO_HANDLERS;
|
|
|
|
/** Port Range structure **/
|
|
typedef struct _VDD_IO_PORTRANGE {
|
|
WORD First;
|
|
WORD Last;
|
|
} VDD_IO_PORTRANGE, *PVDD_IO_PORTRANGE;
|
|
|
|
/** Memory mapped I/O handler. **/
|
|
|
|
typedef VOID (*PVDD_MEMORY_HANDLER) (PVOID FaultAddress, ULONG RWMode);
|
|
|
|
/** Buffer for returning DMA information **/
|
|
typedef struct _VDD_DMA_INFO {
|
|
WORD addr;
|
|
WORD count;
|
|
WORD page;
|
|
BYTE status;
|
|
BYTE mode;
|
|
BYTE mask;
|
|
} VDD_DMA_INFO, *PVDD_DMA_INFO;
|
|
|
|
/*** VDDInstallIOHook - This service is provided for VDDs to hook the
|
|
* IO ports they are responsible for.
|
|
*
|
|
* INPUT:
|
|
* hVDD ; VDD Handle
|
|
* cPortRange; Number of VDD_IO_PORTRANGE structures
|
|
* pPortRange; Pointer to array of VDD_IO_PORTRANGE
|
|
* IOhandler : VDD handler for the ports.
|
|
*
|
|
* OUTPUT
|
|
* SUCCESS : Returns TRUE
|
|
* FAILURE : Returns FALSE
|
|
* GetLastError has the extended error information.
|
|
*
|
|
* NOTES:
|
|
* 1. The first one to hook a port will get control. Subsequent
|
|
* requests will be failed. There is no concept of chaining
|
|
* the hooks.
|
|
*
|
|
* 2. IOHandler must atleast provide a byte read and a byte write
|
|
* handler. Others can be NULL.
|
|
*
|
|
* 3. If word or string handlers are not provided, their effect
|
|
* will be emulated using byte handlers.
|
|
*
|
|
* 4. VDDs should not hook DMA ports. NTVDM manages it for all
|
|
* the clients and services are provided to perform DMA
|
|
* operations and to access and modify DMA data.
|
|
*
|
|
* 5. VDDs should not hook video ports as well. Such a hooking
|
|
* will succeed but there is no gurantee that the IO handler will
|
|
* get called.
|
|
*
|
|
* 6. Each Vdd is allowed to install only one set of IO hooks
|
|
* at a time.
|
|
*
|
|
* 7. Extended Error codes:
|
|
*
|
|
* ERROR_ACCESS_DENIED - One of the requested ports is already hooked
|
|
* ERROR_ALREADY_EXISTS - Vdd already has active IO port handlers
|
|
* ERROR_OUTOFMEMORY - Insufficient resources for additional VDD
|
|
* Port handler set.
|
|
* ERROR_INVALID_ADDRESS - One of the IO port handlers has an invalid
|
|
* address.
|
|
*/
|
|
BOOL VDDInstallIOHook (
|
|
HANDLE hVdd,
|
|
WORD cPortRange,
|
|
PVDD_IO_PORTRANGE pPortRange,
|
|
PVDD_IO_HANDLERS pIOFn
|
|
);
|
|
|
|
/*** VDDDeInstallIOHook - This service is provided for VDDs to unhook the
|
|
* IO ports they have hooked.
|
|
*
|
|
* INPUT:
|
|
* hVDD : VDD Handle
|
|
*
|
|
* OUTPUT
|
|
* None
|
|
*
|
|
* NOTES
|
|
*
|
|
* 1. On Deinstalling a hook, the defult hook is placed back on
|
|
* those ports. Default hook returns 0xff on reading
|
|
* and ignores the write operations.
|
|
*
|
|
*/
|
|
VOID VDDDeInstallIOHook (
|
|
HANDLE hVdd,
|
|
WORD cPortRange,
|
|
PVDD_IO_PORTRANGE pPortRange
|
|
);
|
|
|
|
/*** VDDInstallMemoryHook - This service is provided for VDDs to hook the
|
|
* Memory Mapped IO addresses they are resposible
|
|
* for.
|
|
*
|
|
* INPUT:
|
|
* hVDD : VDD Handle
|
|
* addr : Starting linear address
|
|
* count : Number of bytes
|
|
* MemoryHandler : VDD handler for the memory addresses
|
|
*
|
|
*
|
|
* OUTPUT
|
|
* SUCCESS : Returns TRUE
|
|
* FAILURE : Returns FALSE
|
|
* GetLastError has the extended error information.
|
|
*
|
|
* NOTES
|
|
* 1. The first one to hook an address will get the control. There
|
|
* is no concept of chaining the hooks. VDD should grab the
|
|
* memory range in its initialization routine. After all
|
|
* the VDDs are loaded, EMM will eat up all the remaining
|
|
* memory ranges for UMB support.
|
|
*
|
|
* 2. Memory handler will be called with the address on which the
|
|
* page fault occured and with a falg telling whether it was a
|
|
* read or write operation.
|
|
*
|
|
* 3. On returning from the hook handler it will be assumed that
|
|
* the page fault was handled and the return will go back to the
|
|
* VDM.
|
|
*
|
|
* 4. Installing a hook on a memory range will result in the
|
|
* consumption of memory based upon page boundaries. The Starting
|
|
* address is rounded down, and the count is rounded up to the
|
|
* next page boundary. The VDD's memory hook handler will be
|
|
* invoked for all addreses within the page(s) hooked. The page(s)
|
|
* will be set aside as mapped reserved sections, and will no
|
|
* longer be available for use by NTVDM or other VDDs. The VDD is
|
|
* permitted to manipulate the memory (commit, free, etc) as needed.
|
|
*
|
|
* 5. After calling the MemoryHandler, NTVDM will return to the
|
|
* faulting cs:ip in the 16bit app. If the VDD does'nt want
|
|
* that to happen it should adjust cs:ip appropriatly by using
|
|
* setCS and setIP.
|
|
*
|
|
* 6. Only one VDD will be allowed to have memory hooks in a page.
|
|
* In other words a page si owned by a VDD exclusively.
|
|
*
|
|
* 7. Extended Error codes:
|
|
*
|
|
* ERROR_ACCESS_DENIED - One of the requested ports is already hooked
|
|
* ERROR_OUTOFMEMORY - Insufficient resources.
|
|
*/
|
|
BOOL VDDInstallMemoryHook (
|
|
HANDLE hVDD,
|
|
PVOID pStart,
|
|
DWORD count,
|
|
PVDD_MEMORY_HANDLER MemoryHandler
|
|
);
|
|
|
|
/*** VDDDeInstallMemoryHook - This service is provided for VDDs to unhook the
|
|
* Memory Mapped IO addresses.
|
|
*
|
|
* INPUT:
|
|
* hVDD : VDD Handle
|
|
* addr : Starting linear address
|
|
* count : Number of addresses
|
|
*
|
|
* OUTPUT
|
|
* None
|
|
*
|
|
* NOTES
|
|
* 1. On Deinstalling a hook, the memory range becomes invalid.
|
|
* VDM's access of this memory range will cause a page fault.
|
|
*
|
|
* 2. Extended Error codes:
|
|
* ERROR_INVALID_PARAMETER - One of the parameter is invalid.
|
|
*/
|
|
BOOL VDDDeInstallMemoryHook (
|
|
HANDLE hVDD,
|
|
PVOID pStart,
|
|
DWORD count
|
|
);
|
|
|
|
/*** VDDRequestDMA - This service is provided for VDDs to request a DMA
|
|
* transfer.
|
|
*
|
|
* INPUT:
|
|
* hVDD VDD Handle
|
|
* iChannel DMA Channel on which the operation to take place
|
|
* Buffer Buffer where to or from transfer to take place
|
|
* length Transfer Count (in bytes)
|
|
* If Zero, returns the Current VDMA transfer count
|
|
* in bytes.
|
|
*
|
|
* OUTPUT
|
|
* DWORD returns bytes transferred
|
|
* if Zero and GetLastError is set means operation failed.
|
|
* if Zero and GetLastError is clear means VDMA transfer count
|
|
* was zero.
|
|
*
|
|
* NOTES
|
|
* 1. This service is intended for those VDDs which do not want to
|
|
* carry on the DMA operation on their own. Carrying on a DMA
|
|
* operation involves understanding all the DMA registers and
|
|
* figuring out what has to be copied, from where and how much.
|
|
*
|
|
* 2. This service will be slower than using VDDQueryDMA/VDDSetDMA and
|
|
* doing the transfer on your own.
|
|
*
|
|
* 3. Extended Error codes:
|
|
*
|
|
* ERROR_ALREADY_EXISTS - Vdd already has active IO port handlers
|
|
* ERROR_OUTOFMEMORY - Insufficient resources for additional VDD
|
|
* Port handler set.
|
|
* ERROR_INVALID_ADDRESS - One of the IO port handlers has an invalid
|
|
* address.
|
|
*
|
|
*/
|
|
DWORD VDDRequestDMA (
|
|
HANDLE hVDD,
|
|
WORD iChannel,
|
|
PVOID Buffer,
|
|
DWORD length
|
|
);
|
|
|
|
/*** VDDQueryDMA - This service is provided for VDDs to collect all the DMA
|
|
* data.
|
|
*
|
|
* INPUT:
|
|
* hVDD VDD Handle
|
|
* iChannel DMA Channel for which to query
|
|
* Buffer Buffer where information will be returned
|
|
*
|
|
* OUTPUT
|
|
* SUCCESS : Returns TRUE
|
|
* FAILURE : Returns FALSE
|
|
* GetLastError has the extended error information.
|
|
*
|
|
*
|
|
* NOTES
|
|
* 1. This service is intended for those VDD which are doing
|
|
* performance critical work. These VDD can do their own DMA
|
|
* transfers and avoid one extra buffer copying which is a
|
|
* overhead in using VDDRequestDMA.
|
|
*
|
|
* 2. VDDs should use VDDSetDMA to properly update the state of
|
|
* DMA after carrying on the operation.
|
|
*
|
|
* 3. Extended Error codes:
|
|
*
|
|
* ERROR_INVALID_ADDRESS - Invalid channel
|
|
*
|
|
*/
|
|
BOOL VDDQueryDMA (
|
|
HANDLE hVDD,
|
|
WORD iChannel,
|
|
PVDD_DMA_INFO pDmaInfo
|
|
);
|
|
|
|
/*** VDDSetDMA - This service is provided for VDDs to set the DMA data.
|
|
*
|
|
* INPUT:
|
|
* hVDD VDD Handle
|
|
* iChannel DMA Channel for which to query
|
|
* fDMA Bit Mask indicating which DMA data fields are to be set
|
|
* VDD_DMA_ADDR
|
|
* VDD_DMA_COUNT
|
|
* VDD_DMA_PAGE
|
|
* VDD_DMA_STATUS
|
|
* VDD_DMA_ALL (all Above)
|
|
* Buffer Buffer with DMA data
|
|
*
|
|
* OUTPUT
|
|
* SUCCESS : Returns TRUE
|
|
* FAILURE : Returns FALSE
|
|
* GetLastError has the extended error information.
|
|
*
|
|
* NOTES
|
|
*
|
|
* 1. Extended Error codes:
|
|
*
|
|
* ERROR_INVALID_ADDRESS - Invalid channel
|
|
*
|
|
*/
|
|
BOOL VDDSetDMA (
|
|
HANDLE hVDD,
|
|
WORD iChannel,
|
|
WORD fDMA,
|
|
PVDD_DMA_INFO pDmaInfo
|
|
);
|
|
|
|
/** VDDAllocMem - Allocates memory at a given virtual address.
|
|
*
|
|
* INPUT
|
|
* hVDD : VDD
|
|
* Address: Address where memory is to be allocated (between 640k and 1Mb)
|
|
* nBytes : Number of bytes to allocate
|
|
*
|
|
* OUTPUT
|
|
* SUCCESS : Returns TRUE
|
|
* FAILURE : Returns FALSE
|
|
* GetLastError has the extended error information.
|
|
* Notes:
|
|
* 1. VDDs have to use this service instead of WIN32 VirtualAlloc
|
|
* to be plateform independent. On non-x86 machines VDDAllocMem
|
|
* tells the CPU emulator about this memory allocation.
|
|
*
|
|
* 2. The address will be made page aligned downwards and nBytes will
|
|
* be streched upward to be page aligned.
|
|
*
|
|
* 3. Extended Error codes:
|
|
* ERROR_OUTOFMEMORY - Insufficient memory
|
|
* ERROR_INVALID_ADDRESS - Invalid address
|
|
*/
|
|
VOID VDDAllocMem (
|
|
HANDLE hVDD,
|
|
PVOID Address,
|
|
ULONG nBytes
|
|
);
|
|
|
|
/** VDDFreeMem - Free memory at a given virtual address.
|
|
*
|
|
* INPUT
|
|
* hVDD : VDD
|
|
* Address: Address where memory is to be freed
|
|
* nBytes : Number of bytes to free
|
|
*
|
|
* OUTPUT
|
|
* SUCCESS : Returns TRUE
|
|
* FAILURE : Returns FALSE
|
|
* GetLastError has the extended error information.
|
|
*
|
|
* Notes:
|
|
* 1. Extended Error codes:
|
|
* ERROR_INVALID_ADDRESS - Invalid address
|
|
*
|
|
* 2. The address will be made page aligned downwards and nBytes will
|
|
* be streched upward to be page aligned.
|
|
*
|
|
*/
|
|
VOID VDDFreeMem (
|
|
HANDLE hVDD,
|
|
PVOID Address,
|
|
ULONG nBytes
|
|
);
|
|
|
|
/** VDDTerminateVDM - Terminate the VDM.
|
|
*
|
|
* INPUT
|
|
* None
|
|
*
|
|
* OUTPUT
|
|
* None
|
|
*
|
|
* Notes:
|
|
* 1. VDD should call this service on encoutering a fatal error,
|
|
* such that VDDs state is inconsistent.
|
|
*
|
|
* 2. VDD can use MessageBox WIN32 API to putup a popup before
|
|
* terminating the VDM.
|
|
*/
|
|
VOID VDDTerminateVDM (
|
|
VOID
|
|
);
|
|
|
|
/** Register Manipulation services
|
|
*
|
|
*/
|
|
|
|
ULONG getEAX(VOID);
|
|
USHORT getAX(VOID);
|
|
UCHAR getAL(VOID);
|
|
UCHAR getAH(VOID);
|
|
ULONG getEBX(VOID);
|
|
USHORT getBX(VOID);
|
|
UCHAR getBL(VOID);
|
|
UCHAR getBH(VOID);
|
|
ULONG getECX(VOID);
|
|
USHORT getCX(VOID);
|
|
UCHAR getCL(VOID);
|
|
UCHAR getCH(VOID);
|
|
ULONG getEDX(VOID);
|
|
USHORT getDX(VOID);
|
|
UCHAR getDL(VOID);
|
|
UCHAR getDH(VOID);
|
|
ULONG getESP(VOID);
|
|
USHORT getSP(VOID);
|
|
ULONG getEBP(VOID);
|
|
USHORT getBP(VOID);
|
|
ULONG getESI(VOID);
|
|
USHORT getSI(VOID);
|
|
ULONG getEDI(VOID);
|
|
USHORT getDI(VOID);
|
|
ULONG getEIP(VOID);
|
|
USHORT getIP(VOID);
|
|
USHORT getCS(VOID);
|
|
USHORT getSS(VOID);
|
|
USHORT getDS(VOID);
|
|
USHORT getES(VOID);
|
|
USHORT getFS(VOID);
|
|
USHORT getGS(VOID);
|
|
ULONG getCF(VOID);
|
|
ULONG getPF(VOID);
|
|
ULONG getAF(VOID);
|
|
ULONG getZF(VOID);
|
|
ULONG getSF(VOID);
|
|
ULONG getIF(VOID);
|
|
ULONG getDF(VOID);
|
|
ULONG getOF(VOID);
|
|
USHORT getMSW(VOID);
|
|
|
|
VOID setEAX(ULONG);
|
|
VOID setAX(USHORT);
|
|
VOID setAH(UCHAR);
|
|
VOID setAL(UCHAR);
|
|
VOID setEBX(ULONG);
|
|
VOID setBX(USHORT);
|
|
VOID setBH(UCHAR);
|
|
VOID setBL(UCHAR);
|
|
VOID setECX(ULONG);
|
|
VOID setCX(USHORT);
|
|
VOID setCH(UCHAR);
|
|
VOID setCL(UCHAR);
|
|
VOID setEDX(ULONG);
|
|
VOID setDX(USHORT);
|
|
VOID setDH(UCHAR);
|
|
VOID setDL(UCHAR);
|
|
VOID setESP(ULONG);
|
|
VOID setSP(USHORT);
|
|
VOID setEBP(ULONG);
|
|
VOID setBP(USHORT);
|
|
VOID setESI(ULONG);
|
|
VOID setSI(USHORT);
|
|
VOID setEDI(ULONG);
|
|
VOID setDI(USHORT);
|
|
VOID setEIP(ULONG);
|
|
VOID setIP(USHORT);
|
|
VOID setCS(USHORT);
|
|
VOID setSS(USHORT);
|
|
VOID setDS(USHORT);
|
|
VOID setES(USHORT);
|
|
VOID setFS(USHORT);
|
|
VOID setGS(USHORT);
|
|
VOID setCF(ULONG);
|
|
VOID setPF(ULONG);
|
|
VOID setAF(ULONG);
|
|
VOID setZF(ULONG);
|
|
VOID setSF(ULONG);
|
|
VOID setIF(ULONG);
|
|
VOID setDF(ULONG);
|
|
VOID setOF(ULONG);
|
|
VOID setMSW(USHORT);
|
|
|
|
/** GetVDMPointer - Findout the linear address of a given VDM address
|
|
*
|
|
* INPUT
|
|
* Address - seg/sel:off (hi word has segment or selector and loword
|
|
* is offset)
|
|
* Size - Range of the pointer
|
|
* ProtectMode - If protectmode == TRUE its sel:off
|
|
* If protectmode == FALSE its seg:off
|
|
*
|
|
* OUTPUT
|
|
* Returns Linear address.
|
|
*
|
|
* NOTES:
|
|
* 1. VDDs should use this service to convert the address rather
|
|
* than shifting the seg by 4 and adding the offset. This makes
|
|
* them plateform independent. On non-x86 machine VDM's 0 and
|
|
* the process's 0 are different and the actual adddress conversion
|
|
* is provided by the CPU emulator.
|
|
*/
|
|
PVOID GetVDMPointer(
|
|
ULONG Address,
|
|
ULONG Size,
|
|
BOOL ProtectedMode
|
|
);
|
|
|
|
/** FlushVDMPointer - Flushes the contents (required because of emulator)
|
|
*
|
|
* INPUT
|
|
* Address - seg/sel:off (hi word has segment or selector and loword
|
|
* is offset)
|
|
* Size - Range of the pointer
|
|
* Buffer - Address returned by GetVDMPointer.
|
|
* ProtectMode - If protecmeode == TRUE its sel:off
|
|
* If protecmeode == FALSE its seg:off
|
|
*
|
|
* OUTPUT
|
|
* Returns Linear address.
|
|
*
|
|
* NOTES:
|
|
* 1. VDDs should use this service to make sure that on non-x86
|
|
* machines, the CPU emulator gets a chance to flush any data
|
|
* associated with a memory range.
|
|
*/
|
|
BOOL FlushVDMPointer(
|
|
ULONG Addr,
|
|
ULONG Size,
|
|
PVOID Buffer,
|
|
BOOL ProtectedMode
|
|
);
|
|
|
|
/** FreeVDMPointer - Frees a pointer previously returned by GetVDMPointer
|
|
*
|
|
* INPUT
|
|
* Address - seg/sel:off (hi word has segment or selector and loword
|
|
* is offset)
|
|
* Size - Range of the pointer
|
|
* ProtectMode - If protecmeode == TRUE its sel:off
|
|
* If protecmeode == FALSE its seg:off
|
|
*
|
|
* OUTPUT
|
|
* None
|
|
*
|
|
* NOTES:
|
|
* 1. FreeVDMPointer does FlushVDMPointer as well.
|
|
*/
|
|
BOOL FreeVDMPointer(
|
|
ULONG Address,
|
|
ULONG Size,
|
|
BOOL ProtectedMode
|
|
);
|
|
|
|
/** VDDSimulateInterrupt - Simulates an interrupt to the VDM.
|
|
*
|
|
* INPUT
|
|
* ms - Is either ICA_MASTER or ICA_SLAVE as appropriate
|
|
* line - Interrupt line
|
|
* count - allows a batch of interrupts to be delivered but will usually
|
|
* be 1.
|
|
*
|
|
* OUTPUT
|
|
* None
|
|
*/
|
|
VOID VDDSimulateInterrupt (
|
|
BYTE ms,
|
|
BYTE line,
|
|
WORD count
|
|
);
|