[DDK] IRP가 비동기적으로 처리되어야 할때

요즘 각종 번역서들이 마음에 안들어서 DDK와 WDK 문서를 보면서

공부를 하고 있다.

영어긴 한데, 거부감없이 보니까 영 거리가 멀진 않은것 같다.

익숙해지면 영어도 늘고 좋겠지,, - _-;

일단 정리해보면, Queuing을 한다.

왜냐? 비동기적으로 처리해야하면 큐에 쌓아놓았다가 처리해야한다.

그러기위해서 Queuing을 해야하는데,

일단 내용을 보면 이렇다.

Force Pending I/O Requests

The Force Pending I/O Requests option randomly returns STATUS_PENDING in response to a driver's calls to IoCallDriver. This option tests the driver's logic for responding to STATUS_PENDING return values from IoCallDriver.

This option is supported only on Windows Vista and later versions of the Windows operating system.

Caution  Do not use this option on a driver unless you have detailed knowledge of the operation of the driver and have verified that the driver is designed to handle STATUS_PENDING return values from all of its calls to IoCallDriver. Running this option on a driver that is not designed to handle STATUS_PENDING from all calls can result in crashes, memory corruptions, and unusual system behavior that can be difficult to debug or correct.

Why Use Force Pending I/O Requests?

Higher-level drivers in a driver stack call IoCallDriver to pass an IRP down to lower-level drivers in the driver stack. The driver dispatch routine in the lower-level driver that receives the IRP can either complete the IRP immediately or return STATUS_PENDING and complete the IRP at a later time.

Typically, the caller must be prepared to handle either outcome. However, because most dispatch routines handle the IRP immediately, the STATUS_PENDING logic in the caller is not often exercised and serious logic errors might not be detected. The Force Pending I/O Requests option intercepts calls to IoCallDriver and returns STATUS_PENDING to test the calling driver's infrequently used logic.

When do you use Force Pending I/O Requests?

Before running this test, review the driver design and source code and confirm that the driver is intended to handle STATUS_PENDING from all of its IoCallDriver calls.

Many drivers are not designed to handle STATUS_PENDING on all calls to IoCallDriver. They might be sending the IRP to a particular well-known driver that is guaranteed to complete the IRP immediately. Sending STATUS_PENDING to a driver that does not handle it can cause driver and system crashes and memory corruption.

How should drivers handle STATUS_PENDING?

The higher-level driver that calls IoCallDriver must handle a STATUS_PENDING return value as follows:

  • Before calling IoCallDriver, the driver must call IoBuildSynchronousFsdRequest to arrange for synchronous processing of the IRP.
  • If IoCallDriver returns STATUS_PENDING, the driver must wait for the completion of the IRP by calling KeWaitForSingleObject on the specified event.
  • The driver must anticipate that the IRP might be freed before the I/O Manager signals the event.
  • After calling IoCallDriver, the caller cannot reference the IRP.

Which Errors Does Force Pending I/O Request Detect?

The Force Pending I/O Request option detects the following errors in the driver that calls IoCallDriver and receives a STATUS_PENDING return value:

  • The driver does not call IoBuildSynchronousFsdRequest to arrange for synchronous processing.
  • The driver does not call KeWaitForSingleObject.
  • The driver references a value in the IRP structure after calling IoCallDriver. After calling IoCallDriver, the higher-level driver cannot access the IRP unless it has set a completion routine and then, only when all lower-level drivers have completed the IRP. If the IRP is freed, the driver will crash.
  • The driver calls a related function incorrectly. For example, the driver calls KeWaitForSingleObject and passes a handle to the event (as the Object parameter), instead of passing a pointer to an event object.
  • The driver waits for the wrong event. For example, the driver calls IoSetCompletionRoutine, but waits for an internal event that is signaled by its own completion routine, instead of waiting for the IRP event that is signaled by the I/O Manager when the IRP is complete.

이런 상황일때 이런 함수를 호출하고 이런상황일때 이런 함수를 호출하고,

이런 내용이다.

  1. Irp->IoStatus.Information = 0;  
  2. Irp->IoStatus.Status = STATUS_PENDING;  
  3. IoMarkIrpPending(Irp);  
  4. IoStartPacket(DeviceObject, Irp, NULL, NULL);   
  5. return STATUS_PENDING;        

<TEXTAREA class="cpp" style="DISPLAY: none" name=code rows=10 cols=60>Irp->IoStatus.Information = 0; Irp->IoStatus.Status = STATUS_PENDING; IoMarkIrpPending(Irp); IoStartPacket(DeviceObject, Irp, NULL, NULL); return STATUS_PENDING; </TEXTAREA>

 

Queuing을 하는 코드의 모습이다. Queuing을 한다고 Irp에 마크를 해주고, 그다음에 STATUS_PENDING을 처리해준다. 흠, 으흠, 다음에는 동기화 문제를 알아보아야한다.

 

출처 : http://ssmhz.tistory.com
위로 스크롤