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 227 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", |
(...skipping 109 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") != NULL; |
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)); |
(...skipping 136 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(), NULL, 0); |
grt (UTC plus 2)
2016/05/27 20:18:04
nullptr everywhere
ananta
2016/05/27 20:42:13
Done.
| |
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(), NULL, |
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 |