Skip to content

Commit

Permalink
Re-factored service controlled for using in new UI.
Browse files Browse the repository at this point in the history
Two Install methods to distinguish between different install cases.
Methods to query service status.


BUG=229183

Review URL: https://chromiumcodereview.appspot.com/13845002

git-svn-id: svn://svn.chromium.org/chrome/trunk/src@193216 0039d316-1c4b-4281-b951-d872f2087c98
  • Loading branch information
vitalybuka@chromium.org committed Apr 9, 2013
1 parent 15852e4 commit 8e6e936
Show file tree
Hide file tree
Showing 3 changed files with 115 additions and 13 deletions.
12 changes: 6 additions & 6 deletions cloud_print/service/win/cloud_print_service.cc
Original file line number Diff line number Diff line change
Expand Up @@ -205,9 +205,9 @@ class CloudPrintServiceModule
if (FAILED(hr))
return hr;

hr = controller_->InstallService(run_as_user, run_as_password,
kServiceSwitch, user_data_dir_switch_,
true);
hr = controller_->InstallConnectorService(
run_as_user, run_as_password, user_data_dir_switch_,
command_line.HasSwitch(switches::kEnableLogging));
if (SUCCEEDED(hr) && command_line.HasSwitch(kStartSwitch))
return controller_->StartService();

Expand Down Expand Up @@ -248,9 +248,9 @@ class CloudPrintServiceModule
*run_as_password = ASCIIToWide(GetOption("Password", "", true));

SetupListener setup(*run_as_user);
if (FAILED(controller_->InstallService(*run_as_user, *run_as_password,
kRequirementsSwitch,
user_data_dir_switch_, false))) {
if (FAILED(controller_->InstallCheckService(*run_as_user,
*run_as_password,
user_data_dir_switch_))) {
LOG(ERROR) << "Failed to install service as " << *run_as_user << ".";
continue;
}
Expand Down
78 changes: 76 additions & 2 deletions cloud_print/service/win/service_controller.cc
Original file line number Diff line number Diff line change
Expand Up @@ -9,16 +9,20 @@
#include <atlctl.h>

#include "base/command_line.h"
#include "base/file_util.h"
#include "base/files/file_path.h"
#include "base/path_service.h"
#include "base/win/scoped_handle.h"
#include "chrome/common/chrome_switches.h"
#include "cloud_print/common/win/cloud_print_utils.h"
#include "cloud_print/service/service_switches.h"
#include "cloud_print/service/win/chrome_launcher.h"
#include "cloud_print/service/win/local_security_policy.h"

namespace {

const wchar_t kServiceExeName[] = L"cloud_print_service.exe";

// The traits class for Windows Service.
class ServiceHandleTraits {
public:
Expand Down Expand Up @@ -84,11 +88,17 @@ ServiceController::~ServiceController() {

HRESULT ServiceController::StartService() {
ServiceHandle service;
HRESULT hr = OpenService(name_, SERVICE_START, &service);
HRESULT hr = OpenService(name_, SERVICE_START| SERVICE_QUERY_STATUS,
&service);
if (FAILED(hr))
return hr;
if (!::StartService(service, 0, NULL))
return cloud_print::GetLastHResult();
SERVICE_STATUS status = {0};
while (::QueryServiceStatus(service, &status) &&
status.dwCurrentState == SERVICE_START_PENDING) {
Sleep(100);
}
return S_OK;
}

Expand All @@ -109,11 +119,29 @@ HRESULT ServiceController::StopService() {
return S_OK;
}

HRESULT ServiceController::InstallConnectorService(
const string16& user,
const string16& password,
const base::FilePath& user_data_dir,
bool enable_logging) {
return InstallService(user, password, true, kServiceSwitch, user_data_dir,
enable_logging);
}

HRESULT ServiceController::InstallCheckService(
const string16& user,
const string16& password,
const base::FilePath& user_data_dir) {
return InstallService(user, password, false, kRequirementsSwitch,
user_data_dir, true);
}

HRESULT ServiceController::InstallService(const string16& user,
const string16& password,
bool auto_start,
const std::string& run_switch,
const base::FilePath& user_data_dir,
bool auto_start) {
bool enable_logging) {
// TODO(vitalybuka): consider "lite" version if we don't want unregister
// printers here.
HRESULT hr = UninstallService();
Expand All @@ -126,10 +154,17 @@ HRESULT ServiceController::InstallService(const string16& user,

base::FilePath service_path;
CHECK(PathService::Get(base::FILE_EXE, &service_path));
service_path = service_path.DirName().Append(base::FilePath(kServiceExeName));
if (!file_util::PathExists(service_path))
return HRESULT_FROM_WIN32(ERROR_FILE_NOT_FOUND);
CommandLine command_line(service_path);
command_line.AppendSwitch(run_switch);
if (!user_data_dir.empty())
command_line.AppendSwitchPath(switches::kUserDataDir, user_data_dir);
if (enable_logging) {
command_line.AppendSwitch(switches::kEnableLogging);
command_line.AppendSwitchASCII(switches::kV, "1");
}
ChromeLauncher::CopySwitchesFromCurrent(&command_line);

LocalSecurityPolicy local_security_policy;
Expand Down Expand Up @@ -183,3 +218,42 @@ HRESULT ServiceController::UninstallService() {
return hr;
}

void ServiceController::UpdateState() {
ServiceHandle service;
state_ = STATE_NOT_FOUND;
user_.clear();
is_logging_enabled_ = false;

HRESULT hr = OpenService(name_, SERVICE_QUERY_STATUS | SERVICE_QUERY_CONFIG,
&service);
if (FAILED(hr))
return;

state_ = STATE_STOPPED;
SERVICE_STATUS status = {0};
if (::QueryServiceStatus(service, &status) &&
status.dwCurrentState == SERVICE_RUNNING) {
state_ = STATE_RUNNING;
}

DWORD config_size = 0;
::QueryServiceConfig(service, NULL, 0, &config_size);
if (!config_size)
return;

std::vector<uint8> buffer(config_size, 0);
QUERY_SERVICE_CONFIG* config =
reinterpret_cast<QUERY_SERVICE_CONFIG*>(&buffer[0]);
if (!::QueryServiceConfig(service, config, buffer.size(), &config_size) ||
config_size != buffer.size()) {
return;
}

CommandLine command_line(CommandLine::FromString(config->lpBinaryPathName));
if (!command_line.HasSwitch(kServiceSwitch)) {
state_ = STATE_NOT_FOUND;
return;
}
is_logging_enabled_ = command_line.HasSwitch(switches::kEnableLogging);
user_ = config->lpServiceStartName;
}
38 changes: 33 additions & 5 deletions cloud_print/service/win/service_controller.h
Original file line number Diff line number Diff line change
Expand Up @@ -17,25 +17,53 @@ class FilePath;

class ServiceController {
public:
enum State {
STATE_UNKNOWN = 0,
STATE_NOT_FOUND,
STATE_STOPPED,
STATE_RUNNING,
};

DECLARE_REGISTRY_APPID_RESOURCEID(IDR_CLOUDPRINTSERVICE,
"{8013FB7C-2E3E-4992-B8BD-05C0C4AB0627}")

explicit ServiceController(const string16& name);
~ServiceController();

HRESULT InstallService(const string16& user,
const string16& password,
const std::string& run_switch,
const base::FilePath& user_data_dir,
bool auto_start);
// Installs temporarily service to check pre-requirements.
HRESULT InstallCheckService(const string16& user,
const string16& password,
const base::FilePath& user_data_dir);

// Installs real service that will run connector.
HRESULT InstallConnectorService(const string16& user,
const string16& password,
const base::FilePath& user_data_dir,
bool enable_logging);

HRESULT UninstallService();

HRESULT StartService();
HRESULT StopService();

// Query service status and options. Results accessible with getters below.
void UpdateState();
State state() const { return state_; }
const string16& user() const { return user_; }
bool is_logging_enabled() const { return is_logging_enabled_; }

private:
HRESULT InstallService(const string16& user,
const string16& password,
bool auto_start,
const std::string& run_switch,
const base::FilePath& user_data_dir,
bool enable_logging);

const string16 name_;
State state_;
string16 user_;
bool is_logging_enabled_;
};

#endif // CLOUD_PRINT_SERVICE_SERVICE_CONTROLLER_H_
Expand Down

0 comments on commit 8e6e936

Please sign in to comment.