IO请求包-IRP

IRP(IO请求包)用于win32和驱动程序通讯,NT内核有一个组件叫做IO管理器。IO管理器负责IRP的分发,驱动程序里创建好设备并且创建好符号链接后,Win32就可以加载驱动了。而要让一个驱动可以处理IRP,必需给驱动添加IRP处理例程。

添加的方法就是再DriverEntry里面对驱动对象DriverObject操作。该参数是一个指针,指向驱动对象,驱动对象内部有一个MajorFunction数组,该数组的类型是
NTSTATUS  (*PDRIVER_DISPATCH) (IN PDEVICE_OBJECT DeviceObject,IN PIRP Irp) 。这是一个函数指针,指向每个IRP对于的处理例程。最后就是为所有需要处理的IRP实现对应的例程。

 

#ifndef _IRP_H_
#define _IRP_H_
/*device type*/
/*0-32767 reserved for M$ */
#define FILE_DEVICE_IRP 0x00008011 
/*IRP*/
/*0-2047 reserved for M$*/
#define IRP_IOCTL_INDEX 0x810 
 

#define IOCTL_IRP_1     CTL_CODE(FILE_DEVICE_IRP,  \
                                     IRP_IOCTL_INDEX, \
                                     METHOD_BUFFERED, \
                                     FILE_ANY_ACCESS)

#define IOCTL_IRP_2     CTL_CODE(FILE_DEVICE_IRP,  \
                                     IRP_IOCTL_INDEX+1,\
                                     METHOD_BUFFERED,   \
                                     FILE_ANY_ACCESS)

#define IOCTL_IRP_3     CTL_CODE(FILE_DEVICE_IRP,  \
                                     IRP_IOCTL_INDEX+2,\
                                     METHOD_BUFFERED,   \
                                     FILE_ANY_ACCESS)            

#endif /*_IRP_H_*/



#include <ntddk.h> #include "irp.h" /* function declares */ NTSTATUS DispatchCreate(IN PDEVICE_OBJECT DeviceObject,IN PIRP Irp); NTSTATUS DispatchClose(IN PDEVICE_OBJECT DeviceObject,IN PIRP Irp); NTSTATUS DispatchDeviceControl(IN PDEVICE_OBJECT DeviceObject,IN PIRP Irp); VOID DriverUnload(PDRIVER_OBJECT DriverObject); /* DriverEntry */ NTSTATUS DriverEntry(IN PDRIVER_OBJECT DriverObject,IN PUNICODE_STRING RegistryPath) { UNICODE_STRING DeviceNameUnicodeString; UNICODE_STRING DeviceLinkUnicodeString; NTSTATUS ntStatus; PDEVICE_OBJECT DeviceObject = NULL; DbgPrint ("Entering DriverEntry"); RtlInitUnicodeString (&DeviceNameUnicodeString, L"\\Device\\irp"); // Create an EXCLUSIVE device object (only 1 thread at a time // can make requests to this device). ntStatus = IoCreateDevice (DriverObject, 0, &DeviceNameUnicodeString, FILE_DEVICE_IRP, 0, TRUE, &DeviceObject); if (NT_SUCCESS(ntStatus)) { // Create dispatch points for device control, create, close. DriverObject->MajorFunction[IRP_MJ_CREATE] = DispatchCreate; DriverObject->MajorFunction[IRP_MJ_CLOSE] = DispatchClose; DriverObject->MajorFunction[IRP_MJ_DEVICE_CONTROL] = DispatchDeviceControl; DriverObject->DriverUnload = DriverUnload; // Create a symbolic link, e.g. a name that a Win32 app can specify // to open the device. RtlInitUnicodeString (&DeviceLinkUnicodeString, L"\\DosDevices\\irp"); ntStatus = IoCreateSymbolicLink (&DeviceLinkUnicodeString, &DeviceNameUnicodeString); if (!NT_SUCCESS(ntStatus)) { // Symbolic link creation failed- note this & then delete the // device object (it's useless if a Win32 app can't get at it). DbgPrint ("ERROR: IoCreateSymbolicLink failed"); IoDeleteDevice (DeviceObject); } } else { DbgPrint ("ERROR: IoCreateDevice failed"); } DbgPrint ("Leaving DriverEntry"); return ntStatus; } /*DriverUnload*/ VOID DriverUnload(PDRIVER_OBJECT DriverObject) { UNICODE_STRING DeviceLinkUnicodeString; NTSTATUS ntStatus; DbgPrint ("Entering DriverUnload"); RtlInitUnicodeString (&DeviceLinkUnicodeString, L"\\DosDevices\\irp"); ntStatus = IoDeleteSymbolicLink (&DeviceLinkUnicodeString); if (NT_SUCCESS(ntStatus)) { IoDeleteDevice (DriverObject->DeviceObject); } else { DbgPrint ("ERROR: IoDeleteSymbolicLink"); } DbgPrint ("Leaving DriverUnload"); } /* DispatchCreate */ NTSTATUS DispatchCreate(IN PDEVICE_OBJECT DeviceObject,IN PIRP Irp) { DbgPrint("CreateFile called"); Irp->IoStatus.Status = STATUS_SUCCESS; Irp->IoStatus.Information = 0; IoCompleteRequest (Irp, IO_NO_INCREMENT); return STATUS_SUCCESS; } /* DispatchClose */ NTSTATUS DispatchClose(IN PDEVICE_OBJECT DeviceObject,IN PIRP Irp) { DbgPrint("CloseHandle called"); Irp->IoStatus.Status = STATUS_SUCCESS; Irp->IoStatus.Information = 0; IoCompleteRequest (Irp, IO_NO_INCREMENT); return STATUS_SUCCESS; } /*DispatchDeviceControl*/ NTSTATUS DispatchDeviceControl(IN PDEVICE_OBJECT DeviceObject,IN PIRP Irp) { PIO_STACK_LOCATION irpStack; NTSTATUS ntStatus; ULONG IoControlCodes; irpStack=IoGetCurrentIrpStackLocation(Irp); Irp->IoStatus.Status = STATUS_SUCCESS; Irp->IoStatus.Information = 0; IoControlCodes=irpStack->Parameters.DeviceIoControl.IoControlCode; switch (IoControlCodes) { case IOCTL_IRP_1: DbgPrint("irp1\n"); break; case IOCTL_IRP_2: DbgPrint("irp2\n"); break; case IOCTL_IRP_3: DbgPrint("irp3\n"); break; default: ntStatus = STATUS_INVALID_DEVICE_REQUEST; break; } ntStatus=Irp->IoStatus.Status; IoCompleteRequest (Irp, IO_NO_INCREMENT); return ntStatus; }
/*win32产生IRP*/ HANDLE hDriver= CreateFile("\\\\.\\irp", GENERIC_WRITE | GENERIC_READ, 0, NULL, OPEN_EXISTING, 0, NULL); ... CloseHandle(hDriver); ... DeviceIoControl(hDriver, IOCTL_IRP_1, NULL, 0, // no input buffer NULL, 0, // output buffer &junk, // # bytes returned (LPOVERLAPPED) NULL) ; // synchronous I/O

posted on 2009-05-29 19:11  devcfei  阅读(4558)  评论(0编辑  收藏  举报