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
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
|
// Copyright (c) 2012 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/common/chrome_paths_internal.h"
#include <windows.h>
#include <knownfolders.h>
#include <shellapi.h>
#include <shlobj.h>
#include <shobjidl.h>
#include "base/command_line.h"
#include "base/file_path.h"
#include "base/path_service.h"
#include "base/win/metro.h"
#include "base/win/scoped_co_mem.h"
#include "chrome/common/chrome_constants.h"
#include "chrome/common/chrome_switches.h"
#include "chrome/installer/util/browser_distribution.h"
#include "content/public/common/content_switches.h"
namespace chrome {
namespace {
// Gets the default user data directory for either the current environment
// (desktop or metro) or for the other one (metro or desktop).
bool GetUserDataDirectoryForEnvironment(bool current, FilePath* result) {
if (!PathService::Get(base::DIR_LOCAL_APP_DATA, result))
return false;
BrowserDistribution* dist = BrowserDistribution::GetDistribution();
*result = result->Append(dist->GetInstallSubDir());
// TODO(rsimha): Continue to return the "Metro" subdirectory to allow testing
// of sync credential caching in the presence of strange singleton mode.
// Delete this block before shipping. See http://crbug.com/144280.
const CommandLine* command_line = CommandLine::ForCurrentProcess();
if ((command_line->HasSwitch(switches::kEnableSyncCredentialCaching)) &&
(base::win::IsMetroProcess() ? current : !current)) {
*result = result->Append(kMetroChromeUserDataSubDir);
}
*result = result->Append(chrome::kUserDataDirname);
return true;
}
// Generic function to call SHGetFolderPath().
bool GetUserDirectory(int csidl_folder, FilePath* result) {
// We need to go compute the value. It would be nice to support paths
// with names longer than MAX_PATH, but the system functions don't seem
// to be designed for it either, with the exception of GetTempPath
// (but other things will surely break if the temp path is too long,
// so we don't bother handling it.
wchar_t path_buf[MAX_PATH];
path_buf[0] = 0;
if (FAILED(SHGetFolderPath(NULL, CSIDL_MYDOCUMENTS, NULL,
SHGFP_TYPE_CURRENT, path_buf))) {
return false;
}
*result = FilePath(path_buf);
return true;
}
} // namespace
bool GetDefaultUserDataDirectory(FilePath* result) {
return GetUserDataDirectoryForEnvironment(true, result);
}
bool GetAlternateUserDataDirectory(FilePath *result) {
return GetUserDataDirectoryForEnvironment(false, result);
}
bool GetChromeFrameUserDataDirectory(FilePath* result) {
if (!PathService::Get(base::DIR_LOCAL_APP_DATA, result))
return false;
BrowserDistribution* dist = BrowserDistribution::GetSpecificDistribution(
BrowserDistribution::CHROME_FRAME);
*result = result->Append(dist->GetInstallSubDir());
*result = result->Append(chrome::kUserDataDirname);
return true;
}
void GetUserCacheDirectory(const FilePath& profile_dir, FilePath* result) {
// This function does more complicated things on Mac/Linux.
*result = profile_dir;
}
bool GetUserDocumentsDirectory(FilePath* result) {
return GetUserDirectory(CSIDL_MYDOCUMENTS, result);
}
// Return a default path for downloads that is safe.
// We just use 'Downloads' under DIR_USER_DOCUMENTS. Localizing
// 'downloads' is not a good idea because Chrome's UI language
// can be changed.
bool GetUserDownloadsDirectorySafe(FilePath* result) {
if (!GetUserDocumentsDirectory(result))
return false;
*result = result->Append(L"Downloads");
return true;
}
// On Vista and higher, use the downloads known folder. Since it can be
// relocated to point to a "dangerous" folder, callers should validate that the
// returned path is not dangerous before using it.
bool GetUserDownloadsDirectory(FilePath* result) {
typedef HRESULT (WINAPI *GetKnownFolderPath)(
REFKNOWNFOLDERID, DWORD, HANDLE, PWSTR*);
GetKnownFolderPath f = reinterpret_cast<GetKnownFolderPath>(
GetProcAddress(GetModuleHandle(L"shell32.dll"), "SHGetKnownFolderPath"));
base::win::ScopedCoMem<wchar_t> path_buf;
if (f && SUCCEEDED(f(FOLDERID_Downloads, 0, NULL, &path_buf))) {
*result = FilePath(std::wstring(path_buf));
return true;
}
return GetUserDownloadsDirectorySafe(result);
}
bool GetUserMusicDirectory(FilePath* result) {
return GetUserDirectory(CSIDL_MYMUSIC, result);
}
bool GetUserPicturesDirectory(FilePath* result) {
return GetUserDirectory(CSIDL_MYPICTURES, result);
}
bool GetUserVideosDirectory(FilePath* result) {
return GetUserDirectory(CSIDL_MYVIDEO, result);
}
bool GetUserDesktop(FilePath* result) {
return GetUserDirectory(CSIDL_DESKTOPDIRECTORY, result);
}
bool ProcessNeedsProfileDir(const std::string& process_type) {
// On windows we don't want subprocesses other than the browser process and
// service processes to be able to use the profile directory because if it
// lies on a network share the sandbox will prevent us from accessing it.
// TODO(pastarmovj): For now gpu and plugin broker processes are whitelisted
// too because they do use the profile dir in some way but this must be
// investigated and fixed if possible.
return process_type.empty() ||
process_type == switches::kServiceProcess ||
process_type == switches::kGpuProcess ||
process_type == switches::kNaClBrokerProcess ||
process_type == switches::kNaClLoaderProcess ||
process_type == switches::kPpapiBrokerProcess;
}
} // namespace chrome
|