summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorvitalybuka@chromium.org <vitalybuka@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2012-05-11 17:16:44 +0000
committervitalybuka@chromium.org <vitalybuka@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2012-05-11 17:16:44 +0000
commitcda584acdcb9dcd8a5e467da7b9af5280b1fdc5c (patch)
treefc6329a27ecfe09f7abfeb94e9fdd0cd7ef5a303
parent9d1e9a22e135fe8e04449bf23ba7fc915320e468 (diff)
downloadchromium_src-cda584acdcb9dcd8a5e467da7b9af5280b1fdc5c.zip
chromium_src-cda584acdcb9dcd8a5e467da7b9af5280b1fdc5c.tar.gz
chromium_src-cda584acdcb9dcd8a5e467da7b9af5280b1fdc5c.tar.bz2
Switched to chromium command line parsing code.
Added logging. Added switche for user data dir. Added usage help. Usage: cloud_print_service.exe [[[ -install -user-data-dir=DIRECTORY [ -quiet ]]] | -uninstall | -start | -stop ] Manages cloud print service. -install Installs cloud print as windows service. -user-data-dir User data directory with "Service State" file. -quiet Fails without questions if something wrong. -uninstall Uninstalls windows service. -start Starts windows service. May be combined with installation. -stop Stops windows service. BUG=125026 TEST=none Review URL: https://chromiumcodereview.appspot.com/10377080 git-svn-id: svn://svn.chromium.org/chrome/trunk/src@136598 0039d316-1c4b-4281-b951-d872f2087c98
-rw-r--r--cloud_print/service/win/cloud_print_service.cc189
-rw-r--r--cloud_print/service/win/cloud_print_service.h1
-rw-r--r--cloud_print/service/win/service.gyp2
3 files changed, 150 insertions, 42 deletions
diff --git a/cloud_print/service/win/cloud_print_service.cc b/cloud_print/service/win/cloud_print_service.cc
index 1898215..976e598 100644
--- a/cloud_print/service/win/cloud_print_service.cc
+++ b/cloud_print/service/win/cloud_print_service.cc
@@ -4,9 +4,28 @@
#include "cloud_print/service/win/cloud_print_service.h"
+#include <iomanip>
+#include <iostream>
+
+#include "base/at_exit.h"
+#include "base/command_line.h"
+#include "base/file_path.h"
+#include "base/path_service.h"
#include "base/win/scoped_handle.h"
#include "cloud_print/service/win/resource.h"
+namespace {
+
+const char kInstallSwitch[] = "install";
+const char kUninstallSwitch[] = "uninstall";
+const char kStartSwitch[] = "start";
+const char kStopSwitch[] = "stop";
+
+const char kServiceSwitch[] = "service";
+
+const char kUserDataDirSwitch[] = "user-data-dir";
+const char kQuietSwitch[] = "quiet";
+
// The traits class for Windows Service.
class ServiceHandleTraits {
public:
@@ -39,6 +58,48 @@ HRESULT HResultFromLastError() {
return hr;
}
+void InvalidUsage() {
+ FilePath service_path;
+ CHECK(PathService::Get(base::FILE_EXE, &service_path));
+
+ std::cout << "Usage: ";
+ std::cout << service_path.BaseName().value();
+ std::cout << " [";
+ std::cout << "[";
+ std::cout << "[";
+ std::cout << " -" << kInstallSwitch;
+ std::cout << " -" << kUserDataDirSwitch << "=DIRECTORY";
+ std::cout << " [ -" << kQuietSwitch << " ]";
+ std::cout << "]";
+ std::cout << "]";
+ std::cout << " | -" << kUninstallSwitch;
+ std::cout << " | -" << kStartSwitch;
+ std::cout << " | -" << kStopSwitch;
+ std::cout << " ]\n";
+ std::cout << "Manages cloud print windows service.\n\n";
+
+ static const struct {
+ const char* name;
+ const char* description;
+ } kSwitchHelp[] = {
+ { kInstallSwitch, "Installs cloud print as service." },
+ { kUserDataDirSwitch, "User data directory with \"Service State\" file." },
+ { kQuietSwitch, "Fails without questions if something wrong." },
+ { kUninstallSwitch, "Uninstalls service." },
+ { kStartSwitch, "Starts service. May be combined with installation." },
+ { kStopSwitch, "Stops service." },
+ };
+
+ for (size_t i = 0; i < arraysize(kSwitchHelp); ++i) {
+ std::cout << std::setiosflags(std::ios::left);
+ std::cout << " -" << std::setw(15) << kSwitchHelp[i].name;
+ std::cout << kSwitchHelp[i].description << "\n";
+ }
+ std::cout << "\n";
+}
+
+} // namespace
+
class CloudPrintServiceModule
: public ATL::CAtlServiceModuleT<CloudPrintServiceModule, IDS_SERVICENAME> {
public:
@@ -54,48 +115,47 @@ class CloudPrintServiceModule
return S_OK;
}
- // Override to set autostart and start service.
- HRESULT RegisterAppId(bool bService = false) {
- HRESULT hr = Base::RegisterAppId(bService);
- if (FAILED(hr))
- return hr;
+ HRESULT Install(const FilePath& user_data_dir) {
+ // TODO(vitalybuka): consider "lite" version if we don't want unregister
+ // printers here.
+ if (!Uninstall())
+ return E_FAIL;
- ServiceHandle service;
- hr = OpenService(SERVICE_CHANGE_CONFIG, &service);
+ FilePath service_path;
+ CHECK(PathService::Get(base::FILE_EXE, &service_path));
+ CommandLine command_line(service_path);
+ command_line.AppendSwitch(kServiceSwitch);
+ command_line.AppendSwitchPath(kUserDataDirSwitch, user_data_dir);
+
+ ServiceHandle scm;
+ HRESULT hr = OpenServiceManager(&scm);
if (FAILED(hr))
return hr;
- if (!::ChangeServiceConfig(service, SERVICE_WIN32_OWN_PROCESS,
- SERVICE_AUTO_START, SERVICE_ERROR_NORMAL, NULL, NULL, NULL, NULL,
- L"NT AUTHORITY\\LocalService", NULL, NULL)) {
+ ServiceHandle service(
+ ::CreateService(
+ scm, m_szServiceName, m_szServiceName, SERVICE_ALL_ACCESS,
+ SERVICE_WIN32_OWN_PROCESS, SERVICE_AUTO_START, SERVICE_ERROR_NORMAL,
+ command_line.GetCommandLineString().c_str(), NULL, NULL, NULL,
+ L"NT AUTHORITY\\LocalService", NULL));
+
+ if (!service.IsValid())
return HResultFromLastError();
- }
return S_OK;
}
- // Override to handle service uninstall case manually.
bool ParseCommandLine(LPCTSTR lpCmdLine, HRESULT* pnRetCode) {
- if (!Base::ParseCommandLine(lpCmdLine, pnRetCode))
- return false;
-
- const wchar_t tokens[] = L"-/";
- *pnRetCode = S_OK;
-
- for (const wchar_t* cur = lpCmdLine; cur = FindOneOf(cur, tokens);) {
- if (WordCmpI(cur, L"UninstallService") == 0) {
- if (!Uninstall())
- *pnRetCode = E_FAIL;
- return false;
- } else if (WordCmpI(cur, L"Start") == 0) {
- *pnRetCode = StartService();
- return false;
- } else if (WordCmpI(cur, L"Stop") == 0) {
- *pnRetCode = StopService();
- return false;
- }
+ CHECK(pnRetCode);
+ CommandLine command_line(CommandLine::NO_PROGRAM);
+ command_line.ParseFromString(lpCmdLine);
+ bool is_service = false;
+ *pnRetCode = ParseCommandLine(command_line, &is_service);
+ if (FAILED(*pnRetCode)) {
+ LOG(ERROR) << "Operation failed. 0x" << std::setw(8) <<
+ std::setbase(16) << *pnRetCode;
}
- return true;
+ return is_service;
}
HRESULT PreMessageLoop(int nShowCmd) {
@@ -118,13 +178,63 @@ class CloudPrintServiceModule
}
private:
+ HRESULT ParseCommandLine(const CommandLine& command_line, bool* is_service) {
+ if (!is_service)
+ return E_INVALIDARG;
+ *is_service = false;
+
+ if (command_line.HasSwitch(kStopSwitch))
+ return StopService();
+
+ if (command_line.HasSwitch(kUninstallSwitch))
+ return Uninstall() ? S_OK : E_FAIL;
+
+ if (command_line.HasSwitch(kInstallSwitch)) {
+ if (!command_line.HasSwitch(kUserDataDirSwitch)) {
+ InvalidUsage();
+ return S_FALSE;
+ }
+
+ FilePath data_dir = command_line.GetSwitchValuePath(kUserDataDirSwitch);
+ HRESULT hr = Install(data_dir);
+ if (SUCCEEDED(hr) && command_line.HasSwitch(kStartSwitch))
+ return StartService();
+
+ return hr;
+ }
+
+ if (command_line.HasSwitch(kStartSwitch))
+ return StartService();
+
+ if (command_line.HasSwitch(kServiceSwitch)) {
+ user_data_dir_ = command_line.GetSwitchValuePath(kUserDataDirSwitch);
+ *is_service = true;
+ return S_OK;
+ }
+
+ InvalidUsage();
+ return S_FALSE;
+ }
+
+ HRESULT OpenServiceManager(ServiceHandle* service_manager) {
+ if (!service_manager)
+ return E_POINTER;
+
+ service_manager->Set(::OpenSCManager(NULL, NULL, SC_MANAGER_ALL_ACCESS));
+ if (!service_manager->IsValid())
+ return HResultFromLastError();
+
+ return S_OK;
+ }
+
HRESULT OpenService(DWORD access, ServiceHandle* service) {
if (!service)
return E_POINTER;
- ServiceHandle scm(::OpenSCManager(NULL, NULL, SC_MANAGER_ALL_ACCESS));
- if (!scm.IsValid())
- return HResultFromLastError();
+ ServiceHandle scm;
+ HRESULT hr = OpenServiceManager(&scm);
+ if (FAILED(hr))
+ return hr;
service->Set(::OpenService(scm, m_szServiceName, access));
@@ -161,14 +271,13 @@ class CloudPrintServiceModule
void StopConnector() {
}
+
+ FilePath user_data_dir_;
};
CloudPrintServiceModule _AtlModule;
-int WINAPI WinMain(__in HINSTANCE hInstance,
- __in HINSTANCE hPrevInstance,
- __in LPSTR lpCmdLine,
- __in int nCmdShow) {
- return _AtlModule.WinMain(nCmdShow);
+int main() {
+ base::AtExitManager at_exit;
+ return _AtlModule.WinMain(0);
}
-
diff --git a/cloud_print/service/win/cloud_print_service.h b/cloud_print/service/win/cloud_print_service.h
index 8c33605..a07189c 100644
--- a/cloud_print/service/win/cloud_print_service.h
+++ b/cloud_print/service/win/cloud_print_service.h
@@ -4,7 +4,6 @@
#ifndef CLOUD_PRINT_SERVICE_CLOUD_PRINT_SERVICE_H_
#define CLOUD_PRINT_SERVICE_CLOUD_PRINT_SERVICE_H_
-#pragma once
#ifndef STRICT
#define STRICT
diff --git a/cloud_print/service/win/service.gyp b/cloud_print/service/win/service.gyp
index 2ce100c..a982c4b 100644
--- a/cloud_print/service/win/service.gyp
+++ b/cloud_print/service/win/service.gyp
@@ -25,7 +25,7 @@
],
'msvs_settings': {
'VCLinkerTool': {
- 'SubSystem': '2', # Set /SUBSYSTEM:WINDOWS
+ 'SubSystem': '1', # Set /SUBSYSTEM:CONSOLE
'UACExecutionLevel': '2', # /level='requireAdministrator'
},
},