1 // Copyright (c) 2011 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 #include <shlobj.h>
6
7 #include "chrome/browser/policy/policy_path_parser.h"
8
9 #include "base/logging.h"
10 #include "base/memory/scoped_ptr.h"
11
12 namespace policy {
13
14 namespace path_parser {
15
16 const WCHAR* kMachineNamePolicyVarName = L"${machine_name}";
17 const WCHAR* kUserNamePolicyVarName = L"${user_name}";
18 const WCHAR* kWinDocumentsFolderVarName = L"${documents}";
19 const WCHAR* kWinLocalAppDataFolderVarName = L"${local_app_data}";
20 const WCHAR* kWinRoamingAppDataFolderVarName = L"${roaming_app_data}";
21 const WCHAR* kWinProfileFolderVarName = L"${profile}";
22 const WCHAR* kWinProgramDataFolderVarName = L"${global_app_data}";
23 const WCHAR* kWinProgramFilesFolderVarName = L"${program_files}";
24 const WCHAR* kWinWindowsFolderVarName = L"${windows}";
25
26 struct WinFolderNamesToCSIDLMapping {
27 const WCHAR* name;
28 int id;
29 };
30
31 // Mapping from variable names to Windows CSIDL ids.
32 const WinFolderNamesToCSIDLMapping win_folder_mapping[] = {
33 { kWinWindowsFolderVarName, CSIDL_WINDOWS},
34 { kWinProgramFilesFolderVarName, CSIDL_PROGRAM_FILES},
35 { kWinProgramDataFolderVarName, CSIDL_COMMON_APPDATA},
36 { kWinProfileFolderVarName, CSIDL_PROFILE},
37 { kWinLocalAppDataFolderVarName, CSIDL_LOCAL_APPDATA},
38 { kWinRoamingAppDataFolderVarName, CSIDL_APPDATA},
39 { kWinDocumentsFolderVarName, CSIDL_PERSONAL}
40 };
41
42 // Replaces all variable occurances in the policy string with the respective
43 // system settings values.
ExpandPathVariables(const FilePath::StringType & untranslated_string)44 FilePath::StringType ExpandPathVariables(
45 const FilePath::StringType& untranslated_string) {
46 FilePath::StringType result(untranslated_string);
47 // First translate all path variables we recognize.
48 for (int i = 0; i < arraysize(win_folder_mapping); ++i) {
49 size_t position = result.find(win_folder_mapping[i].name);
50 if (position != std::wstring::npos) {
51 WCHAR path[MAX_PATH];
52 ::SHGetSpecialFolderPath(0, path, win_folder_mapping[i].id, false);
53 std::wstring path_string(path);
54 result.replace(position, wcslen(win_folder_mapping[i].name), path_string);
55 }
56 }
57 // Next translate two speacial variables ${user_name} and ${machine_name}
58 size_t position = result.find(kUserNamePolicyVarName);
59 if (position != std::wstring::npos) {
60 DWORD return_length = 0;
61 ::GetUserName(NULL, &return_length);
62 if (return_length != 0) {
63 scoped_array<WCHAR> username(new WCHAR[return_length]);
64 ::GetUserName(username.get(), &return_length);
65 std::wstring username_string(username.get());
66 result.replace(position, wcslen(kUserNamePolicyVarName), username_string);
67 }
68 }
69 position = result.find(kMachineNamePolicyVarName);
70 if (position != std::wstring::npos) {
71 DWORD return_length = 0;
72 ::GetComputerNameEx(ComputerNamePhysicalDnsHostname, NULL, &return_length);
73 if (return_length != 0) {
74 scoped_array<WCHAR> machinename(new WCHAR[return_length]);
75 ::GetComputerNameEx(ComputerNamePhysicalDnsHostname,
76 machinename.get(), &return_length);
77 std::wstring machinename_string(machinename.get());
78 result.replace(
79 position, wcslen(kMachineNamePolicyVarName), machinename_string);
80 }
81 }
82 return result;
83 }
84
85 } // namespace path_parser
86
87 } // namespace policy
88