''' 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 ') 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)