none
IRP built by IoBuildSynchronousFsdRequest send to the lower driver hung. RRS feed

  • Question

  • I modified the DDK sampel code diskperf and use it as a volume filter driver.

    I write 2  functions to read/write the volume raw data, the code is build a new IRP and send the IRP to lower driver

    my functions can work fine in DeviceIoControl call.

    but they hung in the Read/Write callback functions

    the following function is the read function.

    NTSTATUS
    RawReadDisk(
       IN PDEVICE_OBJECT   DeviceObject,
       OUT CHAR *pBuffer,
       IN ULONGLONG Offset,
       IN ULONG ToReadLen,
       OUT ULONG* pReadedLen
       )
    {
     KEVENT                  Event;
     NTSTATUS                status;
     PIRP                    irp;
     IO_STATUS_BLOCK         ioStatusBlock;


     LARGE_INTEGER StartOffset;


     StartOffset.QuadPart = Offset;


     KeInitializeEvent( &Event, NotificationEvent, FALSE );

     irp = IoBuildSynchronousFsdRequest( IRP_MJ_READ,
      DeviceObject,
      pBuffer,
      ToReadLen,
      &StartOffset,
      &Event,
      &ioStatusBlock );

     if (irp == NULL) {
      status = STATUS_INSUFFICIENT_RESOURCES;
      goto End;
     }


     irp->IoStatus.Status = STATUS_SUCCESS ;


     status = IoCallDriver( DeviceObject, irp );

     if (status == STATUS_PENDING) {

      KeWaitForSingleObject( &Event, Executive, KernelMode, FALSE, NULL );
      status = ioStatusBlock.Status;
     }

     *pReadedLen = ioStatusBlock.Information;


    End:
     return status;

    }

    the upper call code is like

    status = RawReadDisk(

    device_extension->TargetDeviceObject,

    device_extension->pTempBuffer,

    Offset,

    Len,

    &rd

    );

    the length and offset are padding with disk sector size, the buffer is non paged memory.

    these code works fine in deviceiocontrol function,

    but it is hung with KeWaitForSingleObject( &Event, Executive, KernelMode, FALSE, NULL ) in READ callback function.

    I checked the IRQL in READ callback function, it is APC_LEVEL

    I don't know why it is hung in the READ callback function.

    any help will be appreciated.

    thanks

    Thursday, January 10, 2013 4:14 AM

Answers

  • IIRC, this api requires an APC to be queued to complete the IRP, running at APC_LEVEL would prevent that. you can easily roll your own synchronous irp with the Io call that will work at apc_level...although it is usually a very bad idea to send sync io in the storage stack.

    d -- This posting is provided "AS IS" with no warranties, and confers no rights.

    • Marked as answer by longforcommit Thursday, January 10, 2013 7:31 AM
    Thursday, January 10, 2013 4:32 AM

All replies

  • IIRC, this api requires an APC to be queued to complete the IRP, running at APC_LEVEL would prevent that. you can easily roll your own synchronous irp with the Io call that will work at apc_level...although it is usually a very bad idea to send sync io in the storage stack.

    d -- This posting is provided "AS IS" with no warranties, and confers no rights.

    • Marked as answer by longforcommit Thursday, January 10, 2013 7:31 AM
    Thursday, January 10, 2013 4:32 AM
  • IIRC, this api requires an APC to be queued to complete the IRP, running at APC_LEVEL would prevent that. you can easily roll your own synchronous irp with the Io call that will work at apc_level...although it is usually a very bad idea to send sync io in the storage stack.

    d -- This posting is provided "AS IS" with no warranties, and confers no rights.

    thank you very much, your suggestion help me solving this problem quickly!

    I change the IRQL from APC_LEVEL to PASSIVE_LEVEL then it works fine.

    Thursday, January 10, 2013 7:33 AM
  • if you didn't raise IRQL in your code you CANNOT lower IRQL.  in other words, if the reads and writes come in at APC_LEVEL to your dispatch routine, you cannot lower the IRQL.  my suggestion was not to lower IRQL, my suggestion was to create your own irp (IoAllocateIrp), set a completion routine, and then set the event in your completion routine to get the same synchronous irp behavior which doesn't require an APC to be queued.


    d -- This posting is provided "AS IS" with no warranties, and confers no rights.

    Thursday, January 10, 2013 8:10 AM