Figure A   Platform Detection

 GetVersionEx(&os);
 // If we're running on Windows NT, load the driver this way.
 if(os.dwPlatformId == VER_PLATFORM_WIN32_NT)
 {
       return CreateFile("\\\\.\\MSJDrvr",
                         GENERIC_READ | GENERIC_WRITE, 
                         FILE_SHARE_READ | FILE_SHARE_WRITE,
                         0,
                         OPEN_EXISTING,
                         FILE_FLAG_OVERLAPPED,
                         0);
 }
 // Otherwise, running under Windows 9x, dynamically load the VxD
 else
 {
       return CreateFile("\\\\.\\MSJDrvr.VXD", 0,0,0,
                         CREATE_NEW, FILE_FLAG_DELETE_ON_CLOSE |
                         FILE_FLAG_OVERLAPPED, 0);
 }

Figure B   MSJDrvr.VxD


 /*
     main.c - 1998 James M. Finnegan - Microsoft Systems Journal
 
     This module is for DeviceIoControl() dispatching on the VxD...
 */
 #define WANTVXDWRAPS
 
 #include <basedef.h>
 #include <vmm.h>
 #include <debug.h>
 #include <vxdwraps.h>
 #include <vwin32.h>
 #include <winerror.h>
 
 #define CVXD_VERSION 0x400
 
 typedef DIOCPARAMETERS *LPDIOC;
 
 #define CTL_CODE( DeviceType, Function, Method, Access ) (                 \
     ((DeviceType) << 16) | ((Access) << 14) | ((Function) << 2) | (Method) \
 )
 
 // Define the method codes for how buffers are passed for I/O and FS controls
 #define METHOD_BUFFERED                 0
 #define METHOD_IN_DIRECT                1
 #define METHOD_OUT_DIRECT               2
 #define METHOD_NEITHER                  3
 
 // Define the access check value for any access
 //
 //
 // The FILE_READ_ACCESS and FILE_WRITE_ACCESS constants are also defined in
 // ntioapi.h as FILE_READ_DATA and FILE_WRITE_DATA. The values for these
 // constants *MUST* always be in sync.
 #define FILE_ANY_ACCESS                 0
 #define FILE_READ_ACCESS          ( 0x0001 )    // file & pipe
 #define FILE_WRITE_ACCESS         ( 0x0002 )    // file & pipe
 
 #define FILE_DEVICE_UNKNOWN             0x00000022
 #define IOCTL_UNKNOWN_BASE              FILE_DEVICE_UNKNOWN
 
 #define IOCTL_MSJDRVR_GET_STRING   CTL_CODE(IOCTL_UNKNOWN_BASE, 0x0800, 
                                             METHOD_BUFFERED, 
                                             FILE_READ_ACCESS | FILE_WRITE_ACCESS)
 
 
 #pragma VxD_LOCKED_CODE_SEG
 #pragma VxD_LOCKED_DATA_SEG
 
 // define wrappers for VWIN32_DIOCCompletionRoutine and Set_Thread_Time_Out
 MAKE_HEADER(VOID,    _stdcall, VWIN32_DIOCCompletionRoutine, (DWORD hEvent))
 #define VWIN32_DIOCCompletionRoutine PREPEND(VWIN32_DIOCCompletionRoutine)
 
 
 
 DWORD _stdcall CVXD_W32_DeviceIOControl(DWORD  dwService,
                                         DWORD  dwDDB,
                                         DWORD  hDevice,
                                         LPDIOC lpDIOCParms)
 {
     DWORD dwRetVal;
 
     
     switch(dwService)
     {
         case DIOC_OPEN:
             // Must return 0 to tell WIN32 that this VxD supports DEVIOCTL
             dwRetVal = 0;
             break;
             
         case DIOC_CLOSEHANDLE:
             dwRetVal = VXD_SUCCESS;
             break;
 
         case IOCTL_MSJDRVR_GET_STRING:
         {
             char szString[] = "Hello from VxD-land!";
             char *szOutput = (char *)lpDIOCParms->lpvOutBuffer;
             int i;
 
             // Copy the string to the caller's buffer...
             for(i = 0; szString[i] != NULL; i++)
                szOutput[i] = szString[i];
 
             // Set the event handle to indicate to the Win32 caller that we're 
             // done...
             VWIN32_DIOCCompletionRoutine((DWORD)((OVERLAPPED *)lpDIOCParms-> 
                 lpoOverlapped)->O_Internal);
             dwRetVal = VXD_SUCCESS;
         }
         break;
 
         default:
             dwRetVal = ERROR_NOT_SUPPORTED;
             break;
     }
 
     return dwRetVal;
 }