I took the liberty of writing some ntoskrnl-based tests: https://testbot.winehq.org/JobDetails.pl?Key=133935
The conclusions that one can apparently draw are:
* Buffered ioctls pass through zero, for both the pointer and size, if either the pointer or the size is zero. This basically contradicts Alexandre's original feedback—at least for buffered ioctls, that really is what's supposed to happen.
* Buffered ioctls return STATUS_ACCESS_VIOLATION if the buffer pointer and size are nonzero but invalid. This is done somewhere in the NT kernel.
* Direct ioctls behave similarly, with the exception that a NULL output buffer is *not* treated as not-specified.
* Neither ioctls simply pass through their parameters without modification.
In order to exactly emulate this behaviour for NEITHER ioctls, we will need extra flags (in order to signal to the Unix side whether the ioctl was originally NULL or not). On the other hand, NEITHER ioctls are kind of generally tetchy. I suspect that the right thing to do is something close to the original patch, possibly limited to buffered ioctls.