Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2012 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/installer/mini_installer/configuration.h" | 5 #include "chrome/installer/mini_installer/configuration.h" |
| 6 | 6 |
| 7 #include <windows.h> | 7 #include <windows.h> |
| 8 #include <shellapi.h> // NOLINT | 8 #include <shellapi.h> // NOLINT |
| 9 #include <stddef.h> | 9 #include <stddef.h> |
| 10 | 10 |
| (...skipping 18 matching lines...) Expand all Loading... | |
| 29 } // namespace | 29 } // namespace |
| 30 | 30 |
| 31 Configuration::Configuration() : args_(NULL) { | 31 Configuration::Configuration() : args_(NULL) { |
| 32 Clear(); | 32 Clear(); |
| 33 } | 33 } |
| 34 | 34 |
| 35 Configuration::~Configuration() { | 35 Configuration::~Configuration() { |
| 36 Clear(); | 36 Clear(); |
| 37 } | 37 } |
| 38 | 38 |
| 39 // When multi_install is true, we are potentially: | 39 bool Configuration::Initialize(HMODULE module) { |
| 40 // 1. Performing a multi-install of some product(s) on a clean machine. | 40 Clear(); |
| 41 // Neither the product(s) nor the multi-installer will have a | 41 ReadResources(module); |
| 42 // ClientState key in the registry, so there is no key to be modified. | 42 return ParseCommandLine(::GetCommandLine()); |
| 43 // 2. Upgrading an existing multi-install. The multi-installer will have | |
| 44 // a ClientState key in the registry. Only it need be modified. | |
| 45 // 3. Migrating a single-install into a multi-install. The product will | |
| 46 // have a ClientState key in the registry. Only it need be modified. | |
| 47 // To handle all cases, we inspect the product's ClientState to see if it | |
| 48 // exists and its "ap" value does not contain "-multi". This is case 3, | |
| 49 // so we modify the product's ClientState. Otherwise, we check the | |
| 50 // multi-installer's ClientState and modify it if it exists. | |
| 51 // TODO(bcwhite): Write a unit test for this that uses registry virtualization. | |
| 52 void Configuration::SetChromeAppGuid() { | |
| 53 const HKEY root_key = | |
| 54 is_system_level_ ? HKEY_LOCAL_MACHINE : HKEY_CURRENT_USER; | |
| 55 const wchar_t* app_guid = | |
| 56 is_side_by_side_ ? google_update::kSxSAppGuid | |
| 57 : google_update::kAppGuid; | |
| 58 | |
| 59 // This is the value for single-install and case 3. | |
| 60 chrome_app_guid_ = app_guid; | |
| 61 | |
| 62 if (is_multi_install_) { | |
| 63 ValueString value; | |
| 64 LONG ret = ERROR_SUCCESS; | |
| 65 if (ReadClientStateRegistryValue(root_key, app_guid, &ret, value)) { | |
| 66 // The product has a client state key. See if it's a single-install. | |
| 67 if (ret == ERROR_FILE_NOT_FOUND || | |
| 68 (ret == ERROR_SUCCESS && | |
| 69 !FindTagInStr(value.get(), kMultiInstallTag, NULL))) { | |
| 70 // yes -- case 3: use the existing key. | |
| 71 return; | |
| 72 } | |
| 73 } | |
| 74 // error, case 1, or case 2: modify the multi-installer's key. | |
| 75 chrome_app_guid_ = google_update::kMultiInstallAppGuid; | |
| 76 } | |
| 77 } | |
| 78 | |
| 79 bool Configuration::ReadClientStateRegistryValue( | |
| 80 const HKEY root_key, const wchar_t* app_guid, | |
| 81 LONG* retval, ValueString& value) { | |
| 82 RegKey key; | |
| 83 if (!OpenClientStateKey(root_key, app_guid, KEY_QUERY_VALUE, &key)) | |
| 84 return false; | |
| 85 *retval = key.ReadSZValue(kApRegistryValue, value.get(), value.capacity()); | |
| 86 return true; | |
| 87 } | 43 } |
| 88 | 44 |
| 89 const wchar_t* Configuration::program() const { | 45 const wchar_t* Configuration::program() const { |
| 90 return args_ == NULL || argument_count_ < 1 ? NULL : args_[0]; | 46 return args_ == NULL || argument_count_ < 1 ? NULL : args_[0]; |
| 91 } | 47 } |
| 92 | 48 |
| 93 void Configuration::Clear() { | 49 void Configuration::Clear() { |
| 94 if (args_ != NULL) { | 50 if (args_ != NULL) { |
| 95 ::LocalFree(args_); | 51 ::LocalFree(args_); |
| 96 args_ = NULL; | 52 args_ = NULL; |
| 97 } | 53 } |
| 98 chrome_app_guid_ = google_update::kAppGuid; | 54 chrome_app_guid_ = google_update::kAppGuid; |
| 99 command_line_ = NULL; | 55 command_line_ = NULL; |
| 100 operation_ = INSTALL_PRODUCT; | 56 operation_ = INSTALL_PRODUCT; |
| 101 argument_count_ = 0; | 57 argument_count_ = 0; |
| 102 has_chrome_ = false; | |
| 103 is_multi_install_ = false; | |
| 104 is_system_level_ = false; | 58 is_system_level_ = false; |
| 105 is_side_by_side_ = false; | 59 is_side_by_side_ = false; |
| 60 is_updating_multi_chrome_ = false; | |
| 106 has_invalid_switch_ = false; | 61 has_invalid_switch_ = false; |
| 107 previous_version_ = NULL; | 62 previous_version_ = NULL; |
| 108 } | 63 } |
| 109 | 64 |
| 110 bool Configuration::Initialize(HMODULE module) { | |
| 111 Clear(); | |
| 112 ReadResources(module); | |
| 113 return ParseCommandLine(::GetCommandLine()); | |
| 114 } | |
| 115 | |
| 116 // |command_line| is shared with this instance in the sense that this | 65 // |command_line| is shared with this instance in the sense that this |
| 117 // instance may refer to it at will throughout its lifetime, yet it will | 66 // instance may refer to it at will throughout its lifetime, yet it will |
| 118 // not release it. | 67 // not release it. |
| 119 bool Configuration::ParseCommandLine(const wchar_t* command_line) { | 68 bool Configuration::ParseCommandLine(const wchar_t* command_line) { |
| 120 command_line_ = command_line; | 69 command_line_ = command_line; |
| 121 args_ = ::CommandLineToArgvW(command_line_, &argument_count_); | 70 args_ = ::CommandLineToArgvW(command_line_, &argument_count_); |
| 122 if (!args_) | 71 if (!args_) |
| 123 return false; | 72 return false; |
| 124 | 73 |
| 125 for (int i = 1; i < argument_count_; ++i) { | 74 for (int i = 1; i < argument_count_; ++i) { |
| 126 if (0 == ::lstrcmpi(args_[i], L"--chrome-sxs")) | 75 if (0 == ::lstrcmpi(args_[i], L"--system-level")) |
| 76 is_system_level_ = true; | |
| 77 #if defined(GOOGLE_CHROME_BUILD) | |
| 78 else if (0 == ::lstrcmpi(args_[i], L"--chrome-sxs")) | |
| 127 is_side_by_side_ = true; | 79 is_side_by_side_ = true; |
| 128 else if (0 == ::lstrcmpi(args_[i], L"--chrome")) | 80 #endif |
| 129 has_chrome_ = true; | |
| 130 else if (0 == ::lstrcmpi(args_[i], L"--multi-install")) | |
| 131 is_multi_install_ = true; | |
| 132 else if (0 == ::lstrcmpi(args_[i], L"--system-level")) | |
| 133 is_system_level_ = true; | |
| 134 else if (0 == ::lstrcmpi(args_[i], L"--cleanup")) | 81 else if (0 == ::lstrcmpi(args_[i], L"--cleanup")) |
| 135 operation_ = CLEANUP; | 82 operation_ = CLEANUP; |
| 136 else if (0 == ::lstrcmpi(args_[i], L"--chrome-frame")) | 83 else if (0 == ::lstrcmpi(args_[i], L"--chrome-frame")) |
| 137 has_invalid_switch_ = true; | 84 has_invalid_switch_ = true; |
| 138 } | 85 } |
| 139 | 86 |
| 140 if (!is_system_level_) | 87 if (!is_system_level_) |
| 141 is_system_level_ = GetGoogleUpdateIsMachineEnvVar(); | 88 is_system_level_ = GetGoogleUpdateIsMachineEnvVar(); |
| 142 SetChromeAppGuid(); | 89 if (is_side_by_side_) |
| 143 if (!is_multi_install_) | 90 chrome_app_guid_ = google_update::kSxSAppGuid; |
|
gab
2016/12/12 21:38:16
Set this in above block on line 79
grt (UTC plus 2)
2016/12/13 09:20:37
Done.
| |
| 144 has_chrome_ = true; | 91 |
| 92 is_updating_multi_chrome_ = IsUpdatingMultiChrome(); | |
| 145 | 93 |
| 146 return true; | 94 return true; |
| 147 } | 95 } |
| 148 | 96 |
| 149 void Configuration::ReadResources(HMODULE module) { | 97 void Configuration::ReadResources(HMODULE module) { |
| 150 HRSRC resource_info_block = | 98 HRSRC resource_info_block = |
| 151 FindResource(module, MAKEINTRESOURCE(ID_PREVIOUS_VERSION), RT_RCDATA); | 99 FindResource(module, MAKEINTRESOURCE(ID_PREVIOUS_VERSION), RT_RCDATA); |
| 152 if (!resource_info_block) | 100 if (!resource_info_block) |
| 153 return; | 101 return; |
| 154 | 102 |
| (...skipping 13 matching lines...) Expand all Loading... | |
| 168 const wchar_t* version_string = reinterpret_cast<wchar_t*>(version_data); | 116 const wchar_t* version_string = reinterpret_cast<wchar_t*>(version_data); |
| 169 size_t version_len = version_size / sizeof(wchar_t); | 117 size_t version_len = version_size / sizeof(wchar_t); |
| 170 | 118 |
| 171 // The string must be terminated. | 119 // The string must be terminated. |
| 172 if (version_string[version_len - 1]) | 120 if (version_string[version_len - 1]) |
| 173 return; | 121 return; |
| 174 | 122 |
| 175 previous_version_ = version_string; | 123 previous_version_ = version_string; |
| 176 } | 124 } |
| 177 | 125 |
| 126 LONG Configuration::ReadRegistryValue(RegistryLocation location, | |
| 127 const wchar_t* app_guid, | |
| 128 const wchar_t* value_name, | |
| 129 ValueString* value) const { | |
| 130 RegKey key; | |
| 131 LONG result = location == RegistryLocation::CLIENTS_KEY | |
| 132 ? OpenClientsKey(is_system_level_ ? HKEY_LOCAL_MACHINE | |
| 133 : HKEY_CURRENT_USER, | |
| 134 app_guid, KEY_QUERY_VALUE, &key) | |
| 135 : OpenClientStateKey(is_system_level_ ? HKEY_LOCAL_MACHINE | |
| 136 : HKEY_CURRENT_USER, | |
| 137 app_guid, KEY_QUERY_VALUE, &key); | |
| 138 if (result == ERROR_SUCCESS) | |
| 139 result = key.ReadSZValue(value_name, value->get(), value->capacity()); | |
| 140 return result; | |
| 141 } | |
| 142 | |
| 143 bool Configuration::IsUpdatingMultiChrome() const { | |
|
gab
2016/12/12 21:38:16
Writing my assumptions here:
1) We update from m
grt (UTC plus 2)
2016/12/13 09:20:37
This CL ensures that "--multi-install" on the comm
| |
| 144 #if defined(GOOGLE_CHROME_BUILD) | |
| 145 // SxS/canary does not support multi-install. | |
| 146 if (is_side_by_side_) | |
| 147 return false; | |
| 148 | |
| 149 // Is Chrome already installed as multi-install? | |
| 150 ValueString value; | |
| 151 return (ReadRegistryValue(RegistryLocation::CLIENTS_KEY, | |
| 152 google_update::kAppGuid, kPvRegistryValue, | |
| 153 &value) == ERROR_SUCCESS && | |
| 154 value.length() != 0 && | |
| 155 ReadRegistryValue( | |
| 156 RegistryLocation::CLIENT_STATE_KEY, google_update::kAppGuid, | |
| 157 kUninstallArgumentsRegistryValue, &value) == ERROR_SUCCESS && | |
| 158 value.findi(L"--multi-install") != nullptr); | |
| 159 #else | |
| 160 return false; | |
| 161 #endif | |
| 162 } | |
| 163 | |
| 178 } // namespace mini_installer | 164 } // namespace mini_installer |
| OLD | NEW |