1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
|
// Copyright (c) 2011 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 <shlobj.h>
#include <wtsapi32.h>
#pragma comment(lib, "wtsapi32.lib")
#include "chrome/browser/policy/policy_path_parser.h"
#include "base/memory/scoped_ptr.h"
#include "base/strings/utf_string_conversions.h"
#include "base/win/registry.h"
#include "chrome/common/chrome_switches.h"
#include "policy/policy_constants.h"
namespace {
// Checks if the key exists in the given hive and expands any string variables.
bool LoadUserDataDirPolicyFromRegistry(HKEY hive, base::FilePath* dir) {
std::wstring value;
std::wstring key_name(base::ASCIIToWide(policy::key::kUserDataDir));
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}";
const WCHAR* kWinLocalAppDataFolderVarName = L"${local_app_data}";
const WCHAR* kWinRoamingAppDataFolderVarName = L"${roaming_app_data}";
const WCHAR* kWinProfileFolderVarName = L"${profile}";
const WCHAR* kWinProgramDataFolderVarName = L"${global_app_data}";
const WCHAR* kWinProgramFilesFolderVarName = L"${program_files}";
const WCHAR* kWinWindowsFolderVarName = L"${windows}";
const WCHAR* kWinClientName = L"${client_name}";
struct WinFolderNamesToCSIDLMapping {
const WCHAR* name;
int id;
};
// Mapping from variable names to Windows CSIDL ids.
const WinFolderNamesToCSIDLMapping win_folder_mapping[] = {
{ kWinWindowsFolderVarName, CSIDL_WINDOWS},
{ kWinProgramFilesFolderVarName, CSIDL_PROGRAM_FILES},
{ kWinProgramDataFolderVarName, CSIDL_COMMON_APPDATA},
{ kWinProfileFolderVarName, CSIDL_PROFILE},
{ kWinLocalAppDataFolderVarName, CSIDL_LOCAL_APPDATA},
{ kWinRoamingAppDataFolderVarName, CSIDL_APPDATA},
{ kWinDocumentsFolderVarName, CSIDL_PERSONAL}
};
} // namespace
namespace policy {
namespace path_parser {
// 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);
if (result.length() == 0)
return result;
// Sanitize quotes in case of any around the whole string.
if (result.length() > 1 &&
((result[0] == L'"' && result[result.length() - 1] == L'"') ||
(result[0] == L'\'' && result[result.length() - 1] == L'\''))) {
// Strip first and last char which should be matching quotes now.
result = result.substr(1, result.length() - 2);
}
// First translate all path variables we recognize.
for (int i = 0; i < arraysize(win_folder_mapping); ++i) {
size_t position = result.find(win_folder_mapping[i].name);
if (position != std::wstring::npos) {
WCHAR path[MAX_PATH];
::SHGetSpecialFolderPath(0, path, win_folder_mapping[i].id, false);
std::wstring path_string(path);
result.replace(position, wcslen(win_folder_mapping[i].name), path_string);
}
}
// Next translate other windows specific variables.
size_t position = result.find(kUserNamePolicyVarName);
if (position != std::wstring::npos) {
DWORD return_length = 0;
::GetUserName(NULL, &return_length);
if (return_length != 0) {
scoped_ptr<WCHAR[]> username(new WCHAR[return_length]);
::GetUserName(username.get(), &return_length);
std::wstring username_string(username.get());
result.replace(position, wcslen(kUserNamePolicyVarName), username_string);
}
}
position = result.find(kMachineNamePolicyVarName);
if (position != std::wstring::npos) {
DWORD return_length = 0;
::GetComputerNameEx(ComputerNamePhysicalDnsHostname, NULL, &return_length);
if (return_length != 0) {
scoped_ptr<WCHAR[]> machinename(new WCHAR[return_length]);
::GetComputerNameEx(ComputerNamePhysicalDnsHostname,
machinename.get(), &return_length);
std::wstring machinename_string(machinename.get());
result.replace(
position, wcslen(kMachineNamePolicyVarName), machinename_string);
}
}
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)) {
std::wstring clientname_string(buffer);
result.replace(position, wcslen(kWinClientName), clientname_string);
::WTSFreeMemory(buffer);
}
}
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, user_data_dir))
LoadUserDataDirPolicyFromRegistry(HKEY_CURRENT_USER, user_data_dir);
}
} // namespace path_parser
} // namespace policy
|