Commit 7fe85d7b authored by Xi Cheng's avatar Xi Cheng Committed by Commit Bot

[notification_helper.exe] Add installation and uninstallation support

Test coverage is also added.

Bug: 734095
Change-Id: Id0fa36d078aa68ccbe4d2b820d55838303bbfdd9
Reviewed-on: https://chromium-review.googlesource.com/896743Reviewed-by: default avatarGreg Thompson <grt@chromium.org>
Commit-Queue: Xi Cheng <chengx@chromium.org>
Cr-Commit-Position: refs/heads/master@{#537797}
parent d215168c
...@@ -7,7 +7,7 @@ ...@@ -7,7 +7,7 @@
#include "chrome/installer/setup/install_worker.h" #include "chrome/installer/setup/install_worker.h"
#include <windows.h> // NOLINT #include <windows.h>
#include <atlsecurity.h> #include <atlsecurity.h>
#include <oaidl.h> #include <oaidl.h>
...@@ -16,6 +16,7 @@ ...@@ -16,6 +16,7 @@
#include <stddef.h> #include <stddef.h>
#include <stdint.h> #include <stdint.h>
#include <time.h> #include <time.h>
#include <wrl/client.h>
#include <memory> #include <memory>
#include <vector> #include <vector>
...@@ -175,6 +176,86 @@ void AddFirewallRulesWorkItems(const InstallerState& installer_state, ...@@ -175,6 +176,86 @@ void AddFirewallRulesWorkItems(const InstallerState& installer_state,
is_new_install)); is_new_install));
} }
// Probes COM machinery to get an instance of notification_helper.exe's
// NotificationActivator class.
//
// This is required so that COM purges its cache of the path to the binary,
// which changes on updates.
//
// This callback unconditionally returns true since an install should not be
// aborted if the probe fails.
bool ProbeNotificationActivatorCallback(const CLSID& toast_activator_clsid,
const CallbackWorkItem& work_item) {
DCHECK(toast_activator_clsid != CLSID_NULL);
// Noop on rollback.
if (work_item.IsRollback())
return true;
Microsoft::WRL::ComPtr<IUnknown> notification_activator;
HRESULT hr =
::CoCreateInstance(toast_activator_clsid, nullptr, CLSCTX_LOCAL_SERVER,
IID_PPV_ARGS(&notification_activator));
if (hr != REGDB_E_CLASSNOTREG) {
LOG(ERROR) << "Unexpected result creating NotificationActivator; hr=0x"
<< std::hex << hr;
}
return true;
}
// Adds work items to |list| to register a COM server with the OS, which is used
// to handle the toast notification activation.
void AddNativeNotificationWorkItems(const InstallerState& installer_state,
const base::FilePath& target_path,
const base::Version& new_version,
WorkItemList* list) {
base::string16 toast_activator_reg_path = GetToastActivatorRegistryPath();
if (toast_activator_reg_path.empty()) {
LOG(DFATAL) << "Cannot retrieve the toast activator registry path";
return;
}
HKEY root = installer_state.root_key();
// Delete the old registration before adding in the new key to ensure that the
// COM probe/flush below does its job. Delete both 64-bit and 32-bit keys to
// handle 32-bit -> 64-bit or 64-bit -> 32-bit migration.
list->AddDeleteRegKeyWorkItem(root, toast_activator_reg_path,
KEY_WOW64_32KEY);
list->AddDeleteRegKeyWorkItem(root, toast_activator_reg_path,
KEY_WOW64_64KEY);
// Force COM to flush its cache containing the path to the old handler.
list->AddCallbackWorkItem(
base::Bind(&ProbeNotificationActivatorCallback,
install_static::GetToastActivatorClsid()));
// The path to the exe (in the version directory).
base::FilePath notification_helper =
target_path.AppendASCII(new_version.GetString())
.Append(kNotificationHelperExe);
// Command-line featuring the quoted path to the exe.
base::string16 command(1, L'"');
command.append(notification_helper.value()).append(1, L'"');
toast_activator_reg_path.append(L"\\LocalServer32");
list->AddCreateRegKeyWorkItem(root, toast_activator_reg_path,
WorkItem::kWow64Default);
list->AddSetRegValueWorkItem(root, toast_activator_reg_path,
WorkItem::kWow64Default, L"", command, true);
list->AddSetRegValueWorkItem(root, toast_activator_reg_path,
WorkItem::kWow64Default, L"ServerExecutable",
notification_helper.value(), true);
}
// This is called when an MSI installation is run. It may be that a user is // This is called when an MSI installation is run. It may be that a user is
// attempting to install the MSI on top of a non-MSI managed installation. If // attempting to install the MSI on top of a non-MSI managed installation. If
// so, try and remove any existing "Add/Remove Programs" entry, as we want the // so, try and remove any existing "Add/Remove Programs" entry, as we want the
...@@ -811,6 +892,11 @@ void AddInstallWorkItems(const InstallationState& original_state, ...@@ -811,6 +892,11 @@ void AddInstallWorkItems(const InstallationState& original_state,
AddFirewallRulesWorkItems(installer_state, dist, current_version == nullptr, AddFirewallRulesWorkItems(installer_state, dist, current_version == nullptr,
install_list); install_list);
// We don't have a version check for Win10+ here so that Windows upgrades
// work.
AddNativeNotificationWorkItems(installer_state, target_path, new_version,
install_list);
InstallUtil::AddUpdateDowngradeVersionItem(installer_state.system_install(), InstallUtil::AddUpdateDowngradeVersionItem(installer_state.system_install(),
current_version, new_version, dist, current_version, new_version, dist,
install_list); install_list);
......
...@@ -7,6 +7,7 @@ ...@@ -7,6 +7,7 @@
#include "chrome/installer/setup/uninstall.h" #include "chrome/installer/setup/uninstall.h"
#include <windows.h> #include <windows.h>
#include <stddef.h> #include <stddef.h>
#include <stdint.h> #include <stdint.h>
...@@ -638,6 +639,15 @@ bool DeleteChromeRegistrationKeys(const InstallerState& installer_state, ...@@ -638,6 +639,15 @@ bool DeleteChromeRegistrationKeys(const InstallerState& installer_state,
reg_app_id.append(install_static::GetBaseAppId() + browser_entry_suffix); reg_app_id.append(install_static::GetBaseAppId() + browser_entry_suffix);
InstallUtil::DeleteRegistryKey(root, reg_app_id, WorkItem::kWow64Default); InstallUtil::DeleteRegistryKey(root, reg_app_id, WorkItem::kWow64Default);
// Delete Software\Classes\CLSID\|toast_activator_clsid|.
base::string16 toast_activator_reg_path = GetToastActivatorRegistryPath();
if (!toast_activator_reg_path.empty()) {
InstallUtil::DeleteRegistryKey(root, toast_activator_reg_path,
WorkItem::kWow64Default);
} else {
LOG(DFATAL) << "Cannot retrieve the toast activator registry path";
}
// Delete all Start Menu Internet registrations that refer to this Chrome. // Delete all Start Menu Internet registrations that refer to this Chrome.
{ {
using base::win::RegistryKeyIterator; using base::win::RegistryKeyIterator;
......
...@@ -41,6 +41,13 @@ ...@@ -41,6 +41,13 @@
}, },
"wow_key": "KEY_WOW64_32KEY" "wow_key": "KEY_WOW64_32KEY"
}, },
"HKEY_CURRENT_USER\\Software\\Classes\\CLSID\\$CHROME_TOAST_ACTIVATOR_CLSID_BETA\\LocalServer32": {
"exists": "required",
"values": {
"type": "SZ",
"data": "$LOCAL_APPDATA\\$CHROME_DIR_BETA\\Application\\$MINI_INSTALLER_FILE_VERSION\\notification_helper.exe"
}
},
"HKEY_CURRENT_USER\\Software\\Classes\\$CHROME_SHORT_NAME_BETA$USER_SPECIFIC_REGISTRY_SUFFIX": { "HKEY_CURRENT_USER\\Software\\Classes\\$CHROME_SHORT_NAME_BETA$USER_SPECIFIC_REGISTRY_SUFFIX": {
"exists": "forbidden" "exists": "forbidden"
} }
......
...@@ -28,6 +28,9 @@ ...@@ -28,6 +28,9 @@
"values": { "values": {
"$CHROME_LONG_NAME_BETA$USER_SPECIFIC_REGISTRY_SUFFIX": {} "$CHROME_LONG_NAME_BETA$USER_SPECIFIC_REGISTRY_SUFFIX": {}
} }
},
"HKEY_CURRENT_USER\\Software\\Classes\\CLSID\\$CHROME_TOAST_ACTIVATOR_CLSID_BETA": {
"exists": "forbidden"
} }
} }
} }
...@@ -41,6 +41,13 @@ ...@@ -41,6 +41,13 @@
}, },
"wow_key": "KEY_WOW64_32KEY" "wow_key": "KEY_WOW64_32KEY"
}, },
"HKEY_CURRENT_USER\\Software\\Classes\\CLSID\\$CHROME_TOAST_ACTIVATOR_CLSID_SXS\\LocalServer32": {
"exists": "required",
"values": {
"type": "SZ",
"data": "$LOCAL_APPDATA\\$CHROME_DIR_SXS\\Application\\$MINI_INSTALLER_FILE_VERSION\\notification_helper.exe"
}
},
"HKEY_CURRENT_USER\\Software\\Classes\\$CHROME_SHORT_NAME_SXS$USER_SPECIFIC_REGISTRY_SUFFIX": { "HKEY_CURRENT_USER\\Software\\Classes\\$CHROME_SHORT_NAME_SXS$USER_SPECIFIC_REGISTRY_SUFFIX": {
"exists": "forbidden" "exists": "forbidden"
} }
......
...@@ -28,6 +28,9 @@ ...@@ -28,6 +28,9 @@
"values": { "values": {
"$CHROME_LONG_NAME_SXS$USER_SPECIFIC_REGISTRY_SUFFIX": {} "$CHROME_LONG_NAME_SXS$USER_SPECIFIC_REGISTRY_SUFFIX": {}
} }
},
"HKEY_CURRENT_USER\\Software\\Classes\\CLSID\\$CHROME_TOAST_ACTIVATOR_CLSID_SXS": {
"exists": "forbidden"
} }
} }
} }
...@@ -41,6 +41,13 @@ ...@@ -41,6 +41,13 @@
}, },
"wow_key": "KEY_WOW64_32KEY" "wow_key": "KEY_WOW64_32KEY"
}, },
"HKEY_CURRENT_USER\\Software\\Classes\\CLSID\\$CHROME_TOAST_ACTIVATOR_CLSID_SXS\\LocalServer32": {
"exists": "required",
"values": {
"type": "SZ",
"data": "$LOCAL_APPDATA\\$CHROME_DIR_SXS\\Application\\$NEXT_VERSION_MINI_INSTALLER_FILE_VERSION\\notification_helper.exe"
}
},
"HKEY_CURRENT_USER\\Software\\Classes\\$CHROME_SHORT_NAME_SXS$USER_SPECIFIC_REGISTRY_SUFFIX": { "HKEY_CURRENT_USER\\Software\\Classes\\$CHROME_SHORT_NAME_SXS$USER_SPECIFIC_REGISTRY_SUFFIX": {
"exists": "forbidden" "exists": "forbidden"
} }
......
...@@ -41,6 +41,13 @@ ...@@ -41,6 +41,13 @@
}, },
"wow_key": "KEY_WOW64_32KEY" "wow_key": "KEY_WOW64_32KEY"
}, },
"HKEY_CURRENT_USER\\Software\\Classes\\CLSID\\$CHROME_TOAST_ACTIVATOR_CLSID_DEV\\LocalServer32": {
"exists": "required",
"values": {
"type": "SZ",
"data": "$LOCAL_APPDATA\\$CHROME_DIR_DEV\\Application\\$MINI_INSTALLER_FILE_VERSION\\notification_helper.exe"
}
},
"HKEY_CURRENT_USER\\Software\\Classes\\$CHROME_SHORT_NAME_DEV$USER_SPECIFIC_REGISTRY_SUFFIX": { "HKEY_CURRENT_USER\\Software\\Classes\\$CHROME_SHORT_NAME_DEV$USER_SPECIFIC_REGISTRY_SUFFIX": {
"exists": "forbidden" "exists": "forbidden"
} }
......
...@@ -28,6 +28,9 @@ ...@@ -28,6 +28,9 @@
"values": { "values": {
"$CHROME_LONG_NAME_DEV$USER_SPECIFIC_REGISTRY_SUFFIX": {} "$CHROME_LONG_NAME_DEV$USER_SPECIFIC_REGISTRY_SUFFIX": {}
} }
},
"HKEY_CURRENT_USER\\Software\\Classes\\CLSID\\$CHROME_TOAST_ACTIVATOR_CLSID_DEV": {
"exists": "forbidden"
} }
} }
} }
...@@ -55,6 +55,13 @@ ...@@ -55,6 +55,13 @@
}, },
"wow_key": "KEY_WOW64_32KEY" "wow_key": "KEY_WOW64_32KEY"
}, },
"HKEY_LOCAL_MACHINE\\Software\\Classes\\CLSID\\$CHROME_TOAST_ACTIVATOR_CLSID\\LocalServer32": {
"exists": "required",
"values": {
"type": "SZ",
"data": "$PROGRAM_FILES\\$CHROME_DIR\\Application\\$MINI_INSTALLER_FILE_VERSION\\notification_helper.exe"
}
},
"HKEY_LOCAL_MACHINE\\Software\\Classes\\$CHROME_SHORT_NAME": { "HKEY_LOCAL_MACHINE\\Software\\Classes\\$CHROME_SHORT_NAME": {
"exists": "forbidden" "exists": "forbidden"
} }
......
...@@ -55,6 +55,13 @@ ...@@ -55,6 +55,13 @@
}, },
"wow_key": "KEY_WOW64_32KEY" "wow_key": "KEY_WOW64_32KEY"
}, },
"HKEY_CURRENT_USER\\Software\\Classes\\CLSID\\$CHROME_TOAST_ACTIVATOR_CLSID\\LocalServer32": {
"exists": "required",
"values": {
"type": "SZ",
"data": "$LOCAL_APPDATA\\$CHROME_DIR\\Application\\$MINI_INSTALLER_FILE_VERSION\\notification_helper.exe"
}
},
"HKEY_CURRENT_USER\\Software\\Classes\\$CHROME_SHORT_NAME$USER_SPECIFIC_REGISTRY_SUFFIX": { "HKEY_CURRENT_USER\\Software\\Classes\\$CHROME_SHORT_NAME$USER_SPECIFIC_REGISTRY_SUFFIX": {
"exists": "forbidden" "exists": "forbidden"
} }
......
...@@ -49,6 +49,13 @@ ...@@ -49,6 +49,13 @@
}, },
"wow_key": "KEY_WOW64_32KEY" "wow_key": "KEY_WOW64_32KEY"
}, },
"HKEY_LOCAL_MACHINE\\Software\\Classes\\CLSID\\$CHROME_TOAST_ACTIVATOR_CLSID\\LocalServer32": {
"exists": "required",
"values": {
"type": "SZ",
"data": "$PROGRAM_FILES\\$CHROME_DIR\\Application\\$MINI_INSTALLER_FILE_VERSION\\notification_helper.exe"
}
},
"HKEY_LOCAL_MACHINE\\Software\\Classes\\$CHROME_SHORT_NAME": { "HKEY_LOCAL_MACHINE\\Software\\Classes\\$CHROME_SHORT_NAME": {
"exists": "forbidden" "exists": "forbidden"
}, },
......
...@@ -34,6 +34,9 @@ ...@@ -34,6 +34,9 @@
"values": { "values": {
"$CHROME_LONG_NAME": {} "$CHROME_LONG_NAME": {}
} }
},
"HKEY_LOCAL_MACHINE\\Software\\Classes\\CLSID\\$CHROME_TOAST_ACTIVATOR_CLSID": {
"exists": "forbidden"
} }
} }
} }
...@@ -49,6 +49,13 @@ ...@@ -49,6 +49,13 @@
}, },
"wow_key": "KEY_WOW64_32KEY" "wow_key": "KEY_WOW64_32KEY"
}, },
"HKEY_LOCAL_MACHINE\\Software\\Classes\\CLSID\\$CHROME_TOAST_ACTIVATOR_CLSID\\LocalServer32": {
"exists": "required",
"values": {
"type": "SZ",
"data": "$PROGRAM_FILES\\$CHROME_DIR\\Application\\$NEXT_VERSION_MINI_INSTALLER_FILE_VERSION\\notification_helper.exe"
}
},
"HKEY_LOCAL_MACHINE\\Software\\Classes\\$CHROME_SHORT_NAME": { "HKEY_LOCAL_MACHINE\\Software\\Classes\\$CHROME_SHORT_NAME": {
"exists": "forbidden" "exists": "forbidden"
}, },
......
...@@ -49,6 +49,13 @@ ...@@ -49,6 +49,13 @@
}, },
"wow_key": "KEY_WOW64_32KEY" "wow_key": "KEY_WOW64_32KEY"
}, },
"HKEY_CURRENT_USER\\Software\\Classes\\CLSID\\$CHROME_TOAST_ACTIVATOR_CLSID\\LocalServer32": {
"exists": "required",
"values": {
"type": "SZ",
"data": "$LOCAL_APPDATA\\$CHROME_DIR\\Application\\$MINI_INSTALLER_FILE_VERSION\\notification_helper.exe"
}
},
"HKEY_CURRENT_USER\\Software\\Classes\\$CHROME_SHORT_NAME$USER_SPECIFIC_REGISTRY_SUFFIX": { "HKEY_CURRENT_USER\\Software\\Classes\\$CHROME_SHORT_NAME$USER_SPECIFIC_REGISTRY_SUFFIX": {
"exists": "forbidden" "exists": "forbidden"
} }
......
...@@ -34,6 +34,9 @@ ...@@ -34,6 +34,9 @@
"values": { "values": {
"$CHROME_LONG_NAME$USER_SPECIFIC_REGISTRY_SUFFIX": {} "$CHROME_LONG_NAME$USER_SPECIFIC_REGISTRY_SUFFIX": {}
} }
},
"HKEY_CURRENT_USER\\Software\\Classes\\CLSID\\$CHROME_TOAST_ACTIVATOR_CLSID": {
"exists": "forbidden"
} }
} }
} }
...@@ -49,6 +49,13 @@ ...@@ -49,6 +49,13 @@
}, },
"wow_key": "KEY_WOW64_32KEY" "wow_key": "KEY_WOW64_32KEY"
}, },
"HKEY_CURRENT_USER\\Software\\Classes\\CLSID\\$CHROME_TOAST_ACTIVATOR_CLSID\\LocalServer32": {
"exists": "required",
"values": {
"type": "SZ",
"data": "$LOCAL_APPDATA\\$CHROME_DIR\\Application\\$NEXT_VERSION_MINI_INSTALLER_FILE_VERSION\\notification_helper.exe"
}
},
"HKEY_CURRENT_USER\\Software\\Classes\\$CHROME_SHORT_NAME$USER_SPECIFIC_REGISTRY_SUFFIX": { "HKEY_CURRENT_USER\\Software\\Classes\\$CHROME_SHORT_NAME$USER_SPECIFIC_REGISTRY_SUFFIX": {
"exists": "forbidden" "exists": "forbidden"
} }
......
...@@ -110,6 +110,14 @@ class VariableExpander: ...@@ -110,6 +110,14 @@ class VariableExpander:
* $VERSION_[XP/SERVER_2003/VISTA/WIN7/WIN8/WIN8_1/WIN10]: a 2-tuple * $VERSION_[XP/SERVER_2003/VISTA/WIN7/WIN8/WIN8_1/WIN10]: a 2-tuple
representing the version of the corresponding OS. representing the version of the corresponding OS.
* $WINDOWS_VERSION: a 2-tuple representing the current Windows version. * $WINDOWS_VERSION: a 2-tuple representing the current Windows version.
* $CHROME_TOAST_ACTIVATOR_CLSID: NotificationActivator's CLSID for
Chrome.
* $CHROME_TOAST_ACTIVATOR_CLSID_BETA: NotificationActivator's CLSID for
Chrome Beta.
* $CHROME_TOAST_ACTIVATOR_CLSID_DEV: NotificationActivator's CLSID for
Chrome Dev.
* $CHROME_TOAST_ACTIVATOR_CLSID_SXS: NotificationActivator's CLSID for
Chrome SxS.
Args: Args:
mini_installer_path: The path to a mini_installer. mini_installer_path: The path to a mini_installer.
...@@ -163,6 +171,8 @@ class VariableExpander: ...@@ -163,6 +171,8 @@ class VariableExpander:
'CHROME_CLIENT_STATE_KEY': ( 'CHROME_CLIENT_STATE_KEY': (
'Software\\Google\\Update\\ClientState\\' 'Software\\Google\\Update\\ClientState\\'
'{8A69D345-D564-463c-AFF1-A69D9E530F96}'), '{8A69D345-D564-463c-AFF1-A69D9E530F96}'),
'CHROME_TOAST_ACTIVATOR_CLSID': (
'{A2C6CB58-C076-425C-ACB7-6D19D64428CD}'),
'CHROME_DIR_BETA': 'Google\\Chrome Beta', 'CHROME_DIR_BETA': 'Google\\Chrome Beta',
'CHROME_DIR_DEV': 'Google\\Chrome Dev', 'CHROME_DIR_DEV': 'Google\\Chrome Dev',
'CHROME_DIR_SXS': 'Google\\Chrome SxS', 'CHROME_DIR_SXS': 'Google\\Chrome SxS',
...@@ -183,7 +193,13 @@ class VariableExpander: ...@@ -183,7 +193,13 @@ class VariableExpander:
'{4ea16ac7-fd5a-47c3-875b-dbf4a2008c20}'), '{4ea16ac7-fd5a-47c3-875b-dbf4a2008c20}'),
'LAUNCHER_UPDATE_REGISTRY_SUBKEY': ( 'LAUNCHER_UPDATE_REGISTRY_SUBKEY': (
'Software\\Google\\Update\\Clients\\' 'Software\\Google\\Update\\Clients\\'
'{FDA71E6F-AC4C-4a00-8B70-9958A68906BF}') '{FDA71E6F-AC4C-4a00-8B70-9958A68906BF}'),
'CHROME_TOAST_ACTIVATOR_CLSID_BETA': (
'{B89B137F-96AA-4AE2-98C4-6373EAA1EA4D}'),
'CHROME_TOAST_ACTIVATOR_CLSID_DEV': (
'{F01C03EB-D431-4C83-8D7A-902771E732FA}'),
'CHROME_TOAST_ACTIVATOR_CLSID_SXS': (
'{FA372A6E-149F-4E95-832D-8F698D40AD7F}'),
}) })
elif mini_installer_product_name == 'Chromium Installer': elif mini_installer_product_name == 'Chromium Installer':
self._variable_mapping.update({ self._variable_mapping.update({
...@@ -195,6 +211,8 @@ class VariableExpander: ...@@ -195,6 +211,8 @@ class VariableExpander:
'CHROME_SHORT_NAME': 'Chromium', 'CHROME_SHORT_NAME': 'Chromium',
'CHROME_UPDATE_REGISTRY_SUBKEY': 'Software\\Chromium', 'CHROME_UPDATE_REGISTRY_SUBKEY': 'Software\\Chromium',
'CHROME_CLIENT_STATE_KEY': 'Software\\Chromium', 'CHROME_CLIENT_STATE_KEY': 'Software\\Chromium',
'CHROME_TOAST_ACTIVATOR_CLSID': (
'{635EFA6F-08D6-4EC9-BD14-8A0FDE975159}'),
}) })
else: else:
raise KeyError("Unknown mini_installer product name '%s'" % raise KeyError("Unknown mini_installer product name '%s'" %
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment