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 <stdlib.h> | |
9 #include <string.h> | 10 #include <string.h> |
10 | 11 |
11 #include <algorithm> | 12 #include <algorithm> |
12 #include <memory> | 13 #include <memory> |
13 #include <sstream> | 14 #include <sstream> |
14 | 15 |
15 #include "chrome/install_static/install_details.h" | 16 #include "chrome/install_static/install_details.h" |
16 #include "chrome/install_static/install_modes.h" | 17 #include "chrome/install_static/install_modes.h" |
18 #include "chrome/install_static/policy_path_parser.h" | |
17 #include "chrome_elf/nt_registry/nt_registry.h" | 19 #include "chrome_elf/nt_registry/nt_registry.h" |
18 | 20 |
19 namespace install_static { | 21 namespace install_static { |
20 | 22 |
21 ProcessType g_process_type = ProcessType::UNINITIALIZED; | 23 ProcessType g_process_type = ProcessType::UNINITIALIZED; |
22 | 24 |
23 const wchar_t kRegValueChromeStatsSample[] = L"UsageStatsInSample"; | 25 const wchar_t kRegValueChromeStatsSample[] = L"UsageStatsInSample"; |
24 | 26 |
25 // TODO(ananta) | 27 // TODO(ananta) |
26 // http://crbug.com/604923 | 28 // http://crbug.com/604923 |
27 // The constants defined in this file are also defined in chrome/installer and | 29 // The constants defined in this file are also defined in chrome/installer and |
28 // other places. we need to unify them. | 30 // other places. we need to unify them. |
29 const wchar_t kHeadless[] = L"CHROME_HEADLESS"; | 31 const wchar_t kHeadless[] = L"CHROME_HEADLESS"; |
30 const wchar_t kShowRestart[] = L"CHROME_CRASHED"; | 32 const wchar_t kShowRestart[] = L"CHROME_CRASHED"; |
31 const wchar_t kRestartInfo[] = L"CHROME_RESTART"; | 33 const wchar_t kRestartInfo[] = L"CHROME_RESTART"; |
32 const wchar_t kRtlLocale[] = L"RIGHT_TO_LEFT"; | 34 const wchar_t kRtlLocale[] = L"RIGHT_TO_LEFT"; |
33 | 35 |
34 const char kGpuProcess[] = "gpu-process"; | 36 const wchar_t kCrashpadHandler[] = L"crashpad-handler"; |
35 const char kPpapiPluginProcess[] = "ppapi"; | 37 const wchar_t kProcessType[] = L"type"; |
36 const char kRendererProcess[] = "renderer"; | 38 const wchar_t kUserDataDirSwitch[] = L"user-data-dir"; |
37 const char kUtilityProcess[] = "utility"; | 39 const wchar_t kUtilityProcess[] = L"utility"; |
38 const char kProcessType[] = "type"; | |
39 const char kCrashpadHandler[] = "crashpad-handler"; | |
40 | 40 |
41 namespace { | 41 namespace { |
42 | 42 |
43 // TODO(ananta) | 43 // TODO(ananta) |
44 // http://crbug.com/604923 | 44 // http://crbug.com/604923 |
45 // The constants defined in this file are also defined in chrome/installer and | 45 // The constants defined in this file are also defined in chrome/installer and |
46 // other places. we need to unify them. | 46 // other places. we need to unify them. |
47 // Chrome channel display names. | 47 // Chrome channel display names. |
48 constexpr wchar_t kChromeChannelDev[] = L"dev"; | 48 constexpr wchar_t kChromeChannelDev[] = L"dev"; |
49 constexpr wchar_t kChromeChannelBeta[] = L"beta"; | 49 constexpr wchar_t kChromeChannelBeta[] = L"beta"; |
50 constexpr wchar_t kChromeChannelStableExplicit[] = L"stable"; | 50 constexpr wchar_t kChromeChannelStableExplicit[] = L"stable"; |
51 | 51 |
52 // TODO(ananta) | 52 // TODO(ananta) |
53 // http://crbug.com/604923 | 53 // http://crbug.com/604923 |
54 // These constants are defined in the chrome/installer directory as well. We | 54 // These constants are defined in the chrome/installer directory as well. We |
55 // need to unify them. | 55 // need to unify them. |
56 constexpr wchar_t kRegValueAp[] = L"ap"; | 56 constexpr wchar_t kRegValueAp[] = L"ap"; |
57 constexpr wchar_t kRegValueUsageStats[] = L"usagestats"; | 57 constexpr wchar_t kRegValueUsageStats[] = L"usagestats"; |
58 constexpr wchar_t kMetricsReportingEnabled[] = L"MetricsReportingEnabled"; | 58 constexpr wchar_t kMetricsReportingEnabled[] = L"MetricsReportingEnabled"; |
59 | 59 |
60 constexpr wchar_t kUserDataDirname[] = L"User Data"; | |
61 constexpr wchar_t kBrowserCrashDumpMetricsSubKey[] = | 60 constexpr wchar_t kBrowserCrashDumpMetricsSubKey[] = |
62 L"\\BrowserCrashDumpAttempts"; | 61 L"\\BrowserCrashDumpAttempts"; |
63 | 62 |
64 void Trace(const wchar_t* format_string, ...) { | 63 void Trace(const wchar_t* format_string, ...) { |
65 static const int kMaxLogBufferSize = 1024; | 64 static const int kMaxLogBufferSize = 1024; |
66 static wchar_t buffer[kMaxLogBufferSize] = {}; | 65 static wchar_t buffer[kMaxLogBufferSize] = {}; |
67 | 66 |
68 va_list args = {}; | 67 va_list args = {}; |
69 | 68 |
70 va_start(args, format_string); | 69 va_start(args, format_string); |
(...skipping 73 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
144 uint32_t size = 0; | 143 uint32_t size = 0; |
145 BOOL r = ::VerQueryValueW(version_resource, sub_block, &value, &size); | 144 BOOL r = ::VerQueryValueW(version_resource, sub_block, &value, &size); |
146 if (r && value) { | 145 if (r && value) { |
147 value_str->assign(static_cast<wchar_t*>(value)); | 146 value_str->assign(static_cast<wchar_t*>(value)); |
148 return true; | 147 return true; |
149 } | 148 } |
150 } | 149 } |
151 return false; | 150 return false; |
152 } | 151 } |
153 | 152 |
154 bool RecursiveDirectoryCreate(const std::wstring& full_path) { | 153 bool DirectoryExists(const std::wstring& path) { |
155 // If the path exists, we've succeeded if it's a directory, failed otherwise. | 154 DWORD file_attributes = ::GetFileAttributes(path.c_str()); |
156 const wchar_t* full_path_str = full_path.c_str(); | 155 if (file_attributes == INVALID_FILE_ATTRIBUTES) |
157 DWORD file_attributes = ::GetFileAttributes(full_path_str); | |
158 if (file_attributes != INVALID_FILE_ATTRIBUTES) { | |
159 if ((file_attributes & FILE_ATTRIBUTE_DIRECTORY) != 0) { | |
160 Trace(L"%hs( %ls directory exists )\n", __func__, full_path_str); | |
161 return true; | |
162 } | |
163 Trace(L"%hs( %ls directory conflicts with an existing file. )\n", __func__, | |
164 full_path_str); | |
165 return false; | 156 return false; |
166 } | 157 return (file_attributes & FILE_ATTRIBUTE_DIRECTORY) != 0; |
167 | |
168 // Invariant: Path does not exist as file or directory. | |
169 | |
170 // Attempt to create the parent recursively. This will immediately return | |
171 // true if it already exists, otherwise will create all required parent | |
172 // directories starting with the highest-level missing parent. | |
173 std::wstring parent_path; | |
174 std::size_t pos = full_path.find_last_of(L"/\\"); | |
175 if (pos != std::wstring::npos) { | |
176 parent_path = full_path.substr(0, pos); | |
177 if (!RecursiveDirectoryCreate(parent_path)) { | |
178 Trace(L"Failed to create one of the parent directories"); | |
179 return false; | |
180 } | |
181 } | |
182 if (!::CreateDirectory(full_path_str, nullptr)) { | |
183 DWORD error_code = ::GetLastError(); | |
184 if (error_code == ERROR_ALREADY_EXISTS) { | |
185 DWORD file_attributes = ::GetFileAttributes(full_path_str); | |
186 if ((file_attributes != INVALID_FILE_ATTRIBUTES) && | |
187 ((file_attributes & FILE_ATTRIBUTE_DIRECTORY) != 0)) { | |
188 // This error code ERROR_ALREADY_EXISTS doesn't indicate whether we | |
189 // were racing with someone creating the same directory, or a file | |
190 // with the same path. If the directory exists, we lost the | |
191 // race to create the same directory. | |
192 return true; | |
193 } else { | |
194 Trace(L"Failed to create directory %ls, last error is %d\n", | |
195 full_path_str, error_code); | |
196 return false; | |
197 } | |
198 } | |
199 } | |
200 return true; | |
201 } | |
202 | |
203 // Appends "[kCompanyPathName\]kProductPathName[install_suffix]" to |path|, | |
204 // returning a reference to |path|. | |
205 std::wstring& AppendChromeInstallSubDirectory(std::wstring* path, | |
206 bool include_suffix) { | |
207 if (*kCompanyPathName) { | |
208 path->append(kCompanyPathName); | |
209 path->push_back(L'\\'); | |
210 } | |
211 path->append(kProductPathName, kProductPathNameLength); | |
212 if (!include_suffix) | |
213 return *path; | |
214 return path->append(InstallDetails::Get().install_suffix()); | |
215 } | 158 } |
216 | 159 |
217 std::wstring GetChromeInstallRegistryPath() { | 160 std::wstring GetChromeInstallRegistryPath() { |
218 std::wstring registry_path = L"Software\\"; | 161 std::wstring registry_path = L"Software\\"; |
219 return AppendChromeInstallSubDirectory(®istry_path, | 162 return AppendChromeInstallSubDirectory(®istry_path, |
220 true /* include_suffix */); | 163 true /* include_suffix */, |
164 InstallDetails::Get()); | |
221 } | 165 } |
222 | 166 |
223 // Returns true if the |source| string matches the |pattern|. The pattern | 167 // Returns true if the |source| string matches the |pattern|. The pattern |
224 // may contain wildcards like '?' which matches one character or a '*' | 168 // may contain wildcards like '?' which matches one character or a '*' |
225 // which matches 0 or more characters. | 169 // which matches 0 or more characters. |
226 // Please note that pattern matches the whole string. If you want to find | 170 // Please note that pattern matches the whole string. If you want to find |
227 // something in the middle of the string then you need to specify the pattern | 171 // something in the middle of the string then you need to specify the pattern |
228 // as '*xyz*'. | 172 // as '*xyz*'. |
229 // |source_index| is the index of the current character being matched in | 173 // |source_index| is the index of the current character being matched in |
230 // |source|. | 174 // |source|. |
(...skipping 186 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
417 KEY_SET_VALUE | KEY_WOW64_32KEY, &key_handle)) { | 361 KEY_SET_VALUE | KEY_WOW64_32KEY, &key_handle)) { |
418 return false; | 362 return false; |
419 } | 363 } |
420 | 364 |
421 bool success = nt::SetRegValueDWORD(key_handle, kRegValueChromeStatsSample, | 365 bool success = nt::SetRegValueDWORD(key_handle, kRegValueChromeStatsSample, |
422 in_sample ? 1 : 0); | 366 in_sample ? 1 : 0); |
423 nt::CloseRegKey(key_handle); | 367 nt::CloseRegKey(key_handle); |
424 return success; | 368 return success; |
425 } | 369 } |
426 | 370 |
371 // Appends "[kCompanyPathName\]kProductPathName[install_suffix]" to |path|, | |
372 // returning a reference to |path|. | |
373 std::wstring& AppendChromeInstallSubDirectory(std::wstring* path, | |
grt (UTC plus 2)
2016/11/22 11:37:09
oops, i goofd when i wrote this -- |path| should b
scottmg
2016/11/22 17:16:07
Done.
| |
374 bool include_suffix, | |
375 const InstallDetails& details) { | |
376 if (*kCompanyPathName) { | |
377 path->append(kCompanyPathName); | |
378 path->push_back(L'\\'); | |
379 } | |
380 path->append(kProductPathName, kProductPathNameLength); | |
381 if (!include_suffix) | |
382 return *path; | |
383 return path->append(details.install_suffix()); | |
384 } | |
385 | |
427 bool ReportingIsEnforcedByPolicy(bool* crash_reporting_enabled) { | 386 bool ReportingIsEnforcedByPolicy(bool* crash_reporting_enabled) { |
428 std::wstring policies_path = L"SOFTWARE\\Policies\\"; | 387 std::wstring policies_path = L"SOFTWARE\\Policies\\"; |
429 AppendChromeInstallSubDirectory(&policies_path, false /* !include_suffix */); | 388 AppendChromeInstallSubDirectory(&policies_path, false /* !include_suffix */, |
389 InstallDetails::Get()); | |
430 DWORD value = 0; | 390 DWORD value = 0; |
431 | 391 |
432 // First, try HKLM. | 392 // First, try HKLM. |
433 if (nt::QueryRegValueDWORD(nt::HKLM, nt::NONE, policies_path.c_str(), | 393 if (nt::QueryRegValueDWORD(nt::HKLM, nt::NONE, policies_path.c_str(), |
434 kMetricsReportingEnabled, &value)) { | 394 kMetricsReportingEnabled, &value)) { |
435 *crash_reporting_enabled = (value != 0); | 395 *crash_reporting_enabled = (value != 0); |
436 return true; | 396 return true; |
437 } | 397 } |
438 | 398 |
439 // Second, try HKCU. | 399 // Second, try HKCU. |
(...skipping 26 matching lines...) Expand all Loading... | |
466 } | 426 } |
467 | 427 |
468 g_process_type = ProcessType::BROWSER_PROCESS; | 428 g_process_type = ProcessType::BROWSER_PROCESS; |
469 } | 429 } |
470 | 430 |
471 bool IsNonBrowserProcess() { | 431 bool IsNonBrowserProcess() { |
472 assert(g_process_type != ProcessType::UNINITIALIZED); | 432 assert(g_process_type != ProcessType::UNINITIALIZED); |
473 return g_process_type == ProcessType::NON_BROWSER_PROCESS; | 433 return g_process_type == ProcessType::NON_BROWSER_PROCESS; |
474 } | 434 } |
475 | 435 |
476 bool GetDefaultUserDataDirectory(std::wstring* result) { | 436 bool GetCrashDumpLocation(std::wstring* crash_dir) { |
grt (UTC plus 2)
2016/11/22 11:37:09
how about making this return the std::wstring sinc
scottmg
2016/11/22 17:16:07
Done.
| |
477 // This environment variable should be set on Windows Vista and later | 437 // In order to be able to start crash handling very early and in chrome_elf, |
478 // (https://msdn.microsoft.com/library/windows/desktop/dd378457.aspx). | 438 // we cannot rely on chrome's PathService entries (for DIR_CRASH_DUMPS) being |
479 std::wstring user_data_dir = GetEnvironmentString16(L"LOCALAPPDATA"); | 439 // available on Windows. See https://crbug.com/564398. |
480 | 440 *crash_dir = InstallDetails::Get().user_data_dir(); |
481 if (user_data_dir.empty()) { | |
482 // LOCALAPPDATA was not set; fallback to the temporary files path. | |
483 DWORD size = ::GetTempPath(0, nullptr); | |
484 if (!size) | |
485 return false; | |
486 user_data_dir.resize(size + 1); | |
487 size = ::GetTempPath(size + 1, &user_data_dir[0]); | |
488 if (!size || size >= user_data_dir.size()) | |
489 return false; | |
490 user_data_dir.resize(size); | |
491 } | |
492 | |
493 result->swap(user_data_dir); | |
494 if ((*result)[result->length() - 1] != L'\\') | |
495 result->push_back(L'\\'); | |
496 AppendChromeInstallSubDirectory(result, true /* include_suffix */); | |
497 result->push_back(L'\\'); | |
498 result->append(kUserDataDirname); | |
499 return true; | |
500 } | |
501 | |
502 bool GetDefaultCrashDumpLocation(std::wstring* crash_dir) { | |
503 // In order to be able to start crash handling very early, we do not rely on | |
504 // chrome's PathService entries (for DIR_CRASH_DUMPS) being available on | |
505 // Windows. See https://crbug.com/564398. | |
506 if (!GetDefaultUserDataDirectory(crash_dir)) | |
507 return false; | |
508 | |
509 // We have to make sure the user data dir exists on first run. See | |
510 // http://crbug.com/591504. | |
511 if (!RecursiveDirectoryCreate(*crash_dir)) | |
512 return false; | |
513 crash_dir->append(L"\\Crashpad"); | 441 crash_dir->append(L"\\Crashpad"); |
514 return true; | 442 return true; |
515 } | 443 } |
516 | 444 |
517 std::string GetEnvironmentString(const std::string& variable_name) { | 445 std::string GetEnvironmentString(const std::string& variable_name) { |
518 return UTF16ToUTF8( | 446 return UTF16ToUTF8( |
519 GetEnvironmentString16(UTF8ToUTF16(variable_name).c_str())); | 447 GetEnvironmentString16(UTF8ToUTF16(variable_name).c_str())); |
520 } | 448 } |
521 | 449 |
522 std::wstring GetEnvironmentString16(const wchar_t* variable_name) { | 450 std::wstring GetEnvironmentString16(const wchar_t* variable_name) { |
(...skipping 121 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
644 bool trim_spaces) { | 572 bool trim_spaces) { |
645 return TokenizeStringT<std::string>(str, delimiter, trim_spaces); | 573 return TokenizeStringT<std::string>(str, delimiter, trim_spaces); |
646 } | 574 } |
647 | 575 |
648 std::vector<std::wstring> TokenizeString16(const std::wstring& str, | 576 std::vector<std::wstring> TokenizeString16(const std::wstring& str, |
649 wchar_t delimiter, | 577 wchar_t delimiter, |
650 bool trim_spaces) { | 578 bool trim_spaces) { |
651 return TokenizeStringT<std::wstring>(str, delimiter, trim_spaces); | 579 return TokenizeStringT<std::wstring>(str, delimiter, trim_spaces); |
652 } | 580 } |
653 | 581 |
654 std::string GetSwitchValueFromCommandLine(const std::string& command_line, | 582 std::wstring GetSwitchValueFromCommandLine(const std::wstring& command_line, |
655 const std::string& switch_name) { | 583 const std::wstring& switch_name) { |
656 assert(!command_line.empty()); | 584 assert(!command_line.empty()); |
657 assert(!switch_name.empty()); | 585 assert(!switch_name.empty()); |
658 | 586 |
659 std::string command_line_copy = command_line; | 587 std::wstring command_line_copy = command_line; |
660 // Remove leading and trailing spaces. | 588 // Remove leading and trailing spaces. |
661 TrimT<std::string>(&command_line_copy); | 589 TrimT<std::wstring>(&command_line_copy); |
662 | 590 |
663 // Find the switch in the command line. If we don't find the switch, return | 591 // Find the switch in the command line. If we don't find the switch, return |
664 // an empty string. | 592 // an empty string. |
665 std::string switch_token = "--"; | 593 std::wstring switch_token = L"--"; |
666 switch_token += switch_name; | 594 switch_token += switch_name; |
667 switch_token += "="; | 595 switch_token += L"="; |
668 size_t switch_offset = command_line_copy.find(switch_token); | 596 size_t switch_offset = command_line_copy.find(switch_token); |
669 if (switch_offset == std::string::npos) | 597 if (switch_offset == std::string::npos) |
670 return std::string(); | 598 return std::wstring(); |
671 | 599 |
672 // The format is "--<switch name>=blah". Look for a space after the | 600 // The format is "--<switch name>=blah". Look for a space after the |
673 // "--<switch name>=" string. If we don't find a space assume that the switch | 601 // "--<switch name>=" string. If we don't find a space assume that the switch |
674 // value ends at the end of the command line. | 602 // value ends at the end of the command line. |
675 size_t switch_value_start_offset = switch_offset + switch_token.length(); | 603 size_t switch_value_start_offset = switch_offset + switch_token.length(); |
676 if (std::string(kWhiteSpaces).find( | 604 if (std::wstring(kWhiteSpaces16).find( |
677 command_line_copy[switch_value_start_offset]) != std::string::npos) { | 605 command_line_copy[switch_value_start_offset]) != std::wstring::npos) { |
678 switch_value_start_offset = command_line_copy.find_first_not_of( | 606 switch_value_start_offset = command_line_copy.find_first_not_of( |
679 GetWhiteSpacesForType<std::string>(), switch_value_start_offset); | 607 GetWhiteSpacesForType<std::wstring>(), switch_value_start_offset); |
680 if (switch_value_start_offset == std::string::npos) | 608 if (switch_value_start_offset == std::wstring::npos) |
681 return std::string(); | 609 return std::wstring(); |
682 } | 610 } |
683 size_t switch_value_end_offset = | 611 size_t switch_value_end_offset = |
684 command_line_copy.find_first_of(GetWhiteSpacesForType<std::string>(), | 612 command_line_copy.find_first_of(GetWhiteSpacesForType<std::wstring>(), |
685 switch_value_start_offset); | 613 switch_value_start_offset); |
686 if (switch_value_end_offset == std::string::npos) | 614 if (switch_value_end_offset == std::wstring::npos) |
687 switch_value_end_offset = command_line_copy.length(); | 615 switch_value_end_offset = command_line_copy.length(); |
688 | 616 |
689 std::string switch_value = command_line_copy.substr( | 617 std::wstring switch_value = command_line_copy.substr( |
690 switch_value_start_offset, | 618 switch_value_start_offset, |
691 switch_value_end_offset - (switch_offset + switch_token.length())); | 619 switch_value_end_offset - (switch_offset + switch_token.length())); |
692 TrimT<std::string>(&switch_value); | 620 TrimT<std::wstring>(&switch_value); |
693 return switch_value; | 621 return switch_value; |
694 } | 622 } |
695 | 623 |
624 bool RecursiveDirectoryCreate(const std::wstring& full_path) { | |
625 // If the path exists, we've succeeded if it's a directory, failed otherwise. | |
626 const wchar_t* full_path_str = full_path.c_str(); | |
627 DWORD file_attributes = ::GetFileAttributes(full_path_str); | |
628 if (file_attributes != INVALID_FILE_ATTRIBUTES) { | |
629 if ((file_attributes & FILE_ATTRIBUTE_DIRECTORY) != 0) { | |
630 Trace(L"%hs( %ls directory exists )\n", __func__, full_path_str); | |
631 return true; | |
632 } | |
633 Trace(L"%hs( %ls directory conflicts with an existing file. )\n", __func__, | |
634 full_path_str); | |
635 return false; | |
636 } | |
637 | |
638 // Invariant: Path does not exist as file or directory. | |
639 | |
640 // Attempt to create the parent recursively. This will immediately return | |
641 // true if it already exists, otherwise will create all required parent | |
642 // directories starting with the highest-level missing parent. | |
643 std::wstring parent_path; | |
644 std::size_t pos = full_path.find_last_of(L"/\\"); | |
645 if (pos != std::wstring::npos) { | |
646 parent_path = full_path.substr(0, pos); | |
647 if (!RecursiveDirectoryCreate(parent_path)) { | |
648 Trace(L"Failed to create one of the parent directories"); | |
649 return false; | |
650 } | |
651 } | |
652 if (!::CreateDirectory(full_path_str, nullptr)) { | |
653 DWORD error_code = ::GetLastError(); | |
654 if (error_code == ERROR_ALREADY_EXISTS && DirectoryExists(full_path_str)) { | |
655 // This error code ERROR_ALREADY_EXISTS doesn't indicate whether we | |
656 // were racing with someone creating the same directory, or a file | |
657 // with the same path. If the directory exists, we lost the | |
658 // race to create the same directory. | |
659 return true; | |
660 } else { | |
661 Trace(L"Failed to create directory %ls, last error is %d\n", | |
662 full_path_str, error_code); | |
663 return false; | |
664 } | |
665 } | |
666 return true; | |
667 } | |
668 | |
696 // This function takes these inputs rather than accessing the module's | 669 // This function takes these inputs rather than accessing the module's |
697 // InstallDetails instance since it is used to bootstrap InstallDetails. | 670 // InstallDetails instance since it is used to bootstrap InstallDetails. |
698 std::wstring DetermineChannel(const InstallConstants& mode, | 671 std::wstring DetermineChannel(const InstallConstants& mode, |
699 bool system_level, | 672 bool system_level, |
700 bool multi_install) { | 673 bool multi_install) { |
701 if (!kUseGoogleUpdateIntegration) | 674 if (!kUseGoogleUpdateIntegration) |
702 return std::wstring(); | 675 return std::wstring(); |
703 | 676 |
704 switch (mode.channel_strategy) { | 677 switch (mode.channel_strategy) { |
705 case ChannelStrategy::UNSUPPORTED: | 678 case ChannelStrategy::UNSUPPORTED: |
706 assert(false); | 679 assert(false); |
707 break; | 680 break; |
708 case ChannelStrategy::ADDITIONAL_PARAMETERS: | 681 case ChannelStrategy::ADDITIONAL_PARAMETERS: |
709 return ChannelFromAdditionalParameters(mode, system_level, multi_install); | 682 return ChannelFromAdditionalParameters(mode, system_level, multi_install); |
710 case ChannelStrategy::FIXED: | 683 case ChannelStrategy::FIXED: |
711 return mode.default_channel_name; | 684 return mode.default_channel_name; |
712 } | 685 } |
713 | 686 |
714 return std::wstring(); | 687 return std::wstring(); |
715 } | 688 } |
716 | 689 |
717 } // namespace install_static | 690 } // namespace install_static |
OLD | NEW |