Mandalika's scratchpad [ Work blog @Oracle | Stock Market Notes | My Music Compositions ]

Old Posts: 09.04  10.04  11.04  12.04  01.05  02.05  03.05  04.05  05.05  06.05  07.05  08.05  09.05  10.05  11.05  12.05  01.06  02.06  03.06  04.06  05.06  06.06  07.06  08.06  09.06  10.06  11.06  12.06  01.07  02.07  03.07  04.07  05.07  06.07  08.07  09.07  10.07  11.07  12.07  01.08  02.08  03.08  04.08  05.08  06.08  07.08  08.08  09.08  10.08  11.08  12.08  01.09  02.09  03.09  04.09  05.09  06.09  07.09  08.09  09.09  10.09  11.09  12.09  01.10  02.10  03.10  04.10  05.10  06.10  07.10  08.10  09.10  10.10  11.10  12.10  01.11  02.11  03.11  04.11  05.11  07.11  08.11  09.11  10.11  11.11  12.11  01.12  02.12  03.12  04.12  05.12  06.12  07.12  08.12  09.12  10.12  11.12  12.12  01.13  02.13  03.13  04.13  05.13  06.13  07.13  08.13  09.13  10.13  11.13  12.13  01.14  02.14  03.14  04.14  05.14  06.14  07.14  09.14  10.14  11.14  12.14  01.15  02.15  03.15  04.15  06.15  09.15  12.15  01.16  03.16  04.16  05.16  06.16  07.16  08.16  09.16  12.16  01.17  02.17  03.17  04.17  06.17  07.17  08.17  09.17  10.17 


Sunday, February 03, 2008
 
Win32 : Life Cycle of a WDM Driver

There are three types of WDM Drivers.
  1. Bus Drivers, responsible for enumerating the devices on the bus. Device object associated with this kind of driver is Physical Device Object (PDO).

  2. Function Drivers, responsible for handling read , write, and device power policies for the devices. These drivers provide operational interface for its devices. Device object associated with this kind of driver is Functional device Object (FDO).

  3. Filter Drivers, to add additional value for the devices. Device object associated with this kind of driver is Filter Device Object (Filter DO). These are optional drivers.

Typical Windows device driver code will have DriverEntry(), AddDevice(), I/O Request Packet routines like IRP_MJ_CREATE, IRP_MJ_CLOSE, IRP_MJ_READ, IRP_MJ_WRITE and DriverUnload().

DriverEntry:

A driver's entry point is through the DriverEntry routine.The IO Manager calls the DriverEntry as soon as the driver is loaded.
Syntax:


NTSTATUS DriverEntry(PDRIVER_OBJECT DriverObject, PUNICODE_STRING RegistryPath)
{
DriverObject->MajorFunction[IRP_MJ_CREATE] = XXXXDispatchCreate;
DriverObject->MajorFunction[IRP_MJ_CLOSE] = XXXXDispatchClose;
DriverObject->MajorFunction[IRP_MJ_PNP] = XXXXDispatchPnp;
DriverObject->MajorFunction[IRP_MJ_POWER] = XXXXDispatchPower;
DriverObject->MajorFunction[IRP_MJ_READ] = XXXXDispatchRead;
DriverObject->MajorFunction[IRP_MJ_WRITE] = XXXXDispatchWrite;
DriverObject->MajorFunction[IRP_MJ_DEVICE_CONTROL] = XXXXDispatchDeviceControl;
DriverObject->DriverUnload = XXXXUnload;
DriverObject->DeviceExtension->AddDevice = XXXXAddDevice;
}

where XXXX is a user specified name eg. GdpDispatchCreate.

The DriverEntry gets pointer to its own driver object (DriverObject).DriverEntry initializes entry points for other routines of the driver and stores their pointers in the DriverObject. DriverEntry also initializes DriverUnload routine and AddDevice routine.

AddDevice:

Syntax:


NTSTATUS XXXXAddDevice(PDRIVER_OBJECT DriverObject, PDEVICE_OBJECT DeviceObject)
{
//.....
}

AddDevice routine is called after the devices get enumerated. AddDevice routine is like a DriverEntry for Plug and Play (PNP). AddDevice routine is responsible for creating Device Objects for the devices enumerated by the PNP Manager This routine calls IoCreateDevice and IoCreateSymbolicLink and IoAttachDeviceToDeviceStack functions mainly. IoCreateDevice function creates Device Object.It returns pointer to the Device Object. After creating the Device Object IoCreateSymbolicLink function is used to create link between the device object name and the user visible name of the device so that the device is visible to Win32. IoAttachDeviceToDeviceStack function is used to attach the device object created by IoCreateDevice to the stack.

DriverUnload :

Syntax:


NTSTATUS XXXXUnload(PDRIVER_OBJECT DriverObject)
{
//…………..
}

Unload routine checks if the device object is deleted or not.It frees up any memory allocated in the driver entry time.Unload routine gets called when the driver is Unloaded or reloaded or replaced with another driver or by the PNP Manager when there are no more device objects after IRP_MN_REMOVE_DEVICE is called .

Apart from DriverUnload and AddDevice rest all routines initialised in DriverEntry share same signature.


NTSTATUS XXXX(PDEVICE_OBJECT DeviceObject, PIRP Irp);

IRP_MJ_CREATE :

Syntax:


NTSTATUS XXXXDispatchCreate(PDEVICE_OBJECT DeviceObject, PIRP Irp)
{
//…………
}

This IRP is called when CreateFile function is called to open a handle to file object or a device object.Win32 makes a call to CreateFile function.Most of the drivers set STATUS_SUCCESS in the IO block and complete the request but this irp can be used to reserve any subsequent IO requests for that handle. The functionality implimented is based on the driver.

All dispatch routines must make a call to the function IoGetCurrentIrpStackLocation to get driver’s associate stack location. Also all dispatch routines must to fill out the PIRP and complete the routine through IoCompleteRequest.

PIRP can be filled as below:


Irp->IoStatus.Status = STATUS_SUCCESS;
Irp->IoStatus.Information = 0;
IoCompleteRequest( Irp,IO_NO_INCREMENT);

IRP_MJ_CLOSE :

Syntax:


NTSTATUS XXXXDispatchClose(PDEVICE_OBJECT DeviceObject, PIRP Irp)
{
//…………
}

This IRP is called when CloseHandle function is called to close the handle created by CreateFile function.Win32 makes a call to CloseHandle function.Most of the drivers set STATUS_SUCCESS in the IO block and complete the request .Additional functionality implimented will be dependent on the driver.Mostly it undos what ever is done by IRP_MJ_CREATE with CreateFile function.

IRP_MJ_PNP:

Syntax


NTSTATUS XXXXDispatchPnp(PDEVICE_OBJECT DeviceObject, PIRP Irp)
{
//…………
}

This IRP is called by the PnP manager during enumeration or device rebalancing or any other tine plug and play activity occurs.

Plug-n-Play (PNP) is acombination of hardware and softawre support that enables a computer to recognize and adapt to new hardware configuration change with little or no user intervension (i.e) user can add or remove devices at run time.

PNP's main responsibilities:

When a device is added to the system at run time some of the steps to be taken care of can be describe briefly as:

PnP has minor functions to support each PnP request accordingly. Few of the required function codes are:

IRP_MN_START_DEVICE
IRP_MN_QUERY_REMOVE_DEVICE
IRP_MN_REMOVE_DEVICE
IRP_MN_CANCEL_REMOVE_DEVICE
IRP_MN_QUERY_STOP_DEVICE
IRP_MN_ STOP_DEVICE
IRP_MN_CANCEL_STOP_DEVICE
IRP_MN_SURPRISE_REMOVAL

IRP_MN_START_DEVICE:

PNP Manager sends this IRP after it has assigned hardware resources to the device.The device may have been recently enumerated and is being started for the very first time or is restarting after being stopped. It an also be sent when driver currently in use requires new set of resources.

IRP_MN_QUERY_REMOVE_DEVICE:

This IRP is sent to query if the device if the device can be removed with out disturbing the system. In response to this IRP drivers inform whether the device can be removed or not.

IRP_MN_REMOVE_DEVICE:

This IRP is used to remove to device’s software representations like device object from the system. This IRP is called when the device is removed in orderly fashion or plugged out with out prior notification or when the driver needs an update.

IRP_MN_CANCEL_REMOVE_DEVICE:

This IRP is sent to inform the driver that the device will not be removed from the system. The status prior to the IRP_MN_QUERY_REMOVE_DEVICE will be restored in this case.

IRP_MN_QUERY_STOP_DEVICE:

This IRP is sent to query whether a device can be stopped to rebalance the resources. In response to this IRP the device informs if it is safe to stop the device or not.

IRP_MN_ STOP_DEVICE:

This IRP is sent to stop the device to reconfigure the hardware resources. In response to this IRP driver stops the device and releases the hardware resources being used by the device.

IRP_MN_CANCEL_STOP_DEVICE:

This IRP is sent to inform the driver that the device will not be stopped for rebalancing of the resources. In response to this IRP the driver must return the device to the started state.

IRP_MN_SURPRISE_REMOVAL:

This IRP is sent to the drivers for a device to inform that the device is no longer available for I/O operations. This may happen for reasons like:-

In response to this IRP, Some of the steps to be taken care of are:

IRP_MJ_POWER :

Syntax


NTSTATUS XXXXDispatchPower(PDEVICE_OBJECT DeviceObject, PIRP Irp)
{
//…………
}

Power manager can send this IRP any time the operating system is running. System power ranges from S0 to s5 and Device power state ranges from D0 to D3. Higher the number lowers the power consumption in either of the cases.
The minor IRPs supported by this IRP are:
IRP_MN_POWER_SEQUENCE
IRP_MN_SET_POWER
IRP_MN_WAIT_WAKE
IRP_MN_QUERY_POWER

IRP_MN_POWER_SEQUENCE:

This IRP is for optimization and is sent to determine whether its device actually entered a specific power state or not. IRP returns the power sequence values for the device.

IRP_MN_SET_POWER:

This IRP is sent to notify the drivers of the change to the system power state or to change the power state of a device for which the power manager is performing idle detection. PoRequestPowerIrp must be called to send this IRP.

IRP_MN_WAIT_WAKE:

This IRP is used to awaken a system/device from sleep state.

IRP_MN_QUERY_POWER:

This IRP is sent to query whether the system power state or the device power state can be changed.PoRequestPowerIrp must be called to send this IRP.

IRP_MJ_DEVICE_CONTROL :

Syntax


NTSTATUS XXXXDeviceControl(PDEVICE_OBJECT DeviceObject, PIRP Irp)
{
//…………
}

Every driver whose device objects belong to a particular device type and has a set of system-defined I/O control codes (IOCTLs) support this IRP. A driver receives this I/O control code because user-mode thread has called the Microsoft Win32 DeviceIoControl function, or a higher-level kernel-mode driver has set up the request. On receipt of a device I/O control request for most I/O control codes, device drivers transfer a small amount of data to or from the buffer.

IRP_MJ_READ :

Syntax


NTSTATUS XXXXDispatchRead(PDEVICE_OBJECT DeviceObject, PIRP Irp)
{
//…………
}

If the driver needs to transfers data from its device to the system it must handle read requests through this IRP. It can also be invoked when a user application or Win32 requested data transfer from the device.

IRP_MJ_WRITE :

Syntax


NTSTATUS XXXXDispatchWrite(PDEVICE_OBJECT DeviceObject, PIRP Irp)

{
//…………
}

This IRP is sent by IO manager and is invoked when Win32 calls functions such as WriteFile.

References:

Windows® 2000 Device Driver Book: A Guide for Programmers, Second Edition
MSDN
___________________
Technorati tags:

| | | |




Comments: Post a Comment

Links to this post:

Create a Link



<< Home


2004-2017 

This page is powered by Blogger. Isn't yours?