summaryrefslogtreecommitdiff
path: root/PC/validate_ucrtbase.py
diff options
context:
space:
mode:
authorSteve Dower <steve.dower@microsoft.com>2016-04-12 20:11:25 -0700
committerSteve Dower <steve.dower@microsoft.com>2016-04-12 20:11:25 -0700
commita7a222fde79af10dcccbfbd30f24e41913b2473d (patch)
tree4d1d6df87b8829bafb3d4c2456881663db910727 /PC/validate_ucrtbase.py
parent1b80b24007154d1f5764b1c14b95c80289cd3c34 (diff)
downloadcpython-git-a7a222fde79af10dcccbfbd30f24e41913b2473d.tar.gz
Closes #26624: Adds validation of ucrtbase[d].dll version with warning for old versions.
Diffstat (limited to 'PC/validate_ucrtbase.py')
-rw-r--r--PC/validate_ucrtbase.py88
1 files changed, 88 insertions, 0 deletions
diff --git a/PC/validate_ucrtbase.py b/PC/validate_ucrtbase.py
new file mode 100644
index 0000000000..6145d5914f
--- /dev/null
+++ b/PC/validate_ucrtbase.py
@@ -0,0 +1,88 @@
+'''
+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 Visual Studio or the Windows SDK.')
+ print('See:')
+ print(' http://bugs.python.org/issue26624')
+ sys.exit(1)