Programming the Microsoft Windows Driver Model
Windows 98/Me Compatibility Notes
The VxD service that NTKERN must use to complete an overlapped IOCTL operation (VWIN32_DIOCCompletionRoutine) doesn t provide for an error code. Thus, if an application performs an overlapped call to a WDM driver, the eventual call to GetOverlappedResult will appear to succeed even if the driver failed the operation.
A Win32 application can use DeviceIoControl to communicate with a Windows 98/Me virtual device driver (VxD) as well as a WDM driver. Three subtle and minor differences exist between IOCTLs for WDM drivers and IOCTLs for VxDs. The most important difference has to do with the meaning of the device handle you obtain from CreateFile. When you re working with a WDM driver, the handle is for a specific device, whereas you get a handle for the driver when you re talking to a VxD. In practice, a VxD might need to implement a pseudohandle mechanism (embedded within the IOCTL data flow) to allow applications to refer to specific instances of the hardware managed by the VxD.
Another difference between VxD and WDM control operations concerns the assignment of numeric control codes. As I discussed earlier, you define a control code for a WDM driver by using the CTL_CODE macro, and you can t define more than 2048 codes. For a VxD, all 32-bit values except 0 and -1 are available. If you want to write an application that can work with either a VxD or a WDM driver, use CTL_CODE to define your control codes because a VxD will be able to work with the resulting numeric values.
The last difference is a pretty minor one: the second-to-last argument to DeviceIoControl a PDWORD pointing to a feedback variable is required when you call a WDM driver but not when you call a VxD. In other words, if you re calling a WDM driver, you must supply a non-NULL value pointing to a DWORD. If you re calling a VxD, however, you can specify NULL if you re not interested in knowing how many data bytes are going into your output buffer. It shouldn t hurt to supply the feedback variable when you call a VxD, though. Furthermore, the fact that this pointer can be NULL is something that a VxD writer might easily overlook, and you might provoke a bug if your application takes advantage of the freedom to say NULL.