Separate Simple Backend creation from initialization.
[chromium-blink-merge.git] / base / base_paths_win.cc
blobf4dd434349d89ff222c73986dee5ac8c4e5400e7
1 // Copyright (c) 2012 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.
6 #include <windows.h>
7 #include <shlobj.h>
9 #include "base/base_paths.h"
10 #include "base/file_util.h"
11 #include "base/files/file_path.h"
12 #include "base/path_service.h"
13 #include "base/win/scoped_co_mem.h"
14 #include "base/win/windows_version.h"
16 // http://blogs.msdn.com/oldnewthing/archive/2004/10/25/247180.aspx
17 extern "C" IMAGE_DOS_HEADER __ImageBase;
19 using base::FilePath;
21 namespace {
23 bool GetQuickLaunchPath(bool default_user, FilePath* result) {
24 if (default_user) {
25 wchar_t system_buffer[MAX_PATH];
26 system_buffer[0] = 0;
27 // As per MSDN, passing -1 for |hToken| indicates the Default user:
28 // http://msdn.microsoft.com/library/windows/desktop/bb762181.aspx
29 if (FAILED(SHGetFolderPath(NULL, CSIDL_APPDATA,
30 reinterpret_cast<HANDLE>(-1), SHGFP_TYPE_CURRENT,
31 system_buffer))) {
32 return false;
34 *result = FilePath(system_buffer);
35 } else if (!PathService::Get(base::DIR_APP_DATA, result)) {
36 // For the current user, grab the APPDATA directory directly from the
37 // PathService cache.
38 return false;
40 // According to various sources, appending
41 // "Microsoft\Internet Explorer\Quick Launch" to %appdata% is the only
42 // reliable way to get the quick launch folder across all versions of Windows.
43 // http://stackoverflow.com/questions/76080/how-do-you-reliably-get-the-quick-
44 // http://www.microsoft.com/technet/scriptcenter/resources/qanda/sept05/hey0901.mspx
45 *result = result->AppendASCII("Microsoft");
46 *result = result->AppendASCII("Internet Explorer");
47 *result = result->AppendASCII("Quick Launch");
48 return true;
51 } // namespace
53 namespace base {
55 bool PathProviderWin(int key, FilePath* result) {
57 // We need to go compute the value. It would be nice to support paths with
58 // names longer than MAX_PATH, but the system functions don't seem to be
59 // designed for it either, with the exception of GetTempPath (but other
60 // things will surely break if the temp path is too long, so we don't bother
61 // handling it.
62 wchar_t system_buffer[MAX_PATH];
63 system_buffer[0] = 0;
65 FilePath cur;
66 switch (key) {
67 case base::FILE_EXE:
68 GetModuleFileName(NULL, system_buffer, MAX_PATH);
69 cur = FilePath(system_buffer);
70 break;
71 case base::FILE_MODULE: {
72 // the resource containing module is assumed to be the one that
73 // this code lives in, whether that's a dll or exe
74 HMODULE this_module = reinterpret_cast<HMODULE>(&__ImageBase);
75 GetModuleFileName(this_module, system_buffer, MAX_PATH);
76 cur = FilePath(system_buffer);
77 break;
79 case base::DIR_WINDOWS:
80 GetWindowsDirectory(system_buffer, MAX_PATH);
81 cur = FilePath(system_buffer);
82 break;
83 case base::DIR_SYSTEM:
84 GetSystemDirectory(system_buffer, MAX_PATH);
85 cur = FilePath(system_buffer);
86 break;
87 case base::DIR_PROGRAM_FILESX86:
88 if (base::win::OSInfo::GetInstance()->architecture() !=
89 base::win::OSInfo::X86_ARCHITECTURE) {
90 if (FAILED(SHGetFolderPath(NULL, CSIDL_PROGRAM_FILESX86, NULL,
91 SHGFP_TYPE_CURRENT, system_buffer)))
92 return false;
93 cur = FilePath(system_buffer);
94 break;
96 // Fall through to base::DIR_PROGRAM_FILES if we're on an X86 machine.
97 case base::DIR_PROGRAM_FILES:
98 if (FAILED(SHGetFolderPath(NULL, CSIDL_PROGRAM_FILES, NULL,
99 SHGFP_TYPE_CURRENT, system_buffer)))
100 return false;
101 cur = FilePath(system_buffer);
102 break;
103 case base::DIR_IE_INTERNET_CACHE:
104 if (FAILED(SHGetFolderPath(NULL, CSIDL_INTERNET_CACHE, NULL,
105 SHGFP_TYPE_CURRENT, system_buffer)))
106 return false;
107 cur = FilePath(system_buffer);
108 break;
109 case base::DIR_COMMON_START_MENU:
110 if (FAILED(SHGetFolderPath(NULL, CSIDL_COMMON_PROGRAMS, NULL,
111 SHGFP_TYPE_CURRENT, system_buffer)))
112 return false;
113 cur = FilePath(system_buffer);
114 break;
115 case base::DIR_START_MENU:
116 if (FAILED(SHGetFolderPath(NULL, CSIDL_PROGRAMS, NULL,
117 SHGFP_TYPE_CURRENT, system_buffer)))
118 return false;
119 cur = FilePath(system_buffer);
120 break;
121 case base::DIR_APP_DATA:
122 if (FAILED(SHGetFolderPath(NULL, CSIDL_APPDATA, NULL, SHGFP_TYPE_CURRENT,
123 system_buffer)))
124 return false;
125 cur = FilePath(system_buffer);
126 break;
127 case base::DIR_COMMON_APP_DATA:
128 if (FAILED(SHGetFolderPath(NULL, CSIDL_COMMON_APPDATA, NULL,
129 SHGFP_TYPE_CURRENT, system_buffer)))
130 return false;
131 cur = FilePath(system_buffer);
132 break;
133 case base::DIR_PROFILE:
134 if (FAILED(SHGetFolderPath(NULL, CSIDL_PROFILE, NULL, SHGFP_TYPE_CURRENT,
135 system_buffer)))
136 return false;
137 cur = FilePath(system_buffer);
138 break;
139 case base::DIR_LOCAL_APP_DATA_LOW:
140 if (win::GetVersion() < win::VERSION_VISTA)
141 return false;
143 // TODO(nsylvain): We should use SHGetKnownFolderPath instead. Bug 1281128
144 if (FAILED(SHGetFolderPath(NULL, CSIDL_APPDATA, NULL, SHGFP_TYPE_CURRENT,
145 system_buffer)))
146 return false;
147 cur = FilePath(system_buffer).DirName().AppendASCII("LocalLow");
148 break;
149 case base::DIR_LOCAL_APP_DATA:
150 if (FAILED(SHGetFolderPath(NULL, CSIDL_LOCAL_APPDATA, NULL,
151 SHGFP_TYPE_CURRENT, system_buffer)))
152 return false;
153 cur = FilePath(system_buffer);
154 break;
155 case base::DIR_SOURCE_ROOT: {
156 FilePath executableDir;
157 // On Windows, unit tests execute two levels deep from the source root.
158 // For example: chrome/{Debug|Release}/ui_tests.exe
159 PathService::Get(base::DIR_EXE, &executableDir);
160 cur = executableDir.DirName().DirName();
161 break;
163 case base::DIR_APP_SHORTCUTS: {
164 if (win::GetVersion() < win::VERSION_WIN8)
165 return false;
167 base::win::ScopedCoMem<wchar_t> path_buf;
168 if (FAILED(SHGetKnownFolderPath(FOLDERID_ApplicationShortcuts, 0, NULL,
169 &path_buf)))
170 return false;
172 cur = FilePath(string16(path_buf));
173 break;
175 case base::DIR_USER_DESKTOP:
176 if (FAILED(SHGetFolderPath(NULL, CSIDL_DESKTOPDIRECTORY, NULL,
177 SHGFP_TYPE_CURRENT, system_buffer))) {
178 return false;
180 cur = FilePath(system_buffer);
181 break;
182 case base::DIR_COMMON_DESKTOP:
183 if (FAILED(SHGetFolderPath(NULL, CSIDL_COMMON_DESKTOPDIRECTORY, NULL,
184 SHGFP_TYPE_CURRENT, system_buffer))) {
185 return false;
187 cur = FilePath(system_buffer);
188 break;
189 case base::DIR_USER_QUICK_LAUNCH:
190 if (!GetQuickLaunchPath(false, &cur))
191 return false;
192 break;
193 case base::DIR_DEFAULT_USER_QUICK_LAUNCH:
194 if (!GetQuickLaunchPath(true, &cur))
195 return false;
196 break;
197 case base::DIR_TASKBAR_PINS:
198 if (!PathService::Get(base::DIR_USER_QUICK_LAUNCH, &cur))
199 return false;
200 cur = cur.AppendASCII("User Pinned");
201 cur = cur.AppendASCII("TaskBar");
202 break;
203 default:
204 return false;
207 *result = cur;
208 return true;
211 } // namespace base