The Windows 95 Connection
If you're writing kernel-mode drivers for both the Windows NT and Windows 95 and Windows 98 platforms, one of your goals should be unifying a common interface between your user mode application and the supporting kernel mode drivers. With a little knowledge and some forethought, you can easily supply a single Win32-based application that depends on specific kernel mode services supplied by your device drivers.
Seeing the coolness of the Windows NT device driver interface from user mode, the Windows 95 team implemented similar functionality for VxDs. Windows 95 introduced both dynamically loadable VxDs (largely for Plug and Play) and a DeviceIoControl interface. Much like Windows NT, VxDs can be dynamically loaded by Win32 user mode apps by calling CreateFile. But there are a
few minor differences that make true unification mildly irritating.
First, even though both Windows 95 and Windows NT utilize CreateFile, passing \\.\drivername as the VxD name or Windows NT driver name, each takes slightly different parameters, making a single call for either OS impossible. As a result, you'll first need to conditionally call CreateFile depending on the environment in which you are running (see Figure A). You end up with a file handle that you can then use to call ReadFile, WriteFile, or DeviceIoControl.
What does this mean? You can have the same piece of user mode code utilizing the same IOCTLs under either OS. However, Windows NT utilizes bits within the IOCTL value to determine various characteristics about the
operation. Windows 95 has no such concept. Therefore, you should make your IOCTL values conform to your needs under Windows NT, and just reuse those values
for your VxD. Let's put this into practice.
Figure B contains the source code to MSJDrvr.VxD. As you can see in MSJ_DeviceIOControl, the IOCTL_MSJDRVR_GET_STRING IOCTL is copying "Hello from VxD-land!" into the caller's buffer. If you run Testapp.exe under Windows 95, you'll see that it successfully calls DeviceIoControl, just as it does under Windows NT, albeit with slightly different results.
The only other consideration is in regard to asynchronous processing. In Windows NT, signaling of the user mode event is handled for you automatically by the I/O Manager. Under Windows 95, it's your responsibility
to signal the user's event upon completion. This is done
by calling:
|