WDM Driver Turotial

IRP的理解

      驱动程序与I/O管理器通信,使用的是IRP,即I/O请求包。IRP分为2部分:

1IRP首部;2IRP堆栈。

IRP首部信息如下:

IRP首部:

IRP首部  IO_STATUS_BLOCK IoStatus  包含I/O请求的状态  PVOID AssociatedIrp.SystemBuffer  如果执行缓冲区I/O,这个指针指向系统缓冲区  PMDL MdlAddress              如果直接I/O,这个指针指向用户缓冲区的存储器描述符表  PVOID UserBuffer  

I/O缓冲区的用户空间地址

IRP首部:

IRP首部  IO_STATUS_BLOCK IoStatus  包含I/O请求的状态  PVOID AssociatedIrp.SystemBuffer  如果执行缓冲区I/O,这个指针指向系统缓冲区  PMDL MdlAddress              如果直接I/O,这个指针指向用户缓冲区的存储器描述符表  PVOID UserBuffer  

I/O缓冲区的用户空间地址

I

IRP堆栈:

UCHAR MajorFunction 指示IRP_MJ_XXX派遣例程

UCHAR MinorFunction 同上,一般文件系统和SCSI驱动程序使用它

union Parameters MajorFunction的联合类型

{

struct Read IRP_MJ_READ的参数

ULONG Length

ULONG Key

LARGE_INTEGER ByteOffset

struct Write IRP_MJ_WRITE的参数

ULONG Length

ULONG Key

LARGE_INTEGER ByteOffset

struct DeviceIoControl IRP_MJ_DEVICE_CONTROL参数

ULONG OutputBufferLength

ULONG InputBufferLength

ULONG IoControlCode

PVOID Type3InputBuffer

}

PDEVICE_OBJECT DeviceObject 请求的目标设备对象的指针

PFILE_OBJECT FileObject请求的目标文件对象的指针,如果有的话

操作IRP。对于不同的IRP函数,操作也是不同的:有的只操作IRP首部;有的只操作IRP堆栈;还有操作IRP整体,下面是一些常用的函数:

 IRP整体:

 IRP整体:

 

IRP整体
名称描述  调用者
 IoStartPacket 发送IRP到 Start I/O 例程  Dispatch
 IoCompleteRequest 表示所有的处理完成  DpcForIsr
 IoStartNextPacket 发送下一个IRP到Start I/O例程  DpcForIsr
 IoCallDriver 发送IRP请求  Dispatch
 IoFreeIrp 释放驱动程序分配的IRP  I/O Completion
   

 

IRP整体
名称描述  调用者
 IoStartPacket 发送IRP到 Start I/O 例程  Dispatch
 IoCompleteRequest 表示所有的处理完成  DpcForIsr
 IoStartNextPacket 发送下一个IRP到Start I/O例程  DpcForIsr
 IoCallDriver 发送IRP请求  Dispatch
 IoFreeIrp 释放驱动程序分配的IRP  I/O Completion
   

 

 

 

 

IRP堆栈:

名称                                          描述                       调用者

IoGetCurrentIrpStackLocation 得到调用者堆栈的指针      Dispatch

IoMarkIrpPending 为进一步的处理标记调用者I/O堆栈      Dispatch

IoGetNextIrpStackLocation  得到下一个驱动程序的I/O堆栈的指针 Dispatch

IoSetNextIrpStackLocation I/O堆栈指针压入堆栈    Dispatch

在驱动程序,IRP派遣例程起着很重要的作用,每个IRP派遣例程,几乎都有对应的Win32函数,下面是几个常用的:

在驱动程序,IRP派遣例程起着很重要的作用,每个IRP派遣例程,几乎都有对应的Win32函数,下面是几个常用的:

IRP派遣例程:

 名称描述 调用者

 名称描述 调用者

IRP_MJ_CREATE      请求一个句柄CreateFile

IRP_MJ_CLEANUP    在关闭句柄时取消悬挂的IRPCloseHandle

IRP_MJ_CLOSE        关闭句柄 CloseHandle

IRP_MJ_READ          从设备得到数据 ReadFile

IRP_MJ_WRITE         传送数据到设备 WriteFile

IRP_MJ_DEVICE_CONTROL控制操作(利用IOCTL宏) DeviceIoControl

IRP_MJ_INTERNAL_DEVICE_CONTROL控制操作(只能被内核调用) N/A

IRP_MJ_QUERY_INFORMATION   得到文件的长度   GetFileSize

IRP_MJ_SET_INFORMATION        设置文件的长度       SetFileSize

IRP_MJ_FLUSH_BUFFERS          写输出缓冲区或者丢弃输入缓冲区   FlushFileBuffers FlushConsoleInputBuffer PurgeComm

IRP_MJ_SHUTDOWN 系统关闭 InitiateSystemShutdown

DEVICE_OBJECT

A device object represents a logical, virtual, or physical device for which a driver handles I/O requests.

Accessible Members

PDRIVER_OBJECT DriverObject

Initialize by operating system .

Pointer to the driver object, representing the driver's loaded image, that was input to the DriverEntry and AddDevice routines.

PDEVICE_OBJECT NextDevice

Pointer to the next device object, if any, created by the same driver. The I/O manager updates this list at each successful call to IoCreateDevice or IoCreateDeviceSecure. A driver that is being unloaded must walk the list of its device objects and delete them. A driver that recreates its device objects dynamically also uses this field.

PIRP CurrentIrp

Pointer to the current IRP if the driver has a StartIo routine whose entry point was set in the driver object and if the driver is currently processing IRP(s). Otherwise, this field is NULL.

ULONG Flags

Device drivers OR this field in their newly created device objects with one or more of the following system-defined values:

DO_BUFFERED_IO or DO_DIRECT_IO

Higher-level drivers OR the field with the same value as the next-lower driver, except possibly for highest-level drivers.

DO_BUS_ENUMERATED_DEVICE

The system sets this flag in each PDO. Drivers must not modify this flag.

DO_DEVICE_INITIALIZING

The I/O manager sets this flag when it creates the device object.

A device function or filter driver clears the flag in its AddDevice routine, after attaching the device object to the device stack, establishing the device power state, and ORing the field with one of the power flags (if necessary). The PnP manager checks that the flag is clear after return from AddDevice.

DO_POWER_INRUSH

Drivers of devices that require inrush current when powering on must set this flag. A driver cannot set both this flag and DO_POWER_PAGABLE.

DO_POWER_PAGABLE

Windows 2000 and later drivers that are pageable, are not part of the paging path, and do not require inrush current must set this flag. The system calls such drivers at IRQL PASSIVE_LEVEL. Drivers cannot set both this flag and DO_POWER_INRUSH.

All WDM, Windows 98, and Windows Me drivers must set DO_POWER_PAGABLE.

DO_VERIFY_VOLUME

Removable-media drivers set this flag while processing transfer requests. Such drivers should also check for this flag in the target for a transfer request before transferring any data. See the Supporting Removable Media for details.

For more information about setting the Flags field, see Initializing a Device Object.

ULONG Characteristics

Specifies one or more system-defined constants, ORed together, that provide additional information about the driver's device. The constants include:

FILE_AUTOGENERATED_DEVICE_NAME

Directs the I/O manager to generate a name for the device, instead of the caller specifying a DeviceName when calling this routine. The I/O manager ensures that the name is unique. This characteristic is typically specified by a PnP bus driver to generate a name for a physical device object (PDO) for a child device on its bus. This characteristic is new for Windows 2000 and Windows 98.

FILE_CHARACTERISTIC_PNP_DEVICE

Indicates that the device object is part of a Plug and Play stack. This flag is required if a bus driver (or bus filter driver) registers WMI support for a device object that has not yet received the IRP_MN_START_DEVICE request. It is also required if a function or filter driver registers for WMI before attaching to its device stack.

FILE_DEVICE_IS_MOUNTED

Indicates that a file system is mounted on the device. Drivers should not set this characteristic.

FILE_DEVICE_SECURE_OPEN

(Windows NT 4.0 SP5 and later)

Directs the I/O manager to apply the security descriptor of the device object to relative opens and trailing file name opens on the device. For more information, see Controlling Device Namespace Access.

FILE_FLOPPY_DISKETTE

Indicates that the device is a floppy disk device.

FILE_READ_ONLY_DEVICE

Indicates that the device cannot be written to.

FILE_REMOTE_DEVICE

Indicates that the device is remote.

FILE_REMOVABLE_MEDIA

Indicates that the storage device supports removable media.

Note that this characteristic indicates removable media, not a removable device. For example, drivers for JAZ drive devices should specify this characteristic, but drivers for PCMCIA flash disks should not.

FILE_VIRTUAL_VOLUME

Indicates that the volume is virtual. Drivers should not set this characteristic.

FILE_WRITE_ONCE_MEDIA

Indicates that the device supports write-once media.

Drivers do not set this member directly. For more information about setting device characteristics, see Specifying Device Characteristics.

PVOID DeviceExtension

Pointer to the device extension. The structure and contents of the device extension are driver-defined. The size is driver-determined, specified in the driver's call to IoCreateDevice or IoCreateDeviceSecure. For more information about device extensions, see Device Extensions.

DEVICE_TYPE DeviceType

Set by IoCreateDevice, using the value specified for that routine's DeviceType parameter. For more information, see Specifying Device Types.

CCHAR StackSize

Specifies the minimum number of stack locations in IRPs to be sent to this driver. IoCreateDevice and IoCreateDeviceSecure sets this field to one in newly created device objects; lowest-level drivers can therefore ignore this field. The I/O manager automatically sets the StackSize field in a higher-level driver's device object to the appropriate value if the driver calls IoAttachDevice or IoAttachDeviceToDeviceStack. Only a higher-level driver that chains itself over another driver with IoGetDeviceObjectPointer must explicitly set the value of StackSize in its own device object(s) to (1 + the StackSize value of the next-lower driver's device object).

ULONG AlignmentRequirement

Specifies the device's address alignment requirement for data transfers. The value must be one of the FILE_XXX_ALIGNMENT values defined in wdm.h and ntddk.h. For more information, see Initializing a Device Object. Also see GetDmaAlignment and ZwQueryInformationFile.

Headers

Defined in wdm.h and ntddk.h. Include wdm.h or ntddk.h.

Comments

The operating system represents devices by device objects. For more information, see Device Objects and Device Stacks.

Drivers create device objects by using the IoCreateDevice and IoCreateDeviceSecure routines. For more information about creating device objects, see Creating a Device Object.

A device object is partially opaque. Drivers do not set members of the device object directly, unless otherwise documented. For information about the members that drivers can modify directly, see Initializing a Device Object. For other device object properties, see Properties of Device Objects.

Undocumented members within a device object must be considered inaccessible. Drivers with dependencies on object member locations or access to undocumented members might not remain portable and interoperable with other drivers over time.

The system-supplied video port driver sets up the fields of the device objects it creates on behalf of video miniport drivers.

The system-supplied SCSI port driver sets up the fields of the device objects it creates on behalf of SCSI miniport drivers.

The system-supplied NDIS library sets up the fields of the device objects it creates on behalf of NDIS miniport drivers.

Function Drivers Structured as Class Drivers and Minidrivers

Common operations for a class of devices can be implemented in a class driver. Driver developers write a much smaller minidriver that interacts with their hardware and that calls the class driver to do most of the work. Taken together, a class driver and a minidriver serve as the function driver for a device.

Microsoft-supplied class drivers handle common system tasks, such as Plug and Play and power management, for all devices of a particular class. Class drivers ensure that the operating system handles such tasks consistently, resulting in a more consistent user experience.

Vendor-supplied minidrivers implement hardware-specific operations and call the appropriate class driver to perform the common tasks. The smaller amount of driver code in the minidriver means fewer code paths that can potentially fail and cause a bad experience for the user.

If an industry standard exists for a device class, the Microsoft-supplied WDM class driver may be able to handle all the necessary tasks for a device that fully implements the standard, which eliminates the need for a third-party minidriver. For example, the Microsoft-supplied HID class driver is based on the USB HID Class Specification, v1.1, and eliminates the need for a third-party minidriver for many USB keyboards, mice, and game controllers.

Microsoft provides the following WDM class drivers:

Stream class driver to support kernel-mode streaming of data for video capture, MPEG decoders, audio, DVD, and broadcast architectures

HID class driver to support input devices

USB and IEEE 1394 bus class drivers

Storage protocol support for serial and parallel buses

阅读更多
想对作者说点什么?

博主推荐

换一批

没有更多推荐了,返回首页