Accessing input & output buffers from completion routines

I'm working on a upper-filter driver that filters IOCTL requests to the "HidBatt" battery driver. As part of that I'm using a completion routine to modify the output from IOCTL requests to the underlying HidBatt driver. The completion routine "PWDF_REQUEST_COMPLETION_PARAMS Params" argument have been invalidated by WdfRequestFormatRequestUsingCurrentType, so I need an alternative mechanism for accessing IOCTL buffers.

I'm currently using WdfRequestRetrieveInputBuffer & WdfRequestRetrieveOutputBuffer to access IOCTL buffers from the completion routine This seem to work, but I'm not sure if it's guaranteed safe, since the "Params" argument have been invalidated. I am therefore seeking advise on "best practice" in this area.

Questions:

  • Is it safe to call WdfRequestRetrieveInputBuffer from a IOCTL completion routine? If not, does it help to move the call to the EvtIoDeviceControl callback function and store the buffer pointer for later access by the completion routine?
  • Is it safe to call WdfRequestRetrieveOutputBuffer from a IOCTL completion routine? If not, does it help to move the call to the EvtIoDeviceControl callback function and store the buffer pointer for later access by the completion routine?

Thanks in advance.

I'm not really sure what you mean about the "Params" argument being "invalidated" by calling WdfRequestFormatxxxx... that made me scratch my head. FormatXxxx is about the parameters for the NEXT driver, not yours.

But, in any case: Yes. WdfRequestRetrievexxxx is safe. It's about the buffers that were passed to YOUR driver. Should be all good, and it's indeed callable at IRQL DISPATCH_LEVEL.

According to EVT_WDF_REQUEST_COMPLETION_ROUTINE callback function then "If the driver formatted the request using either WdfRequestFormatRequestUsingCurrentType or WdfRequestWdmFormatUsingStackLocation, only the IoStatus field in the completion parameters structure is valid". This is also what I'm observing.

Thanks for confirming Peter. This was the answer I was hoping for.

As a side note, it CAN be very useful to attach a context to your WDFREQUESTs and store the information you need in there, for later use in the completion routine. It may not be necessary in your case, but it's a useful technique for your toolbox.

1 Like

Excellent point Tim! I'm in fact already capturing the IOCTL code and a field from the input buffer in WDF request context (impl), since I was unsure if it was safe to access the input buffer from the completion handler.