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

Side by Side 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: comments 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 unified diff | Download patch | Annotate | Revision Log
« 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 »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "cloud_print/service/win/cloud_print_service.h" 5 #include "cloud_print/service/win/cloud_print_service.h"
6 6
7 #include <iomanip>
8 #include <iostream>
9
10 #include "base/at_exit.h"
11 #include "base/command_line.h"
12 #include "base/file_path.h"
13 #include "base/path_service.h"
7 #include "base/win/scoped_handle.h" 14 #include "base/win/scoped_handle.h"
8 #include "cloud_print/service/win/resource.h" 15 #include "cloud_print/service/win/resource.h"
9 16
17 namespace {
18
19 const char kInstallSwitch[] = "install";
20 const char kUninstallSwitch[] = "uninstall";
21 const char kStartSwitch[] = "start";
22 const char kStopSwitch[] = "stop";
23
24 const char kServiceSwitch[] = "service";
25
26 const char kUserDataDirSwitch[] = "user-data-dir";
27 const char kQuietSwitch[] = "quiet";
28
10 // The traits class for Windows Service. 29 // The traits class for Windows Service.
11 class ServiceHandleTraits { 30 class ServiceHandleTraits {
12 public: 31 public:
13 typedef SC_HANDLE Handle; 32 typedef SC_HANDLE Handle;
14 33
15 // Closes the handle. 34 // Closes the handle.
16 static bool CloseHandle(Handle handle) { 35 static bool CloseHandle(Handle handle) {
17 return ::CloseServiceHandle(handle) != FALSE; 36 return ::CloseServiceHandle(handle) != FALSE;
18 } 37 }
19 38
(...skipping 12 matching lines...) Expand all
32 typedef base::win::GenericScopedHandle<ServiceHandleTraits> ServiceHandle; 51 typedef base::win::GenericScopedHandle<ServiceHandleTraits> ServiceHandle;
33 52
34 HRESULT HResultFromLastError() { 53 HRESULT HResultFromLastError() {
35 HRESULT hr = HRESULT_FROM_WIN32(GetLastError()); 54 HRESULT hr = HRESULT_FROM_WIN32(GetLastError());
36 // Something already failed if function called. 55 // Something already failed if function called.
37 if (SUCCEEDED(hr)) 56 if (SUCCEEDED(hr))
38 hr = E_FAIL; 57 hr = E_FAIL;
39 return hr; 58 return hr;
40 } 59 }
41 60
61 void InvalidUsage() {
62 FilePath service_path;
63 CHECK(PathService::Get(base::FILE_EXE, &service_path));
64
65 std::cout << "Usage: ";
66 std::cout << service_path.BaseName().value();
67 std::cout << " [";
68 std::cout << "[";
69 std::cout << "[";
70 std::cout << " -" << kInstallSwitch;
71 std::cout << " -" << kUserDataDirSwitch << "=DIRECTORY";
72 std::cout << " [ -" << kQuietSwitch << " ]";
73 std::cout << "]";
74 std::cout << "]";
75 std::cout << " | -" << kUninstallSwitch;
76 std::cout << " | -" << kStartSwitch;
77 std::cout << " | -" << kStopSwitch;
78 std::cout << " ]\n";
79 std::cout << "Manages cloud print windows service.\n\n";
80
81 static const struct {
82 const char* name;
83 const char* description;
84 } kSwitchHelp[] = {
85 { kInstallSwitch, "Installs cloud print as service." },
86 { kUserDataDirSwitch, "User data directory with \"Service State\" file." },
87 { kQuietSwitch, "Fails without questions if something wrong." },
88 { kUninstallSwitch, "Uninstalls service." },
89 { kStartSwitch, "Starts service. May be combined with installation." },
90 { kStopSwitch, "Stops service." },
91 };
92
93 for (size_t i = 0; i < arraysize(kSwitchHelp); ++i) {
94 std::cout << std::setiosflags(std::ios::left);
95 std::cout << " -" << std::setw(15) << kSwitchHelp[i].name;
96 std::cout << kSwitchHelp[i].name << "\n";
gene 2012/05/10 22:58:49 .name -> .description
Vitaly Buka (NO REVIEWS) 2012/05/10 23:04:54 Done.
97 }
98 std::cout << "\n";
99 }
100
101 } // namespace
102
42 class CloudPrintServiceModule 103 class CloudPrintServiceModule
43 : public ATL::CAtlServiceModuleT<CloudPrintServiceModule, IDS_SERVICENAME> { 104 : public ATL::CAtlServiceModuleT<CloudPrintServiceModule, IDS_SERVICENAME> {
44 public: 105 public:
45 typedef ATL::CAtlServiceModuleT<CloudPrintServiceModule, 106 typedef ATL::CAtlServiceModuleT<CloudPrintServiceModule,
46 IDS_SERVICENAME> Base; 107 IDS_SERVICENAME> Base;
47 108
48 DECLARE_REGISTRY_APPID_RESOURCEID(IDR_CLOUDPRINTSERVICE, 109 DECLARE_REGISTRY_APPID_RESOURCEID(IDR_CLOUDPRINTSERVICE,
49 "{8013FB7C-2E3E-4992-B8BD-05C0C4AB0627}") 110 "{8013FB7C-2E3E-4992-B8BD-05C0C4AB0627}")
50 111
51 HRESULT InitializeSecurity() { 112 HRESULT InitializeSecurity() {
52 // TODO(gene): Check if we need to call CoInitializeSecurity and provide 113 // TODO(gene): Check if we need to call CoInitializeSecurity and provide
53 // the appropriate security settings for service. 114 // the appropriate security settings for service.
54 return S_OK; 115 return S_OK;
55 } 116 }
56 117
57 // Override to set autostart and start service. 118 HRESULT Install(const FilePath& user_data_dir) {
58 HRESULT RegisterAppId(bool bService = false) { 119 // TODO(vitalybuka): consider "lite" version if we don't want unregister
59 HRESULT hr = Base::RegisterAppId(bService); 120 // printers here.
121 if (!Uninstall())
122 return E_FAIL;
123
124 FilePath service_path;
125 CHECK(PathService::Get(base::FILE_EXE, &service_path));
126 CommandLine command_line(service_path);
127 command_line.AppendSwitch(kServiceSwitch);
128 command_line.AppendSwitchPath(kUserDataDirSwitch, user_data_dir);
129
130 ServiceHandle scm;
131 HRESULT hr = OpenServiceManager(&scm);
60 if (FAILED(hr)) 132 if (FAILED(hr))
61 return hr; 133 return hr;
62 134
63 ServiceHandle service; 135 ServiceHandle service(
64 hr = OpenService(SERVICE_CHANGE_CONFIG, &service); 136 ::CreateService(
65 if (FAILED(hr)) 137 scm, m_szServiceName, m_szServiceName, SERVICE_ALL_ACCESS,
66 return hr; 138 SERVICE_WIN32_OWN_PROCESS, SERVICE_AUTO_START, SERVICE_ERROR_NORMAL,
139 command_line.GetCommandLineString().c_str(), NULL, NULL, NULL,
140 L"NT AUTHORITY\\LocalService", NULL));
67 141
68 if (!::ChangeServiceConfig(service, SERVICE_WIN32_OWN_PROCESS, 142 if (!service.IsValid())
69 SERVICE_AUTO_START, SERVICE_ERROR_NORMAL, NULL, NULL, NULL, NULL,
70 L"NT AUTHORITY\\LocalService", NULL, NULL)) {
71 return HResultFromLastError(); 143 return HResultFromLastError();
72 }
73 144
74 return S_OK; 145 return S_OK;
75 } 146 }
76 147
77 // Override to handle service uninstall case manually.
78 bool ParseCommandLine(LPCTSTR lpCmdLine, HRESULT* pnRetCode) { 148 bool ParseCommandLine(LPCTSTR lpCmdLine, HRESULT* pnRetCode) {
79 if (!Base::ParseCommandLine(lpCmdLine, pnRetCode)) 149 CHECK(pnRetCode);
80 return false; 150 CommandLine command_line(CommandLine::NO_PROGRAM);
81 151 command_line.ParseFromString(lpCmdLine);
82 const wchar_t tokens[] = L"-/"; 152 bool is_service = false;
83 *pnRetCode = S_OK; 153 *pnRetCode = ParseCommandLine(command_line, &is_service);
84 154 if (FAILED(*pnRetCode)) {
85 for (const wchar_t* cur = lpCmdLine; cur = FindOneOf(cur, tokens);) { 155 LOG(ERROR) << "Operation failed. 0x" << std::setw(8) <<
86 if (WordCmpI(cur, L"UninstallService") == 0) { 156 std::setbase(16) << *pnRetCode;
87 if (!Uninstall())
88 *pnRetCode = E_FAIL;
89 return false;
90 } else if (WordCmpI(cur, L"Start") == 0) {
91 *pnRetCode = StartService();
92 return false;
93 } else if (WordCmpI(cur, L"Stop") == 0) {
94 *pnRetCode = StopService();
95 return false;
96 }
97 } 157 }
98 return true; 158 return is_service;
99 } 159 }
100 160
101 HRESULT PreMessageLoop(int nShowCmd) { 161 HRESULT PreMessageLoop(int nShowCmd) {
102 HRESULT hr = Base::PreMessageLoop(nShowCmd); 162 HRESULT hr = Base::PreMessageLoop(nShowCmd);
103 if (FAILED(hr)) 163 if (FAILED(hr))
104 return hr; 164 return hr;
105 165
106 hr = StartConnector(); 166 hr = StartConnector();
107 if (FAILED(hr)) 167 if (FAILED(hr))
108 return hr; 168 return hr;
109 169
110 LogEvent(_T("Service started/resumed")); 170 LogEvent(_T("Service started/resumed"));
111 SetServiceStatus(SERVICE_RUNNING); 171 SetServiceStatus(SERVICE_RUNNING);
112 return hr; 172 return hr;
113 } 173 }
114 174
115 HRESULT PostMessageLoop() { 175 HRESULT PostMessageLoop() {
116 StopConnector(); 176 StopConnector();
117 return Base::PostMessageLoop(); 177 return Base::PostMessageLoop();
118 } 178 }
119 179
120 private: 180 private:
181 HRESULT ParseCommandLine(const CommandLine& command_line, bool* is_service) {
182 if (!is_service)
183 return E_INVALIDARG;
184 *is_service = false;
185
186 if (command_line.HasSwitch(kStopSwitch))
187 return StopService();
188
189 if (command_line.HasSwitch(kUninstallSwitch))
190 return Uninstall() ? S_OK : E_FAIL;
191
192 if (command_line.HasSwitch(kInstallSwitch)) {
193 if (!command_line.HasSwitch(kUserDataDirSwitch)) {
194 InvalidUsage();
195 return S_FALSE;
196 }
197
198 FilePath data_dir = command_line.GetSwitchValuePath(kUserDataDirSwitch);
199 HRESULT hr = Install(data_dir);
200 if (FAILED(hr) || !command_line.HasSwitch(kStartSwitch))
201 return hr;
202
203 return StartService();
gene 2012/05/10 22:58:49 if (command_line.HasSwitch(kStartSwitch)) ???
Vitaly Buka (NO REVIEWS) 2012/05/10 23:04:54 at line 200 On 2012/05/10 22:58:49, gene wrote:
204 }
205
206 if (command_line.HasSwitch(kStartSwitch))
207 return StartService();
208
209 if (command_line.HasSwitch(kServiceSwitch)) {
210 user_data_dir_ = command_line.GetSwitchValuePath(kUserDataDirSwitch);
211 *is_service = true;
212 return S_OK;
213 }
214
215 InvalidUsage();
216 return S_FALSE;
217 }
218
219 HRESULT OpenServiceManager(ServiceHandle* service_manager) {
220 if (!service_manager)
221 return E_POINTER;
222
223 service_manager->Set(::OpenSCManager(NULL, NULL, SC_MANAGER_ALL_ACCESS));
224 if (!service_manager->IsValid())
225 return HResultFromLastError();
226
227 return S_OK;
228 }
229
121 HRESULT OpenService(DWORD access, ServiceHandle* service) { 230 HRESULT OpenService(DWORD access, ServiceHandle* service) {
122 if (!service) 231 if (!service)
123 return E_POINTER; 232 return E_POINTER;
124 233
125 ServiceHandle scm(::OpenSCManager(NULL, NULL, SC_MANAGER_ALL_ACCESS)); 234 ServiceHandle scm;
126 if (!scm.IsValid()) 235 HRESULT hr = OpenServiceManager(&scm);
127 return HResultFromLastError(); 236 if (FAILED(hr))
237 return hr;
128 238
129 service->Set(::OpenService(scm, m_szServiceName, access)); 239 service->Set(::OpenService(scm, m_szServiceName, access));
130 240
131 if (!service->IsValid()) 241 if (!service->IsValid())
132 return HResultFromLastError(); 242 return HResultFromLastError();
133 243
134 return S_OK; 244 return S_OK;
135 } 245 }
136 246
137 HRESULT StartService() { 247 HRESULT StartService() {
(...skipping 16 matching lines...) Expand all
154 return HResultFromLastError(); 264 return HResultFromLastError();
155 return S_OK; 265 return S_OK;
156 } 266 }
157 267
158 HRESULT StartConnector() { 268 HRESULT StartConnector() {
159 return S_OK; 269 return S_OK;
160 } 270 }
161 271
162 void StopConnector() { 272 void StopConnector() {
163 } 273 }
274
275 FilePath user_data_dir_;
164 }; 276 };
165 277
166 CloudPrintServiceModule _AtlModule; 278 CloudPrintServiceModule _AtlModule;
167 279
168 int WINAPI WinMain(__in HINSTANCE hInstance, 280 int main() {
169 __in HINSTANCE hPrevInstance, 281 base::AtExitManager at_exit;
170 __in LPSTR lpCmdLine, 282 return _AtlModule.WinMain(0);
171 __in int nCmdShow) {
172 return _AtlModule.WinMain(nCmdShow);
173 } 283 }
174
OLDNEW
« 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