Win32 API in pywin32

eryk sun eryksun at gmail.com
Sat Aug 13 06:48:08 EDT 2016


On Sat, Aug 13, 2016 at 4:22 AM, Lawrence D’Oliveiro
<lawrencedo99 at gmail.com> wrote:
> On Friday, August 5, 2016 at 11:58:05 AM UTC+12, I wrote:
>>
>> Are people still using Win32? I thought Windows went 64-bit years ago.
>
> Here <http://arstechnica.com/apple/2008/05/microsoft-learn-from-apple-ii/3/> is a little titbit I was looking for:
>
>     Win32 has a function for getting the size of a file. File sizes on
>     Windows are limited to 2^64 bytes, and so they need a 64-bit integer to
>     be expressed easily. But the API call to get the size of a file doesn't
>     give you a 64-bit value. Instead, it gives you a pair of 32-bit values
>     that have to be combined in a particular way. For 32-bit Windows, that's
>     sort of understandable; 32-bit Windows is, well, 32-bit, so you might not
>     expect to be able to use 64-bit integers. But if you use the same API in
>     64-bit Windows, it still gives you the pair of numbers, rather than just
>     a nice simple 64-bit number. While this made some kind of sense on 32-bit
>     Windows, it makes no sense at all on 64-bit Windows, since 64-bit Windows
>     can, by definition, use 64-bit numbers.
>
> This is why it’s still called “Win32” and not “Win64”...

You can call GetFileSizeEx [1]. Or call GetFileInformationByHandleEx
[2] to get the FileStandardInfo. These APIs use the LARGE_INTEGER
union type, which has a long long "QuadPart" member. Pointer casting
between LARGE_INTEGER and long long (or int64_t from stdint.h) poses
no alignment problem. That's why ctypes can define LARGE_INTEGER
simply as a c_longlong:

    >>> wintypes.LARGE_INTEGER
    <class 'ctypes.c_longlong'>

In contrast, FILETIME isn't a union, so ctypes has to define the low
and high parts separately to get the correct 4-byte alignment:

    >>> wintypes.FILETIME._fields_
    [('dwLowDateTime', <class 'ctypes.c_ulong'>),
     ('dwHighDateTime', <class 'ctypes.c_ulong'>)]
    >>> ctypes.alignment(wintypes.FILETIME)
    4

FILETIME is a legacy of the Windows API. The kernel and user-mode
runtime library (i.e. Rtl* in ntdll) use LARGE_INTEGER. Note that all
of the info classes for GetFileInformationByHandleEx also use
LARGE_INTEGER because they're basically a thin layer over the NT API.
For example, compare WinAPI FileFullDirectoryInfo [3] with NT API
FileFullDirectoryInformation [4]. They're identical. Using the WinAPI
wrapper is just missing some features of the native
NtQueryDirectoryFile system call, such as the ability to use an event
or APC routine to operate asynchronously and also the FileName
parameter that supports wildcards (NT style [5], not DOS).

[1]: https://msdn.microsoft.com/en-us/library/aa364957
[2]: https://msdn.microsoft.com/en-us/library/aa364953
[3]: https://msdn.microsoft.com/en-us/library/hh447298
[4]: https://msdn.microsoft.com/en-us/library/ff540289
[5]: https://msdn.microsoft.com/en-us/library/ff546850



More information about the Python-list mailing list