diff options
Diffstat (limited to 'third_party/python/gyp/test/lib/TestWin.py')
-rw-r--r-- | third_party/python/gyp/test/lib/TestWin.py | 101 |
1 files changed, 101 insertions, 0 deletions
diff --git a/third_party/python/gyp/test/lib/TestWin.py b/third_party/python/gyp/test/lib/TestWin.py new file mode 100644 index 0000000000..ef676db121 --- /dev/null +++ b/third_party/python/gyp/test/lib/TestWin.py @@ -0,0 +1,101 @@ +# Copyright (c) 2014 Google Inc. All rights reserved. +# Use of this source code is governed by a BSD-style license that can be +# found in the LICENSE file. + +""" +TestWin.py: a collection of helpers for testing on Windows. +""" + +import errno +import os +import re +import sys +import subprocess + +class Registry(object): + def _QueryBase(self, sysdir, key, value): + """Use reg.exe to read a particular key. + + While ideally we might use the win32 module, we would like gyp to be + python neutral, so for instance cygwin python lacks this module. + + Arguments: + sysdir: The system subdirectory to attempt to launch reg.exe from. + key: The registry key to read from. + value: The particular value to read. + Return: + stdout from reg.exe, or None for failure. + """ + # Skip if not on Windows or Python Win32 setup issue + if sys.platform not in ('win32', 'cygwin'): + return None + # Setup params to pass to and attempt to launch reg.exe + cmd = [os.path.join(os.environ.get('WINDIR', ''), sysdir, 'reg.exe'), + 'query', key] + if value: + cmd.extend(['/v', value]) + p = subprocess.Popen(cmd, stdout=subprocess.PIPE, stderr=subprocess.PIPE) + # Get the stdout from reg.exe, reading to the end so p.returncode is valid + # Note that the error text may be in [1] in some cases + text = p.communicate()[0].decode('utf-8', 'ignore') + # Check return code from reg.exe; officially 0==success and 1==error + if p.returncode: + return None + return text + + def Query(self, key, value=None): + r"""Use reg.exe to read a particular key through _QueryBase. + + First tries to launch from %WinDir%\Sysnative to avoid WoW64 redirection. If + that fails, it falls back to System32. Sysnative is available on Vista and + up and available on Windows Server 2003 and XP through KB patch 942589. Note + that Sysnative will always fail if using 64-bit python due to it being a + virtual directory and System32 will work correctly in the first place. + + KB 942589 - http://support.microsoft.com/kb/942589/en-us. + + Arguments: + key: The registry key. + value: The particular registry value to read (optional). + Return: + stdout from reg.exe, or None for failure. + """ + text = None + try: + text = self._QueryBase('Sysnative', key, value) + except OSError as e: + if e.errno == errno.ENOENT: + text = self._QueryBase('System32', key, value) + else: + raise + return text + + def GetValue(self, key, value): + """Use reg.exe to obtain the value of a registry key. + + Args: + key: The registry key. + value: The particular registry value to read. + Return: + contents of the registry key's value, or None on failure. + """ + text = self.Query(key, value) + if not text: + return None + # Extract value. + match = re.search(r'REG_\w+\s+([^\r]+)\r\n', text) + if not match: + return None + return match.group(1) + + def KeyExists(self, key): + """Use reg.exe to see if a key exists. + + Args: + key: The registry key to check. + Return: + True if the key exists + """ + if not self.Query(key): + return False + return True |