[Python-checkins] cpython (merge 3.5 -> default): Closes #26624: Adds validation of ucrtbase[d].dll version with warning for old

steve.dower python-checkins at python.org
Tue Apr 12 23:12:45 EDT 2016


https://hg.python.org/cpython/rev/6ff020df61b8
changeset:   100950:6ff020df61b8
parent:      100948:5c4303c46a18
parent:      100949:605fde022b15
user:        Steve Dower <steve.dower at microsoft.com>
date:        Tue Apr 12 20:11:45 2016 -0700
summary:
  Closes #26624: Adds validation of ucrtbase[d].dll version with warning for old versions.

files:
  Misc/NEWS               |   3 +
  PC/python_ver_rc.h      |   3 +-
  PC/validate_ucrtbase.py |  88 +++++++++++++++++++++++++++++
  PCbuild/python.vcxproj  |   7 ++
  4 files changed, 99 insertions(+), 2 deletions(-)


diff --git a/Misc/NEWS b/Misc/NEWS
--- a/Misc/NEWS
+++ b/Misc/NEWS
@@ -973,6 +973,9 @@
 Build
 -----
 
+- Issue #26624: Adds validation of ucrtbase[d].dll version with warning
+  for old versions.
+
 - Issue #17603: Avoid error about nonexistant fileblocks.o file by using a
   lower-level check for st_blocks in struct stat.
 
diff --git a/PC/python_ver_rc.h b/PC/python_ver_rc.h
--- a/PC/python_ver_rc.h
+++ b/PC/python_ver_rc.h
@@ -9,11 +9,10 @@
 #define MS_WINDOWS
 #include "modsupport.h"
 #include "patchlevel.h"
+#include <pythonnt_rc.h>
 #ifdef _DEBUG
-#   include <pythonnt_rc_d.h>
 #   define PYTHON_DEBUG_EXT "_d"
 #else
-#   include <pythonnt_rc.h>
 #   define PYTHON_DEBUG_EXT
 #endif
 
diff --git a/PC/validate_ucrtbase.py b/PC/validate_ucrtbase.py
new file mode 100644
--- /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)
diff --git a/PCbuild/python.vcxproj b/PCbuild/python.vcxproj
--- a/PCbuild/python.vcxproj
+++ b/PCbuild/python.vcxproj
@@ -83,6 +83,13 @@
   <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
   <ImportGroup Label="ExtensionTargets">
   </ImportGroup>
+  <Target Name="ValidateUcrtbase" AfterTargets="AfterBuild">
+    <PropertyGroup>
+      <UcrtName>ucrtbase</UcrtName>
+      <UcrtName Condition="'$(Configuration)' == 'Debug'">ucrtbased</UcrtName>
+    </PropertyGroup>
+    <Exec Command='"$(OutDir)python$(PyDebugExt).exe" "$(PySourcePath)PC\validate_ucrtbase.py" $(UcrtName)' ContinueOnError="true" />
+  </Target>
   <Target Name="GeneratePythonBat" AfterTargets="AfterBuild">
     <PropertyGroup>
       <_Content>@rem This script invokes the most recently built Python with all arguments

-- 
Repository URL: https://hg.python.org/cpython


More information about the Python-checkins mailing list