// Licensed to the Software Freedom Conservancy (SFC) under one // or more contributor license agreements. See the NOTICE file // distributed with this work for additional information // regarding copyright ownership. The SFC licenses this file // to you under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. #include "RegistryUtilities.h" #include #include "logging.h" namespace webdriver { RegistryUtilities::RegistryUtilities(void) { } RegistryUtilities::~RegistryUtilities(void) { } bool RegistryUtilities::GetRegistryValue(const HKEY root_key, const std::wstring& subkey, const std::wstring& value_name, std::wstring *value) { return GetRegistryValue(root_key, subkey, value_name, false, value); } bool RegistryUtilities::GetRegistryValue(const HKEY root_key, const std::wstring& subkey, const std::wstring& value_name, const bool bypass_registry_redirection, std::wstring *value) { std::string root_key_description = "HKEY_CURRENT_USER"; if (root_key == HKEY_CLASSES_ROOT) { root_key_description = "HKEY_CLASSES_ROOT"; } else if (root_key == HKEY_LOCAL_MACHINE) { root_key_description = "HKEY_LOCAL_MACHINE"; } LOG(TRACE) << "Attempting to get registry value " << LOGWSTRING(value_name) << " from " << LOGWSTRING(root_key_description) << "\\" << LOGWSTRING(subkey); bool value_retrieved = false; DWORD required_buffer_size; DWORD value_type; HKEY key_handle; REGSAM desired_security_mask = KEY_QUERY_VALUE; if (Is64BitWindows() && bypass_registry_redirection) { desired_security_mask |= KEY_WOW64_64KEY; } long registry_call_result = ::RegOpenKeyEx(root_key, subkey.c_str(), 0, desired_security_mask, &key_handle); if (ERROR_SUCCESS == registry_call_result) { registry_call_result = ::RegQueryValueEx(key_handle, value_name.c_str(), NULL, &value_type, NULL, &required_buffer_size); if (ERROR_SUCCESS == registry_call_result) { if (value_type == REG_SZ || value_type == REG_EXPAND_SZ || value_type == REG_MULTI_SZ) { std::vector value_buffer(required_buffer_size); registry_call_result = ::RegQueryValueEx(key_handle, value_name.c_str(), NULL, &value_type, reinterpret_cast(&value_buffer[0]), &required_buffer_size); if (ERROR_SUCCESS == registry_call_result) { *value = &value_buffer[0]; value_retrieved = true; } } else if (value_type == REG_DWORD) { DWORD numeric_value = 0; registry_call_result = ::RegQueryValueEx(key_handle, value_name.c_str(), NULL, &value_type, reinterpret_cast(&numeric_value), &required_buffer_size); if (ERROR_SUCCESS == registry_call_result) { // Coerce the numeric value to a string to return back. // Assume 10 characters will be enough to hold the size // of the value. std::vector numeric_value_buffer(10); _ltow_s(numeric_value, &numeric_value_buffer[0], numeric_value_buffer.size(), 10); *value = &numeric_value_buffer[0]; value_retrieved = true; } } else { LOG(WARN) << "Unexpected value type of " << value_type << " for RegQueryValueEx was found for value with name " << LOGWSTRING(value_name) << " in subkey " << LOGWSTRING(subkey) << " in hive " << root_key_description; } if (ERROR_SUCCESS != registry_call_result) { LOG(WARN) << "RegQueryValueEx failed with error code " << registry_call_result << " retrieving value with name " << LOGWSTRING(value_name) << " in subkey " << LOGWSTRING(subkey) << "in hive " << root_key_description; } } else { LOG(WARN) << "RegQueryValueEx failed with error code " << registry_call_result << " retrieving required buffer size for value with name " << LOGWSTRING(value_name) << " in subkey " << LOGWSTRING(subkey) << " in hive " << root_key_description; } ::RegCloseKey(key_handle); } else { LOG(WARN) << "RegOpenKeyEx failed with error code " << registry_call_result << " attempting to open subkey " << LOGWSTRING(subkey) << " in hive " << root_key_description; } if (value_retrieved) { LOG(TRACE) << "Retrieved value " << LOGWSTRING(*value); } return value_retrieved; } bool RegistryUtilities::RegistryKeyExists(HKEY root_key, const std::wstring& subkey) { HKEY key_handle; long registry_call_result = ::RegOpenKeyEx(root_key, subkey.c_str(), 0, KEY_QUERY_VALUE, &key_handle); bool result = (ERROR_SUCCESS == registry_call_result); if (result) { ::RegCloseKey(key_handle); } return result; } bool RegistryUtilities::Is64BitWindows() { SYSTEM_INFO system_info; ::GetNativeSystemInfo(&system_info); if (system_info.wProcessorArchitecture == 0) { // wProcessorArchitecture == 0 means processor architecture // is "x86", and therefore 32-bit. Note that we don't check // for specific processor flavors because we don't support // the driver running on any architecture other than x86 or // x64 (AMD or Intel). return false; } return true; } } // namespace webdriver