Archives
 
 
 
  Special
 
 
 
  About Us
 
 
 

Newsletter
Free E-mail Newsletter from BYTE.com

 
    
           
Visit the home page Browse the four-year online archive Download platform-neutral CPU/FPU benchmarks Find information for advertisers, authors, vendors, subscribers Request free information on products written about or advertised in BYTE Submit a press release, or scan recent announcements Talk with BYTE's staff and readers about products and technologies

ArticlesVxDs In Windows 95


June 1996 / Core Technologies / VxDs In Windows 95

VxDs must now be two-faced, providing APIs for 32-bit as well as 16-bit Windows applications.

By Rick Grehan

VxDs--virtual device drivers--are the hidden supports of Windows 3.x and 95. Like the small thieves in Terry Gilliam's Time Bandits who enjoyed access to the plumbings of the universe, VxDs simultaneously operate at the lowest and highest levels: Lowest in the sense that they directly access system hardware, and highest in that they run at the ring 0 privilege level.

Windows 95 has magnified the importance of VxDs, which are the means by which Microsoft extends the capabilities of the OS kernel. VxDs in Win 9 5 handle everything from file systems to sound cards to network systems.

Perh aps you haven't considered the fact that VxDs, though 32-bit in nature, were birthed in a 16-bit, nonthreaded, nonpreemptive OS. Now they're expected--required even--to participate in an OS that has all these characteristics. This is not a simple metamorphosis.

The Grand Illusion

A virtual machine (VM) is an illusion. Specifically, the illusion is that a given process "thinks" it has exclusive access to all a computer's hardware. This includes memory, I/O ports, interrupts, and whatever other components the process chooses to manipulate. VxDs help to create this illusion.

Two kinds of VMs existed in Windows 3.1: DOS boxes and the Windows VM itself. (The latter is called the "System VM"--within which runs all Windows applications.) A third software entity, the VM manager (VMM), though not a VM itself, acted as the chief supervisor for active VMs and VxDs. For example, the VMM had the job of handling the preemptive time-slicing among the executing VMs.

Additionally, any Vx D that was to serve as the virtualizing mechanism for an I/O device had to register itself with the VMM. So, if a VxD wanted to act as the handler for a particular I/O port, it had to ask the VMM to "hook" that port. Subsequently, whenever a Windows application attempted access on that port, an exception was sent to the VMM, which would pass the access request along to the appropriate VxD.

Under Win 95, life is much the same, but better in key ways. There's still one VM per DOS box and still one VM for all the Windows processes. But now some of the Windows processes are Win32 applications with more capabilities than the Win32s programs of Windows 3.x.

This produces a variety of new twists that VxD designers must be aware of. For example, Win32 applications in Win 95 can be multithreaded. No longer must a VxD be aware only of which VM requires service; there are occasions wherein a VxD must discover which thread within a particular VM needs help.

By the way, some read ers might suspect that each Win32 application is its own VM in Win 95, as I first did. This turns out not to be the case. Each Win32 application runs as a member of the System VM, though with its own address space.

More important, a successful VxD in Win 95 had better be prepared to cooperate with old 16-bit Windows applications as well as with new 32-bit Win32 applications. And when it comes to VxDs, "cooperation" can mean a number of different things.

The Old Way

Although VxDs can hook I/O ports and interrupts and perform other ring 0 feats to virtualize the hardware, this turns out to be only part of what VxDs do on behalf of applications. VxDs can also provide callable APIs so that an application can directly petition a VxD for services.

In Windows 3.x, it's possible to get at a VxD's API via interrupt 2Fh. I demonstrated how to do this in "The Software Stopwatch" (April 1995 BYTE), where I described how you can access the API of Window s' virtual timing device.

This mechanism still works in Win 95, provided you use it from a 16-bit application. In fact, Win 95 allows a variation: Rather than loading the device ID in the BX register, you set the BX register to zero and place a pointer in the ES:DI register pair. This pointer references an eight-character, blank-padded, uppercase string, which is the name of the VxD. As before, after your program issues an INT 2Fh instruction, the address of the VxD's API is returned in ES:DI.

Unfortunately, you can't use the INT 2Fh technique from a Win32 application. In fact, Win32 applications can't execute software interrupts, period; they'll crash if they try.

Does this mean that Win32 applications and VxDs live on opposite sides of an uncrossable digital chasm? A VxD can still do such things as virtualizing I/O ports on behalf of a 32-bit application, but what if you want to allow your VxD to expose its API to Win32 programs? Thankfully, your VxD can provide both a 16-bit and a 32-b it API, and thus play happily with 16-bit Windows applications as well as Win32 applications in the Win 95 environment.

The New VxD

Whenever an event occurs of which a VxD must be notified, that VxD is sent a control message. These messages can come from the VMM or other VxDs, and they are processed by the VxD much as a Windows program processes Windows events. Ordinarily, these messages tell the VxD things such as, "An application is trying to access an I/O port that you said you'd handle. Here's the infotake care of it."

Win 95 adds a new message, W32_DEVICEIOCONTROL. This message is sent to the VxD in response to a Win32 application's issuing a DeviceIoControl( ) to the VxD, and it's the mechanism whereby a Win32 application can call a VxD directly.

From the Win32 application's standpoint, it must first obtain a handle to the particular VxD by calling (oddly enough) the CreateFile( ) routine. Ordinarily, this function is used to create or open disk f iles. But if your program prefixes the filename with \\.\ when making the call, the system recognizes that the filename corresponds to a VxD name. (Of course, in C or C++, backslash characters appearing in a string must be prefixed with more backslash characters, so \\.\ becomes \\\\.\\ . Oh, well.)

The CreateFile( ) call returns a handle--in this case, it's a handle to the VxD. The application can then use this handle in subsequent calls to DeviceIoControl( ) to send messages to the VxD. (Calling DeviceIoControl( ) actually calls an "intermediary" VxD, VWIN32, which in turn calls the control-dispatch-entry point of the VxD on behalf of the application.)

DeviceIoControl( ) provides parameters for informing the VxD of which function to perform, as well as input and output buffer pointers for transferring data between the application and the VxD. (We won't show DeviceIoControl( ) 's function prototype here; you can easily find i t in any Win32 reference manual.)

Dynamic VxDs

There's an additional benefit that comes from using DeviceIoControl( ) to communicate with a VxD. If you step back into Windows 3.1 for a moment, you discover that VxDs are statically loaded. That is, all the VxDs a system will use are loaded when Windows starts up, and they hang around for the lifetime of Windows' execution.

Win 95 (and Windows for Workgroups 3.11) allows for dynamically loaded (and unloaded) VxDs. When an application issues a CreateFile( ) call to access a VxD, the system keeps track of how many handles are open on each VxD. When an application is terminating, it should issue a CloseHandle( ) call to release the VxD's handle, which causes the system to decrement the handle count. (It's important to note that the handles associated with a process are automatically called when the process exits.)

Once a VxD's handle count reaches zero, the system issues to the VxD the control messa ge SYS_DYNAMIC_DEVICE _EXIT, telling it in essence: "You're about to be unloadedplease clean up before you leave." Once the VxD processes this message, the system unloads it.

VxDs Forever

Of course, we haven't quite closed the loop here. For any of this to work, the VxD authors have to craft the additional handlers to process the W32_DEVICEIOCONTROL message. Although building a separate route into the VxD's API might be something of a pain, it will likely be a well-trodden route as the number of Win32 programs multiplies.

Actually, this separate route is not really separate at all. A VxD will already have a control-dispatch handler in place to capture incoming messages sent to it by the VMM. Typically, this amounts to a jump table that pairs event codes with handler routines. Once the code to deal with W32_DEVICEIOCONTROL messages is written, it should be a simple matter to insert an additional entry into the jump table to complete the wiring.

With the DeviceIoContro l( ) calling mechanism, there is no reason why Win32 applications have to be left out in the virtual cold.


Acknowledgment

Thanks to Fred Hewett and Stephen Lewin-Berlin of Vireo Software for their technical assistance.


Calling a VxD

illustration_link (9 Kbytes)


How Does It Know?

illustration_link (4 Kbytes)

How does Windows know where the VxD's entry point is? The DDB (device descriptor block) is stored in the VxD and examined when the VxD is loaded. It contains, among other things, the VxD's API entry-point address.


Rick Grehan is a BYTE senior technical editor with an M.S. in mathematics/computer science. You can reach him by sending e-mail to rick_g@bix.com .

Up to the Core Technologies section contentsGo to previous article: SearchSend a comment on this articleSubscribe to BYTE or BYTE on CD-ROM  
Flexible C++
Matthew Wilson
My approach to software engineering is far more pragmatic than it is theoretical--and no language better exemplifies this than C++.

more...

BYTE Digest

BYTE Digest editors every month analyze and evaluate the best articles from Information Week, EE Times, Dr. Dobb's Journal, Network Computing, Sys Admin, and dozens of other CMP publications—bringing you critical news and information about wireless communication, computer security, software development, embedded systems, and more!

Find out more

BYTE.com Store

BYTE CD-ROM
NOW, on one CD-ROM, you can instantly access more than 8 years of BYTE.
 
The Best of BYTE Volume 1: Programming Languages
The Best of BYTE
Volume 1: Programming Languages
In this issue of Best of BYTE, we bring together some of the leading programming language designers and implementors...

Copyright © 2005 CMP Media LLC, Privacy Policy, Your California Privacy rights, Terms of Service
Site comments: webmaster@byte.com
SDMG Web Sites: BYTE.com, C/C++ Users Journal, Dr. Dobb's Journal, MSDN Magazine, New Architect, SD Expo, SD Magazine, Sys Admin, The Perl Journal, UnixReview.com, Windows Developer Network