OSRLogo
OSRLogoOSRLogoOSRLogo x Subscribe to The NT Insider
OSRLogo
x

Everything Windows Driver Development

x
x
x
GoToHomePage xLoginx
 
 

    Thu, 14 Mar 2019     118020 members

   Login
   Join


 
 
Contents
  Online Dump Analyzer
OSR Dev Blog
The NT Insider
The Basics
File Systems
Downloads
ListServer / Forum
  Express Links
  · The NT Insider Digital Edition - May-June 2016 Now Available!
  · Windows 8.1 Update: VS Express Now Supported
  · HCK Client install on Windows N versions
  · There's a WDFSTRING?
  · When CAN You Call WdfIoQueueP...ously

Exactly What Is A Driver?

If you come from the world of application programming, you probably have a fuzzy idea of what a driver is.  You probably know that it’s some piece of software that runs in kernel mode that controls hardware.  But beyond that…

 

The easiest way that we know of to describe a driver to application writers is that it is pretty similar to a Dynamic Link Library (DLL).   It has a main entry point similar to “DllMain” named “DriverEntry”.  In the case of a Driver, “DriverEntry” it is only called once, when the driver is loaded by the Operating System, whereas “DLLMain” can get called enumerable times, depending on how many applications and threads are using the DLL.

 

A DLL defines its own interfaces, which it exports via a “.LIB” file that applications can link to; A Driver exports a standard set of entry points in its “DriverEntry” routine by filling in a data structure created by the Operating System called a DRIVER_OBJECT.  The Operating System looks at this data structure to retrieve a pointer to the appropriate function to call whenever a request is targeted to a Device, described by a DEVICE_OBJECT,  which is created by the Driver to represent either the “physical” or “virtual” device that the Driver supports.

 

A DRIVER_OBJECT is a block of memory allocated and partially initialized by the Operating System.  This object describes where the Driver Code is loaded into memory, the name of the Driver, and it contains Function Address Pointers that must be filled in by the Driver to indicate which functions the Driver supports.  One of the Function Address Pointers that must be filled in is a table of Pointers called the “Function Dispatch Table”.  This table contains one entry for each Major Function Code that the Operating System supports.  There are currently 28 functions that the driver can elect to support however most driver usually support about 8 functions; IRP_MJ_CREATE, IRP_MJ_CLOSE, IRP_MJ_READ, IRP_MJ_WRITE, IRP_MJ_PNP, IRP_MJ_POWER, IRP_MJ_DEVICE_CONTROL, and IRP_MJ_SYSTEM_CONTROL (By default the Operating System initializes all the entries in this table to a routine which indicates that the Major Function is not supported).   Whenever a user makes a request to the Operating System to perform a function, the Operating System determines which Major Function Code corresponds to the operation and delivers the operation to the Device that the user

specified.

 

As mentioned above, a Driver creates DEVICE_OBJECTs to describe either “physical” or “virtual” devices that the Driver supports.  These DEVICE_OBJECTs are targets of I/O requests and the DEVICE_OBJECTs must have names created for them so that user applications or other drivers can “Open” those devices in order to communicate with them.  So, for example, when a user application does a “CreateFile” Win32 request specifying the name ”Com1”, what the operating system is doing is performing a open of the DEVICE_OBJECT whose name is “COM1”.  Upon a successful completion of the “CreateFile” request, the application is returned a HANDLE which it uses in all subsequent requests that it is making to the Device.

 

Remember that Drivers are processing requests sent by programs running in user mode and can also sometimes be processing requests coming from other drivers in the Operating System.  These requests are targeted at DEVICE_OBJECTs that the Driver has created.  In the case of user mode applications, the request is built into a packet called an I/O Request Packet (IRP).  The IRP is built by the I/O Manager, and Operating System Component, and contains the Major Function Code indicating to the Driver what it is supposed to do on the Device.  Once the IRP has been built, the I/O Manager calls the Driver at the entry point it has exported via the “Function Dispatch Table” contained within the DRIVER_OBJECT.   In the case of one driver sending a request to another driver, the driver that communicates with your driver is responsible for building an IRP and using the Operating System routines to pass the IRP to your Driver.

 

Once the Driver receives the IRP it has 3 options on how to process the request.   It can either immediately do the operation that the user has requested, in which case it can immediately tell the Operating System that the IRP is complete; It can hold onto the IRP and tell the Operating System that its processing is Pending and will be completed later on (probably because it has to program it’s hardware device to do the requested operation); or finally, the Driver can determine that it cannot process the request itself and must pass the IRP to some other driver who will process the request.

 

If the Driver is controlling some actual physical device, then it is the Drivers responsibility to program the device to perform the requested operation.  Typically these devices “Interrupt” when the requested operation is complete.   A Driver whose device “Interrupts”, registers an “Interrupt Service Routine” (ISR) with the Operating System.  This registration associates the “Interrupt” with the ISR.  So, when the Device Interrupts the Operating System calls the appropriate ISR.   It is the ISRs responsibility to determine if it is its device interrupting, since the device could be on a shared interrupt bus.   If it is not its device interrupting then it returns and indicates to the Operating System that the interrupt was not handled, in which case the Operating System calls the next registered interrupt handler.   If the Interrupt was for this device, however, then the ISR must save away any context it needs about the interrupt, acknowledge the interrupt (i.e. indicate to the device that it has seen the interrupt), and finally queue a “Deferred Procedure Call” (DPC).

 

A DPC routine is a kernel mode callback and it is responsible for completing the IRP whose work was performed by the signaled interrupt and for propagating the execution of the driver.  In other words, it is responsible for making sure that any IRP that was received by the Driver and queued because the device was busy working on a previous request, is taken off the queue and started on the device.

 

So, that is a driver in a nutshell.  There is one other critical thing that a potential Driver write needs to understand: Drivers can’t make mistakes!  Unlike user mode programming, where a bug in the user program causes just the application to abort, in kernel mode, a Driver making an error causes the system to abort (i.e. a system crash, the blue screen of death), hideously corrupts something, or hang.   Therefore driver writing requires good design skills, attention to detail, good testing skills, paranoia, and patience.  Oh, and it also requires understanding how the operating system works.  

 

User Comments
Rate this article and give us feedback. Do you find anything missing? Share your opinion with the community!
Post Your Comment

"Nice!"
Very nice!

Rating:
28-Nov-11, Lucas Sanches


"Exactly What Is A Driver?"
Nicely explained

Rating:
03-Dec-09, Netmonk Paul


"Great Explaination"
To explain difficult( to understand ) things in a simple way is really difficult. OSR has made life simpler.

Rating:
05-Nov-09, Rupesh Prasad


"Rating"
Good

Rating:
09-Jul-08, Saurabh Srivastava


"Very Good!"

Rating:
14-Mar-08, John Li


"Excellent"
Really good

Rating:
28-Jan-08, Michael Richard


"Pretty basic and simple"
The brilliance lies in its simplicity. Good work.

Rating:
21-Jun-07, Mukil Kesavan


"excellent"
Hello, I am a newbie and I really loved the way you presented the article. I really do not know the authenticity of the same but hope its correct. But really I got an insight of what it is and really loved reading it. Keep it up!!!!

Rating:
24-Apr-07, Abhijit Dutta


"Well Done"
For the beginners like me, it was very useful and written in a simple and placid manner.

Rating:
20-Apr-07, Rajneesh Bhardwaj


"Nice"
I find the information in this post very helpful. I also higly rate this site for any driver developer. As a newbie this post is very useful. Thank you.

Rating:
27-Sep-06, Jeevan Amarasekera


"Very good..."
Hi,

now i know how a basic (NT-Based) Driver works. The article is very good for beginners...but the DKK is a must!

Rating:
16-Jul-06, Kerem G


"Rating...."
Really nice one for a newbie like me...

Rating:
09-Mar-06, Sam Pan


"Addition"
Could you also add more about Interrupts and DPC

Rating:
29-Nov-05, Ravi Shankar


"Good Starter"
Very well built article. Best Appetizer for Driver writer newbies or Wannabes. You could start a series for a step by step increase in complexity of understanding the drivers.

Rating:
29-Nov-05, Ravi Shankar


"Corrections..."
"In the case of a Driver, “DriverEntry” it is only called once, when the driver is loaded by the Operating System,"

But driver can be loaded and unloaded so many times, ones wants! And correct me if I'm wrong [and I'm sure I'm not], but each time driver is loaded, DriverEntry routine is called. So saying that DriverEntry is called only once, is imho oversimplification.

"whereas “DLLMain” can get called enumerable times, depending on how many applications and threads are using the DLL."

First of all DLL doesn't have to have DLLMain. Second, suppose the author was thinking about DLLEntry, [which in fact can be named as you like if only you'll give compiler tip, this is entry point of a dll,] it may happen that it'll be called just once, even if many applications are using given dll, because dlls are shared.

Rating:
12-Sep-05, Michal Spadlinski


"Excellent..for the Begineer"
It is giving a lot of idea to work with driver for the begineers.

Rating:
23-Aug-05, Muthukumaran Natarajan


"excellent"
Thanks to you, people wanting to start developing drivers have a start point. I'm not talking just about this article, but about the entire site. Thank You.

Rating:
17-Mar-05, Gica Galbenu


"Physical or Virtual?"
I would like to see something added here to make clear the difference between driver requirements for "Physical" and "Virtual" Devices

22-Jun-04, terrence smyth


"excellent explaination"
Well i think this is an excellent explaination for a beginner. The link between a application and the Kernel driver made it alot clearer

thanks

Rating:
03-Jul-03, Dennis Smits


"Excellent Resource for Beginners"
This gives a brighter picture abt a driver..Beginners would get an excellent starting with this document.Expects more stuff like this

Rating:
29-May-03, Prasad Rajasekharan


"what about non-programmers? :)"
Great article. I always thought explaning what a driver was to people who are clueless about programming was quite challenging.

- "It is like an application but users don't see it, it has no window... but without it, you wouldn't be able to use your computer. It drives your hardware!"

-"uh... hm. ok."

Rating:
28-May-03, Mathieu Routhier


Post Your Comments.
Print this article.
Email this article.
bottom nav links