Commit 83e1dbb3 authored by S. Ganesh's avatar S. Ganesh Committed by Commit Bot

InstallServiceWorkItem multiple class registration support

Multiple class registration functionality is needed to allow for both
the Control and Update service in a single system service.

Bug: 1112572
Change-Id: Ied14f5f61dd35b938faaaa3cc1198f815f91d3df
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2335806
Commit-Queue: S. Ganesh <ganesh@chromium.org>
Reviewed-by: default avatarSorin Jianu <sorin@chromium.org>
Reviewed-by: default avatarGreg Thompson <grt@chromium.org>
Cr-Commit-Position: refs/heads/master@{#794754}
parent e0a6616f
......@@ -395,7 +395,7 @@ void AddElevationServiceWorkItems(const base::FilePath& elevation_service_path,
install_static::GetElevationServiceDisplayName(),
base::CommandLine(elevation_service_path),
install_static::GetClientStateKeyPath(),
install_static::GetElevatorClsid(), install_static::GetElevatorIid());
{install_static::GetElevatorClsid()}, {install_static::GetElevatorIid()});
install_service_work_item->set_best_effort(true);
list->AddWorkItem(install_service_work_item);
}
......
......@@ -679,8 +679,8 @@ bool DeleteChromeRegistrationKeys(const InstallerState& installer_state,
if (!InstallServiceWorkItem::DeleteService(
install_static::GetElevationServiceName(),
install_static::GetClientStateKeyPath(),
install_static::GetElevatorClsid(),
install_static::GetElevatorIid())) {
{install_static::GetElevatorClsid()},
{install_static::GetElevatorIid()})) {
LOG(WARNING) << "Failed to delete "
<< install_static::GetElevationServiceName();
}
......
......@@ -14,14 +14,14 @@ InstallServiceWorkItem::InstallServiceWorkItem(
const base::string16& display_name,
const base::CommandLine& service_cmd_line,
const base::string16& registry_path,
const GUID& clsid,
const GUID& iid)
const std::vector<GUID>& clsids,
const std::vector<GUID>& iids)
: impl_(std::make_unique<InstallServiceWorkItemImpl>(service_name,
display_name,
service_cmd_line,
registry_path,
clsid,
iid)) {}
clsids,
iids)) {}
InstallServiceWorkItem::~InstallServiceWorkItem() = default;
......@@ -36,12 +36,12 @@ void InstallServiceWorkItem::RollbackImpl() {
// static
bool InstallServiceWorkItem::DeleteService(const base::string16& service_name,
const base::string16& registry_path,
const GUID& clsid,
const GUID& iid) {
const std::vector<GUID>& clsids,
const std::vector<GUID>& iids) {
return InstallServiceWorkItemImpl(
service_name, base::string16(),
base::CommandLine(base::CommandLine::NO_PROGRAM), registry_path,
clsid, iid)
clsids, iids)
.DeleteServiceImpl();
}
......
......@@ -13,6 +13,7 @@
#define CHROME_INSTALLER_UTIL_INSTALL_SERVICE_WORK_ITEM_H_
#include <memory>
#include <vector>
#include "base/macros.h"
#include "base/strings/string16.h"
......@@ -47,25 +48,22 @@ class InstallServiceWorkItem : public WorkItem {
// persist a versioned service name. An example |registry_path| is
// "Software\ProductFoo".
//
// |clsid| is the CLSID and AppId to register.
// If COM CLSID/AppId registration is not required, pass in GUID_NULL for
// |clsid|.
// |iid| is the Interface and Typelib to register.
// If COM Interface/Typelib registration is not required, pass in
// GUID_NULL for |iid|.
// If COM CLSID/AppId registration is required, |clsids| should contain the
// CLSIDs and AppIds to register. If COM Interface/Typelib registration is
// required, |iids| should contain the Interfaces and Typelibs to register.
InstallServiceWorkItem(const base::string16& service_name,
const base::string16& display_name,
const base::CommandLine& service_cmd_line,
const base::string16& registry_path,
const GUID& clsid,
const GUID& iid);
const std::vector<GUID>& clsids,
const std::vector<GUID>& iids);
~InstallServiceWorkItem() override;
static bool DeleteService(const base::string16& service_name,
const base::string16& registry_path,
const GUID& clsid,
const GUID& iid);
const std::vector<GUID>& clsids,
const std::vector<GUID>& iids);
private:
friend class InstallServiceWorkItemTest;
......
......@@ -147,15 +147,15 @@ InstallServiceWorkItemImpl::InstallServiceWorkItemImpl(
const base::string16& display_name,
const base::CommandLine& service_cmd_line,
const base::string16& registry_path,
const GUID& clsid,
const GUID& iid)
const std::vector<GUID>& clsids,
const std::vector<GUID>& iids)
: com_registration_work_items_(WorkItem::CreateWorkItemList()),
service_name_(service_name),
display_name_(display_name),
service_cmd_line_(service_cmd_line),
registry_path_(registry_path),
clsid_(clsid),
iid_(iid),
clsids_(clsids),
iids_(iids),
rollback_existing_service_(false),
rollback_new_service_(false),
original_service_still_exists_(false) {}
......@@ -232,15 +232,15 @@ bool InstallServiceWorkItemImpl::DoInstallService() {
}
bool InstallServiceWorkItemImpl::DoComRegistration() {
if (clsid_ != GUID_NULL) {
const base::string16 clsid_reg_path = GetComClsidRegistryPath(clsid_);
const base::string16 appid_reg_path = GetComAppidRegistryPath(clsid_);
for (const auto& clsid : clsids_) {
const base::string16 clsid_reg_path = GetComClsidRegistryPath(clsid);
const base::string16 appid_reg_path = GetComAppidRegistryPath(clsid);
com_registration_work_items_->AddCreateRegKeyWorkItem(
HKEY_LOCAL_MACHINE, clsid_reg_path, WorkItem::kWow64Default);
com_registration_work_items_->AddSetRegValueWorkItem(
HKEY_LOCAL_MACHINE, clsid_reg_path, WorkItem::kWow64Default, L"AppID",
base::win::WStringFromGUID(clsid_), true);
base::win::WStringFromGUID(clsid), true);
com_registration_work_items_->AddCreateRegKeyWorkItem(
HKEY_LOCAL_MACHINE, appid_reg_path, WorkItem::kWow64Default);
com_registration_work_items_->AddSetRegValueWorkItem(
......@@ -248,9 +248,9 @@ bool InstallServiceWorkItemImpl::DoComRegistration() {
L"LocalService", GetCurrentServiceName(), true);
}
if (iid_ != GUID_NULL) {
const base::string16 iid_reg_path = GetComIidRegistryPath(iid_);
const base::string16 typelib_reg_path = GetComTypeLibRegistryPath(iid_);
for (const auto& iid : iids_) {
const base::string16 iid_reg_path = GetComIidRegistryPath(iid);
const base::string16 typelib_reg_path = GetComTypeLibRegistryPath(iid);
// Registering the Ole Automation marshaler with the CLSID
// {00020424-0000-0000-C000-000000000046} as the proxy/stub for the
......@@ -269,7 +269,7 @@ bool InstallServiceWorkItemImpl::DoComRegistration() {
WorkItem::kWow64Default);
com_registration_work_items_->AddSetRegValueWorkItem(
HKEY_LOCAL_MACHINE, iid_reg_path + L"\\TypeLib",
WorkItem::kWow64Default, L"", base::win::WStringFromGUID(iid_), true);
WorkItem::kWow64Default, L"", base::win::WStringFromGUID(iid), true);
com_registration_work_items_->AddSetRegValueWorkItem(
HKEY_LOCAL_MACHINE, iid_reg_path + L"\\TypeLib",
WorkItem::kWow64Default, L"Version", L"1.0", true);
......@@ -359,20 +359,22 @@ void InstallServiceWorkItemImpl::RollbackImpl() {
bool InstallServiceWorkItemImpl::DeleteServiceImpl() {
// Uninstall the elevation service.
if (clsid_ != GUID_NULL) {
for (const auto& clsid : clsids_) {
for (const auto& reg_path :
{GetComClsidRegistryPath(clsid_), GetComAppidRegistryPath(clsid_)}) {
{GetComClsidRegistryPath(clsid), GetComAppidRegistryPath(clsid)}) {
InstallUtil::DeleteRegistryKey(HKEY_LOCAL_MACHINE, reg_path,
WorkItem::kWow64Default);
}
}
if (iid_ != GUID_NULL) {
for (const auto& iid : iids_) {
for (const auto& reg_path :
{GetComIidRegistryPath(iid_), GetComTypeLibRegistryPath(iid_)}) {
{GetComIidRegistryPath(iid), GetComTypeLibRegistryPath(iid)}) {
InstallUtil::DeleteRegistryKey(HKEY_LOCAL_MACHINE, reg_path,
WorkItem::kWow64Default);
}
}
scm_.Set(::OpenSCManager(nullptr, nullptr, SC_MANAGER_CONNECT));
if (!scm_.IsValid()) {
DPLOG(ERROR) << "::OpenSCManager Failed";
......
......@@ -54,8 +54,8 @@ class InstallServiceWorkItemImpl {
const base::string16& display_name,
const base::CommandLine& service_cmd_line,
const base::string16& registry_path,
const GUID& clsid,
const GUID& iid);
const std::vector<GUID>& clsids,
const std::vector<GUID>& iids);
~InstallServiceWorkItemImpl();
......@@ -170,13 +170,12 @@ class InstallServiceWorkItemImpl {
// to the 32-bit view of the registry.
const base::string16 registry_path_;
// If COM CLSID/AppId registration is required, |clsid| would contain a valid
// CLSID.
const GUID clsid_;
// If COM CLSID/AppId registration is required, |clsids_| would be populated.
const std::vector<GUID> clsids_;
// If COM Interface/Typelib registration is required, |iid| would contain a
// valid IID.
const GUID iid_;
// If COM Interface/Typelib registration is required, |iids_| would be
// populated.
const std::vector<GUID> iids_;
ScopedScHandle scm_;
ScopedScHandle service_;
......
......@@ -36,6 +36,8 @@ constexpr GUID kClsid = {0x76ede292,
0x9c33,
0x4a09,
{0x9b, 0x3a, 0x3b, 0x88, 0xd, 0xf6, 0x44, 0x40}};
const std::vector<GUID> kClsids = {kClsid};
constexpr base::char16 kClsidRegPath[] =
L"Software\\Classes\\CLSID\\{76EDE292-9C33-4A09-9B3A-3B880DF64440}";
constexpr base::char16 kAppidRegPath[] =
......@@ -46,6 +48,8 @@ constexpr GUID kIid = {0xf9a0c1c,
0xa94a,
0x4c0a,
{0x93, 0xc7, 0x81, 0x33, 0x5, 0x26, 0xac, 0x7b}};
const std::vector<GUID> kIids = {kIid};
#define IID_REGISTRY_PATH \
L"Software\\Classes\\Interface\\{0F9A0C1C-A94A-4C0A-93C7-81330526AC7B}"
constexpr base::char16 kIidPSRegPath[] =
......@@ -116,7 +120,7 @@ TEST_F(InstallServiceWorkItemTest, Do_FreshInstall) {
auto item = std::make_unique<InstallServiceWorkItem>(
kServiceName, kServiceDisplayName,
base::CommandLine(base::FilePath(kServiceProgramPath)), kProductRegPath,
kClsid, kIid);
kClsids, kIids);
ASSERT_TRUE(item->Do());
EXPECT_TRUE(GetImpl(item.get())->OpenService());
......@@ -177,21 +181,21 @@ TEST_F(InstallServiceWorkItemTest, Do_FreshInstallThenDeleteService) {
auto item = std::make_unique<InstallServiceWorkItem>(
kServiceName, kServiceDisplayName,
base::CommandLine(base::FilePath(kServiceProgramPath)), kProductRegPath,
kClsid, kIid);
kClsids, kIids);
ASSERT_TRUE(item->Do());
EXPECT_TRUE(GetImpl(item.get())->OpenService());
EXPECT_TRUE(IsServiceCorrectlyConfigured(item.get()));
EXPECT_TRUE(InstallServiceWorkItem::DeleteService(
kServiceName, kProductRegPath, kClsid, kIid));
kServiceName, kProductRegPath, kClsids, kIids));
}
TEST_F(InstallServiceWorkItemTest, Do_UpgradeNoChanges) {
auto item = std::make_unique<InstallServiceWorkItem>(
kServiceName, kServiceDisplayName,
base::CommandLine(base::FilePath(kServiceProgramPath)), kProductRegPath,
kClsid, kIid);
kClsids, kIids);
ASSERT_TRUE(item->Do());
EXPECT_TRUE(IsServiceCorrectlyConfigured(item.get()));
......@@ -200,7 +204,7 @@ TEST_F(InstallServiceWorkItemTest, Do_UpgradeNoChanges) {
auto item_upgrade = std::make_unique<InstallServiceWorkItem>(
kServiceName, kServiceDisplayName,
base::CommandLine(base::FilePath(kServiceProgramPath)), kProductRegPath,
kClsid, kIid);
kClsids, kIids);
EXPECT_TRUE(item_upgrade->Do());
item_upgrade->Rollback();
......@@ -213,7 +217,7 @@ TEST_F(InstallServiceWorkItemTest, Do_UpgradeChangedCmdLine) {
auto item = std::make_unique<InstallServiceWorkItem>(
kServiceName, kServiceDisplayName,
base::CommandLine(base::FilePath(kServiceProgramPath)), kProductRegPath,
kClsid, kIid);
kClsids, kIids);
ASSERT_TRUE(item->Do());
EXPECT_TRUE(IsServiceCorrectlyConfigured(item.get()));
......@@ -222,7 +226,7 @@ TEST_F(InstallServiceWorkItemTest, Do_UpgradeChangedCmdLine) {
auto item_upgrade = std::make_unique<InstallServiceWorkItem>(
kServiceName, kServiceDisplayName,
base::CommandLine::FromString(L"NewCmd.exe arg1 arg2"), kProductRegPath,
kClsid, kIid);
kClsids, kIids);
EXPECT_TRUE(item_upgrade->Do());
item_upgrade->Rollback();
......@@ -238,7 +242,7 @@ TEST_F(InstallServiceWorkItemTest, Do_ServiceName) {
auto item = std::make_unique<InstallServiceWorkItem>(
kServiceName, kServiceDisplayName,
base::CommandLine(base::FilePath(kServiceProgramPath)), kProductRegPath,
kClsid, kIid);
kClsids, kIids);
EXPECT_STREQ(kServiceName,
GetImpl(item.get())->GetCurrentServiceName().c_str());
......
......@@ -93,7 +93,7 @@ void AddComServiceWorkItems(const base::FilePath& com_service_path,
list->AddWorkItem(new installer::InstallServiceWorkItem(
kWindowsServiceName, kWindowsServiceName,
base::CommandLine(com_service_path), base::ASCIIToUTF16(UPDATER_KEY),
CLSID_UpdaterServiceClass, GUID_NULL));
{CLSID_UpdaterServiceClass}, {}));
}
// Adds work items to register the COM Interfaces with Windows.
......
......@@ -50,7 +50,7 @@ void DeleteComService() {
WorkItem::kWow64Default);
if (!installer::InstallServiceWorkItem::DeleteService(
kWindowsServiceName, base::ASCIIToUTF16(UPDATER_KEY),
CLSID_UpdaterServiceClass, GUID_NULL))
{CLSID_UpdaterServiceClass}, {}))
LOG(WARNING) << "DeleteService failed.";
}
......
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