OLD | NEW |
(Empty) | |
| 1 # Copyright 2017 The Chromium Authors. All rights reserved. |
| 2 # Use of this source code is governed by a BSD-style license that can be |
| 3 # found in the LICENSE file. |
| 4 |
| 5 import _winreg |
| 6 |
| 7 import entry |
| 8 |
| 9 class RegistryKey(entry.Entry): |
| 10 |
| 11 def __init__(self, variable_expander, visitor): |
| 12 super(RegistryKey, self).__init__(variable_expander, visitor) |
| 13 self.key = None |
| 14 self.sub_key = None |
| 15 self.root_key_value = None |
| 16 self.should_key_exist = None |
| 17 self.key_handle = None |
| 18 |
| 19 def Check(self, entry_name, entry_value): |
| 20 self.key = self._variable_expander.Expand(entry_name) |
| 21 root_key, self.sub_key = self.key.split('\\', 1) |
| 22 self.root_key_value = self._RootKeyConstant(root_key) |
| 23 self.should_key_exist = entry_value['exists'] |
| 24 try: |
| 25 # Query the Windows registry for the registry key. It will throw a |
| 26 # WindowsError if the key doesn't exist. |
| 27 self.key_handle = _winreg.OpenKey(self.root_key_value, self.sub_key, 0, |
| 28 _winreg.KEY_QUERY_VALUE) |
| 29 except WindowsError: |
| 30 # Key doesn't exist. See that it matches the expectation. |
| 31 # Values are not checked if the missing key's existence is optional. |
| 32 pass |
| 33 # The key exists, see that it matches the expectation. |
| 34 self._visitor.VisitRegistryKey(self) |
| 35 |
| 36 def _RootKeyConstant(self, root_key): |
| 37 """Converts a root registry key string into a _winreg.HKEY_* constant.""" |
| 38 root_key_mapping = { |
| 39 'HKEY_CLASSES_ROOT': _winreg.HKEY_CLASSES_ROOT, |
| 40 'HKEY_CURRENT_USER': _winreg.HKEY_CURRENT_USER, |
| 41 'HKEY_LOCAL_MACHINE': _winreg.HKEY_LOCAL_MACHINE, |
| 42 'HKEY_USERS': _winreg.HKEY_USERS, |
| 43 } |
| 44 if root_key not in root_key_mapping: |
| 45 raise KeyError("Unknown root registry key '%s'" % root_key) |
| 46 return root_key_mapping[root_key] |
| 47 |
| 48 |
| 49 class RegistryValue(entry.Entry): |
| 50 def __init__(self, variable_expander, visitor): |
| 51 super(RegistryValue, self).__init__(variable_expander, visitor) |
| 52 self.key = None |
| 53 self.value = None |
| 54 self.value_data = None |
| 55 self.value_type = None |
| 56 self.expected_data = None |
| 57 self.expected_type = None |
| 58 |
| 59 def Check(self, value, value_expectation, registry_key): |
| 60 # Query the value. It will throw a WindowsError if the value doesn't |
| 61 # exist. |
| 62 self.value = value |
| 63 self.key = registry_key.key |
| 64 self.value_data = None |
| 65 self.value_type = None |
| 66 self.expected_data = value_expectation.get('data', None) |
| 67 if isinstance(self.expected_data, basestring): |
| 68 self.expected_data = self._variable_expander.Expand(self.expected_data) |
| 69 self.expected_type = self._ValueTypeConstant( |
| 70 value_expectation.get('type', None)) |
| 71 |
| 72 try: |
| 73 self.value_data, self.value_type = _winreg.QueryValueEx( |
| 74 registry_key.key_handle, value) |
| 75 except WindowsError: |
| 76 pass |
| 77 |
| 78 self._visitor.VisitRegistryValue(self) |
| 79 |
| 80 def _ValueTypeConstant(self, value_type): |
| 81 """Converts a registry value type string into a _winreg.REG_* constant.""" |
| 82 if value_type is None: |
| 83 return None |
| 84 value_type_mapping = { |
| 85 'BINARY': _winreg.REG_BINARY, |
| 86 'DWORD': _winreg.REG_DWORD, |
| 87 'DWORD_LITTLE_ENDIAN': _winreg.REG_DWORD_LITTLE_ENDIAN, |
| 88 'DWORD_BIG_ENDIAN': _winreg.REG_DWORD_BIG_ENDIAN, |
| 89 'EXPAND_SZ': _winreg.REG_EXPAND_SZ, |
| 90 'LINK': _winreg.REG_LINK, |
| 91 'MULTI_SZ': _winreg.REG_MULTI_SZ, |
| 92 'NONE': _winreg.REG_NONE, |
| 93 'SZ': _winreg.REG_SZ, |
| 94 } |
| 95 if value_type not in value_type_mapping: |
| 96 raise KeyError("Unknown registry value type '%s'" % value_type) |
| 97 return value_type_mapping[value_type] |
| 98 |
| 99 |
| 100 class Registry(entry.Entry): |
| 101 """ Visitor for registry entry in property. |
| 102 """ |
| 103 def Check(self, entry_name, entry_value): |
| 104 """ Visit one registry entry's key and values. Values are not checked if |
| 105 the key is not present in the registry. |
| 106 |
| 107 Args: |
| 108 entry_name: A string represents regsitry name in the property. |
| 109 entry_value: A dictionary represents the following keys and values: |
| 110 'exists' - a string indicating whether the registry key's existence |
| 111 is 'required', 'optional', or 'forbidden'. |
| 112 'values' - (optional) a dictionary where each key is a registry |
| 113 value and its associated value is a dictionary with the |
| 114 following key and values: |
| 115 |
| 116 'type' - (optional) a string indicating the type of the |
| 117 registry value. If not present, the corresponding |
| 118 value is expected to be absent in the registry. |
| 119 'data' - the associated data of the registry value if |
| 120 'type' is specified. If it is a string, it is |
| 121 expanded using Expand. |
| 122 """ |
| 123 registry_key = RegistryKey(self._variable_expander, self._visitor) |
| 124 registry_key.Check(entry_name, entry_value) |
| 125 |
| 126 # Verify the expected values if key exists. |
| 127 if registry_key.key_handle is None or 'values' not in entry_value: |
| 128 return |
| 129 |
| 130 for value, value_expectation in entry_value['values'].iteritems(): |
| 131 registry_value = RegistryValue(self._variable_expander, self._visitor) |
| 132 registry_value.Check(value, value_expectation, registry_key) |
OLD | NEW |