基础IRP 和I/O Stack location 的关系

   对于刚学驱动的人来说,或许对IRP和IO stack location的关系还有点不清楚。这里就说说他们之间的关系。具体IRP 和IO stack location相关知识,会在以后文章中说明。下面先放上IRP和IO stack location结构的定义。可惜的是IRP是半透明的。

 

<textarea cols="84" rows="17" name="code" class="cpp">typedef struct _IRP { . . PMDL MdlAddress; ULONG Flags; union { struct _IRP *MasterIrp; . . PVOID SystemBuffer; } AssociatedIrp; . . IO_STATUS_BLOCK IoStatus; KPROCESSOR_MODE RequestorMode; BOOLEAN PendingReturned; . . BOOLEAN Cancel; KIRQL CancelIrql; . . PDRIVER_CANCEL CancelRoutine; PVOID UserBuffer; union { struct { . . union { KDEVICE_QUEUE_ENTRY DeviceQueueEntry; struct { PVOID DriverContext[4]; }; }; . . PETHREAD Thread; . . LIST_ENTRY ListEntry; . . } Overlay; . . } Tail; } IRP, *PIRP;</textarea>

 

 

 

 

 

<textarea cols="84" rows="16" name="code" class="cpp">typedef struct _IO_STACK_LOCATION { UCHAR MajorFunction; UCHAR MinorFunction; UCHAR Flags; UCHAR Control; union { // // Parameters for IRP_MJ_CREATE // struct { PIO_SECURITY_CONTEXT SecurityContext; ULONG Options; USHORT POINTER_ALIGNMENT FileAttributes; USHORT ShareAccess; ULONG POINTER_ALIGNMENT EaLength; } Create; // // Parameters for IRP_MJ_READ // struct { ULONG Length; ULONG POINTER_ALIGNMENT Key; LARGE_INTEGER ByteOffset; } Read; // // Parameters for IRP_MJ_WRITE // struct { ULONG Length; ULONG POINTER_ALIGNMENT Key; LARGE_INTEGER ByteOffset; } Write; // // Parameters for IRP_MJ_QUERY_INFORMATION // struct { ULONG Length; FILE_INFORMATION_CLASS POINTER_ALIGNMENT FileInformationClass; } QueryFile; // // Parameters for IRP_MJ_SET_INFORMATION // struct { ULONG Length; FILE_INFORMATION_CLASS POINTER_ALIGNMENT FileInformationClass; PFILE_OBJECT FileObject; union { struct { BOOLEAN ReplaceIfExists; BOOLEAN AdvanceOnly; }; ULONG ClusterCount; HANDLE DeleteHandle; }; } SetFile; // // Parameters for IRP_MJ_QUERY_VOLUME_INFORMATION // struct { ULONG Length; FS_INFORMATION_CLASS POINTER_ALIGNMENT FsInformationClass; } QueryVolume; // // Parameters for IRP_MJ_DEVICE_CONTROL and IRP_MJ_INTERNAL_DEVICE_CONTROL // struct { ULONG OutputBufferLength; ULONG POINTER_ALIGNMENT InputBufferLength; ULONG POINTER_ALIGNMENT IoControlCode; PVOID Type3InputBuffer; } DeviceIoControl; // // Nonsystem service parameters. // // Parameters for IRP_MN_MOUNT_VOLUME // struct { PVOID DoNotUse1; PDEVICE_OBJECT DeviceObject; } MountVolume; // // Parameters for IRP_MN_VERIFY_VOLUME // struct { PVOID DoNotUse1; PDEVICE_OBJECT DeviceObject; } VerifyVolume; // // Parameters for Scsi using IRP_MJ_INTERNAL_DEVICE_CONTROL // struct { struct _SCSI_REQUEST_BLOCK *Srb; } Scsi; // // Parameters for IRP_MN_QUERY_DEVICE_RELATIONS // struct { DEVICE_RELATION_TYPE Type; } QueryDeviceRelations; // // Parameters for IRP_MN_QUERY_INTERFACE // struct { CONST GUID *InterfaceType; USHORT Size; USHORT Version; PINTERFACE Interface; PVOID InterfaceSpecificData; } QueryInterface; // // Parameters for IRP_MN_QUERY_CAPABILITIES // struct { PDEVICE_CAPABILITIES Capabilities; } DeviceCapabilities; // // Parameters for IRP_MN_FILTER_RESOURCE_REQUIREMENTS // struct { PIO_RESOURCE_REQUIREMENTS_LIST IoResourceRequirementList; } FilterResourceRequirements; // // Parameters for IRP_MN_READ_CONFIG and IRP_MN_WRITE_CONFIG // struct { ULONG WhichSpace; PVOID Buffer; ULONG Offset; ULONG POINTER_ALIGNMENT Length; } ReadWriteConfig; // // Parameters for IRP_MN_SET_LOCK // struct { BOOLEAN Lock; } SetLock; // // Parameters for IRP_MN_QUERY_ID // struct { BUS_QUERY_ID_TYPE IdType; } QueryId; // // Parameters for IRP_MN_QUERY_DEVICE_TEXT // struct { DEVICE_TEXT_TYPE DeviceTextType; LCID POINTER_ALIGNMENT LocaleId; } QueryDeviceText; // // Parameters for IRP_MN_DEVICE_USAGE_NOTIFICATION // struct { BOOLEAN InPath; BOOLEAN Reserved[3]; DEVICE_USAGE_NOTIFICATION_TYPE POINTER_ALIGNMENT Type; } UsageNotification; // // Parameters for IRP_MN_WAIT_WAKE // struct { SYSTEM_POWER_STATE PowerState; } WaitWake; // // Parameter for IRP_MN_POWER_SEQUENCE // struct { PPOWER_SEQUENCE PowerSequence; } PowerSequence; // // Parameters for IRP_MN_SET_POWER and IRP_MN_QUERY_POWER // struct { ULONG SystemContext; POWER_STATE_TYPE POINTER_ALIGNMENT Type; POWER_STATE POINTER_ALIGNMENT State; POWER_ACTION POINTER_ALIGNMENT ShutdownType; } Power; // // Parameters for IRP_MN_START_DEVICE // struct { PCM_RESOURCE_LIST AllocatedResources; PCM_RESOURCE_LIST AllocatedResourcesTranslated; } StartDevice; // // Parameters for WMI Minor IRPs // struct { ULONG_PTR ProviderId; PVOID DataPath; ULONG BufferSize; PVOID Buffer; } WMI; // // Others - driver-specific // struct { PVOID Argument1; PVOID Argument2; PVOID Argument3; PVOID Argument4; } Others; } Parameters; PDEVICE_OBJECT DeviceObject; PFILE_OBJECT FileObject; . . } IO_STACK_LOCATION, *PIO_STACK_LOCATION; </textarea>

 

IO manager每次构造一个IRP数据包时都会分配一个或多个IO stack location,具体的数量依赖于相应设备栈的多少。在IRP结构中有保存了当前IO stack location的索引。其实IO stack location的位置其实紧接着IRP之后的。或许IRP的最后一个域应该是IO_STACK_LOCATION  IoStackLocation[1],这只是我个人的猜测。这样做就可以很方便的得到指定的IoStackLocation了。既然是一个数组,可能有人会想到数组第一个应该就是在设备栈最顶端的设备了,其实不然,数组第一其实是最后一个。为什么这么做呢,我有在一本书上看到是说为了检测IoStackLocation的位置,在最后一个是预留使用,当检查到最后一个是0的时候,可以说已经到了能出来这个IRP的最低端了。这种做法可能防止访问异常的问题。集合看一下wrk中的代码,就会清晰一点了。IO stack Location中才保存了当前需要进行的操作类型,参数等信息。需要做文件系统驱动的人,肯定是更为的要熟悉这一结构了。

    简单的说,IRP总是和IO stack Location在一起的,不管从位置布局上,还是从功能使用上。

 

你可能感兴趣的:(基础IRP 和I/O Stack location 的关系)