At the moment I feel like I should say I plan on posting something like every month from now on.

This is just a small post warning you guys for some very annoying behavior in DeviceIoControl. After a quick read of the documentation I did code like this:

static bool ControlDevice(HIDECOMMAND Command, HIDEINFO* HideInfo)
    HANDLE hDevice = GetDeviceHandle();
    if (hDevice == INVALID_HANDLE_VALUE)
	    return false;
    bool result = !!DeviceIoControl(hDevice, //hDevice
                                    Command, //dwIoControlCode
                                    HideInfo, //lpInBuffer
                                    sizeof(HIDEINFO), //nInBufferSize
                                    NULL, //lpOutBuffer
                                    0, //nOutBufferSize
                                    NULL, //lpBytesReturned
                                    NULL //lpOverlapped
                                   ); //
    return result;

Reading the documentation in a quick glance it looked like lpBytesReturned and lpOverlapped are optional (it says so in the function definition).

I tested the code on Windows 8.1 and everything worked fine, so I published the code. After a while however, my client told me there was a crash on Windows 7 near DeviceIoControl.

Reading the documentation again I stumbled across this sentence:

If lpOverlapped is NULL, lpBytesReturned cannot be NULL. Even when an operation returns no output data and lpOutBuffer is NULL, DeviceIoControl makes use of lpBytesReturned. After such an operation, the value of lpBytesReturned is meaningless.

Moral of the story: don’t assume optional actually means a parameter is optional in WinAPI documentation :)

Cya around,


blog comments powered by Disqus


21 March 2015