blob: 389b0bb64878ee14ad8973c9b4a2e9e32279919c [file] [log] [blame]
initial.commit3f4a7322008-07-27 06:49:38 +09001// Copyright 2008, Google Inc.
2// All rights reserved.
3//
4// Redistribution and use in source and binary forms, with or without
5// modification, are permitted provided that the following conditions are
6// met:
7//
8// * Redistributions of source code must retain the above copyright
9// notice, this list of conditions and the following disclaimer.
10// * Redistributions in binary form must reproduce the above
11// copyright notice, this list of conditions and the following disclaimer
12// in the documentation and/or other materials provided with the
13// distribution.
14// * Neither the name of Google Inc. nor the names of its
15// contributors may be used to endorse or promote products derived from
16// this software without specific prior written permission.
17//
18// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
19// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
20// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
21// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
22// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
23// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
24// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
25// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
26// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
27// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
28// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
29
30#include "base/base_paths.h"
31
32#include <shlobj.h>
33
34#include "base/file_util.h"
35#include "base/path_service.h"
36
37// This is here for the sole purpose of looking up the corresponding HMODULE.
38static int handle_lookup = 0;
39
40namespace base {
41
42bool PathProvider(int key, std::wstring* result) {
43 // NOTE: DIR_CURRENT is a special cased in PathService::Get
44
45 // We need to go compute the value. It would be nice to support paths with
46 // names longer than MAX_PATH, but the system functions don't seem to be
47 // designed for it either, with the exception of GetTempPath (but other
48 // things will surely break if the temp path is too long, so we don't bother
49 // handling it.
50 wchar_t system_buffer[MAX_PATH];
51 system_buffer[0] = 0;
52
53 std::wstring cur;
54 switch (key) {
55 case base::FILE_EXE:
56 GetModuleFileName(NULL, system_buffer, MAX_PATH);
57 cur = system_buffer;
58 break;
59 case base::FILE_MODULE: {
60 // the resource containing module is assumed to be the one that
61 // this code lives in, whether that's a dll or exe
62 MEMORY_BASIC_INFORMATION info = { 0 };
63 VirtualQuery(reinterpret_cast<void*>(&handle_lookup),
64 &info, sizeof(info));
65 // Module handles are just the allocation base address of the module.
66 HMODULE this_module = reinterpret_cast<HMODULE>(info.AllocationBase);
67 GetModuleFileName(this_module, system_buffer, MAX_PATH);
68 cur = system_buffer;
69 break;
70 }
71 case base::DIR_EXE:
72 PathProvider(base::FILE_EXE, &cur);
73 file_util::TrimFilename(&cur);
74 break;
75 case base::DIR_MODULE:
76 PathProvider(base::FILE_MODULE, &cur);
77 file_util::TrimFilename(&cur);
78 break;
79 case base::DIR_TEMP:
80 if (!file_util::GetTempDir(&cur))
81 return false;
82 break;
83 case base::DIR_WINDOWS:
84 GetWindowsDirectory(system_buffer, MAX_PATH);
85 cur = system_buffer;
86 break;
87 case base::DIR_SYSTEM:
88 GetSystemDirectory(system_buffer, MAX_PATH);
89 cur = system_buffer;
90 break;
91 case base::DIR_PROGRAM_FILES:
92 if (FAILED(SHGetFolderPath(NULL, CSIDL_PROGRAM_FILES, NULL,
93 SHGFP_TYPE_CURRENT, system_buffer)))
94 return false;
95 cur = system_buffer;
96 break;
97 case base::DIR_SOURCE_ROOT:
98 // By default, unit tests execute two levels deep from the source root.
99 // For example: chrome/{Debug|Release}/ui_tests.exe
100 PathProvider(base::DIR_EXE, &cur);
101 file_util::UpOneDirectory(&cur);
102 file_util::UpOneDirectory(&cur);
103 break;
104 case base::DIR_APP_DATA:
105 if (FAILED(SHGetFolderPath(NULL, CSIDL_APPDATA, NULL, SHGFP_TYPE_CURRENT,
106 system_buffer)))
107 return false;
108 cur = system_buffer;
109 break;
110 case base::DIR_LOCAL_APP_DATA_LOW:
111 // TODO(nsylvain): We should use SHGetKnownFolderPath instead. Bug 1281128
112 if (FAILED(SHGetFolderPath(NULL, CSIDL_APPDATA, NULL, SHGFP_TYPE_CURRENT,
113 system_buffer)))
114 return false;
115 cur = system_buffer;
116 file_util::UpOneDirectory(&cur);
117 file_util::AppendToPath(&cur, L"LocalLow");
118 break;
119 case base::DIR_LOCAL_APP_DATA:
120 if (FAILED(SHGetFolderPath(NULL, CSIDL_LOCAL_APPDATA, NULL,
121 SHGFP_TYPE_CURRENT, system_buffer)))
122 return false;
123 cur = system_buffer;
124 break;
125 case base::DIR_IE_INTERNET_CACHE:
126 if (FAILED(SHGetFolderPath(NULL, CSIDL_INTERNET_CACHE, NULL,
127 SHGFP_TYPE_CURRENT, system_buffer)))
128 return false;
129 cur = system_buffer;
130 break;
131 case base::DIR_COMMON_START_MENU:
132 if (FAILED(SHGetFolderPath(NULL, CSIDL_COMMON_PROGRAMS, NULL,
133 SHGFP_TYPE_CURRENT, system_buffer)))
134 return false;
135 cur = system_buffer;
136 break;
137 case base::DIR_START_MENU:
138 if (FAILED(SHGetFolderPath(NULL, CSIDL_PROGRAMS, NULL,
139 SHGFP_TYPE_CURRENT, system_buffer)))
140 return false;
141 cur = system_buffer;
142 break;
143 default:
144 return false;
145 }
146
147 result->swap(cur);
148 return true;
149}
150
151} // namespace base