1''' 2This script gets the version number from ucrtbased.dll and checks 3whether it is a version with a known issue. 4''' 5 6import sys 7 8from ctypes import (c_buffer, POINTER, byref, create_unicode_buffer, 9 Structure, WinDLL) 10from ctypes.wintypes import DWORD, HANDLE 11 12class 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 29kernel32 = WinDLL('kernel32') 30version = WinDLL('version') 31 32if len(sys.argv) < 2: 33 print('Usage: validate_ucrtbase.py <ucrtbase|ucrtbased>') 34 sys.exit(2) 35 36try: 37 ucrtbased = WinDLL(sys.argv[1]) 38except 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. 48name_len = actual_len = 130 49while 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 58size = version.GetFileVersionInfoSizeW(name, None) 59if not size: 60 print('Failed to get size of version info.') 61 sys.exit(2) 62 63ver_block = c_buffer(size) 64if (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 69pvi = POINTER(VS_FIXEDFILEINFO)() 70if not version.VerQueryValueW(ver_block, "", byref(pvi), byref(DWORD())): 71 print('Failed to get version value from info.') 72 sys.exit(2) 73 74ver = ( 75 pvi.contents.dwProductVersionMS >> 16, 76 pvi.contents.dwProductVersionMS & 0xFFFF, 77 pvi.contents.dwProductVersionLS >> 16, 78 pvi.contents.dwProductVersionLS & 0xFFFF, 79) 80 81print('{} is version {}.{}.{}.{}'.format(name.value, *ver)) 82 83if 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