Chromium Code Reviews| Index: chrome/install_static/policy_path_parser.cc |
| diff --git a/chrome/browser/policy/policy_path_parser_win.cc b/chrome/install_static/policy_path_parser.cc |
| similarity index 56% |
| copy from chrome/browser/policy/policy_path_parser_win.cc |
| copy to chrome/install_static/policy_path_parser.cc |
| index 9de7ed9da96a9f77ac5b1848d2bce64c45010ced..a2c00ea1912c613584557f9e52906e4b6c56bbd6 100644 |
| --- a/chrome/browser/policy/policy_path_parser_win.cc |
| +++ b/chrome/install_static/policy_path_parser.cc |
| @@ -1,37 +1,19 @@ |
| -// Copyright (c) 2011 The Chromium Authors. All rights reserved. |
| +// Copyright 2016 The Chromium Authors. All rights reserved. |
| // Use of this source code is governed by a BSD-style license that can be |
| // found in the LICENSE file. |
| -#include "chrome/browser/policy/policy_path_parser.h" |
| +#include "chrome/install_static/policy_path_parser.h" |
| +#include <assert.h> |
| #include <shlobj.h> |
| #include <stddef.h> |
| +#include <stdlib.h> |
| #include <wtsapi32.h> |
| #include <memory> |
| -#include "base/macros.h" |
| -#include "base/strings/utf_string_conversions.h" |
| -#include "base/win/registry.h" |
| -#include "chrome/common/chrome_switches.h" |
| -#include "components/policy/policy_constants.h" |
| - |
| namespace { |
| -// Checks if the key exists in the given hive and expands any string variables. |
| -bool LoadUserDataDirPolicyFromRegistry(HKEY hive, |
| - const char* key_name_str, |
| - base::FilePath* dir) { |
| - base::string16 value; |
| - base::string16 key_name(base::ASCIIToUTF16(key_name_str)); |
| - base::win::RegKey key(hive, policy::kRegistryChromePolicyKey, KEY_READ); |
| - if (key.ReadValue(key_name.c_str(), &value) == ERROR_SUCCESS) { |
| - *dir = base::FilePath(policy::path_parser::ExpandPathVariables(value)); |
| - return true; |
| - } |
| - return false; |
| -} |
| - |
| const WCHAR* kMachineNamePolicyVarName = L"${machine_name}"; |
| const WCHAR* kUserNamePolicyVarName = L"${user_name}"; |
| const WCHAR* kWinDocumentsFolderVarName = L"${documents}"; |
| @@ -50,7 +32,7 @@ struct WinFolderNamesToCSIDLMapping { |
| }; |
| // Mapping from variable names to Windows CSIDL ids. |
| -const WinFolderNamesToCSIDLMapping win_folder_mapping[] = { |
| +const WinFolderNamesToCSIDLMapping kWinFolderMapping[] = { |
| { kWinWindowsFolderVarName, CSIDL_WINDOWS}, |
| { kWinProgramFilesFolderVarName, CSIDL_PROGRAM_FILES}, |
| { kWinProgramDataFolderVarName, CSIDL_COMMON_APPDATA}, |
| @@ -60,17 +42,53 @@ const WinFolderNamesToCSIDLMapping win_folder_mapping[] = { |
| { kWinDocumentsFolderVarName, CSIDL_PERSONAL} |
| }; |
| -} // namespace |
| +template <class FunctionType> |
| +struct ScopedFunctionHelper { |
| + ScopedFunctionHelper(const wchar_t* library_name, const char* function_name) { |
| + library_ = LoadLibrary(library_name); |
| + assert(library_); |
| + if (library_) { |
| + // Strip off any leading :: that may have come from stringifying the |
| + // function's name. |
| + if (function_name[0] == ':' && function_name[1] == ':' && |
| + function_name[2] && function_name[2] != ':') { |
| + function_name += 2; |
| + } |
| + function_ = reinterpret_cast<FunctionType *>( |
| + GetProcAddress(library_, function_name)); |
| + assert(function_); |
| + } |
| + } |
| + |
| + ~ScopedFunctionHelper() { |
| + if (library_) |
| + FreeLibrary(library_); |
| + } |
| + |
| + template <class... Args> auto operator()(Args... a) { |
| + return function_(a...); |
| + } |
| -namespace policy { |
| + private: |
| + HMODULE library_; |
| + FunctionType* function_; |
| +}; |
| + |
| +#define SCOPED_LOAD_FUNCTION(library, function) \ |
| + ScopedFunctionHelper<decltype(function)>(library, #function) |
| + |
| +} // namespace |
| -namespace path_parser { |
| +namespace install_static { |
| // Replaces all variable occurances in the policy string with the respective |
| // system settings values. |
| -base::FilePath::StringType ExpandPathVariables( |
| - const base::FilePath::StringType& untranslated_string) { |
| - base::FilePath::StringType result(untranslated_string); |
| +// Note that this uses GetProcAddress to load DLLs that cannot be loaded before |
| +// the blacklist in the DllMain of chrome_elf has been applied. This function |
| +// should only be used after DllMain() has run. |
| +std::wstring ExpandPathVariables( |
| + const std::wstring& untranslated_string) { |
| + std::wstring result(untranslated_string); |
| if (result.length() == 0) |
| return result; |
| // Sanitize quotes in case of any around the whole string. |
| @@ -78,26 +96,30 @@ base::FilePath::StringType ExpandPathVariables( |
| ((result.front() == L'"' && result.back() == L'"') || |
| (result.front() == L'\'' && result.back() == L'\''))) { |
| // Strip first and last char which should be matching quotes now. |
| - result = result.substr(1, result.length() - 2); |
| + result.pop_back(); |
| + result.erase(0, 1); |
| } |
| + auto sh_get_special_folder_path = |
| + SCOPED_LOAD_FUNCTION(L"shell32.dll", ::SHGetSpecialFolderPathW); |
|
grt (UTC plus 2)
2016/11/22 11:37:09
do you expect that these are already loaded in the
scottmg
2016/11/22 17:16:07
No, I don't think there's any reason for these to
|
| // First translate all path variables we recognize. |
| - for (size_t i = 0; i < arraysize(win_folder_mapping); ++i) { |
| - size_t position = result.find(win_folder_mapping[i].name); |
| + for (size_t i = 0; i < _countof(kWinFolderMapping); ++i) { |
| + size_t position = result.find(kWinFolderMapping[i].name); |
| if (position != std::wstring::npos) { |
| WCHAR path[MAX_PATH]; |
| - ::SHGetSpecialFolderPath(0, path, win_folder_mapping[i].id, false); |
| + sh_get_special_folder_path(nullptr, path, kWinFolderMapping[i].id, false); |
| std::wstring path_string(path); |
| - result.replace(position, wcslen(win_folder_mapping[i].name), path_string); |
| + result.replace(position, wcslen(kWinFolderMapping[i].name), path_string); |
| } |
| } |
| // Next translate other windows specific variables. |
| + auto get_user_name = SCOPED_LOAD_FUNCTION(L"advapi32.dll", ::GetUserNameW); |
| size_t position = result.find(kUserNamePolicyVarName); |
| if (position != std::wstring::npos) { |
| DWORD return_length = 0; |
| - ::GetUserName(NULL, &return_length); |
| + get_user_name(nullptr, &return_length); |
| if (return_length != 0) { |
| std::unique_ptr<WCHAR[]> username(new WCHAR[return_length]); |
| - ::GetUserName(username.get(), &return_length); |
| + get_user_name(username.get(), &return_length); |
| std::wstring username_string(username.get()); |
| result.replace(position, wcslen(kUserNamePolicyVarName), username_string); |
| } |
| @@ -115,28 +137,30 @@ base::FilePath::StringType ExpandPathVariables( |
| position, wcslen(kMachineNamePolicyVarName), machinename_string); |
| } |
| } |
| + auto wts_query_session_information = |
| + SCOPED_LOAD_FUNCTION(L"wtsapi32.dll", ::WTSQuerySessionInformationW); |
| + auto wts_free_memory = SCOPED_LOAD_FUNCTION(L"wtsapi32.dll", ::WTSFreeMemory); |
| position = result.find(kWinClientName); |
| if (position != std::wstring::npos) { |
| LPWSTR buffer = NULL; |
| DWORD buffer_length = 0; |
| - if (::WTSQuerySessionInformation(WTS_CURRENT_SERVER, WTS_CURRENT_SESSION, |
| - WTSClientName, |
| - &buffer, &buffer_length)) { |
| + if (wts_query_session_information(WTS_CURRENT_SERVER, WTS_CURRENT_SESSION, |
| + WTSClientName, &buffer, &buffer_length)) { |
| std::wstring clientname_string(buffer); |
| result.replace(position, wcslen(kWinClientName), clientname_string); |
| - ::WTSFreeMemory(buffer); |
| + wts_free_memory(buffer); |
| } |
| } |
| position = result.find(kWinSessionName); |
| if (position != std::wstring::npos) { |
| LPWSTR buffer = NULL; |
| DWORD buffer_length = 0; |
| - if (::WTSQuerySessionInformation(WTS_CURRENT_SERVER, WTS_CURRENT_SESSION, |
| - WTSWinStationName, |
| - &buffer, &buffer_length)) { |
| + if (wts_query_session_information(WTS_CURRENT_SERVER, WTS_CURRENT_SESSION, |
| + WTSWinStationName, &buffer, |
| + &buffer_length)) { |
| std::wstring sessionname_string(buffer); |
| result.replace(position, wcslen(kWinSessionName), sessionname_string); |
| - ::WTSFreeMemory(buffer); |
| + wts_free_memory(buffer); |
| } |
| } |
| // TODO(pastarmovj): Consider reorganizing this code once there are even more |
| @@ -146,25 +170,4 @@ base::FilePath::StringType ExpandPathVariables( |
| return result; |
| } |
| -void CheckUserDataDirPolicy(base::FilePath* user_data_dir) { |
| - DCHECK(user_data_dir); |
| - // Policy from the HKLM hive has precedence over HKCU. |
| - if (!LoadUserDataDirPolicyFromRegistry(HKEY_LOCAL_MACHINE, key::kUserDataDir, |
| - user_data_dir)) { |
| - LoadUserDataDirPolicyFromRegistry(HKEY_CURRENT_USER, key::kUserDataDir, |
| - user_data_dir); |
| - } |
| -} |
| - |
| -void CheckDiskCacheDirPolicy(base::FilePath* disk_cache_dir) { |
| - DCHECK(disk_cache_dir); |
| - if (!LoadUserDataDirPolicyFromRegistry(HKEY_LOCAL_MACHINE, key::kDiskCacheDir, |
| - disk_cache_dir)) { |
| - LoadUserDataDirPolicyFromRegistry(HKEY_CURRENT_USER, key::kDiskCacheDir, |
| - disk_cache_dir); |
| - } |
| -} |
| - |
| -} // namespace path_parser |
| - |
| -} // namespace policy |
| +} // namespace install_static |