summaryrefslogtreecommitdiffstats
path: root/chrome/common/chrome_paths_win.cc
blob: 55cad3f23586121c742c21ce12e7724538dcec23 (plain)
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
// 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/files/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 "components/nacl/common/nacl_switches.h"

namespace chrome {

namespace {

// Generic function to call SHGetFolderPath().
bool GetUserDirectory(int csidl_folder, base::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_folder, NULL,
                             SHGFP_TYPE_CURRENT, path_buf))) {
    return false;
  }
  *result = base::FilePath(path_buf);
  return true;
}

}  // namespace

bool GetDefaultUserDataDirectory(base::FilePath* result) {
  if (!PathService::Get(base::DIR_LOCAL_APP_DATA, result))
    return false;
  BrowserDistribution* dist = BrowserDistribution::GetDistribution();
  *result = result->Append(dist->GetInstallSubDir());
  *result = result->Append(chrome::kUserDataDirname);
  return true;
}

bool GetChromeFrameUserDataDirectory(base::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 base::FilePath& profile_dir,
                           base::FilePath* result) {
  // This function does more complicated things on Mac/Linux.
  *result = profile_dir;
}

bool GetUserDocumentsDirectory(base::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(base::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(base::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 = base::FilePath(std::wstring(path_buf));
    return true;
  }
  return GetUserDownloadsDirectorySafe(result);
}

bool GetUserMusicDirectory(base::FilePath* result) {
  return GetUserDirectory(CSIDL_MYMUSIC, result);
}

bool GetUserPicturesDirectory(base::FilePath* result) {
  return GetUserDirectory(CSIDL_MYPICTURES, result);
}

bool GetUserVideosDirectory(base::FilePath* result) {
  return GetUserDirectory(CSIDL_MYVIDEO, 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.

  if (process_type.empty() || process_type == switches::kServiceProcess)
    return true;

#if !defined(DISABLE_NACL)
  if (process_type == switches::kNaClBrokerProcess ||
      process_type == switches::kNaClLoaderProcess) {
    return true;
  }
#endif

  return false;
}

}  // namespace chrome