In particular cases in which you are writing both the device driver and the user mode code, you may find it useful to put more restrictions on the type of access with which your driver can cope.

For instance, if implementing a particular protocol, you might dictate that a command has to be written first using WriteFile and the results read back using ReadFile. Alternatively, you could ignore WriteFile and ReadFile completely and just use DeviceIoControl with your own IOCTL codes.

Whatever approach you use, make sure that you follow a specification. If you are interfacing your hardware to a system class driver, you will have to work to a specification laid down in the Microsoft Driver Development Kit (DDK). Otherwise, you will have to create a specification for your API that your Win32 colleagues will have to follow.

Other Win32 Access to Drivers

The file metaphor is used for most device driver interactions in Win32 programs. However, Windows calls drivers in other situations. For example, keyboard keypresses arrive in programs as Windows messages. These keypresses come from a device driver. Internally, Windows calls the system keyboard driver using the file metaphor.

Many other specialised aspects of Win32 also use device drivers, DirectInput and DirectDraw to mention two. As another example, Human Input Device (HID) user mode clients use various routines, such as HidD_SetFeature, that end up as a driver call.

All these different ways of accessing drivers from Win32 end up as calls using the file metaphor. Therefore, all WDM and NT style device drivers have the same basic structure as they process the same sorts of calls.

Conclusion

In this book, I will explain the Windows Driver Model, including how to write device drivers that work in Windows 98 and Windows 2000. I will also cover NT style drivers that work in Windows NT 3.51 and NT 4.

A driver writer has a job completely different from a standard Windows programmer. There is much terminology to learn and each type of device has its own detailed hardware and software specifications. However, in the end, a device must be made available to Win32 programs and users.

Before writing a device driver in earnest, the next couple of chapters look at the big picture: device driver design and the crucial concepts and structures needed in the driver model.

If you are itching for something to do, order your MSDN Professional subscription. Install the MSDN library, the DDKs, and the Platform SDK. If you are writing a driver for both Windows 98 and Windows 2000, either set up a dual boot machine or get another test computer to hand.

Chapter 2

The Big Picture

A device driver has many jobs to do, some mandatory and others optional. In this chapter, I will give an overview of these jobs, so you know what tasks your driver will have to implement. I will also describe the big picture to show the different types of device drivers and the environment in which drivers run. If possible, you should consider writing a driver that uses one of the Windows Driver Model system drivers, as it simplifies your work and makes it fit in.

Choosing how to implement your driver is one of the most crucial decisions you will need to make. You need to know which jobs it must perform and which tasks it can offload to a class driver. If you are writing a driver for a Universal Serial Bus (USB) device, it soon becomes obvious that you should use the USB class driver. However, if you are going to support Power Management, it is best to decide this at the start as it may well effect the rest of your design.

Device Driver Components

Here are some of the jobs that a device driver can do:

• Initialize itself

• Create and delete devices

• Process Win32 requests to open and close a file handle

• Process Win32 Input/Output (I/O) requests

• Serialize access to hardware

• Talk to hardware

• Call other drivers

• Cancel I/O requests

• Time-out I/O requests

• Cope if a hot-pluggable device is added or removed

• Handle Power Management requests

• Report to administrators using Windows Management Instrumentation and NT events

Figure 2.1 Device driver components

Figure 2.1 shows how I have divided up a device driver's functionality into different modules. The figure also shows the filenames that I have used for the modules in this book.

Strictly speaking, only the Initialization module is mandatory. In practice, all drivers have dispatch routines to handle user I/O requests. A WDM device driver needs a Plug and Play module, along with an installation INF file. NT style drivers will usually create their devices in their Initialization routine and delete them in an Unload routine. All other modules are optional, though in WDM drivers it is best to write minimal Power Management and Windows Management Instrumentation modules, simply to pass any requests to lower drivers.

Obviously, there will be many interactions between these different modules. Some of these interactions will be direct function calls. However, a lot of information will be passed in data structures. For example, a 'device object' data structure stores information about each device.

If writing your first driver, you will no doubt be keen to know how to process reads and 1 writes. As the figure shows, the module that handles these basic I/O requests is a depressingly small part of the whole device driver. The only consolation I can offer is this: if you base your driver on one of the examples in this book, you should be able to concentrate on your device's functionality. However, you cannot ignore what is going on in all the other modules.

Driver Entry Points and Callbacks

The kernel usually runs code in your driver by sending I/O Request Packets (IRPs). For example, a Win32 ReadFile call arrives in a device driver as a Read IRP. The size and location of the read buffer are specified as parameters within the IRP structure. The IRP structure is fundamental to device drivers. I shall be looking at IRPs more in the next chapter, and throughout the rest of the book.

A driver has one main initialization entry point — a routine that you must call DriverEntry. It has a standard function prototype. The kernel calls your DriverEntry routine when your driver is loaded, as is shown in Chapter 4.

Subsequently, the kernel may call many other routines in your driver. These routines are given the general name of callbacks. You tell the kernel the name of the routine and later on the kernel calls the routine back in the right circumstances. For example, if you want to handle interrupts, you must tell the kernel the name of your Interrupt Service Routine (ISR) callback. Each callback has a standard function prototype, appropriate for the circumstance in which it is called.

Table 2.1 lists all the driver entry points and callbacks. I will briefly describe these routines in this chapter and fully explain them later in the book, so do not worry about the details yet. New drivers can also provide a Common Object Model (COM) interface to the kernel, a defined series of routines that the driver implements.

Table 2.1 Standard driver entry points and callback routines

DriverEntry Initial driver entry point. Sets up main callbacks.
I/O Request Packet (IRP) handlers Called to process the IRPs that you wish to handle.
Unload Unload the driver.
AddDevice
Добавить отзыв
ВСЕ ОТЗЫВЫ О КНИГЕ В ИЗБРАННОЕ

0

Вы можете отметить интересные вам фрагменты текста, которые будут доступны по уникальной ссылке в адресной строке браузера.

Отметить Добавить цитату
×