(root)/
Python-3.12.0/
PC/
validate_ucrtbase.py
       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 ESC[4;38;5;81mVS_FIXEDFILEINFO(ESC[4;38;5;149mStructure):
      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)