| OLD | NEW |
| 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 <windows.h> |
| 8 #include <assert.h> | 8 #include <assert.h> |
| 9 #include <algorithm> | 9 #include <algorithm> |
| 10 #include <iostream> |
| 11 #include <iterator> |
| 10 #include <memory> | 12 #include <memory> |
| 13 #include <sstream> |
| 11 | 14 |
| 12 #include "base/macros.h" | 15 #include "base/macros.h" |
| 13 #include "build/build_config.h" | 16 #include "build/build_config.h" |
| 14 | 17 |
| 15 namespace install_static { | 18 namespace install_static { |
| 16 | 19 |
| 17 ProcessType g_process_type = ProcessType::UNINITIALIZED; | 20 ProcessType g_process_type = ProcessType::UNINITIALIZED; |
| 18 | 21 |
| 19 // TODO(ananta) | 22 // TODO(ananta) |
| 20 // http://crbug.com/604923 | 23 // http://crbug.com/604923 |
| (...skipping 65 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 86 va_end(args); | 89 va_end(args); |
| 87 } | 90 } |
| 88 | 91 |
| 89 // Reads a string value identified by |value_to_read| from the registry path | 92 // 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 | 93 // under |key_path|. We look in HKLM or HKCU depending on whether the |
| 91 // |system_install| parameter is true. | 94 // |system_install| parameter is true. |
| 92 // Please note that this function only looks in the 32bit view of the registry. | 95 // Please note that this function only looks in the 32bit view of the registry. |
| 93 bool ReadKeyValueString(bool system_install, const wchar_t* key_path, | 96 bool ReadKeyValueString(bool system_install, const wchar_t* key_path, |
| 94 const wchar_t* guid, const wchar_t* value_to_read, | 97 const wchar_t* guid, const wchar_t* value_to_read, |
| 95 base::string16* value_out) { | 98 base::string16* value_out) { |
| 96 HKEY key = NULL; | 99 HKEY key = nullptr; |
| 97 value_out->clear(); | 100 value_out->clear(); |
| 98 | 101 |
| 99 base::string16 full_key_path(key_path); | 102 base::string16 full_key_path(key_path); |
| 100 if (guid && *guid) { | 103 if (guid && *guid) { |
| 101 full_key_path.append(1, L'\\'); | 104 full_key_path.append(1, L'\\'); |
| 102 full_key_path.append(guid); | 105 full_key_path.append(guid); |
| 103 } | 106 } |
| 104 | 107 |
| 105 if (::RegOpenKeyEx(system_install ? HKEY_LOCAL_MACHINE : HKEY_CURRENT_USER, | 108 if (::RegOpenKeyEx(system_install ? HKEY_LOCAL_MACHINE : HKEY_CURRENT_USER, |
| 106 full_key_path.c_str(), 0, | 109 full_key_path.c_str(), 0, |
| (...skipping 30 matching lines...) Expand all Loading... |
| 137 return result == ERROR_SUCCESS; | 140 return result == ERROR_SUCCESS; |
| 138 } | 141 } |
| 139 | 142 |
| 140 // Reads a DWORD value identified by |value_to_read| from the registry path | 143 // 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 | 144 // under |key_path|. We look in HKLM or HKCU depending on whether the |
| 142 // |system_install| parameter is true. | 145 // |system_install| parameter is true. |
| 143 // Please note that this function only looks in the 32bit view of the registry. | 146 // Please note that this function only looks in the 32bit view of the registry. |
| 144 bool ReadKeyValueDW(bool system_install, const wchar_t* key_path, | 147 bool ReadKeyValueDW(bool system_install, const wchar_t* key_path, |
| 145 base::string16 guid, const wchar_t* value_to_read, | 148 base::string16 guid, const wchar_t* value_to_read, |
| 146 DWORD* value_out) { | 149 DWORD* value_out) { |
| 147 HKEY key = NULL; | 150 HKEY key = nullptr; |
| 148 *value_out = 0; | 151 *value_out = 0; |
| 149 | 152 |
| 150 base::string16 full_key_path(key_path); | 153 base::string16 full_key_path(key_path); |
| 151 full_key_path.append(1, L'\\'); | 154 full_key_path.append(1, L'\\'); |
| 152 full_key_path.append(guid); | 155 full_key_path.append(guid); |
| 153 | 156 |
| 154 if (::RegOpenKeyEx(system_install ? HKEY_LOCAL_MACHINE : HKEY_CURRENT_USER, | 157 if (::RegOpenKeyEx(system_install ? HKEY_LOCAL_MACHINE : HKEY_CURRENT_USER, |
| 155 full_key_path.c_str(), 0, | 158 full_key_path.c_str(), 0, |
| 156 KEY_QUERY_VALUE | KEY_WOW64_32KEY, &key) != | 159 KEY_QUERY_VALUE | KEY_WOW64_32KEY, &key) != |
| 157 ERROR_SUCCESS) { | 160 ERROR_SUCCESS) { |
| (...skipping 90 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 248 } | 251 } |
| 249 | 252 |
| 250 // Returns the executable path for the current process. | 253 // Returns the executable path for the current process. |
| 251 base::string16 GetCurrentProcessExePath() { | 254 base::string16 GetCurrentProcessExePath() { |
| 252 wchar_t exe_path[MAX_PATH]; | 255 wchar_t exe_path[MAX_PATH]; |
| 253 if (GetModuleFileName(nullptr, exe_path, arraysize(exe_path)) == 0) | 256 if (GetModuleFileName(nullptr, exe_path, arraysize(exe_path)) == 0) |
| 254 return base::string16(); | 257 return base::string16(); |
| 255 return exe_path; | 258 return exe_path; |
| 256 } | 259 } |
| 257 | 260 |
| 258 // UTF8 to UTF16 and vice versa conversion helpers. We cannot use the base | |
| 259 // string conversion utilities here as they bring about a dependency on | |
| 260 // user32.dll which is not allowed in this file. | |
| 261 | |
| 262 // Convert a UTF16 string to an UTF8 string. | |
| 263 std::string utf16_to_utf8(const base::string16 &source) { | |
| 264 if (source.empty()) | |
| 265 return std::string(); | |
| 266 int size = ::WideCharToMultiByte(CP_UTF8, 0, &source[0], | |
| 267 static_cast<int>(source.size()), nullptr, 0, nullptr, nullptr); | |
| 268 std::string result(size, '\0'); | |
| 269 if (::WideCharToMultiByte(CP_UTF8, 0, &source[0], | |
| 270 static_cast<int>(source.size()), &result[0], size, nullptr, | |
| 271 nullptr) != size) { | |
| 272 assert(false); | |
| 273 return std::string(); | |
| 274 } | |
| 275 return result; | |
| 276 } | |
| 277 | |
| 278 // Convert a UTF8 string to a UTF16 string. | |
| 279 base::string16 utf8_to_string16(const std::string &source) { | |
| 280 if (source.empty()) | |
| 281 return base::string16(); | |
| 282 int size = ::MultiByteToWideChar(CP_UTF8, 0, &source[0], | |
| 283 static_cast<int>(source.size()), nullptr, 0); | |
| 284 base::string16 result(size, L'\0'); | |
| 285 if (::MultiByteToWideChar(CP_UTF8, 0, &source[0], | |
| 286 static_cast<int>(source.size()), &result[0], size) != size) { | |
| 287 assert(false); | |
| 288 return base::string16(); | |
| 289 } | |
| 290 return result; | |
| 291 } | |
| 292 | |
| 293 bool RecursiveDirectoryCreate(const base::string16& full_path) { | 261 bool RecursiveDirectoryCreate(const base::string16& full_path) { |
| 294 // If the path exists, we've succeeded if it's a directory, failed otherwise. | 262 // If the path exists, we've succeeded if it's a directory, failed otherwise. |
| 295 const wchar_t* full_path_str = full_path.c_str(); | 263 const wchar_t* full_path_str = full_path.c_str(); |
| 296 DWORD file_attributes = ::GetFileAttributes(full_path_str); | 264 DWORD file_attributes = ::GetFileAttributes(full_path_str); |
| 297 if (file_attributes != INVALID_FILE_ATTRIBUTES) { | 265 if (file_attributes != INVALID_FILE_ATTRIBUTES) { |
| 298 if ((file_attributes & FILE_ATTRIBUTE_DIRECTORY) != 0) { | 266 if ((file_attributes & FILE_ATTRIBUTE_DIRECTORY) != 0) { |
| 299 Trace(L"%hs( %ls directory exists )\n", __FUNCTION__, full_path_str); | 267 Trace(L"%hs( %ls directory exists )\n", __FUNCTION__, full_path_str); |
| 300 return true; | 268 return true; |
| 301 } | 269 } |
| 302 Trace(L"%hs( %ls directory conflicts with an existing file. )\n", | 270 Trace(L"%hs( %ls directory conflicts with an existing file. )\n", |
| 303 __FUNCTION__, full_path_str); | 271 __FUNCTION__, full_path_str); |
| 304 return false; | 272 return false; |
| 305 } | 273 } |
| 306 | 274 |
| 307 // Invariant: Path does not exist as file or directory. | 275 // Invariant: Path does not exist as file or directory. |
| 308 | 276 |
| 309 // Attempt to create the parent recursively. This will immediately return | 277 // Attempt to create the parent recursively. This will immediately return |
| 310 // true if it already exists, otherwise will create all required parent | 278 // true if it already exists, otherwise will create all required parent |
| 311 // directories starting with the highest-level missing parent. | 279 // directories starting with the highest-level missing parent. |
| 312 base::string16 parent_path; | 280 base::string16 parent_path; |
| 313 std::size_t pos = full_path.find_last_of(L"/\\"); | 281 std::size_t pos = full_path.find_last_of(L"/\\"); |
| 314 if (pos != base::string16::npos) { | 282 if (pos != base::string16::npos) { |
| 315 parent_path = full_path.substr(0, pos); | 283 parent_path = full_path.substr(0, pos); |
| 316 if (!RecursiveDirectoryCreate(parent_path)) { | 284 if (!RecursiveDirectoryCreate(parent_path)) { |
| 317 Trace(L"Failed to create one of the parent directories"); | 285 Trace(L"Failed to create one of the parent directories"); |
| 318 return false; | 286 return false; |
| 319 } | 287 } |
| 320 } | 288 } |
| 321 if (!::CreateDirectory(full_path_str, NULL)) { | 289 if (!::CreateDirectory(full_path_str, nullptr)) { |
| 322 DWORD error_code = ::GetLastError(); | 290 DWORD error_code = ::GetLastError(); |
| 323 if (error_code == ERROR_ALREADY_EXISTS) { | 291 if (error_code == ERROR_ALREADY_EXISTS) { |
| 324 DWORD file_attributes = ::GetFileAttributes(full_path_str); | 292 DWORD file_attributes = ::GetFileAttributes(full_path_str); |
| 325 if ((file_attributes != INVALID_FILE_ATTRIBUTES) && | 293 if ((file_attributes != INVALID_FILE_ATTRIBUTES) && |
| 326 ((file_attributes & FILE_ATTRIBUTE_DIRECTORY) != 0)) { | 294 ((file_attributes & FILE_ATTRIBUTE_DIRECTORY) != 0)) { |
| 327 // This error code ERROR_ALREADY_EXISTS doesn't indicate whether we | 295 // This error code ERROR_ALREADY_EXISTS doesn't indicate whether we |
| 328 // were racing with someone creating the same directory, or a file | 296 // were racing with someone creating the same directory, or a file |
| 329 // with the same path. If the directory exists, we lost the | 297 // with the same path. If the directory exists, we lost the |
| 330 // race to create the same directory. | 298 // race to create the same directory. |
| 331 return true; | 299 return true; |
| (...skipping 80 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 412 // 1. We consider current character of source. | 380 // 1. We consider current character of source. |
| 413 // 2. We ignore current character of source. | 381 // 2. We ignore current character of source. |
| 414 if (pattern[pattern_index] == L'*') { | 382 if (pattern[pattern_index] == L'*') { |
| 415 return MatchPatternImpl(source, pattern, source_index + 1, | 383 return MatchPatternImpl(source, pattern, source_index + 1, |
| 416 pattern_index) || | 384 pattern_index) || |
| 417 MatchPatternImpl(source, pattern, source_index, pattern_index + 1); | 385 MatchPatternImpl(source, pattern, source_index, pattern_index + 1); |
| 418 } | 386 } |
| 419 return false; | 387 return false; |
| 420 } | 388 } |
| 421 | 389 |
| 390 // Defines the type of whitespace characters typically found in strings. |
| 391 constexpr char kWhiteSpaces[] = " \t\n\r\f\v"; |
| 392 |
| 393 // Trim whitespaces from left & right |
| 394 void Trim(std::string* str) { |
| 395 str->erase(str->find_last_not_of(kWhiteSpaces) + 1); |
| 396 str->erase(0, str->find_first_not_of(kWhiteSpaces)); |
| 397 } |
| 398 |
| 399 bool IsValidNumber(const std::string& str) { |
| 400 if (str.empty()) |
| 401 return false; |
| 402 return std::all_of(str.begin(), str.end(), ::isdigit); |
| 403 } |
| 404 |
| 422 } // namespace | 405 } // namespace |
| 423 | 406 |
| 424 bool IsSxSChrome(const wchar_t* exe_path) { | 407 bool IsSxSChrome(const wchar_t* exe_path) { |
| 425 return wcsstr(exe_path, L"Chrome SxS\\Application") != NULL; | 408 return wcsstr(exe_path, L"Chrome SxS\\Application") != nullptr; |
| 426 } | 409 } |
| 427 | 410 |
| 428 bool IsSystemInstall(const wchar_t* exe_path) { | 411 bool IsSystemInstall(const wchar_t* exe_path) { |
| 429 wchar_t program_dir[MAX_PATH] = {}; | 412 wchar_t program_dir[MAX_PATH] = {}; |
| 430 DWORD ret = ::GetEnvironmentVariable(L"PROGRAMFILES", program_dir, | 413 DWORD ret = ::GetEnvironmentVariable(L"PROGRAMFILES", program_dir, |
| 431 arraysize(program_dir)); | 414 arraysize(program_dir)); |
| 432 if (ret && ret < arraysize(program_dir) && | 415 if (ret && ret < arraysize(program_dir) && |
| 433 !wcsnicmp(exe_path, program_dir, ret)) { | 416 !wcsnicmp(exe_path, program_dir, ret)) { |
| 434 return true; | 417 return true; |
| 435 } | 418 } |
| (...skipping 20 matching lines...) Expand all Loading... |
| 456 | 439 |
| 457 bool GetCollectStatsConsent() { | 440 bool GetCollectStatsConsent() { |
| 458 return GetCollectStatsConsentImpl(GetCurrentProcessExePath()); | 441 return GetCollectStatsConsentImpl(GetCurrentProcessExePath()); |
| 459 } | 442 } |
| 460 | 443 |
| 461 bool GetCollectStatsConsentForTesting(const base::string16& exe_path) { | 444 bool GetCollectStatsConsentForTesting(const base::string16& exe_path) { |
| 462 return GetCollectStatsConsentImpl(exe_path); | 445 return GetCollectStatsConsentImpl(exe_path); |
| 463 } | 446 } |
| 464 | 447 |
| 465 bool ReportingIsEnforcedByPolicy(bool* metrics_is_enforced_by_policy) { | 448 bool ReportingIsEnforcedByPolicy(bool* metrics_is_enforced_by_policy) { |
| 466 HKEY key = NULL; | 449 HKEY key = nullptr; |
| 467 DWORD value = 0; | 450 DWORD value = 0; |
| 468 BYTE* value_bytes = reinterpret_cast<BYTE*>(&value); | 451 BYTE* value_bytes = reinterpret_cast<BYTE*>(&value); |
| 469 DWORD size = sizeof(value); | 452 DWORD size = sizeof(value); |
| 470 DWORD type = REG_DWORD; | 453 DWORD type = REG_DWORD; |
| 471 | 454 |
| 472 if (::RegOpenKeyEx(HKEY_LOCAL_MACHINE, kRegPathChromePolicy, 0, | 455 if (::RegOpenKeyEx(HKEY_LOCAL_MACHINE, kRegPathChromePolicy, 0, |
| 473 KEY_QUERY_VALUE, &key) == ERROR_SUCCESS) { | 456 KEY_QUERY_VALUE, &key) == ERROR_SUCCESS) { |
| 474 if (::RegQueryValueEx(key, kMetricsReportingEnabled, 0, &type, | 457 if (::RegQueryValueEx(key, kMetricsReportingEnabled, 0, &type, |
| 475 value_bytes, &size) == ERROR_SUCCESS) { | 458 value_bytes, &size) == ERROR_SUCCESS) { |
| 476 *metrics_is_enforced_by_policy = value != 0; | 459 *metrics_is_enforced_by_policy = value != 0; |
| (...skipping 13 matching lines...) Expand all Loading... |
| 490 } | 473 } |
| 491 | 474 |
| 492 return false; | 475 return false; |
| 493 } | 476 } |
| 494 | 477 |
| 495 void InitializeProcessType() { | 478 void InitializeProcessType() { |
| 496 assert(g_process_type == ProcessType::UNINITIALIZED); | 479 assert(g_process_type == ProcessType::UNINITIALIZED); |
| 497 typedef bool (*IsSandboxedProcessFunc)(); | 480 typedef bool (*IsSandboxedProcessFunc)(); |
| 498 IsSandboxedProcessFunc is_sandboxed_process_func = | 481 IsSandboxedProcessFunc is_sandboxed_process_func = |
| 499 reinterpret_cast<IsSandboxedProcessFunc>( | 482 reinterpret_cast<IsSandboxedProcessFunc>( |
| 500 GetProcAddress(GetModuleHandle(NULL), "IsSandboxedProcess")); | 483 GetProcAddress(GetModuleHandle(nullptr), "IsSandboxedProcess")); |
| 501 if (is_sandboxed_process_func && is_sandboxed_process_func()) { | 484 if (is_sandboxed_process_func && is_sandboxed_process_func()) { |
| 502 g_process_type = ProcessType::NON_BROWSER_PROCESS; | 485 g_process_type = ProcessType::NON_BROWSER_PROCESS; |
| 503 return; | 486 return; |
| 504 } | 487 } |
| 505 | 488 |
| 506 // TODO(robertshield): Drop the command line check when we drop support for | 489 // TODO(robertshield): Drop the command line check when we drop support for |
| 507 // enabling chrome_elf in unsandboxed processes. | 490 // enabling chrome_elf in unsandboxed processes. |
| 508 const wchar_t* command_line = GetCommandLine(); | 491 const wchar_t* command_line = GetCommandLine(); |
| 509 if (command_line && wcsstr(command_line, L"--type")) { | 492 if (command_line && wcsstr(command_line, L"--type")) { |
| 510 g_process_type = ProcessType::NON_BROWSER_PROCESS; | 493 g_process_type = ProcessType::NON_BROWSER_PROCESS; |
| (...skipping 57 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 568 // We have to make sure the user data dir exists on first run. See | 551 // We have to make sure the user data dir exists on first run. See |
| 569 // http://crbug.com/591504. | 552 // http://crbug.com/591504. |
| 570 if (!RecursiveDirectoryCreate(crash_dir->c_str())) | 553 if (!RecursiveDirectoryCreate(crash_dir->c_str())) |
| 571 return false; | 554 return false; |
| 572 crash_dir->append(L"\\Crashpad"); | 555 crash_dir->append(L"\\Crashpad"); |
| 573 return true; | 556 return true; |
| 574 } | 557 } |
| 575 | 558 |
| 576 | 559 |
| 577 std::string GetEnvironmentString(const std::string& variable_name) { | 560 std::string GetEnvironmentString(const std::string& variable_name) { |
| 578 DWORD value_length = ::GetEnvironmentVariable( | 561 DWORD value_length = |
| 579 utf8_to_string16(variable_name).c_str(), NULL, 0); | 562 ::GetEnvironmentVariable(UTF8ToUTF16(variable_name).c_str(), nullptr, 0); |
| 580 if (value_length == 0) | 563 if (value_length == 0) |
| 581 return std::string(); | 564 return std::string(); |
| 582 std::unique_ptr<wchar_t[]> value(new wchar_t[value_length]); | 565 std::unique_ptr<wchar_t[]> value(new wchar_t[value_length]); |
| 583 ::GetEnvironmentVariable(utf8_to_string16(variable_name).c_str(), | 566 ::GetEnvironmentVariable(UTF8ToUTF16(variable_name).c_str(), value.get(), |
| 584 value.get(), value_length); | 567 value_length); |
| 585 return utf16_to_utf8(value.get()); | 568 return UTF16ToUTF8(value.get()); |
| 586 } | 569 } |
| 587 | 570 |
| 588 bool SetEnvironmentString(const std::string& variable_name, | 571 bool SetEnvironmentString(const std::string& variable_name, |
| 589 const std::string& new_value) { | 572 const std::string& new_value) { |
| 590 return !!SetEnvironmentVariable(utf8_to_string16(variable_name).c_str(), | 573 return !!SetEnvironmentVariable(UTF8ToUTF16(variable_name).c_str(), |
| 591 utf8_to_string16(new_value).c_str()); | 574 UTF8ToUTF16(new_value).c_str()); |
| 592 } | 575 } |
| 593 | 576 |
| 594 bool HasEnvironmentVariable(const std::string& variable_name) { | 577 bool HasEnvironmentVariable(const std::string& variable_name) { |
| 595 return !!::GetEnvironmentVariable(utf8_to_string16(variable_name).c_str(), | 578 return !!::GetEnvironmentVariable(UTF8ToUTF16(variable_name).c_str(), nullptr, |
| 596 NULL, 0); | 579 0); |
| 597 } | 580 } |
| 598 | 581 |
| 599 bool GetExecutableVersionDetails(const base::string16& exe_path, | 582 bool GetExecutableVersionDetails(const base::string16& exe_path, |
| 600 base::string16* product_name, | 583 base::string16* product_name, |
| 601 base::string16* version, | 584 base::string16* version, |
| 602 base::string16* special_build, | 585 base::string16* special_build, |
| 603 base::string16* channel_name) { | 586 base::string16* channel_name) { |
| 604 assert(product_name); | 587 assert(product_name); |
| 605 assert(version); | 588 assert(version); |
| 606 assert(special_build); | 589 assert(special_build); |
| (...skipping 98 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 705 std::string GetGoogleUpdateVersion() { | 688 std::string GetGoogleUpdateVersion() { |
| 706 // TODO(ananta) | 689 // TODO(ananta) |
| 707 // Consider whether Chromium should connect to Google update to manage | 690 // Consider whether Chromium should connect to Google update to manage |
| 708 // updates. Should this be returning an empty string for Chromium builds?. | 691 // updates. Should this be returning an empty string for Chromium builds?. |
| 709 base::string16 update_version; | 692 base::string16 update_version; |
| 710 if (ReadKeyValueString(IsSystemInstall(GetCurrentProcessExePath().c_str()), | 693 if (ReadKeyValueString(IsSystemInstall(GetCurrentProcessExePath().c_str()), |
| 711 kRegPathGoogleUpdate, | 694 kRegPathGoogleUpdate, |
| 712 nullptr, | 695 nullptr, |
| 713 kRegGoogleUpdateVersion, | 696 kRegGoogleUpdateVersion, |
| 714 &update_version)) { | 697 &update_version)) { |
| 715 return utf16_to_utf8(update_version); | 698 return UTF16ToUTF8(update_version); |
| 716 } | 699 } |
| 717 return std::string(); | 700 return std::string(); |
| 718 } | 701 } |
| 719 | 702 |
| 720 base::string16 GetChromeInstallSubDirectory() { | 703 base::string16 GetChromeInstallSubDirectory() { |
| 721 #if defined(GOOGLE_CHROME_BUILD) | 704 #if defined(GOOGLE_CHROME_BUILD) |
| 722 base::string16 result = kGoogleChromeInstallSubDir1; | 705 base::string16 result = kGoogleChromeInstallSubDir1; |
| 723 result += L"\\"; | 706 result += L"\\"; |
| 724 result += kGoogleChromeInstallSubDir2; | 707 result += kGoogleChromeInstallSubDir2; |
| 725 if (IsSxSChrome(GetCurrentProcessExePath().c_str())) | 708 if (IsSxSChrome(GetCurrentProcessExePath().c_str())) |
| (...skipping 10 matching lines...) Expand all Loading... |
| 736 registry_path += kBrowserCrashDumpMetricsSubKey; | 719 registry_path += kBrowserCrashDumpMetricsSubKey; |
| 737 return registry_path; | 720 return registry_path; |
| 738 } | 721 } |
| 739 | 722 |
| 740 bool MatchPattern(const base::string16& source, | 723 bool MatchPattern(const base::string16& source, |
| 741 const base::string16& pattern) { | 724 const base::string16& pattern) { |
| 742 assert(pattern.find(L"**") == base::string16::npos); | 725 assert(pattern.find(L"**") == base::string16::npos); |
| 743 return MatchPatternImpl(source, pattern, 0, 0); | 726 return MatchPatternImpl(source, pattern, 0, 0); |
| 744 } | 727 } |
| 745 | 728 |
| 729 std::string UTF16ToUTF8(const base::string16& source) { |
| 730 if (source.empty() || |
| 731 static_cast<int>(source.size()) > std::numeric_limits<int>::max()) { |
| 732 return std::string(); |
| 733 } |
| 734 int size = ::WideCharToMultiByte(CP_UTF8, 0, &source[0], |
| 735 static_cast<int>(source.size()), nullptr, 0, |
| 736 nullptr, nullptr); |
| 737 std::string result(size, '\0'); |
| 738 if (::WideCharToMultiByte(CP_UTF8, 0, &source[0], |
| 739 static_cast<int>(source.size()), &result[0], size, |
| 740 nullptr, nullptr) != size) { |
| 741 assert(false); |
| 742 return std::string(); |
| 743 } |
| 744 return result; |
| 745 } |
| 746 |
| 747 base::string16 UTF8ToUTF16(const std::string& source) { |
| 748 if (source.empty() || |
| 749 static_cast<int>(source.size()) > std::numeric_limits<int>::max()) { |
| 750 return base::string16(); |
| 751 } |
| 752 int size = ::MultiByteToWideChar(CP_UTF8, 0, &source[0], |
| 753 static_cast<int>(source.size()), nullptr, 0); |
| 754 base::string16 result(size, L'\0'); |
| 755 if (::MultiByteToWideChar(CP_UTF8, 0, &source[0], |
| 756 static_cast<int>(source.size()), &result[0], |
| 757 size) != size) { |
| 758 assert(false); |
| 759 return base::string16(); |
| 760 } |
| 761 return result; |
| 762 } |
| 763 |
| 764 std::vector<std::string> TokenizeString(const std::string& str, |
| 765 char delimiter, |
| 766 bool trim_spaces) { |
| 767 std::vector<std::string> tokens; |
| 768 std::istringstream buffer(str); |
| 769 for (std::string token; std::getline(buffer, token, delimiter);) { |
| 770 if (trim_spaces) |
| 771 Trim(&token); |
| 772 tokens.push_back(token); |
| 773 } |
| 774 return tokens; |
| 775 } |
| 776 |
| 777 bool CompareVersionStrings(const std::string& version1, |
| 778 const std::string& version2, |
| 779 int* result) { |
| 780 if (version1.empty() || version2.empty()) |
| 781 return false; |
| 782 |
| 783 // Tokenize both version strings with "." as the separator. If either of |
| 784 // the returned token lists are empty then bail. |
| 785 std::vector<std::string> version1_components = |
| 786 TokenizeString(version1, '.', false); |
| 787 if (version1_components.empty()) |
| 788 return false; |
| 789 |
| 790 std::vector<std::string> version2_components = |
| 791 TokenizeString(version2, '.', false); |
| 792 if (version2_components.empty()) |
| 793 return false; |
| 794 |
| 795 // You may have less tokens in either string. Use the minimum of the number |
| 796 // of tokens as the initial count. |
| 797 const size_t count = |
| 798 std::min(version1_components.size(), version2_components.size()); |
| 799 for (size_t i = 0; i < count; ++i) { |
| 800 // If either of the version components don't contain valid numeric digits |
| 801 // bail. |
| 802 if (!IsValidNumber(version1_components[i]) || |
| 803 !IsValidNumber(version2_components[i])) { |
| 804 return false; |
| 805 } |
| 806 |
| 807 int version1_component = std::stoi(version1_components[i]); |
| 808 int version2_component = std::stoi(version2_components[i]); |
| 809 |
| 810 if (version1_component > version2_component) { |
| 811 *result = 1; |
| 812 return true; |
| 813 } |
| 814 |
| 815 if (version1_component < version2_component) { |
| 816 *result = -1; |
| 817 return true; |
| 818 } |
| 819 } |
| 820 |
| 821 // Handle remaining tokens. Here if we have non zero tokens remaining in the |
| 822 // version 1 list then it means that the version1 string is larger. If the |
| 823 // version 1 token list has tokens left, then if either of these tokens is |
| 824 // greater than 0 then it means that the version1 string is smaller than the |
| 825 // version2 string. |
| 826 if (version1_components.size() > version2_components.size()) { |
| 827 for (size_t i = count; i < version1_components.size(); ++i) { |
| 828 // If the version components don't contain valid numeric digits bail. |
| 829 if (!IsValidNumber(version1_components[i])) |
| 830 return false; |
| 831 |
| 832 if (std::stoi(version1_components[i]) > 0) { |
| 833 *result = 1; |
| 834 return true; |
| 835 } |
| 836 } |
| 837 } else if (version1_components.size() < version2_components.size()) { |
| 838 for (size_t i = count; i < version2_components.size(); ++i) { |
| 839 // If the version components don't contain valid numeric digits bail. |
| 840 if (!IsValidNumber(version2_components[i])) |
| 841 return false; |
| 842 |
| 843 if (std::stoi(version2_components[i]) > 0) { |
| 844 *result = -1; |
| 845 return true; |
| 846 } |
| 847 } |
| 848 } |
| 849 // Here it means that both versions are equal. |
| 850 *result = 0; |
| 851 return true; |
| 852 } |
| 853 |
| 746 } // namespace install_static | 854 } // namespace install_static |
| OLD | NEW |