看板 ott
作者 ott (寶貝)
標題 IRP
時間 2013年11月06日 Wed. AM 03:52:06

     
   


http://msdn.microsoft.com/en-us/library/windows/hardware/ff550694(v=vs.85).aspx

IRP


The IRP structure is a partial opaque structure that represents an I/O request packet. Drivers can use the following members of the IRP structure.


 

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;    
   

Members

MdlAddress

 memory descriptor list (MDL)

Pointer to an MDL describing a user buffer, if the driver is using direct I/O, and the IRP major function code is one of the following:


IRP_MJ_READ

The MDL describes an empty buffer that the device or driver fills in.


IRP_MJ_WRITE

The MDL describes a buffer that contains data for the device or driver.


IRP_MJ_DEVICE_CONTROL or IRP_MJ_INTERNAL_DEVICE_CONTROL

If the IOCTL code specifies the METHOD_IN_DIRECT transfer type, the MDL describes a buffer that contains data for the device or driver.


If the IOCTL code specifies the METHOD_OUT_DIRECT transfer type, the MDL describes an empty buffer that the device or driver fills in.

For more information about the buffers that are associated with METHOD_IN_DIRECT and METHOD_OUT_DIRECT transfer types in IOCTL codes, see Buffer Descriptions for I/O Control Codes.
If the driver is not using direct I/O, this pointer is NULL.


Flags

File system drivers use this field, which is read-only for all drivers. Network and, possibly, highest-level device drivers also might read this field. This field is set either to zero or to the bitwise-OR of one or more of the following system-defined flag bits:

IRP_NOCACHE
IRP_PAGING_IO
IRP_MOUNT_COMPLETION
IRP_SYNCHRONOUS_API
IRP_ASSOCIATED_IRP
IRP_BUFFERED_IO
IRP_DEALLOCATE_BUFFER
IRP_INPUT_OPERATION
IRP_SYNCHRONOUS_PAGING_IO
IRP_CREATE_OPERATION
IRP_READ_OPERATION
IRP_WRITE_OPERATION
IRP_CLOSE_OPERATION
IRP_DEFER_IO_COMPLETION
IRP_OB_QUERY_NAME
IRP_HOLD_DEVICE_QUEUE
IRP_UM_DRIVER_INITIATED_IO


AssociatedIrp.MasterIrp

Pointer to the master IRP in an IRP that was created by a highest-level driver's call to IoMakeAssociatedIrp.


AssociatedIrp.SystemBuffer

Pointer to a system-space buffer.
If the driver is using buffered I/O, the buffer's purpose is determined by the IRP major function code, as follows:
IRP_MJ_READ
The buffer receives data from the device or driver. The buffer's length is specified by Parameters.Read.Length in the driver's IO_STACK_LOCATION structure.
IRP_MJ_WRITE
The buffer supplies data for the device or driver. The buffer's length is specified by Parameters.Write.Length in the driver's IO_STACK_LOCATION structure.
IRP_MJ_DEVICE_CONTROL or IRP_MJ_INTERNAL_DEVICE_CONTROL
The buffer represents both the input and output buffers that are supplied to DeviceIoControl and IoBuildDeviceIoControlRequest. Output data overwrites input data.
For input, the buffer's length is specified by Parameters.DeviceIoControl.InputBufferLength in the driver's IO_STACK_LOCATION structure.
For output, the buffer's length is specified by Parameters.DeviceIoControl.OutputBufferLength in the driver's IO_STACK_LOCATION structure.
For more information, see Buffer Descriptions for I/O Control Codes.
If the driver is using direct I/O, the buffer's purpose is determined by the IRP major function code, as follows:
IRP_MJ_READ
NULL.
IRP_MJ_WRITE
NULL.
IRP_MJ_DEVICE_CONTROL or IRP_MJ_INTERNAL_DEVICE_CONTROL
The buffer represents the input buffer that is supplied to DeviceIoControl and IoBuildDeviceIoControlRequest.
The buffer's length is specified by Parameters.DeviceIoControl.InputBufferLength in the driver's IO_STACK_LOCATION structure.
For more information, see Buffer Descriptions for I/O Control Codes.


IoStatus

Contains the IO_STATUS_BLOCK structure in which a driver stores status and information before calling IoCompleteRequest.

RequestorMode

Indicates the execution mode of the original requester of the operation, one of UserMode or KernelMode.


PendingReturned

If set to TRUE, a driver has marked the IRP pending. Each IoCompletion routine should check the value of this flag. If the flag is TRUE, and if the IoCompletion routine will not return STATUS_MORE_PROCESSING_REQUIRED, the routine should call IoMarkIrpPending to propagate the pending status to drivers above it in the device stack.


Cancel

If set to TRUE, the IRP either is or should be canceled.


CancelIrql

Contains the IRQL at which a driver is running when IoAcquireCancelSpinLock is called.


CancelRoutine

Contains the entry point for a driver-supplied Cancel routine to be called if the IRP is canceled. NULL indicates that the IRP is not currently cancelable.


UserBuffer

Contains the address of an output buffer if both of the following conditions apply:
The major function code in the I/O stack location is IRP_MJ_DEVICE_CONTROL or IRP_MJ_INTERNAL_DEVICE_CONTROL.
The I/O control code was defined with METHOD_NEITHER or METHOD_BUFFERED.
For METHOD_BUFFERED, the driver should use the buffer pointed to by Irp->AssociatedIrp.SystemBuffer as the output buffer. When the driver completes the request, the I/O manager copies the contents of this buffer to the output buffer that is pointed to by Irp->UserBuffer. The driver should not write directly to the buffer pointed to by Irp->UserBuffer. For more information, see Buffer Descriptions for I/O Control Codes.


Tail.Overlay.DeviceQueueEntry

If IRPs are queued in the device queue associated with the driver's device object, this field links IRPs in the device queue. These links can be used only while the driver is processing the IRP.


Tail.Overlay.DriverContext

If IRPs are not queued in the device queue associated with the driver's device object, this field can be used by the driver to store up to four pointers. This field can be used only while the driver owns the IRP.


Tail.Overlay.Thread

Is a pointer to the caller's thread control block. Higher-level drivers that allocate IRPs for lower-level removable-media drivers must set this field in the IRPs they allocate. Otherwise, the FSD cannot determine which thread to notify if the underlying device driver indicates that the media requires verification.


Tail.Overlay.ListEntry

If a driver manages its own internal queues of IRPs, it uses this field to link one IRP to the next. These links can be used only while the driver is holding the IRP in its queue or is processing the IRP.


Remarks

Undocumented members of the IRP structure are reserved, used only by the I/O manager or, in some cases, by FSDs.
An IRP is the basic I/O manager structure used to communicate with drivers and to allow drivers to communicate with each other. A packet consists of two different parts:
Header, or fixed part of the packet— This is used by the I/O manager to store information about the original request, such as the caller's device-independent parameters, the address of the device object upon which a file is open, and so on. It is also used by drivers to store information such as the final status of the request.
I/O stack locations— Following the header is a set of I/O stack locations, one per driver in the chain of layered drivers for which the request is bound. Each stack location contains the parameters, function codes, and context used by the corresponding driver to determine what it is supposed to be doing. For more information, see the IO_STACK_LOCATION structure.
While a higher-level driver might check the value of the Cancel Boolean in an IRP, that driver cannot assume the IRP will be completed with STATUS_CANCELLED by a lower-level driver even if the value is TRUE.
Requirements
Header
Wdm.h (include Wdm.h, Ntddk.h, or Ntifs.h)
See also
IoCreateDevice
IoGetCurrentIrpStackLocation
IoGetNextIrpStackLocation
IoSetCancelRoutine
IoSetNextIrpStackLocation
IO_STACK_LOCATION
IO_STATUS_BLOCK
 
 
Send comments about this topic to Microsoft
Build date: 10/12/2013






















 
 




[圖]
 



[圖]
 


   
 
http://graffine.pixnet.net/blog/post/13597308-irp-(i-o-request-packet)
IRP (I/O Request Packet)
     
IRP (I/O Request Packet) : 內含command, data的一組封包。系統和Driver溝通時使用。

1. 系統偵測到device,將對應的driver load到memory,呼叫driver的DeviceEntry()。

2. 系統的PnP Manager 呼叫driver的AddDevice( )。

3. PnP將IRP 傳送給driver,讓driver處理。

4. Application 開啟裝置,導致系統將一些IRP傳送給driver。

5. Application 讀取裝置,系統將對應的IRP傳送給driver,driver把data備妥,放到message中傳回給系統。

6. device有INT 發生時,driver的中斷服務常式開始工作。

7. 系統偵測到device移除,PnP Manager 送一些IRP給driver,然後呼叫driver的DriverUnload( )。
完成後,系統將driver從memory中移出。

以上看來Driver要實做三類function:
*Basic
DriverEntry( ), AddDevice( ), DriverUnload( )

*I/O control
StartIo( ), AdapterControl( ), OnInterrupt( ),

*Dispatch
DispatchPnP, DispatchPower, DispatchWmi

======================================

系統偵測到裝置時,如何找倒對應的driver呢?

PnP裝置:
PnP裝置必須要包含自己的id,大概是像PCI device中的Vender-function-type code,
所以當PCI controller可以讀取pci card的這個id。 對照 Registry 和 INF 檔,找到對應的driver。
有PnP功能的bus有: PCI,USB,PCMCIA。

非PnP裝置:
非PnP裝置沒有id,所以需要user作加入device的動作( Add New Hardware Wizard)。
之後,系統由registry和INF檔找到driver。
沒有PnP功能的bus有:ISA。

WDM和以往NT, 95的VxD不一樣,WDM完全被動的由系統呼叫,VxD則要自己載入,自己偵測硬體。

=======================================


WDM 至少包含兩種driver 程式:function driver 和 bus driver。

Function Driver : 處理device的function
Bus Driver : 處理device hardware - bus相關的動作

有些WDM還會有 Filter Driver: Upper-level Filter / Lower-Level Filter
這些driver的相依關係可以由IRP的傳遞過程來看,系統利用IRP和driver溝通

IRP -> UpperLevelFilter -> Function -> LowerLevel -> Bus

========================================

把一開始的第一點: “系統偵測到裝置,把對應的driver load到memory”的動作說得更詳細一點:

1. 系統的bus drver (PCI, USB, PCMCIA)偵測到有hardware 加入,呼叫系統的IoInvalidate DeviceRelation( ),這個function 會通知PnP Manager 硬體裝置有改變。

2. PnP Manager知道硬體裝置有改變後,發送一個IRP給bus driver,取得更新後的裝置PDO (Physical Device Object)序列。PnP可以對照序列中有哪一個PDO是新增加的。

3. PnP Manager傳送另一個IRP給bus driver,詢問某個新增加的PDO他的device identifier是甚麼。

4. device driver讀取該硬體的id,轉成device identifier傳給PnP Manager
device identifier 是一個像這樣的字串: “PCI\VEN_100C&DEV_001E&SUBSYS_000001″

5. PnP Manager將device_identifier的hardware_key(VEN_..以下)放到registry中 (HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Enum\…busname..)。

[圖]
 


 
 




[圖]
 


※ 編輯: ott 時間: 2013-11-08 07:19:26
※ 看板: ott 文章推薦值: 0 目前人氣: 0 累積人氣: 242 
分享網址: 複製 已複製
uefangsmith 轉錄至看板 uefacool (使用複製) 時間:2013-12-08 20:46:20
guest
x)推文 r)回覆 e)編輯 d)刪除 M)收藏 ^x)轉錄 同主題: =)首篇 [)上篇 ])下篇