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

Side by Side Diff: chrome/installer/mini_installer/configuration.cc

Issue 2507293005: Force migrate all clients from multi-install back to single-install. (Closed)
Patch Set: mini_installer too Created 4 years 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 (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
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
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
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698