Skip to content

Commit

Permalink
Closes python#26624: Adds validation of ucrtbase[d].dll version with …
Browse files Browse the repository at this point in the history
…warning for old versions.
  • Loading branch information
zooba committed Apr 13, 2016
1 parent 1b80b24 commit a7a222f
Show file tree
Hide file tree
Showing 4 changed files with 99 additions and 2 deletions.
3 changes: 3 additions & 0 deletions Misc/NEWS
Original file line number Diff line number Diff line change
Expand Up @@ -385,6 +385,9 @@ Tests
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.

Expand Down
3 changes: 1 addition & 2 deletions PC/python_ver_rc.h
Original file line number Diff line number Diff line change
Expand Up @@ -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

Expand Down
88 changes: 88 additions & 0 deletions PC/validate_ucrtbase.py
Original file line number Diff line number Diff line change
@@ -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)
7 changes: 7 additions & 0 deletions PCbuild/python.vcxproj
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down

0 comments on commit a7a222f

Please sign in to comment.