A VDD is implemented as a 32-bit DLL. Accordingly, it follows all the rules described for Win32 DLLs in the Win32 SDK. The system calls the DLL’s main entry point function when initializing the DLL and also when terminating it.
At initialization, a VDD allocates and initializes any memory it needs. The VDD should also get a handle to the 32-bit kernel-mode driver for its device. The kernel-mode driver for the device registers a Win32 name for itself when the driver is initialized. The VDD can use this virtual name to get a handle for the driver by calling CreateFile. For example, the kernel-mode driver for a fax board might register itself under the name “fax1.” The VDD can obtain a handle to the fax board driver by supplying the name “\\ .\fax1” to the CreateFile function. When the VDD has a handle to the driver, it can make ReadFile, WriteFile, or DeviceIoControl calls to communicate with the driver. If the VDD can’t open the kernel-mode driver for its device, it should return FALSE to indicate an error.
If the VDD is relying on the VDM to intercept device access by the MS-DOS application, the VDD initialization must install its callback functions for handling I/O port and board-memory accesses, as explained in I/O Ports and 8.3.4. After these callback functions (also called hooks) are installed, they do the real work of the VDD. The VDM calls your callback functions to handle I/O port operations as well as accesses to board memory from the application.
If the VDD is relying on a modified MS-DOS application to directly call the VDD, there is no need to install I/O or memory access hooks.
A skeleton for the VDD initialization function is shown as follows:
BOOL VDDInitialize(IN PVOID DllHandle, IN ULONG Reason,
IN PCONTEXT Context OPTIONAL) /*++ Routine Description: Arguments: DllHandle - Not Used Reason - Attach or Detach Context - Not Used Return Value: SUCCESS - TRUE FAILURE - FALSE --*/ { switch (Reason) { case DLL_PROCESS_ATTACH: // Allocate VDD's local heap if needed. Check that NT FAX driver // is available by opening that device. break; case DLL_PROCESS_DETACH: // Deallocate VDD's local heap if needed. // Communicate to appropriate Device driver about your departure. break; default: break; } return TRUE; }