Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
allendowney
GitHub Repository: allendowney/cpython
Path: blob/main/PC/validate_ucrtbase.py
12 views
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
91