Reporting required buffer size to caller of DeviceIoControl (WDF)

I can’t seem to figure what is the Feng shui way of reporting the buffer size requiroment to caller of DeviceIoControl when it fails with a STATUS_BUFFER_TOO_SMALL.
If I try to put the size inside the return buffer, and then say STATUS_MORE_PROCESSING_REQUIRED, I get nothing inside the output buffer, but a fat stack of 0’s.
What am I doing wrong : ( ?

The Information field of the IO_STATUS struct tells the I/O system how much data you returned. In KMDF, WdfRequestCompleteWithInformation. If the user specified a zero-length buffer, you can return STATUS_BUFFER_OVERFLOW and return the actual needed buffer size in the Information field. The user will get it back in the dwActual parameter and can reallocate and resubmit.

STATUS_MORE_PROCESSING_REQUIRED actually means “this request is not done yet, don’t give it back to the user”.

WdfRequestCompleteWithInformation would that be the same as calling
WdfRequestSetInformation followed with WdfRequestComplete ?
Where do I get dwActual from ?

  1. Yes, same thing.
  2. What I mean is the penultimate parameter to ReadFile, WriteFile and DeviceIoControl. I guess the docs call it lpBytesReturned.

Now why in the name of all that is holy, microsoft documentation mentions it … absolutely nowhere

Of course it does. Just look at the pages for ReadFile, WriteFile etc. where else could this value come from?

Now, knowing what you know now, reading the same page again will read differently. I read even the things I have written differently when I read them later

I wasn’t looking at those, as I was working on DeviceIoControl and I don’t recall finding anything about that anywhere on that page

I think your expectations are unreasonable. The DeviceIoControl page describes things from a user-mode perspective. You get back a status, and you get back a “number of bytes”. As a driver writer, you’re expected to know that you always need to fill in the IO_STATUS structure in the IRP when you’re done, which contains two fields: Status and Information. It doesn’t take a huge leap to connect that Status becomes GetLastError, and Information becomes lpBytesReturned. That information wouldn’t be useful to an application writer.

Now you know.

Well neither does WdfRequestCompleteWithInformation or WdfRequestSetInformation mention anything about that, that would be a reasonable expectation. I wouldn’t have been posting if that was how it was, I tried doing this exact same thing and was getting 0 because I returned the wrong status, that actually was very similar. STATUS_INSUFFICIENT_BUFFER was giving me zero in “Bytes Returned” and STATUS_BUFFER_OVERFLOW gave me the requisite byte count in “Bytes Returned” now I don’t see how this makes sense without clarification.

It’s is kind of a “trick” that you have to know about.

STATUS_BUFFER_OVERFLOW isn’t an error status. It’s a WARNING status. STSTUS_BUFFER_TOO_SMALL is an ERROR. In the Win32 API the value from the Information field does not get copied to lpBytesWritten when an error is returned. Which sucks, but that’s the way it is.

STATUS_MORE_PROCESSING_REQUIRED is a very special status that happens to never, ever, be legal for use in completing a Request.

Peter

it’s sad that winapi is full of these tricks that you can only ever know if you ask someone who happens to know :frowning:
It costs me alot of missed productivity and managmenet is breathing down my neck :confused:

@“Peter_Viscarola_(OSR)” said:
It’s is kind of a “trick” that you have to know about.

STATUS_BUFFER_OVERFLOW isn’t an error status. It’s a WARNING status. STSTUS_BUFFER_TOO_SMALL is an ERROR. In the Win32 API the value from the Information field does not get copied to lpBytesWritten when an error is returned. Which sucks, but that’s the way it is.

STATUS_MORE_PROCESSING_REQUIRED is a very special status that happens to never, ever, be legal for use in completing a Request.

In my opinion it is very bad that (as far as I know) there is no official page (anymore) that indicates which NTSTATUS codes returned from kernel space are translated to which error codes that arrive in user space, and which levels of NTSTATUS codes (error, warning, …) let the ioctl function in user space return success or failure.

Martin

You know about this page, right?

Peter