blob: d4125191676bed67edbd33be122a78bd874c4129 [file] [log] [blame]
// Copyright 2018 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#ifndef CHROME_INSTALLER_UTIL_INSTALL_SERVICE_WORK_ITEM_IMPL_H_
#define CHROME_INSTALLER_UTIL_INSTALL_SERVICE_WORK_ITEM_IMPL_H_
#include <windows.h>
#include <vector>
#include "base/command_line.h"
#include "base/macros.h"
#include "base/strings/string16.h"
#include "base/win/scoped_handle.h"
#include "base/win/windows_types.h"
#include "chrome/installer/util/work_item_list.h"
namespace base {
class CommandLine;
} // namespace base
namespace installer {
// Helper class for the implementation of InstallServiceWorkItem.
class InstallServiceWorkItemImpl {
public:
struct ServiceConfig {
ServiceConfig();
ServiceConfig(uint32_t service_type,
uint32_t service_start_type,
uint32_t service_error_control,
const base::string16& service_cmd_line,
const base::char16* dependencies_multi_sz);
ServiceConfig(ServiceConfig&& rhs);
ServiceConfig& operator=(ServiceConfig&& rhs) = default;
~ServiceConfig();
bool is_valid;
uint32_t type;
uint32_t start_type;
uint32_t error_control;
base::string16 cmd_line;
std::vector<base::char16> dependencies;
DISALLOW_COPY_AND_ASSIGN(ServiceConfig);
};
InstallServiceWorkItemImpl(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);
~InstallServiceWorkItemImpl();
bool DoImpl();
void RollbackImpl();
bool DeleteServiceImpl();
// Member functions that help with service installation or upgrades.
bool IsServiceCorrectlyConfigured(const ServiceConfig& config);
bool DeleteCurrentService();
// Helper functions for service install/upgrade/delete/rollback.
bool OpenService();
bool GetServiceConfig(ServiceConfig* config) const;
// Stores in the registry a versioned service name generated by
// GenerateVersionedServiceName().
bool CreateAndSetServiceName() const;
// Returns the versioned service name if one exists in the registry under the
// named value service_name_. In other cases, it returns service_name_.
base::string16 GetCurrentServiceName() const;
// Returns a display name of the following format:
// "Chrome Elevation Service (ChromeElevationService)"
// or:
// "Chrome Elevation Service (ChromeElevationService1d59511c58deaa8)"
//
// The "Chrome Elevation Service" fragment is the display_name_, and the
// "ChromeElevationService1d59511c58deaa8" fragment is the versioned service
// name returned from GetCurrentServiceName().
base::string16 GetCurrentServiceDisplayName() const;
// Copies and returns a vector containing a sequence of C-style strings
// terminated with '\0\0'. Return an empty vector if the input is nullptr.
static std::vector<base::char16> MultiSzToVector(
const base::char16* multi_sz);
private:
class ScHandleTraits {
public:
using Handle = SC_HANDLE;
static bool CloseHandle(SC_HANDLE handle) {
return ::CloseServiceHandle(handle) != FALSE;
}
static bool IsHandleValid(SC_HANDLE handle) { return handle != nullptr; }
static SC_HANDLE NullHandle() { return nullptr; }
private:
DISALLOW_IMPLICIT_CONSTRUCTORS(ScHandleTraits);
};
using ScopedScHandle =
base::win::GenericScopedHandle<ScHandleTraits,
base::win::DummyVerifierTraits>;
// This is the core functionality for installing the Windows Service itself.
bool DoInstallService();
// This is the core functionality for COM registration for the Service.
bool DoComRegistration();
// Member functions that help with service installation or upgrades.
bool InstallNewService();
// Upgrades an existing service's configuration in-place. Returns true if the
// service was already properly configured, or if it was successfully
// upgraded; otherwise, returns false in case of any failure.
// Side-effects of this function:
// * Saves the original service's config in |original_service_config_| if
// the new service configuration will be different.
// |original_service_config_| is used in rollback scenarios, specifically
// in ReinstallOriginalService() and RestoreOriginalServiceConfig().
// * Sets |rollback_existing_service_| to true if the service is
// successfully upgraded, which is used by RollbackImpl().
bool UpgradeService();
// Member functions that help with rollbacks.
bool ReinstallOriginalService();
bool RestoreOriginalServiceConfig();
// Helper functions for service install/upgrade/delete/rollback.
bool InstallService(const ServiceConfig& config);
bool ChangeServiceConfig(const ServiceConfig& config);
bool DeleteService(ScopedScHandle service) const;
// Generates a versioned service name prefixed with service_name_ and suffixed
// with the current system time in hexadecimal format.
base::string16 GenerateVersionedServiceName() const;
// Persists the given service name in the registry.
bool SetServiceName(const base::string16& service_name) const;
// The COM registration is done using a contained WorkItemList.
std::unique_ptr<WorkItemList> com_registration_work_items_;
// The service name, or in the case of a conflict, the prefix for the service
// name.
const base::string16 service_name_;
// The service name displayed to the user.
const base::string16 display_name_;
// The desired service command line.
const base::CommandLine service_cmd_line_;
// The path under HKEY_LOCAL_MACHINE where the service persists information,
// such as a versioned service name. For legacy reasons, this path is mapped
// 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 Interface/Typelib registration is required, |iid| would contain a
// valid IID.
const GUID iid_;
ScopedScHandle scm_;
ScopedScHandle service_;
// Rollback-specific data.
// True if original_service_config_ and service_ are both valid, and the
// former should be applied to the latter on rollback.
bool rollback_existing_service_;
// True if service_ represents a newly-installed service that is to be deleted
// on rollback.
bool rollback_new_service_;
// The configuration of a pre-existing service on the machine that may have
// been modified or deleted.
ServiceConfig original_service_config_;
// The service name prior to any modifications; may be either |service_name_|
// or a value read from the registry.
base::string16 original_service_name_;
// True if a pre-existing service (named |original_service_name_|) could not
// be deleted and still exists on rollback.
bool original_service_still_exists_;
DISALLOW_COPY_AND_ASSIGN(InstallServiceWorkItemImpl);
};
} // namespace installer
#endif // CHROME_INSTALLER_UTIL_INSTALL_SERVICE_WORK_ITEM_IMPL_H_