Chromium Code Reviews| Index: chrome/installer/mini_installer/configuration.cc | 
| diff --git a/chrome/installer/mini_installer/configuration.cc b/chrome/installer/mini_installer/configuration.cc | 
| index 87e08be387e3c3eaaea5ebeac5b5d72a7bc5047b..d05f3da5bce92596997fa953c3d509bdc88a657e 100644 | 
| --- a/chrome/installer/mini_installer/configuration.cc | 
| +++ b/chrome/installer/mini_installer/configuration.cc | 
| @@ -7,7 +7,9 @@ | 
| #include <shellapi.h> // NOLINT | 
| #include "chrome/installer/mini_installer/appid.h" | 
| +#include "chrome/installer/mini_installer/mini_installer_constants.h" | 
| #include "chrome/installer/mini_installer/mini_installer_resource.h" | 
| +#include "chrome/installer/mini_installer/regkey.h" | 
| namespace mini_installer { | 
| @@ -19,6 +21,57 @@ Configuration::~Configuration() { | 
| Clear(); | 
| } | 
| +// When multi_install is true, we are potentially: | 
| +// 1. Performing a multi-install of some product(s) on a clean machine. | 
| +// Neither the product(s) nor the multi-installer will have a | 
| +// ClientState key in the registry, so there is no key to be modified. | 
| +// 2. Upgrading an existing multi-install. The multi-installer will have | 
| +// a ClientState key in the registry. Only it need be modified. | 
| +// 3. Migrating a single-install into a multi-install. The product will | 
| +// have a ClientState key in the registry. Only it need be modified. | 
| +// To handle all cases, we inspect the product's ClientState to see if it | 
| +// exists and its "ap" value does not contain "-multi". This is case 3, | 
| +// so we modify the product's ClientState. Otherwise, we check the | 
| +// multi-installer's ClientState and modify it if it exists. | 
| +// TODO(bcwhite): Write a unit test for this that uses registry virtualization. | 
| +void Configuration::SetChromeAppGuid() { | 
| + const HKEY root_key = | 
| + is_system_level_ ? HKEY_LOCAL_MACHINE : HKEY_CURRENT_USER; | 
| + const wchar_t* app_guid = | 
| + has_chrome_frame_ ? | 
| 
 
robertshield
2015/08/04 03:11:36
Maybe out of scope for your change, but why does t
 
bcwhite
2015/08/04 19:34:30
It was existing code.  At one point I had removed
 
robertshield
2015/08/05 18:39:48
SGTM.
 
 | 
| + google_update::kChromeFrameAppGuid : | 
| + google_update::kAppGuid; | 
| + | 
| + // This is the value for single-install and case 3. | 
| + chrome_app_guid_ = app_guid; | 
| + | 
| + if (is_multi_install_) { | 
| + ValueString value; | 
| + LONG ret = ERROR_SUCCESS; | 
| + if (ReadClientStateRegistryValue(root_key, app_guid, &ret, value)) { | 
| + // The product has a client state key. See if it's a single-install. | 
| + if (ret == ERROR_FILE_NOT_FOUND || | 
| + (ret == ERROR_SUCCESS && | 
| + !FindTagInStr(value.get(), kMultiInstallTag, NULL))) { | 
| + // yes -- case 3: use the existing key. | 
| + return; | 
| + } | 
| + } | 
| + // error, case 1, or case 2: modify the multi-installer's key. | 
| + chrome_app_guid_ = google_update::kMultiInstallAppGuid; | 
| + } | 
| +} | 
| + | 
| +bool Configuration::ReadClientStateRegistryValue( | 
| + const HKEY root_key, const wchar_t* app_guid, | 
| + LONG* retval, ValueString& value) { | 
| + RegKey key; | 
| + if (!RegKey::OpenClientStateKey(root_key, app_guid, KEY_QUERY_VALUE, &key)) | 
| + return false; | 
| + *retval = key.ReadSZValue(kApRegistryValue, value.get(), value.capacity()); | 
| + return true; | 
| +} | 
| + | 
| const wchar_t* Configuration::program() const { | 
| return args_ == NULL || argument_count_ < 1 ? NULL : args_[0]; | 
| } | 
| @@ -68,8 +121,11 @@ bool Configuration::ParseCommandLine(const wchar_t* command_line) { | 
| } | 
| // Single-install defaults to Chrome. | 
| - if (!is_multi_install_) | 
| + if (is_multi_install_) { | 
| + SetChromeAppGuid(); | 
| + } else { | 
| has_chrome_ = !has_chrome_frame_; | 
| + } | 
| } | 
| return args_ != NULL; |