106741cbc25cd4227a9fba40dfd0273bfcc1a587aBen Murdoch// Copyright (c) 2006-2008 The Chromium Authors. All rights reserved.
206741cbc25cd4227a9fba40dfd0273bfcc1a587aBen Murdoch// Use of this source code is governed by a BSD-style license that can be
306741cbc25cd4227a9fba40dfd0273bfcc1a587aBen Murdoch// found in the LICENSE file.
406741cbc25cd4227a9fba40dfd0273bfcc1a587aBen Murdoch
506741cbc25cd4227a9fba40dfd0273bfcc1a587aBen Murdoch#include "chrome/common/chrome_paths_internal.h"
606741cbc25cd4227a9fba40dfd0273bfcc1a587aBen Murdoch
706741cbc25cd4227a9fba40dfd0273bfcc1a587aBen Murdoch#include <windows.h>
806741cbc25cd4227a9fba40dfd0273bfcc1a587aBen Murdoch#include <knownfolders.h>
906741cbc25cd4227a9fba40dfd0273bfcc1a587aBen Murdoch#include <shellapi.h>
1006741cbc25cd4227a9fba40dfd0273bfcc1a587aBen Murdoch#include <shlobj.h>
1106741cbc25cd4227a9fba40dfd0273bfcc1a587aBen Murdoch#include <shobjidl.h>
1206741cbc25cd4227a9fba40dfd0273bfcc1a587aBen Murdoch
133f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen#include "app/win/scoped_co_mem.h"
1406741cbc25cd4227a9fba40dfd0273bfcc1a587aBen Murdoch#include "base/file_path.h"
1506741cbc25cd4227a9fba40dfd0273bfcc1a587aBen Murdoch#include "base/path_service.h"
1606741cbc25cd4227a9fba40dfd0273bfcc1a587aBen Murdoch#include "chrome/common/chrome_constants.h"
1706741cbc25cd4227a9fba40dfd0273bfcc1a587aBen Murdoch#include "chrome/installer/util/browser_distribution.h"
1806741cbc25cd4227a9fba40dfd0273bfcc1a587aBen Murdoch
1906741cbc25cd4227a9fba40dfd0273bfcc1a587aBen Murdochnamespace chrome {
2006741cbc25cd4227a9fba40dfd0273bfcc1a587aBen Murdoch
2106741cbc25cd4227a9fba40dfd0273bfcc1a587aBen Murdochbool GetDefaultUserDataDirectory(FilePath* result) {
2206741cbc25cd4227a9fba40dfd0273bfcc1a587aBen Murdoch  if (!PathService::Get(base::DIR_LOCAL_APP_DATA, result))
2306741cbc25cd4227a9fba40dfd0273bfcc1a587aBen Murdoch    return false;
2406741cbc25cd4227a9fba40dfd0273bfcc1a587aBen Murdoch  BrowserDistribution* dist = BrowserDistribution::GetDistribution();
2506741cbc25cd4227a9fba40dfd0273bfcc1a587aBen Murdoch  *result = result->Append(dist->GetInstallSubDir());
2606741cbc25cd4227a9fba40dfd0273bfcc1a587aBen Murdoch  *result = result->Append(chrome::kUserDataDirname);
2706741cbc25cd4227a9fba40dfd0273bfcc1a587aBen Murdoch  return true;
2806741cbc25cd4227a9fba40dfd0273bfcc1a587aBen Murdoch}
2906741cbc25cd4227a9fba40dfd0273bfcc1a587aBen Murdoch
3006741cbc25cd4227a9fba40dfd0273bfcc1a587aBen Murdochbool GetChromeFrameUserDataDirectory(FilePath* result) {
3106741cbc25cd4227a9fba40dfd0273bfcc1a587aBen Murdoch  if (!PathService::Get(base::DIR_LOCAL_APP_DATA, result))
3206741cbc25cd4227a9fba40dfd0273bfcc1a587aBen Murdoch    return false;
3321d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen  BrowserDistribution* dist = BrowserDistribution::GetSpecificDistribution(
3472a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen      BrowserDistribution::CHROME_FRAME);
3521d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen  *result = result->Append(dist->GetInstallSubDir());
3606741cbc25cd4227a9fba40dfd0273bfcc1a587aBen Murdoch  *result = result->Append(chrome::kUserDataDirname);
3706741cbc25cd4227a9fba40dfd0273bfcc1a587aBen Murdoch  return true;
3806741cbc25cd4227a9fba40dfd0273bfcc1a587aBen Murdoch}
3906741cbc25cd4227a9fba40dfd0273bfcc1a587aBen Murdoch
40201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdochvoid GetUserCacheDirectory(const FilePath& profile_dir, FilePath* result) {
41201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch  // This function does more complicated things on Mac/Linux.
42201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch  *result = profile_dir;
43201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch}
44201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch
4506741cbc25cd4227a9fba40dfd0273bfcc1a587aBen Murdochbool GetUserDocumentsDirectory(FilePath* result) {
4606741cbc25cd4227a9fba40dfd0273bfcc1a587aBen Murdoch  wchar_t path_buf[MAX_PATH];
4706741cbc25cd4227a9fba40dfd0273bfcc1a587aBen Murdoch  if (FAILED(SHGetFolderPath(NULL, CSIDL_MYDOCUMENTS, NULL,
4806741cbc25cd4227a9fba40dfd0273bfcc1a587aBen Murdoch                             SHGFP_TYPE_CURRENT, path_buf)))
4906741cbc25cd4227a9fba40dfd0273bfcc1a587aBen Murdoch    return false;
5006741cbc25cd4227a9fba40dfd0273bfcc1a587aBen Murdoch  *result = FilePath(path_buf);
5106741cbc25cd4227a9fba40dfd0273bfcc1a587aBen Murdoch  return true;
5206741cbc25cd4227a9fba40dfd0273bfcc1a587aBen Murdoch}
5306741cbc25cd4227a9fba40dfd0273bfcc1a587aBen Murdoch
5406741cbc25cd4227a9fba40dfd0273bfcc1a587aBen Murdoch// Return a default path for downloads that is safe.
5506741cbc25cd4227a9fba40dfd0273bfcc1a587aBen Murdoch// We just use 'Downloads' under DIR_USER_DOCUMENTS. Localizing
5606741cbc25cd4227a9fba40dfd0273bfcc1a587aBen Murdoch// 'downloads' is not a good idea because Chrome's UI language
5706741cbc25cd4227a9fba40dfd0273bfcc1a587aBen Murdoch// can be changed.
5806741cbc25cd4227a9fba40dfd0273bfcc1a587aBen Murdochbool GetUserDownloadsDirectorySafe(FilePath* result) {
5906741cbc25cd4227a9fba40dfd0273bfcc1a587aBen Murdoch  if (!GetUserDocumentsDirectory(result))
6006741cbc25cd4227a9fba40dfd0273bfcc1a587aBen Murdoch    return false;
6106741cbc25cd4227a9fba40dfd0273bfcc1a587aBen Murdoch
6206741cbc25cd4227a9fba40dfd0273bfcc1a587aBen Murdoch  *result = result->Append(L"Downloads");
6306741cbc25cd4227a9fba40dfd0273bfcc1a587aBen Murdoch  return true;
6406741cbc25cd4227a9fba40dfd0273bfcc1a587aBen Murdoch}
6506741cbc25cd4227a9fba40dfd0273bfcc1a587aBen Murdoch
6606741cbc25cd4227a9fba40dfd0273bfcc1a587aBen Murdoch// On Vista and higher, use the downloads known folder. Since it can be
6706741cbc25cd4227a9fba40dfd0273bfcc1a587aBen Murdoch// relocated to point to a "dangerous" folder, callers should validate that the
6806741cbc25cd4227a9fba40dfd0273bfcc1a587aBen Murdoch// returned path is not dangerous before using it.
6906741cbc25cd4227a9fba40dfd0273bfcc1a587aBen Murdochbool GetUserDownloadsDirectory(FilePath* result) {
7006741cbc25cd4227a9fba40dfd0273bfcc1a587aBen Murdoch  typedef HRESULT (WINAPI *GetKnownFolderPath)(
7106741cbc25cd4227a9fba40dfd0273bfcc1a587aBen Murdoch      REFKNOWNFOLDERID, DWORD, HANDLE, PWSTR*);
7206741cbc25cd4227a9fba40dfd0273bfcc1a587aBen Murdoch  GetKnownFolderPath f = reinterpret_cast<GetKnownFolderPath>(
7306741cbc25cd4227a9fba40dfd0273bfcc1a587aBen Murdoch      GetProcAddress(GetModuleHandle(L"shell32.dll"), "SHGetKnownFolderPath"));
743f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen  app::win::ScopedCoMem<wchar_t> path_buf;
7506741cbc25cd4227a9fba40dfd0273bfcc1a587aBen Murdoch  if (f && SUCCEEDED(f(FOLDERID_Downloads, 0, NULL, &path_buf))) {
7606741cbc25cd4227a9fba40dfd0273bfcc1a587aBen Murdoch    *result = FilePath(std::wstring(path_buf));
7706741cbc25cd4227a9fba40dfd0273bfcc1a587aBen Murdoch    return true;
7806741cbc25cd4227a9fba40dfd0273bfcc1a587aBen Murdoch  }
7906741cbc25cd4227a9fba40dfd0273bfcc1a587aBen Murdoch  return GetUserDownloadsDirectorySafe(result);
8006741cbc25cd4227a9fba40dfd0273bfcc1a587aBen Murdoch}
8106741cbc25cd4227a9fba40dfd0273bfcc1a587aBen Murdoch
8206741cbc25cd4227a9fba40dfd0273bfcc1a587aBen Murdochbool GetUserDesktop(FilePath* result) {
8306741cbc25cd4227a9fba40dfd0273bfcc1a587aBen Murdoch  // We need to go compute the value. It would be nice to support paths
8406741cbc25cd4227a9fba40dfd0273bfcc1a587aBen Murdoch  // with names longer than MAX_PATH, but the system functions don't seem
8506741cbc25cd4227a9fba40dfd0273bfcc1a587aBen Murdoch  // to be designed for it either, with the exception of GetTempPath
8606741cbc25cd4227a9fba40dfd0273bfcc1a587aBen Murdoch  // (but other things will surely break if the temp path is too long,
8706741cbc25cd4227a9fba40dfd0273bfcc1a587aBen Murdoch  // so we don't bother handling it.
8806741cbc25cd4227a9fba40dfd0273bfcc1a587aBen Murdoch  wchar_t system_buffer[MAX_PATH];
8906741cbc25cd4227a9fba40dfd0273bfcc1a587aBen Murdoch  system_buffer[0] = 0;
9006741cbc25cd4227a9fba40dfd0273bfcc1a587aBen Murdoch  if (FAILED(SHGetFolderPath(NULL, CSIDL_DESKTOPDIRECTORY, NULL,
9106741cbc25cd4227a9fba40dfd0273bfcc1a587aBen Murdoch                             SHGFP_TYPE_CURRENT, system_buffer)))
9206741cbc25cd4227a9fba40dfd0273bfcc1a587aBen Murdoch    return false;
9306741cbc25cd4227a9fba40dfd0273bfcc1a587aBen Murdoch  *result = FilePath(system_buffer);
9406741cbc25cd4227a9fba40dfd0273bfcc1a587aBen Murdoch  return true;
9506741cbc25cd4227a9fba40dfd0273bfcc1a587aBen Murdoch}
9606741cbc25cd4227a9fba40dfd0273bfcc1a587aBen Murdoch
9706741cbc25cd4227a9fba40dfd0273bfcc1a587aBen Murdoch}  // namespace chrome
98