base_paths_win.cc revision c7f5f8508d98d5952d42ed7648c2a8f30a4da156
1// Copyright (c) 2006-2008 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 "base/base_paths_win.h" 6 7#include <windows.h> 8#include <shlobj.h> 9 10#include "base/file_path.h" 11#include "base/file_util.h" 12#include "base/path_service.h" 13#include "base/win_util.h" 14 15// http://blogs.msdn.com/oldnewthing/archive/2004/10/25/247180.aspx 16extern "C" IMAGE_DOS_HEADER __ImageBase; 17 18namespace base { 19 20bool PathProviderWin(int key, FilePath* result) { 21 22 // We need to go compute the value. It would be nice to support paths with 23 // names longer than MAX_PATH, but the system functions don't seem to be 24 // designed for it either, with the exception of GetTempPath (but other 25 // things will surely break if the temp path is too long, so we don't bother 26 // handling it. 27 wchar_t system_buffer[MAX_PATH]; 28 system_buffer[0] = 0; 29 30 FilePath cur; 31 std::wstring wstring_path; 32 switch (key) { 33 case base::FILE_EXE: 34 GetModuleFileName(NULL, system_buffer, MAX_PATH); 35 cur = FilePath(system_buffer); 36 break; 37 case base::FILE_MODULE: { 38 // the resource containing module is assumed to be the one that 39 // this code lives in, whether that's a dll or exe 40 HMODULE this_module = reinterpret_cast<HMODULE>(&__ImageBase); 41 GetModuleFileName(this_module, system_buffer, MAX_PATH); 42 cur = FilePath(system_buffer); 43 break; 44 } 45 case base::DIR_WINDOWS: 46 GetWindowsDirectory(system_buffer, MAX_PATH); 47 cur = FilePath(system_buffer); 48 break; 49 case base::DIR_SYSTEM: 50 GetSystemDirectory(system_buffer, MAX_PATH); 51 cur = FilePath(system_buffer); 52 break; 53 case base::DIR_PROGRAM_FILES: 54 if (FAILED(SHGetFolderPath(NULL, CSIDL_PROGRAM_FILES, NULL, 55 SHGFP_TYPE_CURRENT, system_buffer))) 56 return false; 57 cur = FilePath(system_buffer); 58 break; 59 case base::DIR_IE_INTERNET_CACHE: 60 if (FAILED(SHGetFolderPath(NULL, CSIDL_INTERNET_CACHE, NULL, 61 SHGFP_TYPE_CURRENT, system_buffer))) 62 return false; 63 cur = FilePath(system_buffer); 64 break; 65 case base::DIR_COMMON_START_MENU: 66 if (FAILED(SHGetFolderPath(NULL, CSIDL_COMMON_PROGRAMS, NULL, 67 SHGFP_TYPE_CURRENT, system_buffer))) 68 return false; 69 cur = FilePath(system_buffer); 70 break; 71 case base::DIR_START_MENU: 72 if (FAILED(SHGetFolderPath(NULL, CSIDL_PROGRAMS, NULL, 73 SHGFP_TYPE_CURRENT, system_buffer))) 74 return false; 75 cur = FilePath(system_buffer); 76 break; 77 case base::DIR_APP_DATA: 78 if (FAILED(SHGetFolderPath(NULL, CSIDL_APPDATA, NULL, SHGFP_TYPE_CURRENT, 79 system_buffer))) 80 return false; 81 cur = FilePath(system_buffer); 82 break; 83 case base::DIR_PROFILE: 84 if (FAILED(SHGetFolderPath(NULL, CSIDL_PROFILE, NULL, SHGFP_TYPE_CURRENT, 85 system_buffer))) 86 return false; 87 cur = FilePath(system_buffer); 88 break; 89 case base::DIR_LOCAL_APP_DATA_LOW: 90 if (win_util::GetWinVersion() < win_util::WINVERSION_VISTA) { 91 return false; 92 } 93 // TODO(nsylvain): We should use SHGetKnownFolderPath instead. Bug 1281128 94 if (FAILED(SHGetFolderPath(NULL, CSIDL_APPDATA, NULL, SHGFP_TYPE_CURRENT, 95 system_buffer))) 96 return false; 97 wstring_path = system_buffer; 98 file_util::UpOneDirectory(&wstring_path); 99 file_util::AppendToPath(&wstring_path, L"LocalLow"); 100 cur = FilePath(wstring_path); 101 break; 102 case base::DIR_LOCAL_APP_DATA: 103 if (FAILED(SHGetFolderPath(NULL, CSIDL_LOCAL_APPDATA, NULL, 104 SHGFP_TYPE_CURRENT, system_buffer))) 105 return false; 106 cur = FilePath(system_buffer); 107 break; 108 case base::DIR_SOURCE_ROOT: 109 // On Windows, unit tests execute two levels deep from the source root. 110 // For example: chrome/{Debug|Release}/ui_tests.exe 111 PathService::Get(base::DIR_EXE, &cur); 112 cur = cur.DirName().DirName(); 113 break; 114 default: 115 return false; 116 } 117 118 *result = cur; 119 return true; 120} 121 122} // namespace base 123