Steve Dower | a7a222f | 2016-04-12 20:11:25 -0700 | [diff] [blame] | 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. ' |
Steve Dower | f2bdb6b | 2016-09-09 18:21:15 -0700 | [diff] [blame] | 85 | 'Please update the Windows 10 SDK.') |
Steve Dower | a7a222f | 2016-04-12 20:11:25 -0700 | [diff] [blame] | 86 | print('See:') |
Steve Dower | f2bdb6b | 2016-09-09 18:21:15 -0700 | [diff] [blame] | 87 | print(' http://bugs.python.org/issue27705') |
| 88 | print(' https://developer.microsoft.com/en-US/windows/downloads/windows-10-sdk') |
Steve Dower | a7a222f | 2016-04-12 20:11:25 -0700 | [diff] [blame] | 89 | sys.exit(1) |