[PATCH 1/4] Handle FSCTL in NtDeviceIoControlFile.

Zebediah Figura (she/her) zfigura at codeweavers.com
Thu Jul 29 15:04:30 CDT 2021

On 7/29/21 1:30 PM, Alex Xu (Hello71) wrote:
> Excerpts from Zebediah Figura (she/her)'s message of July 26, 2021 12:36 pm:
>> On 7/26/21 9:13 AM, Alex Xu (Hello71) wrote:
>>> Excerpts from Chip Davis's message of July 25, 2021 4:06 pm:
>>>> Needs tests showing that FSCTLs do indeed work with NtDeviceIoControlFile().
>>>> Chip
>>> Yes, I see your point.
>>> It looks like it should be simple to add NtDeviceIoControlFile in
>>> dlls/ntdll/tests/file.c, but I was wondering: there don't seem to be any
>>> tests already, and it seems like it should make more sense to add a test
>>> for DeviceIoControl instead (since that is what most applications will
>>> care about).
>>> However, looking at that, there are two implementations of
>>> DeviceIoControl, in kernelbase and kernel32. Why doesn't the kernel32
>>> one forward to kernelbase like most kernel32 functions? Also, why is the
>>> kernelbase function different from the kernel32 function? I don't know
>>> anything about VxDs, but it seems odd that the kernel32 one uses
>>> Information only for non-overlapped IO, but kernelbase uses it for
>>> overlapped too. Actually, looking at dlls/ntdll, it doesn't seem like
>>> InternalHigh is actually used for anything? It seems like it might
>>> happen to work on little-endian machines by chance due to alignment of
>>> OVERLAPPED and IO_STATUS_BLOCK, but this doesn't seem like a reliable
>>> method.
>>> I checked git history, seems like InternalHigh should actually be
>>> Information everywhere? Thoughts?
>> No, this was done intentionally by Microsoft. OVERLAPPED is a documented
>> user API; IO_STATUS_BLOCK is not (although now it is a documented kernel
>> API). The fields of IO_STATUS_BLOCK are handled at the
>> kernel32/kernelbase level but this handling is obscured in the user API
>> by calling them "Internal" and "InternalHigh". The fields in the two
>> structures match regardless of endianness.
> How is this done in Wine? IO_STATUS_BLOCK in include/winternl.h has
> Status then Information, and include/winbase.h has InternalHigh then
> Internal for WORDS_BIGENDIAN, and reversed if not. Seems to me like
> InternalHigh is Information on LE, and Status/Pointer on BE.
> I think Windows probably won't actually support BE CPUs in the future,
> considering they are becoming less and less popular, and looks like
> MinGW does not support it, but why should we intentionally write to
> Information and then read from InternalHigh? It seems unnecessarily
> confusing. The only value explicitly stored in InternalHigh in Wine
> appears to be 0; all other values are aliased.

Actually, I think our definition is wrong, and the ordering of Internal 
and InternalHigh shouldn't depend on endianness. It was added in [1], 
but I think that commit incorrectly assumed that InternalHigh was a 
"high" part of Internal in any meaningful way, which it is not.

For that matter, is the Offset/OffsetHigh part correct? I'm not sure 
there are any places where we alias those members with a LARGE_INTEGER.

[Did Windows *ever* support BE CPUs? I know that early versions of NT 
supported Alpha, MIPS, PowerPC (and current version support ARM), but my 
research tells me that even at the time all were bi-endian and that 
Windows ran them in LE.]

[1] https://www.winehq.org/pipermail/wine-patches/2005-March/016419.html

>> I'm not sure why we don't load VXD drivers in kernelbase; there doesn't
>> seem to be any obvious reason why we can't, but we don't anyway.
> I guess maybe the logic is that Win9x-era programs should use kernel32,
> not kernelbase? kernelbase DeviceIoControl is only 1.5 years old, maybe
> Julliard remembers?
> I think current VxD behavior is basically "non-standard Wine extension"
> nowadays anyways; as long as programs work with no VxDs installed I
> don't see the issue either way.
>> There aren't any generic tests for NtDeviceIoControlFile and
>> NtFsControlFile because all of the tests are rather specific to the
>> different ioctls used. I'd recommend finding any place in the tests
>> where one is used and testing the other as well. It wouldn't surprise me
>> if both are identical nowadays.
> OK, sounds good.
> Regards,
> Alex.

More information about the wine-devel mailing list