• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 // Copyright (c) 2010 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/windows_version.h"
14 
15 // http://blogs.msdn.com/oldnewthing/archive/2004/10/25/247180.aspx
16 extern "C" IMAGE_DOS_HEADER __ImageBase;
17 
18 namespace base {
19 
PathProviderWin(int key,FilePath * result)20 bool 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   switch (key) {
32     case base::FILE_EXE:
33       GetModuleFileName(NULL, system_buffer, MAX_PATH);
34       cur = FilePath(system_buffer);
35       break;
36     case base::FILE_MODULE: {
37       // the resource containing module is assumed to be the one that
38       // this code lives in, whether that's a dll or exe
39       HMODULE this_module = reinterpret_cast<HMODULE>(&__ImageBase);
40       GetModuleFileName(this_module, system_buffer, MAX_PATH);
41       cur = FilePath(system_buffer);
42       break;
43     }
44     case base::DIR_WINDOWS:
45       GetWindowsDirectory(system_buffer, MAX_PATH);
46       cur = FilePath(system_buffer);
47       break;
48     case base::DIR_SYSTEM:
49       GetSystemDirectory(system_buffer, MAX_PATH);
50       cur = FilePath(system_buffer);
51       break;
52     case base::DIR_PROGRAM_FILES:
53       if (FAILED(SHGetFolderPath(NULL, CSIDL_PROGRAM_FILES, NULL,
54                                  SHGFP_TYPE_CURRENT, system_buffer)))
55         return false;
56       cur = FilePath(system_buffer);
57       break;
58     case base::DIR_IE_INTERNET_CACHE:
59       if (FAILED(SHGetFolderPath(NULL, CSIDL_INTERNET_CACHE, NULL,
60                                  SHGFP_TYPE_CURRENT, system_buffer)))
61         return false;
62       cur = FilePath(system_buffer);
63       break;
64     case base::DIR_COMMON_START_MENU:
65       if (FAILED(SHGetFolderPath(NULL, CSIDL_COMMON_PROGRAMS, NULL,
66                                  SHGFP_TYPE_CURRENT, system_buffer)))
67         return false;
68       cur = FilePath(system_buffer);
69       break;
70     case base::DIR_START_MENU:
71       if (FAILED(SHGetFolderPath(NULL, CSIDL_PROGRAMS, NULL,
72                                  SHGFP_TYPE_CURRENT, system_buffer)))
73         return false;
74       cur = FilePath(system_buffer);
75       break;
76     case base::DIR_APP_DATA:
77       if (FAILED(SHGetFolderPath(NULL, CSIDL_APPDATA, NULL, SHGFP_TYPE_CURRENT,
78                                  system_buffer)))
79         return false;
80       cur = FilePath(system_buffer);
81       break;
82     case base::DIR_PROFILE:
83       if (FAILED(SHGetFolderPath(NULL, CSIDL_PROFILE, NULL, SHGFP_TYPE_CURRENT,
84                                  system_buffer)))
85         return false;
86       cur = FilePath(system_buffer);
87       break;
88     case base::DIR_LOCAL_APP_DATA_LOW:
89       if (win::GetVersion() < win::VERSION_VISTA) {
90         return false;
91       }
92       // TODO(nsylvain): We should use SHGetKnownFolderPath instead. Bug 1281128
93       if (FAILED(SHGetFolderPath(NULL, CSIDL_APPDATA, NULL, SHGFP_TYPE_CURRENT,
94                                  system_buffer)))
95         return false;
96       cur = FilePath(system_buffer).DirName().AppendASCII("LocalLow");
97       break;
98     case base::DIR_LOCAL_APP_DATA:
99       if (FAILED(SHGetFolderPath(NULL, CSIDL_LOCAL_APPDATA, NULL,
100                                  SHGFP_TYPE_CURRENT, system_buffer)))
101         return false;
102       cur = FilePath(system_buffer);
103       break;
104     case base::DIR_SOURCE_ROOT: {
105       FilePath executableDir;
106       // On Windows, unit tests execute two levels deep from the source root.
107       // For example:  chrome/{Debug|Release}/ui_tests.exe
108       PathService::Get(base::DIR_EXE, &executableDir);
109       cur = executableDir.DirName().DirName();
110       FilePath checkedPath =
111           cur.Append(FILE_PATH_LITERAL("base/base_paths_win.cc"));
112       if (!file_util::PathExists(checkedPath)) {
113         // Check for WebKit-only checkout. Executable files are put into
114         // WebKit/WebKit/chromium/{Debug|Relese}, and we should return
115         // WebKit/WebKit/chromium.
116         cur = executableDir.DirName();
117       }
118       break;
119     }
120     default:
121       return false;
122   }
123 
124   *result = cur;
125   return true;
126 }
127 
128 }  // namespace base
129