1 ''' 2 This script gets the version number from ucrtbased.dll and checks 3 whether it is a version with a known issue. 4 ''' 5 6 import sys 7 8 from ctypes import (c_buffer, POINTER, byref, create_unicode_buffer, 9 Structure, WinDLL) 10 from ctypes.wintypes import DWORD, HANDLE 11 12 class VS_FIXEDFILEINFO(Structure): 13 _fields_ = [ 14 ("dwSignature", DWORD), 15 ("dwStrucVersion", DWORD), 16 ("dwFileVersionMS", DWORD), 17 ("dwFileVersionLS", DWORD), 18 ("dwProductVersionMS", DWORD), 19 ("dwProductVersionLS", DWORD), 20 ("dwFileFlagsMask", DWORD), 21 ("dwFileFlags", DWORD), 22 ("dwFileOS", DWORD), 23 ("dwFileType", DWORD), 24 ("dwFileSubtype", DWORD), 25 ("dwFileDateMS", DWORD), 26 ("dwFileDateLS", DWORD), 27 ] 28 29 kernel32 = WinDLL('kernel32') 30 version = WinDLL('version') 31 32 if len(sys.argv) < 2: 33 print('Usage: validate_ucrtbase.py <ucrtbase|ucrtbased>') 34 sys.exit(2) 35 36 try: 37 ucrtbased = WinDLL(sys.argv[1]) 38 except OSError: 39 print('Cannot find ucrtbased.dll') 40 # This likely means that VS is not installed, but that is an 41 # obvious enough problem if you're trying to produce a debug 42 # build that we don't need to fail here. 43 sys.exit(0) 44 45 # We will immediately double the length up to MAX_PATH, but the 46 # path may be longer, so we retry until the returned string is 47 # shorter than our buffer. 48 name_len = actual_len = 130 49 while actual_len == name_len: 50 name_len *= 2 51 name = create_unicode_buffer(name_len) 52 actual_len = kernel32.GetModuleFileNameW(HANDLE(ucrtbased._handle), 53 name, len(name)) 54 if not actual_len: 55 print('Failed to get full module name.') 56 sys.exit(2) 57 58 size = version.GetFileVersionInfoSizeW(name, None) 59 if not size: 60 print('Failed to get size of version info.') 61 sys.exit(2) 62 63 ver_block = c_buffer(size) 64 if (not version.GetFileVersionInfoW(name, None, size, ver_block) or 65 not ver_block): 66 print('Failed to get version info.') 67 sys.exit(2) 68 69 pvi = POINTER(VS_FIXEDFILEINFO)() 70 if not version.VerQueryValueW(ver_block, "", byref(pvi), byref(DWORD())): 71 print('Failed to get version value from info.') 72 sys.exit(2) 73 74 ver = ( 75 pvi.contents.dwProductVersionMS >> 16, 76 pvi.contents.dwProductVersionMS & 0xFFFF, 77 pvi.contents.dwProductVersionLS >> 16, 78 pvi.contents.dwProductVersionLS & 0xFFFF, 79 ) 80 81 print('{} is version {}.{}.{}.{}'.format(name.value, *ver)) 82 83 if ver < (10, 0, 10586): 84 print('WARN: ucrtbased contains known issues. ' 85 'Please update the Windows 10 SDK.') 86 print('See:') 87 print(' http://bugs.python.org/issue27705') 88 print(' https://developer.microsoft.com/en-US/windows/downloads/windows-10-sdk') 89 sys.exit(1) 90