| OLD | NEW |
| (Empty) |
| 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. | |
| 4 | |
| 5 #include <windows.h> | |
| 6 #include <shlobj.h> | |
| 7 | |
| 8 #include "base/base_paths.h" | |
| 9 #include "base/environment.h" | |
| 10 #include "base/files/file_path.h" | |
| 11 #include "base/path_service.h" | |
| 12 #include "base/strings/utf_string_conversions.h" | |
| 13 #include "base/win/scoped_co_mem.h" | |
| 14 #include "base/win/windows_version.h" | |
| 15 | |
| 16 // http://blogs.msdn.com/oldnewthing/archive/2004/10/25/247180.aspx | |
| 17 extern "C" IMAGE_DOS_HEADER __ImageBase; | |
| 18 | |
| 19 using base::FilePath; | |
| 20 | |
| 21 namespace base { | |
| 22 | |
| 23 bool PathProviderWin(int key, FilePath* result) { | |
| 24 // We need to go compute the value. It would be nice to support paths with | |
| 25 // names longer than MAX_PATH, but the system functions don't seem to be | |
| 26 // designed for it either, with the exception of GetTempPath (but other | |
| 27 // things will surely break if the temp path is too long, so we don't bother | |
| 28 // handling it. | |
| 29 wchar_t system_buffer[MAX_PATH]; | |
| 30 system_buffer[0] = 0; | |
| 31 | |
| 32 FilePath cur; | |
| 33 switch (key) { | |
| 34 case base::FILE_EXE: | |
| 35 if (GetModuleFileName(NULL, system_buffer, MAX_PATH) == 0) | |
| 36 return false; | |
| 37 cur = FilePath(system_buffer); | |
| 38 break; | |
| 39 case base::FILE_MODULE: { | |
| 40 // the resource containing module is assumed to be the one that | |
| 41 // this code lives in, whether that's a dll or exe | |
| 42 HMODULE this_module = reinterpret_cast<HMODULE>(&__ImageBase); | |
| 43 if (GetModuleFileName(this_module, system_buffer, MAX_PATH) == 0) | |
| 44 return false; | |
| 45 cur = FilePath(system_buffer); | |
| 46 break; | |
| 47 } | |
| 48 case base::DIR_WINDOWS: | |
| 49 GetWindowsDirectory(system_buffer, MAX_PATH); | |
| 50 cur = FilePath(system_buffer); | |
| 51 break; | |
| 52 case base::DIR_SYSTEM: | |
| 53 GetSystemDirectory(system_buffer, MAX_PATH); | |
| 54 cur = FilePath(system_buffer); | |
| 55 break; | |
| 56 case base::DIR_PROGRAM_FILESX86: | |
| 57 if (base::win::OSInfo::GetInstance()->architecture() != | |
| 58 base::win::OSInfo::X86_ARCHITECTURE) { | |
| 59 if (FAILED(SHGetFolderPath(NULL, CSIDL_PROGRAM_FILESX86, NULL, | |
| 60 SHGFP_TYPE_CURRENT, system_buffer))) | |
| 61 return false; | |
| 62 cur = FilePath(system_buffer); | |
| 63 break; | |
| 64 } | |
| 65 // Fall through to base::DIR_PROGRAM_FILES if we're on an X86 machine. | |
| 66 case base::DIR_PROGRAM_FILES: | |
| 67 if (FAILED(SHGetFolderPath(NULL, CSIDL_PROGRAM_FILES, NULL, | |
| 68 SHGFP_TYPE_CURRENT, system_buffer))) | |
| 69 return false; | |
| 70 cur = FilePath(system_buffer); | |
| 71 break; | |
| 72 case base::DIR_PROGRAM_FILES6432: | |
| 73 #if !defined(_WIN64) | |
| 74 if (base::win::OSInfo::GetInstance()->wow64_status() == | |
| 75 base::win::OSInfo::WOW64_ENABLED) { | |
| 76 scoped_ptr<base::Environment> env(base::Environment::Create()); | |
| 77 std::string programfiles_w6432; | |
| 78 // 32-bit process running in WOW64 sets ProgramW6432 environment | |
| 79 // variable. See | |
| 80 // https://msdn.microsoft.com/library/windows/desktop/aa384274.aspx. | |
| 81 if (!env->GetVar("ProgramW6432", &programfiles_w6432)) | |
| 82 return false; | |
| 83 // GetVar returns UTF8 - convert back to Wide. | |
| 84 cur = FilePath(UTF8ToWide(programfiles_w6432)); | |
| 85 break; | |
| 86 } | |
| 87 #endif | |
| 88 if (FAILED(SHGetFolderPath(NULL, CSIDL_PROGRAM_FILES, NULL, | |
| 89 SHGFP_TYPE_CURRENT, system_buffer))) | |
| 90 return false; | |
| 91 cur = FilePath(system_buffer); | |
| 92 break; | |
| 93 case base::DIR_IE_INTERNET_CACHE: | |
| 94 if (FAILED(SHGetFolderPath(NULL, CSIDL_INTERNET_CACHE, NULL, | |
| 95 SHGFP_TYPE_CURRENT, system_buffer))) | |
| 96 return false; | |
| 97 cur = FilePath(system_buffer); | |
| 98 break; | |
| 99 case base::DIR_COMMON_START_MENU: | |
| 100 if (FAILED(SHGetFolderPath(NULL, CSIDL_COMMON_PROGRAMS, NULL, | |
| 101 SHGFP_TYPE_CURRENT, system_buffer))) | |
| 102 return false; | |
| 103 cur = FilePath(system_buffer); | |
| 104 break; | |
| 105 case base::DIR_START_MENU: | |
| 106 if (FAILED(SHGetFolderPath(NULL, CSIDL_PROGRAMS, NULL, | |
| 107 SHGFP_TYPE_CURRENT, system_buffer))) | |
| 108 return false; | |
| 109 cur = FilePath(system_buffer); | |
| 110 break; | |
| 111 case base::DIR_APP_DATA: | |
| 112 if (FAILED(SHGetFolderPath(NULL, CSIDL_APPDATA, NULL, SHGFP_TYPE_CURRENT, | |
| 113 system_buffer))) | |
| 114 return false; | |
| 115 cur = FilePath(system_buffer); | |
| 116 break; | |
| 117 case base::DIR_COMMON_APP_DATA: | |
| 118 if (FAILED(SHGetFolderPath(NULL, CSIDL_COMMON_APPDATA, NULL, | |
| 119 SHGFP_TYPE_CURRENT, system_buffer))) | |
| 120 return false; | |
| 121 cur = FilePath(system_buffer); | |
| 122 break; | |
| 123 case base::DIR_LOCAL_APP_DATA: | |
| 124 if (FAILED(SHGetFolderPath(NULL, CSIDL_LOCAL_APPDATA, NULL, | |
| 125 SHGFP_TYPE_CURRENT, system_buffer))) | |
| 126 return false; | |
| 127 cur = FilePath(system_buffer); | |
| 128 break; | |
| 129 case base::DIR_SOURCE_ROOT: { | |
| 130 FilePath executableDir; | |
| 131 // On Windows, unit tests execute two levels deep from the source root. | |
| 132 // For example: chrome/{Debug|Release}/ui_tests.exe | |
| 133 PathService::Get(base::DIR_EXE, &executableDir); | |
| 134 cur = executableDir.DirName().DirName(); | |
| 135 break; | |
| 136 } | |
| 137 case base::DIR_APP_SHORTCUTS: { | |
| 138 if (win::GetVersion() < win::VERSION_WIN8) | |
| 139 return false; | |
| 140 | |
| 141 base::win::ScopedCoMem<wchar_t> path_buf; | |
| 142 if (FAILED(SHGetKnownFolderPath(FOLDERID_ApplicationShortcuts, 0, NULL, | |
| 143 &path_buf))) | |
| 144 return false; | |
| 145 | |
| 146 cur = FilePath(string16(path_buf)); | |
| 147 break; | |
| 148 } | |
| 149 case base::DIR_USER_DESKTOP: | |
| 150 if (FAILED(SHGetFolderPath(NULL, CSIDL_DESKTOPDIRECTORY, NULL, | |
| 151 SHGFP_TYPE_CURRENT, system_buffer))) { | |
| 152 return false; | |
| 153 } | |
| 154 cur = FilePath(system_buffer); | |
| 155 break; | |
| 156 case base::DIR_COMMON_DESKTOP: | |
| 157 if (FAILED(SHGetFolderPath(NULL, CSIDL_COMMON_DESKTOPDIRECTORY, NULL, | |
| 158 SHGFP_TYPE_CURRENT, system_buffer))) { | |
| 159 return false; | |
| 160 } | |
| 161 cur = FilePath(system_buffer); | |
| 162 break; | |
| 163 case base::DIR_USER_QUICK_LAUNCH: | |
| 164 if (!PathService::Get(base::DIR_APP_DATA, &cur)) | |
| 165 return false; | |
| 166 // According to various sources, appending | |
| 167 // "Microsoft\Internet Explorer\Quick Launch" to %appdata% is the only | |
| 168 // reliable way to get the quick launch folder across all versions of | |
| 169 // Windows. | |
| 170 // http://stackoverflow.com/questions/76080/how-do-you-reliably-get-the-qu
ick- | |
| 171 // http://www.microsoft.com/technet/scriptcenter/resources/qanda/sept05/he
y0901.mspx | |
| 172 cur = cur.AppendASCII("Microsoft") | |
| 173 .AppendASCII("Internet Explorer") | |
| 174 .AppendASCII("Quick Launch"); | |
| 175 break; | |
| 176 case base::DIR_TASKBAR_PINS: | |
| 177 if (!PathService::Get(base::DIR_USER_QUICK_LAUNCH, &cur)) | |
| 178 return false; | |
| 179 cur = cur.AppendASCII("User Pinned"); | |
| 180 cur = cur.AppendASCII("TaskBar"); | |
| 181 break; | |
| 182 case base::DIR_WINDOWS_FONTS: | |
| 183 if (FAILED(SHGetFolderPath( | |
| 184 NULL, CSIDL_FONTS, NULL, SHGFP_TYPE_CURRENT, system_buffer))) { | |
| 185 return false; | |
| 186 } | |
| 187 cur = FilePath(system_buffer); | |
| 188 break; | |
| 189 default: | |
| 190 return false; | |
| 191 } | |
| 192 | |
| 193 *result = cur; | |
| 194 return true; | |
| 195 } | |
| 196 | |
| 197 } // namespace base | |
| OLD | NEW |