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