diff options
author | vitalybuka@chromium.org <vitalybuka@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2012-05-09 17:15:22 +0000 |
---|---|---|
committer | vitalybuka@chromium.org <vitalybuka@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2012-05-09 17:15:22 +0000 |
commit | 6c511d3b56ca0c74838e2650f326ec6a617a4350 (patch) | |
tree | ba950f1b844784e1ff518386814c657f0d089130 /cloud_print/service | |
parent | 83ec721088b5631d51ce094501abf0f2c433dfc4 (diff) | |
download | chromium_src-6c511d3b56ca0c74838e2650f326ec6a617a4350.zip chromium_src-6c511d3b56ca0c74838e2650f326ec6a617a4350.tar.gz chromium_src-6c511d3b56ca0c74838e2650f326ec6a617a4350.tar.bz2 |
- Move UninstallService handling code.
- Install cloud_print_service with AUTORUN as LocalService user.
- Disable COM support.
- Enable UAC to get admin.
- Added parameters to start/stop service.
BUG=125026
Review URL: https://chromiumcodereview.appspot.com/10382026
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@136054 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'cloud_print/service')
-rw-r--r-- | cloud_print/service/win/cloud_print_service.cc | 161 | ||||
-rw-r--r-- | cloud_print/service/win/cloud_print_service.h | 3 | ||||
-rw-r--r-- | cloud_print/service/win/service.gyp | 4 |
3 files changed, 154 insertions, 14 deletions
diff --git a/cloud_print/service/win/cloud_print_service.cc b/cloud_print/service/win/cloud_print_service.cc index 6c6ae19..1898215 100644 --- a/cloud_print/service/win/cloud_print_service.cc +++ b/cloud_print/service/win/cloud_print_service.cc @@ -4,18 +4,163 @@ #include "cloud_print/service/win/cloud_print_service.h" +#include "base/win/scoped_handle.h" #include "cloud_print/service/win/resource.h" +// The traits class for Windows Service. +class ServiceHandleTraits { + public: + typedef SC_HANDLE Handle; + + // Closes the handle. + static bool CloseHandle(Handle handle) { + return ::CloseServiceHandle(handle) != FALSE; + } + + static bool IsHandleValid(Handle handle) { + return handle != NULL; + } + + static Handle NullHandle() { + return NULL; + } + + private: + DISALLOW_IMPLICIT_CONSTRUCTORS(ServiceHandleTraits); +}; + +typedef base::win::GenericScopedHandle<ServiceHandleTraits> ServiceHandle; + +HRESULT HResultFromLastError() { + HRESULT hr = HRESULT_FROM_WIN32(GetLastError()); + // Something already failed if function called. + if (SUCCEEDED(hr)) + hr = E_FAIL; + return hr; +} + class CloudPrintServiceModule - : public ATL::CAtlServiceModuleT<CloudPrintServiceModule, IDS_SERVICENAME> { + : public ATL::CAtlServiceModuleT<CloudPrintServiceModule, IDS_SERVICENAME> { public: + typedef ATL::CAtlServiceModuleT<CloudPrintServiceModule, + IDS_SERVICENAME> Base; + DECLARE_REGISTRY_APPID_RESOURCEID(IDR_CLOUDPRINTSERVICE, "{8013FB7C-2E3E-4992-B8BD-05C0C4AB0627}") - HRESULT InitializeSecurity() throw() { + + HRESULT InitializeSecurity() { // TODO(gene): Check if we need to call CoInitializeSecurity and provide // the appropriate security settings for service. 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; + + ServiceHandle service; + hr = OpenService(SERVICE_CHANGE_CONFIG, &service); + 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)) { + 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; + } + } + return true; + } + + HRESULT PreMessageLoop(int nShowCmd) { + HRESULT hr = Base::PreMessageLoop(nShowCmd); + if (FAILED(hr)) + return hr; + + hr = StartConnector(); + if (FAILED(hr)) + return hr; + + LogEvent(_T("Service started/resumed")); + SetServiceStatus(SERVICE_RUNNING); + return hr; + } + + HRESULT PostMessageLoop() { + StopConnector(); + return Base::PostMessageLoop(); + } + + private: + 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(); + + service->Set(::OpenService(scm, m_szServiceName, access)); + + if (!service->IsValid()) + return HResultFromLastError(); + + return S_OK; + } + + HRESULT StartService() { + ServiceHandle service; + HRESULT hr = OpenService(SERVICE_START, &service); + if (FAILED(hr)) + return hr; + if (!::StartService(service, 0, NULL)) + return HResultFromLastError(); + return S_OK; + } + + HRESULT StopService() { + ServiceHandle service; + HRESULT hr = OpenService(SERVICE_STOP, &service); + if (FAILED(hr)) + return hr; + SERVICE_STATUS status = {0}; + if (!::ControlService(service, SERVICE_CONTROL_STOP, &status)) + return HResultFromLastError(); + return S_OK; + } + + HRESULT StartConnector() { + return S_OK; + } + + void StopConnector() { + } }; CloudPrintServiceModule _AtlModule; @@ -24,18 +169,6 @@ int WINAPI WinMain(__in HINSTANCE hInstance, __in HINSTANCE hPrevInstance, __in LPSTR lpCmdLine, __in int nCmdShow) { - // Handle service unstall case manually. - // Service install is handled through ATL, command line flag "/Service" - // http://msdn.microsoft.com/en-US/library/z8868y94(v=vs.80).aspx - if (StrStrA(lpCmdLine, "/UninstallService") != NULL) { - _AtlModule.Uninstall(); - return 0; - } - - // TODO(gene): When running this program with "/Service" flag it fails - // silently if command prompt is not elevated. - // Consider adding manifest to require elevated prompt, or at least - // print warning in this case. return _AtlModule.WinMain(nCmdShow); } diff --git a/cloud_print/service/win/cloud_print_service.h b/cloud_print/service/win/cloud_print_service.h index 770a72e..8c33605 100644 --- a/cloud_print/service/win/cloud_print_service.h +++ b/cloud_print/service/win/cloud_print_service.h @@ -14,6 +14,9 @@ #define _ATL_NO_AUTOMATIC_NAMESPACE +// Service has no COM objects. http://support.microsoft.com/kb/2480736 +#define _ATL_NO_COM_SUPPORT + // some CString constructors will be explicit #define _ATL_CSTRING_EXPLICIT_CONSTRUCTORS diff --git a/cloud_print/service/win/service.gyp b/cloud_print/service/win/service.gyp index cd58acb..2ce100c 100644 --- a/cloud_print/service/win/service.gyp +++ b/cloud_print/service/win/service.gyp @@ -20,9 +20,13 @@ 'cloud_print_service.rc', 'resource.h', ], + 'dependencies': [ + '../../../base/base.gyp:base', + ], 'msvs_settings': { 'VCLinkerTool': { 'SubSystem': '2', # Set /SUBSYSTEM:WINDOWS + 'UACExecutionLevel': '2', # /level='requireAdministrator' }, }, }, |