How to get WdfRequestComplete status value after DeviceIoControl call

Hi
I try to communicate with driver from my app with DeviceIoControl
I just noticed that DeviceIoControl returns bool
When complete I/O request with WdfRequestComplete I can pass status value
So is there any api available I can check this value from application side?
Or do I need to pass this kind of info through output buffer?
Thanks in advance

Hi, here is what I know so far:

The kernel driver lets the IOCTL handler return one of the NTSTATUS codes. However, Windows maps that NTSTATUS code to some WIN32 error code when ithe IOCTL result is passed up to user space. If the calling DeviceIoControl() function returns 0/false, you can retrieve the mapped WIN32 error code using GetLastError(), as usual.

However, the mappings may be strange in some cases. There used to be a web page that listed the mappings, but the page has vanished now:
https://support.microsoft.com/en-us/help/113996

Please note there are NT_STATUS codes that are considered an error, and there may be different status code that are not considered an error. When I investigated on this I was unable to find out exactly in which case the user space function returns “true” or “false”.

Things become interesting if your kernel driver needs to return some status/error information that is not covered by the predefined status codes. Again, when I investigated on this quite some time ago I found that it is possible to defined custom NTSTATUS codes in kernel space, e.g.
((NTSTATUS) (0xC0000000 | 0x20000000 | 31)).

Apparently, such custom error status codes are passed up to user space, and GetLastError() after the IOCTL call then returns a negative number, i.e. -31 for the example here. So if GetLastError() returns a positive number it’s one of the codes predefined by Windows, and it the number is negative it’s your custom code.

I have tested this in the past and found that it worked, but I don’t know if its safe to do this, or if that won’t work anymore in future Windows versions.

And once more, I haven’t found a clear description which class of the NTSTATUS codes (STATUS_SEVERITY_SUCCESS, STATUS_SEVERITY_INFORMATIONAL, STATUS_SEVERITY_WARNING, STATUS_SEVERITY_ERROR) results in a “false” return in user space. This should be pretty obvious for codes of class STATUS_SEVERITY_SUCCESS or STATUS_SEVERITY_ERROR, but would STATUS_SEVERITY_INFORMATIONAL or STATUS_SEVERITY_WARNING be evaluated as success or error when it is passed to user space? I haven’t tried this.

Any more details, experience or reference are welcome! :wink:

Martin

1 Like

Mr. Burnicki reminded me, above, that our friends in Redmond have removed the KB page that had The Table that mapped NTSTATUS to Win32 error values. This caused me nothing but aggravation and annoyance as I labored to choose error codes in my last two driver projects. I, quite literally, resorted to using a version of the table from an old, obviously cached/cloned, page on Chinese web site.

So, I resolved to do something about it this morning. I built my own up-to-date version of The Table. You can find the link here.

Enjoy.

1 Like

OK… back to the OP’s question:

Yes, you get the Win32 ERROR value (that your NTSTATUS value gets mapped to) using GetLastError. You will notice that it very cleverly mentions this in the documentation:

Peter

@“Peter_Viscarola_(OSR)” said:
OK… back to the OP’s question:

Yes, you get the Win32 ERROR value (that your NTSTATUS value gets mapped to) using GetLastError. You will notice that it very cleverly mentions this in the documentation:

Peter

Hi Peter, thank for pointing out this