cpython/PC/validate_ucrtbase.py

89 lines
2.7 KiB
Python

'''
This script gets the version number from ucrtbased.dll and checks
whether it is a version with a known issue.
'''
import sys
from ctypes import (c_buffer, POINTER, byref, create_unicode_buffer,
Structure, WinDLL)
from ctypes.wintypes import DWORD, HANDLE
class VS_FIXEDFILEINFO(Structure):
_fields_ = [
("dwSignature", DWORD),
("dwStrucVersion", DWORD),
("dwFileVersionMS", DWORD),
("dwFileVersionLS", DWORD),
("dwProductVersionMS", DWORD),
("dwProductVersionLS", DWORD),
("dwFileFlagsMask", DWORD),
("dwFileFlags", DWORD),
("dwFileOS", DWORD),
("dwFileType", DWORD),
("dwFileSubtype", DWORD),
("dwFileDateMS", DWORD),
("dwFileDateLS", DWORD),
]
kernel32 = WinDLL('kernel32')
version = WinDLL('version')
if len(sys.argv) < 2:
print('Usage: validate_ucrtbase.py <ucrtbase|ucrtbased>')
sys.exit(2)
try:
ucrtbased = WinDLL(sys.argv[1])
except OSError:
print('Cannot find ucrtbased.dll')
# This likely means that VS is not installed, but that is an
# obvious enough problem if you're trying to produce a debug
# build that we don't need to fail here.
sys.exit(0)
# We will immediately double the length up to MAX_PATH, but the
# path may be longer, so we retry until the returned string is
# shorter than our buffer.
name_len = actual_len = 130
while actual_len == name_len:
name_len *= 2
name = create_unicode_buffer(name_len)
actual_len = kernel32.GetModuleFileNameW(HANDLE(ucrtbased._handle),
name, len(name))
if not actual_len:
print('Failed to get full module name.')
sys.exit(2)
size = version.GetFileVersionInfoSizeW(name, None)
if not size:
print('Failed to get size of version info.')
sys.exit(2)
ver_block = c_buffer(size)
if (not version.GetFileVersionInfoW(name, None, size, ver_block) or
not ver_block):
print('Failed to get version info.')
sys.exit(2)
pvi = POINTER(VS_FIXEDFILEINFO)()
if not version.VerQueryValueW(ver_block, "", byref(pvi), byref(DWORD())):
print('Failed to get version value from info.')
sys.exit(2)
ver = (
pvi.contents.dwProductVersionMS >> 16,
pvi.contents.dwProductVersionMS & 0xFFFF,
pvi.contents.dwProductVersionLS >> 16,
pvi.contents.dwProductVersionLS & 0xFFFF,
)
print('{} is version {}.{}.{}.{}'.format(name.value, *ver))
if ver < (10, 0, 10586):
print('WARN: ucrtbased contains known issues. '
'Please update the Windows 10 SDK.')
print('See:')
print(' http://bugs.python.org/issue27705')
print(' https://developer.microsoft.com/en-US/windows/downloads/windows-10-sdk')
sys.exit(1)