In latests x86 builds(211), both 2.7 and 3.6, when called with FileBasicInfo
, GetFileInformationByHandleEx
throws an exeption with winerror code ERROR_BAD_LENGTH
:
Python 2.7.13 x86 with latest Pythonwin on windows 7sp1-64:
>>> from win32file import *; from win32con import * >>> hfile = CreateFile(r'C:\Windows\notepad.exe', GENERIC_READ, FILE_SHARE_READ, None, OPEN_EXISTING, 0, None) >>> GetFileInformationByHandleEx(hfile, FileBasicInfo) Traceback (most recent call last): File "<interactive input>", line 1, in <module> error: (24, 'GetFileInformationByHandleEx', 'The program issued a command but the command length is incorrect.')
The cause of the error is a bug in <winsock2.h>
included from win32file.i
.
Here's some cl.exe output with /showIncludes
switch:
Note: including file: \WinSDK\Include\winsock2.h Note: including file: \WinSDK\Include\pshpack4.h << pragma pack(push, 4) here Note: including file: \WinSDK\Include\windows.h << all Windows stuff gets compiled with non default alignment Note: including file: \WinSDK\Include\sdkddkver.h ...cut Note: including file: \WinSDK\Include\poppack.h
This bug can tracked to 2003, it's present in 7.0a SDK and is fixed already in 8.1.
Struct FILE_BASIC_INFO
contains four int64 fields and one int32 so its sizeof
by default would be 40 bytes with padding, the odd packing directive decreases its size by omitting padding and GetFileInformationByHandleEx
refuses to fill the struct.
The obvious fix would be to just include windows.h
before winsock2
but it's not that easy due to conflict between winsock2
and winsock
. The second option is to define WIN32
macro before inclusion of winsock2.h
but I don't know will it work with all supported SDKs.
I'll attach a patch later today.
Here is a test that reveals the error
fix v1: define
WIN32
macroLast edit: robyschek 2017-06-15
fix v2: include windows before winsock2, tricky
Last edit: robyschek 2017-06-15
Thanks for the patch! Note I wont be able to get to this for a couple of weeks (I will before the next release though!), but in the meantime could you please:
Thanks!
Yes we do need winsock2. Windows.h only pulls winsock.h,
another beast from early 1990-ties, which does not provide API used in win32file.
This old winsock also causes multiple redefinition errors when included before winsock2.
MSDN recommends to just
'#include <winsock2.h>'
alone as it has been done in this module initially, but if'#include <windows.h>'
is required MSDN suggests to defineWIN32_LEAN_AND_MEAN
to avoid collisions with the old winsock.We then have to explicitly include some not so lean headers,
namely:
ole2.h
required bypywintypes.h
andWinefs.h
- NTFS encryption.I think WIN32_LEAN_AND_MEAN is the cleanest solution.
Here is the unified patch
Sorry for the delay - fixed via https://github.com/mhammond/pywin32/issues/752