Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(69)

Unified Diff: cloud_print/service/win/cloud_print_service.cc

Issue 10377080: Switched to chromium command line parsing code. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Created 8 years, 7 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
« no previous file with comments | « cloud_print/service/win/cloud_print_service.h ('k') | cloud_print/service/win/service.gyp » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: cloud_print/service/win/cloud_print_service.cc
diff --git a/cloud_print/service/win/cloud_print_service.cc b/cloud_print/service/win/cloud_print_service.cc
index 189821587159608192c579688a039152da78894f..67ff0943eb1e9662398d6fc500d4d75e4a1ae701 100644
--- a/cloud_print/service/win/cloud_print_service.cc
+++ b/cloud_print/service/win/cloud_print_service.cc
@@ -4,9 +4,26 @@
#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 kUserDataDirSwitch[] = "user-data-dir";
+const char kQuietSwitch[] = "quiet";
+
// The traits class for Windows Service.
class ServiceHandleTraits {
public:
@@ -39,6 +56,51 @@ HRESULT HResultFromLastError() {
return hr;
}
+void InvalidUsage() {
+ FilePath service_path;
+ CHECK(PathService::Get(base::FILE_EXE, &service_path));
+
+ std::cerr << "Usage: ";
gene 2012/05/10 22:11:45 cout?
Vitaly Buka (NO REVIEWS) 2012/05/10 22:49:12 Done.
+ std::cerr << service_path.BaseName().value();
+ std::cerr << " [";
+ std::cerr << "[";
+ std::cerr << "[";
+ std::cerr << " -" << kInstallSwitch;
+ std::cerr << " -" << kUserDataDirSwitch << "=DIRECTORY";
+ std::cerr << " [ -" << kQuietSwitch << " ]";
+ std::cerr << "]";
+ std::cerr << "]";
+ std::cerr << " | -" << kUninstallSwitch;
+ std::cerr << " | -" << kStartSwitch;
+ std::cerr << " | -" << kStopSwitch;
+ std::cerr << " ]\n";
+ std::cerr << "Manages cloud print service.\n\n";
+
+ static const char* kSwitchHelp[] = {
+ kInstallSwitch,
+ "Installs cloud print as windows service.",
+ kUserDataDirSwitch,
+ "User data directory with \"Service State\" file.",
+ kQuietSwitch,
+ "Fails without questions if something wrong.",
+ kUninstallSwitch,
+ "Uninstalls windows service.",
+ kStartSwitch,
+ "Starts windows service. May be combined with installation.",
+ kStopSwitch,
+ "Stops windows service.",
+ };
+
+ for (size_t i = 0; i < arraysize(kSwitchHelp) / 2; ++i) {
gene 2012/05/10 22:11:45 change this to not use i*2+1
Vitaly Buka (NO REVIEWS) 2012/05/10 22:49:12 Done.
+ std::cerr << std::setiosflags(std::ios::left);
+ std::cerr << " -" << std::setw(15) << kSwitchHelp[i * 2];
+ std::cerr << kSwitchHelp[i * 2 + 1] << "\n";
+ }
+ std::cerr << "\n";
+}
+
+} // namespace
+
class CloudPrintServiceModule
: public ATL::CAtlServiceModuleT<CloudPrintServiceModule, IDS_SERVICENAME> {
public:
@@ -54,48 +116,51 @@ 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) {
+ if (!Uninstall())
gene 2012/05/10 22:11:45 We probably should not uninstall here, but rather
Vitaly Buka (NO REVIEWS) 2012/05/10 22:49:12 Done.
+ return E_FAIL;
- ServiceHandle service;
- hr = OpenService(SERVICE_CHANGE_CONFIG, &service);
+ if (user_data_dir.empty()) {
gene 2012/05/10 22:11:45 you can probably check this condition in the Parse
Vitaly Buka (NO REVIEWS) 2012/05/10 22:49:12 Done.
+ std::cerr << "Invalid value --user_data_dir=" << user_data_dir.value() <<
+ "\n";
+ return E_INVALIDARG;
+ }
+
+ FilePath service_path;
+ CHECK(PathService::Get(base::FILE_EXE, &service_path));
+ CommandLine command_line(service_path);
+ 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);
+ *pnRetCode = ParseCommandLine(command_line);
+ if (*pnRetCode == S_OK)
+ return true; // Run as service.
+ if (FAILED(*pnRetCode)) {
+ LOG(ERROR) << "Operation failed. 0x" << std::setw(8) <<
+ std::setbase(16) << *pnRetCode;
}
- return true;
+ return false; // Exit process.
}
HRESULT PreMessageLoop(int nShowCmd) {
@@ -118,13 +183,70 @@ class CloudPrintServiceModule
}
private:
+ // Returns S_OK if it's called as service.
+ // Returns S_FALSE on success or usage error.
+ // Returns error code for any other error.
+ HRESULT ParseCommandLine(const CommandLine& command_line) {
+ HRESULT hr = E_INVALIDARG;
+ if (command_line.HasSwitch(kStopSwitch)) {
+ hr = StopService();
gene 2012/05/10 22:11:45 I think we shall return here no matter what StopSe
Vitaly Buka (NO REVIEWS) 2012/05/10 22:49:12 Done.
+ if (FAILED(hr))
+ return hr;
+ }
+
+ if (command_line.HasSwitch(kUninstallSwitch)) {
+ hr = Uninstall() ? S_OK : E_FAIL;
+ if (FAILED(hr))
gene 2012/05/10 22:11:45 Same as above here.
Vitaly Buka (NO REVIEWS) 2012/05/10 22:49:12 Done.
+ return hr;
+ }
+
+ if (command_line.HasSwitch(kInstallSwitch)) {
+ if (!command_line.HasSwitch(kUserDataDirSwitch)) {
+ InvalidUsage();
+ return S_FALSE;
+ }
+
+ FilePath data_dir = command_line.GetSwitchValuePath(kUserDataDirSwitch);
+ hr = Install(data_dir);
+ if (FAILED(hr))
+ return hr;
+ }
+
+ if (command_line.HasSwitch(kStartSwitch)) {
+ hr = StartService();
+ if (FAILED(hr))
+ return hr;
+ }
+
+ // No main switch matched, so it was called by SCM or just usage error.
+ if (hr == E_INVALIDARG) {
+ if (command_line.HasSwitch(kUserDataDirSwitch))
+ 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));
@@ -165,10 +287,7 @@ class CloudPrintServiceModule
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);
}
-
« no previous file with comments | « cloud_print/service/win/cloud_print_service.h ('k') | cloud_print/service/win/service.gyp » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698