diff options
author | vitalybuka@chromium.org <vitalybuka@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2012-05-11 17:16:44 +0000 |
---|---|---|
committer | vitalybuka@chromium.org <vitalybuka@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2012-05-11 17:16:44 +0000 |
commit | cda584acdcb9dcd8a5e467da7b9af5280b1fdc5c (patch) | |
tree | fc6329a27ecfe09f7abfeb94e9fdd0cd7ef5a303 | |
parent | 9d1e9a22e135fe8e04449bf23ba7fc915320e468 (diff) | |
download | chromium_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.cc | 189 | ||||
-rw-r--r-- | cloud_print/service/win/cloud_print_service.h | 1 | ||||
-rw-r--r-- | cloud_print/service/win/service.gyp | 2 |
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' }, }, |