Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(42)

Side by Side Diff: chrome/install_static/install_util.cc

Issue 1913943003: Remove dependencies on chrome\installer from the ChromeCrashReporterClient class on Windows. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Declare common constants in install_util.h and remove dups from chrome_elf_util_unittest.cc Created 4 years, 7 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
1 // Copyright 2014 The Chromium Authors. All rights reserved. 1 // Copyright 2014 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "chrome/install_static/install_util.h" 5 #include "chrome/install_static/install_util.h"
6 6
7 #include <windows.h>
7 #include <assert.h> 8 #include <assert.h>
8 #include <windows.h> 9 #include <memory>
9 #include <stddef.h>
10 10
11 #include "base/macros.h" 11 #include "base/macros.h"
12 #include "base/strings/string16.h" 12 #include "build/build_config.h"
13
14 namespace install_static {
13 15
14 ProcessType g_process_type = ProcessType::UNINITIALIZED; 16 ProcessType g_process_type = ProcessType::UNINITIALIZED;
15 17
16 namespace { 18 // TODO(ananta)
19 // http://crbug.com/604923
20 // The constants defined in this file are also defined in chrome/installer and
21 // other places. we need to unify them.
17 22
23 // Chrome channel display names.
24 const wchar_t kChromeChannelUnknown[] = L"unknown";
25 const wchar_t kChromeChannelCanary[] = L"canary";
26 const wchar_t kChromeChannelDev[] = L"dev";
27 const wchar_t kChromeChannelBeta[] = L"beta";
28 const wchar_t kChromeChannelStable[] = L"";
29 const wchar_t kChromeChannelStableExplicit[] = L"stable";
30
31
32 #if defined(GOOGLE_CHROME_BUILD)
18 const wchar_t kRegPathClientState[] = L"Software\\Google\\Update\\ClientState"; 33 const wchar_t kRegPathClientState[] = L"Software\\Google\\Update\\ClientState";
19 const wchar_t kRegPathClientStateMedium[] = 34 const wchar_t kRegPathClientStateMedium[] =
20 L"Software\\Google\\Update\\ClientStateMedium"; 35 L"Software\\Google\\Update\\ClientStateMedium";
21 #if defined(GOOGLE_CHROME_BUILD)
22 const wchar_t kRegPathChromePolicy[] = L"SOFTWARE\\Policies\\Google\\Chrome"; 36 const wchar_t kRegPathChromePolicy[] = L"SOFTWARE\\Policies\\Google\\Chrome";
37 const wchar_t kRegApField[] = L"ap";
23 #else 38 #else
39 const wchar_t kRegPathClientState[] =
40 L"Software\\Chromium\\Update\\ClientState";
41 const wchar_t kRegPathClientStateMedium[] =
42 L"Software\\Chromium\\Update\\ClientStateMedium";
24 const wchar_t kRegPathChromePolicy[] = L"SOFTWARE\\Policies\\Chromium"; 43 const wchar_t kRegPathChromePolicy[] = L"SOFTWARE\\Policies\\Chromium";
25 #endif // defined(GOOGLE_CHROME_BUILD) 44 #endif
26 45
27 const wchar_t kRegValueUsageStats[] = L"usagestats"; 46 const wchar_t kRegValueUsageStats[] = L"usagestats";
28 const wchar_t kUninstallArgumentsField[] = L"UninstallArguments"; 47 const wchar_t kUninstallArgumentsField[] = L"UninstallArguments";
29 const wchar_t kMetricsReportingEnabled[] = L"MetricsReportingEnabled"; 48 const wchar_t kMetricsReportingEnabled[] = L"MetricsReportingEnabled";
30 49
31 const wchar_t kAppGuidCanary[] = 50 const wchar_t kAppGuidCanary[] =
32 L"{4ea16ac7-fd5a-47c3-875b-dbf4a2008c20}"; 51 L"{4ea16ac7-fd5a-47c3-875b-dbf4a2008c20}";
33 const wchar_t kAppGuidGoogleChrome[] = 52 const wchar_t kAppGuidGoogleChrome[] =
34 L"{8A69D345-D564-463c-AFF1-A69D9E530F96}"; 53 L"{8A69D345-D564-463c-AFF1-A69D9E530F96}";
35 const wchar_t kAppGuidGoogleBinaries[] = 54 const wchar_t kAppGuidGoogleBinaries[] =
36 L"{4DC8B4CA-1BDA-483e-B5FA-D3C12E15B62D}"; 55 L"{4DC8B4CA-1BDA-483e-B5FA-D3C12E15B62D}";
37 56
57 namespace {
58
59 // TODO(ananta)
60 // http://crbug.com/604923
61 // These constants are defined in the chrome/installer directory as well. We
62 // need to unify them.
63 #if defined(GOOGLE_CHROME_BUILD)
64 const wchar_t kSxSSuffix[] = L" SxS";
65 const wchar_t kGoogleChromeInstallSubDir1[] = L"Google";
66 const wchar_t kGoogleChromeInstallSubDir2[] = L"Chrome";
67 #else
68 const wchar_t kChromiumInstallSubDir[] = L"Chromium";
69 #endif // defined(GOOGLE_CHROME_BUILD)
70
71 const wchar_t kUserDataDirname[] = L"User Data";
72 const wchar_t kBrowserCrashDumpMetricsSubKey[] = L"\\BrowserCrashDumpAttempts";
73
74 const wchar_t kRegPathGoogleUpdate[] = L"Software\\Google\\Update";
75 const wchar_t kRegGoogleUpdateVersion[] = L"version";
76
77 void Trace(const wchar_t* format_string, ...) {
78 static const int kMaxLogBufferSize = 1024;
79 static wchar_t buffer[kMaxLogBufferSize] = {};
80
81 va_list args = {};
82
83 va_start(args, format_string);
84 vswprintf(buffer, arraysize(buffer), format_string, args);
85 OutputDebugString(buffer);
86 va_end(args);
87 }
88
89 // Reads a string value identified by |value_to_read| from the registry path
90 // under |key_path|. We look in HKLM or HKCU depending on whether the
91 // |system_install| parameter is true.
92 // Please note that this function only looks in the 32bit view of the registry.
38 bool ReadKeyValueString(bool system_install, const wchar_t* key_path, 93 bool ReadKeyValueString(bool system_install, const wchar_t* key_path,
39 const wchar_t* guid, const wchar_t* value_to_read, 94 const wchar_t* guid, const wchar_t* value_to_read,
40 base::string16* value_out) { 95 base::string16* value_out) {
41 HKEY key = NULL; 96 HKEY key = NULL;
42 value_out->clear(); 97 value_out->clear();
43 98
44 base::string16 full_key_path(key_path); 99 base::string16 full_key_path(key_path);
45 full_key_path.append(1, L'\\'); 100 if (guid && *guid) {
46 full_key_path.append(guid); 101 full_key_path.append(1, L'\\');
102 full_key_path.append(guid);
103 }
47 104
48 if (::RegOpenKeyEx(system_install ? HKEY_LOCAL_MACHINE : HKEY_CURRENT_USER, 105 if (::RegOpenKeyEx(system_install ? HKEY_LOCAL_MACHINE : HKEY_CURRENT_USER,
49 full_key_path.c_str(), 0, 106 full_key_path.c_str(), 0,
50 KEY_QUERY_VALUE | KEY_WOW64_32KEY, &key) != 107 KEY_QUERY_VALUE | KEY_WOW64_32KEY, &key) !=
51 ERROR_SUCCESS) { 108 ERROR_SUCCESS) {
52 return false; 109 return false;
53 } 110 }
54 111
55 const size_t kMaxStringLength = 1024; 112 const size_t kMaxStringLength = 1024;
56 wchar_t raw_value[kMaxStringLength] = {}; 113 wchar_t raw_value[kMaxStringLength] = {};
(...skipping 16 matching lines...) Expand all
73 } 130 }
74 131
75 if (result == ERROR_SUCCESS) 132 if (result == ERROR_SUCCESS)
76 *value_out = raw_value; 133 *value_out = raw_value;
77 134
78 ::RegCloseKey(key); 135 ::RegCloseKey(key);
79 136
80 return result == ERROR_SUCCESS; 137 return result == ERROR_SUCCESS;
81 } 138 }
82 139
140 // Reads a DWORD value identified by |value_to_read| from the registry path
141 // under |key_path|. We look in HKLM or HKCU depending on whether the
142 // |system_install| parameter is true.
143 // Please note that this function only looks in the 32bit view of the registry.
83 bool ReadKeyValueDW(bool system_install, const wchar_t* key_path, 144 bool ReadKeyValueDW(bool system_install, const wchar_t* key_path,
84 base::string16 guid, const wchar_t* value_to_read, 145 base::string16 guid, const wchar_t* value_to_read,
85 DWORD* value_out) { 146 DWORD* value_out) {
86 HKEY key = NULL; 147 HKEY key = NULL;
87 *value_out = 0; 148 *value_out = 0;
88 149
89 base::string16 full_key_path(key_path); 150 base::string16 full_key_path(key_path);
90 full_key_path.append(1, L'\\'); 151 full_key_path.append(1, L'\\');
91 full_key_path.append(guid); 152 full_key_path.append(guid);
92 153
93 if (::RegOpenKeyEx(system_install ? HKEY_LOCAL_MACHINE : HKEY_CURRENT_USER, 154 if (::RegOpenKeyEx(system_install ? HKEY_LOCAL_MACHINE : HKEY_CURRENT_USER,
94 full_key_path.c_str(), 0, 155 full_key_path.c_str(), 0,
95 KEY_QUERY_VALUE | KEY_WOW64_32KEY, &key) != 156 KEY_QUERY_VALUE | KEY_WOW64_32KEY, &key) !=
96 ERROR_SUCCESS) { 157 ERROR_SUCCESS) {
97 return false; 158 return false;
98 } 159 }
99 160
100 DWORD size = sizeof(*value_out); 161 DWORD size = sizeof(*value_out);
101 DWORD type = REG_DWORD; 162 DWORD type = REG_DWORD;
102 LONG result = ::RegQueryValueEx(key, value_to_read, 0, &type, 163 LONG result = ::RegQueryValueEx(key, value_to_read, 0, &type,
103 reinterpret_cast<BYTE*>(value_out), &size); 164 reinterpret_cast<BYTE*>(value_out), &size);
104 165
105 ::RegCloseKey(key); 166 ::RegCloseKey(key);
106 167
107 return result == ERROR_SUCCESS && size == sizeof(*value_out); 168 return result == ERROR_SUCCESS && size == sizeof(*value_out);
108 } 169 }
109 170
171 bool GetLanguageAndCodePageFromVersionResource(const char* version_resource,
172 WORD* language,
173 WORD* code_page) {
174 if (!version_resource)
175 return false;
176
177 struct LanguageAndCodePage {
178 WORD language;
179 WORD code_page;
180 };
181
182 LanguageAndCodePage* translation_info = nullptr;
183 uint32_t data_size_in_bytes = 0;
184 BOOL query_result = VerQueryValue(version_resource,
185 L"\\VarFileInfo\\Translation",
186 reinterpret_cast<void**>(&translation_info),
187 &data_size_in_bytes);
188 if (!query_result)
189 return false;
190
191 *language = translation_info->language;
192 *code_page = translation_info->code_page;
193 return true;
194 }
195
196 bool GetValueFromVersionResource(const char* version_resource,
197 const base::string16& name,
198 base::string16* value_str) {
199 assert(value_str);
200 value_str->clear();
201
202 WORD language = 0;
203 WORD code_page = 0;
204 if (!GetLanguageAndCodePageFromVersionResource(version_resource,
205 &language,
206 &code_page)) {
207 return false;
208 }
209
210 WORD lang_codepage[8] = {};
211 size_t i = 0;
212 // Use the language and codepage
213 lang_codepage[i++] = language;
214 lang_codepage[i++] = code_page;
215 // Use the default language and codepage from the resource.
216 lang_codepage[i++] = ::GetUserDefaultLangID();
217 lang_codepage[i++] = code_page;
218 // Use the language from the resource and Latin codepage (most common).
219 lang_codepage[i++] = language;
220 lang_codepage[i++] = 1252;
221 // Use the default language and Latin codepage (most common).
222 lang_codepage[i++] = ::GetUserDefaultLangID();
223 lang_codepage[i++] = 1252;
224
225 static_assert((arraysize(lang_codepage) % 2) == 0,
226 "Language code page size should be a multiple of 2");
227 assert(arraysize(lang_codepage) == i);
228
229 for (i = 0; i < arraysize(lang_codepage);) {
230 wchar_t sub_block[MAX_PATH];
231 WORD language = lang_codepage[i++];
232 WORD code_page = lang_codepage[i++];
233 _snwprintf_s(sub_block, MAX_PATH, MAX_PATH,
234 L"\\StringFileInfo\\%04hx%04hx\\%ls", language, code_page,
235 name.c_str());
236 void* value = nullptr;
237 uint32_t size = 0;
238 BOOL r = ::VerQueryValue(version_resource, sub_block, &value, &size);
239 if (r && value) {
240 value_str->assign(static_cast<wchar_t*>(value));
241 return true;
242 }
243 }
244 return false;
245 }
246
247 // Returns the executable path for the current process.
248 base::string16 GetCurrentProcessExePath() {
249 wchar_t exe_path[MAX_PATH];
250 if (GetModuleFileName(nullptr, exe_path, arraysize(exe_path)) == 0)
251 return base::string16();
252 return exe_path;
253 }
254
255 // UTF8 to UTF16 and vice versa conversion helpers. We cannot use the base
256 // string conversion utilities here as they bring about a dependency on
257 // user32.dll which is not allowed in this file.
258
259 // Convert a UTF16 string to an UTF8 string.
260 std::string utf16_to_utf8(const base::string16 &source) {
261 if (source.empty())
262 return std::string();
263 int size = ::WideCharToMultiByte(CP_UTF8, 0, &source[0],
264 static_cast<int>(source.size()), nullptr, 0, nullptr, nullptr);
265 std::string result(size, L'\0');
266 if (::WideCharToMultiByte(CP_UTF8, 0, &source[0],
267 static_cast<int>(source.size()), &result[0], size, nullptr,
268 nullptr) != size) {
269 assert(false);
270 return std::string();
271 }
272 return result;
273 }
274
275 // Convert a UTF8 string to a UTF16 string.
276 base::string16 utf8_to_string16(const std::string &source) {
277 if (source.empty())
278 return base::string16();
279 int size = ::MultiByteToWideChar(CP_UTF8, 0, &source[0],
280 static_cast<int>(source.size()), nullptr, 0);
281 base::string16 result(size, 0);
282 if (::MultiByteToWideChar(CP_UTF8, 0, &source[0],
283 static_cast<int>(source.size()), &result[0], size) != size) {
284 assert(false);
285 return base::string16();
286 }
287 return result;
288 }
289
290 bool RecursiveDirectoryCreate(const base::string16& full_path) {
291 // If the path exists, we've succeeded if it's a directory, failed otherwise.
292 const wchar_t* full_path_str = full_path.c_str();
293 DWORD file_attributes = ::GetFileAttributes(full_path_str);
294 if (file_attributes != INVALID_FILE_ATTRIBUTES) {
295 if ((file_attributes & FILE_ATTRIBUTE_DIRECTORY) != 0) {
296 Trace(L"%hs( %ls directory exists )\n", __FUNCTION__, full_path_str);
297 return true;
298 }
299 Trace(L"%hs( %ls directory conflicts with an existing file. )\n",
300 __FUNCTION__, full_path_str);
301 return false;
302 }
303
304 // Invariant: Path does not exist as file or directory.
305
306 // Attempt to create the parent recursively. This will immediately return
307 // true if it already exists, otherwise will create all required parent
308 // directories starting with the highest-level missing parent.
309 base::string16 parent_path;
310 std::size_t pos = full_path.find_last_of(L"/\\");
311 if (pos != base::string16::npos) {
312 parent_path = full_path.substr(0, pos);
313 if (!RecursiveDirectoryCreate(parent_path)) {
314 Trace(L"Failed to create one of the parent directories");
315 return false;
316 }
317 }
318 if (!::CreateDirectory(full_path_str, NULL)) {
319 DWORD error_code = ::GetLastError();
320 if (error_code == ERROR_ALREADY_EXISTS) {
321 DWORD file_attributes = GetFileAttributes(full_path_str);
322 if ((file_attributes != INVALID_FILE_ATTRIBUTES) &&
323 ((file_attributes & FILE_ATTRIBUTE_DIRECTORY) != 0)) {
324 // This error code ERROR_ALREADY_EXISTS doesn't indicate whether we
325 // were racing with someone creating the same directory, or a file
326 // with the same path. If the directory exists, we lost the
327 // race to create the same directory.
328 return true;
329 } else {
330 Trace(L"Failed to create directory %ls, last error is %d\n",
331 full_path_str, error_code);
332 return false;
333 }
334 }
335 }
336 return true;
337 }
338
339 bool GetCollectStatsConsentImpl(const base::string16& exe_path) {
340 bool enabled = true;
341 if (ReportingIsEnforcedByPolicy(&enabled))
342 return enabled;
343
344 bool system_install = IsSystemInstall(exe_path.c_str());
345 base::string16 app_guid;
346
347 if (IsSxSChrome(exe_path.c_str())) {
348 app_guid = kAppGuidCanary;
349 } else {
350 app_guid = IsMultiInstall(system_install) ? kAppGuidGoogleBinaries :
351 kAppGuidGoogleChrome;
352 }
353
354 DWORD out_value = 0;
355 if (system_install &&
356 ReadKeyValueDW(system_install, kRegPathClientStateMedium, app_guid,
357 kRegValueUsageStats, &out_value)) {
358 return out_value == 1;
359 }
360
361 return ReadKeyValueDW(system_install, kRegPathClientState, app_guid,
362 kRegValueUsageStats, &out_value) && out_value == 1;
363 }
364
365 // Returns true if the |source| string matches the |pattern|. The pattern
366 // may contain wildcards like '?' which matches one character or a '*'
367 // which matches 0 or more characters.
368 // Please note that pattern matches the whole string. If you want to find
369 // something in the middle of the string then you need to specify the pattern
370 // as '*xyz*'.
371 // |source_index| is the index of the current character being matched in
372 // |source|.
373 // |pattern_index| is the index of the current pattern character in |pattern|
374 // which is matched with source.
375 bool MatchPatternImpl(const base::string16& source,
376 const base::string16& pattern,
377 size_t source_index,
378 size_t pattern_index) {
379 if (source.empty() && pattern.empty())
380 return true;
381
382 if (source_index > source.length() || pattern_index > pattern.length())
383 return false;
384
385 // If we reached the end of both strings, then we are done.
386 if ((source_index == source.length()) &&
387 (pattern_index == pattern.length())) {
388 return true;
389 }
390
391 // If the current character in the pattern is a '*' then make sure that
392 // characters after the pattern are present in the source string. This
393 // assumes that you won't have two consecutive '*' characters in the pattern.
394 if ((pattern[pattern_index] == L'*') &&
395 (pattern_index + 1 < pattern.length()) &&
396 (source_index >= source.length())) {
397 return false;
398 }
399
400 // If the pattern contains wildcard characters '?' or '.' or there is a match
401 // then move ahead in both strings.
402 if ((pattern[pattern_index] == L'?') ||
403 (pattern[pattern_index] == source[source_index])) {
404 return MatchPatternImpl(source, pattern, source_index + 1,
405 pattern_index + 1);
406 }
407
408 // If we have a '*' then there are two possibilities
409 // 1. We consider current character of source.
410 // 2. We ignore current character of source.
411 if (pattern[pattern_index] == L'*') {
412 return MatchPatternImpl(source, pattern, source_index + 1,
413 pattern_index) ||
414 MatchPatternImpl(source, pattern, source_index, pattern_index + 1);
415 }
416 return false;
417 }
418
110 } // namespace 419 } // namespace
111 420
112 bool IsCanary(const wchar_t* exe_path) { 421 bool IsSxSChrome(const wchar_t* exe_path) {
113 return wcsstr(exe_path, L"Chrome SxS\\Application") != NULL; 422 return wcsstr(exe_path, L"Chrome SxS\\Application") != NULL;
114 } 423 }
115 424
116 bool IsSystemInstall(const wchar_t* exe_path) { 425 bool IsSystemInstall(const wchar_t* exe_path) {
117 wchar_t program_dir[MAX_PATH] = {}; 426 wchar_t program_dir[MAX_PATH] = {};
118 DWORD ret = ::GetEnvironmentVariable(L"PROGRAMFILES", program_dir, 427 DWORD ret = ::GetEnvironmentVariable(L"PROGRAMFILES", program_dir,
119 arraysize(program_dir)); 428 arraysize(program_dir));
120 if (ret && ret < MAX_PATH && !wcsncmp(exe_path, program_dir, ret)) 429 if (ret && ret < arraysize(program_dir) &&
430 !wcsnicmp(exe_path, program_dir, ret)) {
121 return true; 431 return true;
432 }
122 433
123 ret = ::GetEnvironmentVariable(L"PROGRAMFILES(X86)", program_dir, 434 ret = ::GetEnvironmentVariable(L"PROGRAMFILES(X86)", program_dir,
124 arraysize(program_dir)); 435 arraysize(program_dir));
125 if (ret && ret < MAX_PATH && !wcsncmp(exe_path, program_dir, ret)) 436 if (ret && ret < arraysize(program_dir) &&
437 !wcsnicmp(exe_path, program_dir, ret)) {
126 return true; 438 return true;
439 }
127 440
128 return false; 441 return false;
129 } 442 }
130 443
131 bool IsMultiInstall(bool is_system_install) { 444 bool IsMultiInstall(bool is_system_install) {
132 base::string16 args; 445 base::string16 args;
133 if (!ReadKeyValueString(is_system_install, kRegPathClientState, 446 if (!ReadKeyValueString(is_system_install, kRegPathClientState,
134 kAppGuidGoogleChrome, kUninstallArgumentsField, 447 kAppGuidGoogleChrome, kUninstallArgumentsField,
135 &args)) { 448 &args)) {
136 return false; 449 return false;
137 } 450 }
138 return args.find(L"--multi-install") != base::string16::npos; 451 return args.find(L"--multi-install") != base::string16::npos;
139 } 452 }
140 453
141 bool AreUsageStatsEnabled(const wchar_t* exe_path) { 454 bool GetCollectStatsConsent() {
142 bool enabled = true; 455 return GetCollectStatsConsentImpl(GetCurrentProcessExePath());
143 bool controlled_by_policy = ReportingIsEnforcedByPolicy(&enabled);
144
145 if (controlled_by_policy && !enabled)
146 return false;
147
148 bool system_install = IsSystemInstall(exe_path);
149 base::string16 app_guid;
150
151 if (IsCanary(exe_path)) {
152 app_guid = kAppGuidCanary;
153 } else {
154 app_guid = IsMultiInstall(system_install) ? kAppGuidGoogleBinaries :
155 kAppGuidGoogleChrome;
156 }
157
158 DWORD out_value = 0;
159 if (system_install &&
160 ReadKeyValueDW(system_install, kRegPathClientStateMedium, app_guid,
161 kRegValueUsageStats, &out_value)) {
162 return out_value == 1;
163 }
164
165 return ReadKeyValueDW(system_install, kRegPathClientState, app_guid,
166 kRegValueUsageStats, &out_value) && out_value == 1;
167 } 456 }
168 457
169 bool ReportingIsEnforcedByPolicy(bool* breakpad_enabled) { 458 bool GetCollectStatsConsentForTesting(const base::string16& exe_path) {
459 return GetCollectStatsConsentImpl(exe_path);
460 }
461
462 bool ReportingIsEnforcedByPolicy(bool* metrics_is_enforced_by_policy) {
170 HKEY key = NULL; 463 HKEY key = NULL;
171 DWORD value = 0; 464 DWORD value = 0;
172 BYTE* value_bytes = reinterpret_cast<BYTE*>(&value); 465 BYTE* value_bytes = reinterpret_cast<BYTE*>(&value);
173 DWORD size = sizeof(value); 466 DWORD size = sizeof(value);
174 DWORD type = REG_DWORD; 467 DWORD type = REG_DWORD;
175 468
176 if (::RegOpenKeyEx(HKEY_LOCAL_MACHINE, kRegPathChromePolicy, 0, 469 if (::RegOpenKeyEx(HKEY_LOCAL_MACHINE, kRegPathChromePolicy, 0,
177 KEY_QUERY_VALUE, &key) == ERROR_SUCCESS) { 470 KEY_QUERY_VALUE, &key) == ERROR_SUCCESS) {
178 if (::RegQueryValueEx(key, kMetricsReportingEnabled, 0, &type, 471 if (::RegQueryValueEx(key, kMetricsReportingEnabled, 0, &type,
179 value_bytes, &size) == ERROR_SUCCESS) { 472 value_bytes, &size) == ERROR_SUCCESS) {
180 *breakpad_enabled = value != 0; 473 *metrics_is_enforced_by_policy = value != 0;
181 } 474 }
182 ::RegCloseKey(key); 475 ::RegCloseKey(key);
183 return size == sizeof(value); 476 return size == sizeof(value);
184 } 477 }
185 478
186 if (::RegOpenKeyEx(HKEY_CURRENT_USER, kRegPathChromePolicy, 0, 479 if (::RegOpenKeyEx(HKEY_CURRENT_USER, kRegPathChromePolicy, 0,
187 KEY_QUERY_VALUE, &key) == ERROR_SUCCESS) { 480 KEY_QUERY_VALUE, &key) == ERROR_SUCCESS) {
188 if (::RegQueryValueEx(key, kMetricsReportingEnabled, 0, &type, 481 if (::RegQueryValueEx(key, kMetricsReportingEnabled, 0, &type,
189 value_bytes, &size) == ERROR_SUCCESS) { 482 value_bytes, &size) == ERROR_SUCCESS) {
190 *breakpad_enabled = value != 0; 483 *metrics_is_enforced_by_policy = value != 0;
191 } 484 }
192 ::RegCloseKey(key); 485 ::RegCloseKey(key);
193 return size == sizeof(value); 486 return size == sizeof(value);
194 } 487 }
195 488
196 return false; 489 return false;
197 } 490 }
198 491
199 void InitializeProcessType() { 492 void InitializeProcessType() {
200 assert(g_process_type == ProcessType::UNINITIALIZED); 493 assert(g_process_type == ProcessType::UNINITIALIZED);
(...skipping 14 matching lines...) Expand all
215 return; 508 return;
216 } 509 }
217 510
218 g_process_type = ProcessType::BROWSER_PROCESS; 511 g_process_type = ProcessType::BROWSER_PROCESS;
219 } 512 }
220 513
221 bool IsNonBrowserProcess() { 514 bool IsNonBrowserProcess() {
222 assert(g_process_type != ProcessType::UNINITIALIZED); 515 assert(g_process_type != ProcessType::UNINITIALIZED);
223 return g_process_type == ProcessType::NON_BROWSER_PROCESS; 516 return g_process_type == ProcessType::NON_BROWSER_PROCESS;
224 } 517 }
518
519 bool GetDefaultUserDataDirectory(base::string16* result) {
520 static const wchar_t kLocalAppData[] = L"%LOCALAPPDATA%";
521
522 std::unique_ptr<wchar_t> user_data_dir_path;
523
524 // This environment variable should be set on Windows 7 and up.
525 // If we fail to find this variable then we default to the temporary files
526 // path.
527 DWORD size = ::ExpandEnvironmentStrings(kLocalAppData, nullptr, 0);
528 if (size) {
529 user_data_dir_path.reset(new wchar_t[size]);
530 if (::ExpandEnvironmentStrings(kLocalAppData,
531 user_data_dir_path.get(),
532 size) != size) {
533 user_data_dir_path.reset();
534 }
535 }
536 // We failed to find the %LOCALAPPDATA% folder. Fallback to the temporary
537 // files path. If we fail to find this we bail.
538 if (!user_data_dir_path.get()) {
539 size = ::GetTempPath(0, nullptr);
540 if (!size)
541 return false;
542 user_data_dir_path.reset(new wchar_t[size + 1]);
543 if (::GetTempPath(size + 1, user_data_dir_path.get()) != size)
544 return false;
545 }
546
547 base::string16 install_sub_directory = GetChromeInstallSubDirectory();
548
549 *result = user_data_dir_path.get();
550 if ((*result)[result->length() - 1] != L'\\')
551 result->append(L"\\");
552 result->append(install_sub_directory);
553 result->append(L"\\");
554 result->append(kUserDataDirname);
555 return true;
556 }
557
558 bool GetDefaultCrashDumpLocation(base::string16* crash_dir) {
559 // In order to be able to start crash handling very early, we do not rely on
560 // chrome's PathService entries (for DIR_CRASH_DUMPS) being available on
561 // Windows. See https://crbug.com/564398.
562 if (!GetDefaultUserDataDirectory(crash_dir))
563 return false;
564
565 // We have to make sure the user data dir exists on first run. See
566 // http://crbug.com/591504.
567 if (!RecursiveDirectoryCreate(crash_dir->c_str()))
568 return false;
569 crash_dir->append(L"\\Crashpad");
570 return true;
571 }
572
573
574 std::string GetEnvironmentString(const std::string& variable_name) {
575 DWORD value_length = ::GetEnvironmentVariable(
576 utf8_to_string16(variable_name).c_str(), NULL, 0);
577 if (value_length == 0)
578 return std::string();
579 std::unique_ptr<wchar_t[]> value(new wchar_t[value_length]);
580 ::GetEnvironmentVariable(utf8_to_string16(variable_name).c_str(),
581 value.get(), value_length);
582 return utf16_to_utf8(value.get());
583 }
584
585 bool SetEnvironmentString(const std::string& variable_name,
586 const std::string& new_value) {
587 return !!SetEnvironmentVariable(utf8_to_string16(variable_name).c_str(),
588 utf8_to_string16(new_value).c_str());
589 }
590
591 bool HasEnvironmentVariable(const std::string& variable_name) {
592 return !!::GetEnvironmentVariable(utf8_to_string16(variable_name).c_str(),
593 NULL, 0);
594 }
595
596 bool GetExecutableVersionDetails(const base::string16& exe_path,
597 base::string16* product_name,
598 base::string16* version,
599 base::string16* special_build,
600 base::string16* channel_name) {
601 assert(product_name);
602 assert(version);
603 assert(special_build);
604 assert(channel_name);
605
606 // Default values in case we don't find a version resource.
607 *product_name = L"Chrome";
608 *version = L"0.0.0.0-devel";
609 *channel_name = kChromeChannelUnknown;
610 special_build->clear();
611
612 DWORD dummy = 0;
613 DWORD length = ::GetFileVersionInfoSize(exe_path.c_str(), &dummy);
614 if (length) {
615 std::unique_ptr<char> data(new char[length]);
616 if (::GetFileVersionInfo(exe_path.c_str(), dummy, length,
617 data.get())) {
618 GetValueFromVersionResource(data.get(), L"ProductVersion", version);
619
620 base::string16 official_build;
621 GetValueFromVersionResource(data.get(), L"Official Build",
622 &official_build);
623 if (official_build != L"1")
624 version->append(L"-devel");
625 GetValueFromVersionResource(data.get(), L"ProductShortName",
626 product_name);
627 GetValueFromVersionResource(data.get(), L"SpecialBuild", special_build);
628 }
629 }
630 GetChromeChannelName(!IsSystemInstall(exe_path.c_str()), channel_name);
631 return true;
632 }
633
634 void GetChromeChannelName(bool is_per_user_install,
635 base::string16* channel_name) {
636 #if !defined(GOOGLE_CHROME_BUILD)
637 *channel_name = kChromeChannelUnknown;
638 return;
639 #else
640 channel_name->clear();
641 // TODO(ananta)
642 // http://crbug.com/604923
643 // Unify this with the chrome/installer/util/channel_info.h/.cc.
644 if (IsSxSChrome(GetCurrentProcessExePath().c_str())) {
645 *channel_name = L"canary";
646 } else {
647 base::string16 value;
648 if (ReadKeyValueString(!is_per_user_install,
649 kRegPathClientState,
650 kAppGuidGoogleChrome,
651 kRegApField,
652 &value)) {
653 static const wchar_t kChromeChannelBetaPattern[] = L"1?1-";
654 static const wchar_t kChromeChannelBetaX64Pattern[] = L"*x64-beta*";
655 static const wchar_t kChromeChannelDevPattern[] = L"2?0-d";
656 static const wchar_t kChromeChannelDevX64Pattern[] = L"x64-dev";
657 static const wchar_t kChromeStableMultiInstallPattern[] = L"*multi*";
658
659 std::transform(value.begin(), value.end(), value.begin(), ::tolower);
660
661 // Channel names containing stable should be reported as an empty string.
662 if (value.find(kChromeChannelStableExplicit) !=
663 base::string16::npos) {
664 return;
665 }
666
667 if (MatchPattern(value, kChromeChannelDevPattern) ||
668 MatchPattern(value, kChromeChannelDevX64Pattern)) {
669 channel_name->assign(kChromeChannelDev);
670 }
671
672 if (MatchPattern(value, kChromeChannelBetaPattern) ||
673 MatchPattern(value, kChromeChannelBetaPattern)) {
674 channel_name->assign(kChromeChannelBeta);
675 }
676
677 if (value.find(kChromeStableMultiInstallPattern) !=
678 base::string16::npos) {
679 *channel_name = L"-m";
680 }
681
682 // If we fail to find any matching pattern in the channel name then we
683 // default to empty which means stable. Not sure if this is ok.
684 // TODO(ananta)
685 // http://crbug.com/604923
686 // Check if this is ok.
687 } else {
688 *channel_name = kChromeChannelUnknown;
689 }
690 }
691 #endif // GOOGLE_CHROME_BUILD
692 }
693
694 std::string GetGoogleUpdateVersion() {
695 base::string16 update_version;
696 if (ReadKeyValueString(IsSystemInstall(GetCurrentProcessExePath().c_str()),
697 kRegPathGoogleUpdate,
698 L"",
699 kRegGoogleUpdateVersion,
700 &update_version)) {
701 return utf16_to_utf8(update_version);
702 }
703 return std::string();
704 }
705
706 base::string16 GetChromeInstallSubDirectory() {
707 base::string16 result;
708 #if defined(GOOGLE_CHROME_BUILD)
709 base::string16 sub_directory = kGoogleChromeInstallSubDir1;
710 sub_directory += L"\\";
711 sub_directory += kGoogleChromeInstallSubDir2;
712 if (IsSxSChrome(GetCurrentProcessExePath().c_str()))
713 sub_directory += kSxSSuffix;
714 return result.append(sub_directory);
715 #else
716 return base::string16(kChromiumInstallSubDir);
717 #endif
718 }
719
720 base::string16 GetBrowserCrashDumpAttemptsRegistryPath() {
721 base::string16 registry_path = L"Software\\";
722 registry_path += GetChromeInstallSubDirectory();
723 registry_path += kBrowserCrashDumpMetricsSubKey;
724 return registry_path;
725 }
726
727 bool MatchPattern(const base::string16& source,
728 const base::string16& pattern) {
729 assert(pattern.find(L"**") == base::string16::npos);
730 return MatchPatternImpl(source, pattern, 0, 0);
731 }
732
733 } // namespace install_static
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698