The secret to understanding how .NET technologies works is to understand the why behind it.This blog tries to answer the Why! Why classes , objects , technologies in .NET were designed the way they are ?

Tuesday, June 24, 2008

Tools and Utilities for Windows Driver Development

I have spent a lot of time finding out and downloading tools and kits for making device drivers, this post tries to give a headstart for people who are new to Windows Device Driver development.

  • DDK : The first and most basic tool required for Device driver development is the DDK or Device Driver Kit as they call it , it is basically a collection of all the functions and header files which provides a framework for the device driver developement.The DDK can be found on the microsoft website and a ISO for the same can be downloaded at the following link. http://www.microsoft.com/whdc/DevTools/DevKits.mspx . The DDK can be downlaoded from the Microsoft connect website and the instruction is mentioned on the site above.
  • HELP FILES : Help for DDK can be found in online MSDN . It can also be downloaded from microsoft connect website.
  • DEBUG & COMPILATION ENVIRONMENT : One of the most common sites for Device driver developer is the BSOD or BSD ( the blue screen of death )

This is the most common site for a driver. Whenever there is a exception in the driver it crashes the entire operation system. It is therefore adviced not to do driver programming on your main machine. The best way to develop drivers is to use Virtual machines. Google Virtual machines by VMWare to find more about it .Basically a VM(Virtual machine) allows a full operation system to run inside a virtual environment, in this way even if there is a crash while developing a driver , it crashes just the VM and your main machine reamins safe.


Now that we are all set with the tools and the utilities required for driver development , how about starting with a hello world driver. There are many resources on the net available which explain in detail the Hello world driver so instead of re-inventing the wheel I am gonna provide some links for hello world drivers :

  1. http://www.sriramkrishnan.com/blog/2007/09/world-windows-driver-from-scratch.html - Blog contains all information for a hello world driver.
  2. http://www.catch22.net/tuts/kernel1.asp - another tutorial with a hello world sample built in , this site also has a utility like DriverLoader from OSROnline.

Now all this is OK if you have idea about what device drivers are , If you do not have any Idea about device driver programming like me , you would do well to get a book in hand and start reading a bit of background. Device driver are closley related to the hardware , so you will have to brush up on your fundas of how some of the basic hardware like Serial port , parallel port , keyboard works , you also need to be clear about some of the concepts about Operationg system. Device driver are completely developed in C/C++ so a brush up on those fundas wont be a waste of time.

Device driver require theoritical background , and reading it cab be pretty boring, but they are must I read a book by Walter Oney called Programming the Microsoft® Windows® Driver Model,its a good book but again lots of theory at the start which gets boring and you start to feel that you are going nowhere.(If you are trying to get this book in India best of Luck , I couldnt get it in my city and had to get it from a book store in Pune).

Some other important links for device drives are
  1. http://www.osronline.com/ - Good site , has answers to a lots of questions.
  2. SysInternals - Now owned by microsoft and now available on Microsoft Technet (without source code for many programs) http://technet.microsoft.com/hi-in/sysinternals/default(en-us).aspx

Happy DDriving.

Compiling Device Drivers in Visual Studios 2005


To compile device drivers in Visual Studios 2005 IDE make changes in the following settings.
Assumption : The DDK is installed in C:\WinDDK
and the version of DDK I am using is 3790.1830.
The paths mentioned may change according to the DDK

Project -> Properties ->Configuration Properties -> c/c++ -> General ->
Additional include directories -C:\WinDDK\3790.1830\inc\wxp
C:\WinDDK\3790.1830\inc\ddk\wxp

Project -> Properties ->Configuration Properties -> c/c++ -> Pre Processor ->
Enable string pooling –NO
Enable C++ exceptions – NO
Enable function level Linking – NO
Project -> Properties ->Configuration Properties -> c/c++ -> Language ->
Enable Run time type info – NO

Project -> Properties ->Configuration Properties -> Linker ->
Add following paths
C:\WinDDK\3790.1830\lib\wxp\i386\ntoskrnl.lib
C:\WinDDK\3790.1830\lib\wxp\i386\hal.lib

Saturday, June 21, 2008

Macros

These days I am trying to make a filter serial deviced driver as a study project as a part of this I came across a sample serial monitor filter driver which makes heavy use of C++ classes and MACROS
This post is the result of revisit to how macros work.

Token concatenation
Token concatenation, also called token pasting, is one of the most subtle — and easy to abuse — features of the C macro preprocessor. Two arguments can be 'glued' together using ## preprocessor operator; this allows two tokens to be concatenated in the preprocessed code. This can be used to construct elaborate macros which act much like C ,C++(without many of their benefits).
For instance:
#define MYCASE(item,id) \
case id: \ item##_##id = id;\
break
switch(x)
{
MYCASE(widget,23);
}
The line MYCASE(widget,23);
gets expanded here into
case 23: widget_23 = 23;
break;
Now the Macro that has been used in the sample program goes something like this .
#define IMPLEMENT_FUNCTION(x) NTSTATUS \
SERMON##x(IN PDEVICE_OBJECT DeviceObject,IN PIRP Irp) \
{ \
return ((CDevice *) \
(DeviceObject->DeviceExtension))->x(Irp); \
}
Now when I write something like this : IMPLEMENT_FUNCTION(Read)
It will convert to
SeremonRead(IN PDEVICE_OBJECT DeviceObject,IN PIRP Irp)
{
return ((CDevice *)
(DeviceObject->DeviceExtension))->Read(Irp);
}

Extern Storage Specifier
Also a word about the extern Storage identifier : The extern storage Identifier makes sure that the variable / function is available to files which are outside the source file. i.e. the same variable can be accessed by another source file.
E.g.
FileA.cpp
extern int i;
incrementFileA() { i++; }
int i=0;
incrementFileA_2() {
i++; }

FileB.cpp
incremenrtFileB() { i++
}
void main()
{
incrementFileA(); incrementFileA_2(); incrementFileB(); }
The values will be 1,2,3. More on MSDN link here Some ofthe other good links for macros and C Preprocessor are http://en.wikipedia.org/wiki/C_preprocessor