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

Side by Side Diff: cloud_print/service/win/cloud_print_service.cc

Issue 13039002: Send data back from service using IPC, not file. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Created 7 years, 9 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/service.gyp ('k') | cloud_print/service/win/cloud_print_service.rc » ('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 <atlbase.h> 5 #include <atlbase.h>
6 #include <security.h> 6 #include <security.h>
7 7
8 #include <iomanip> 8 #include <iomanip>
9 #include <iostream> 9 #include <iostream>
10 10
11 #include "base/at_exit.h" 11 #include "base/at_exit.h"
12 #include "base/command_line.h" 12 #include "base/command_line.h"
13 #include "base/file_util.h" 13 #include "base/file_util.h"
14 #include "base/guid.h" 14 #include "base/guid.h"
15 #include "base/logging.h" 15 #include "base/logging.h"
16 #include "base/path_service.h" 16 #include "base/path_service.h"
17 #include "base/string_util.h" 17 #include "base/string_util.h"
18 #include "base/utf_string_conversions.h" 18 #include "base/utf_string_conversions.h"
19 #include "chrome/installer/launcher_support/chrome_launcher_support.h" 19 #include "base/win/scoped_handle.h"
20 #include "cloud_print/service/service_state.h" 20 #include "cloud_print/service/service_state.h"
21 #include "cloud_print/service/service_switches.h" 21 #include "cloud_print/service/service_switches.h"
22 #include "cloud_print/service/win/chrome_launcher.h" 22 #include "cloud_print/service/win/chrome_launcher.h"
23 #include "cloud_print/service/win/service_controller.h" 23 #include "cloud_print/service/win/service_controller.h"
24 #include "cloud_print/service/win/service_listener.h"
24 #include "cloud_print/service/win/service_utils.h" 25 #include "cloud_print/service/win/service_utils.h"
25 #include "printing/backend/print_backend.h" 26 #include "cloud_print/service/win/setup_listener.h"
26 27
27 namespace { 28 namespace {
28 29
29 const char kChromeIsNotAvalible[] = "\nChrome is not available\n";
30 const char kChromeIsAvalible[] = "\nChrome is available\n";
31 const wchar_t kRequirementsFileName[] = L"cloud_print_service_requirements.txt";
32 const wchar_t kServiceStateFileName[] = L"Service State"; 30 const wchar_t kServiceStateFileName[] = L"Service State";
33 31
34 void InvalidUsage() { 32 void InvalidUsage() {
35 base::FilePath service_path; 33 base::FilePath service_path;
36 CHECK(PathService::Get(base::FILE_EXE, &service_path)); 34 CHECK(PathService::Get(base::FILE_EXE, &service_path));
37 35
38 std::cout << "Usage: "; 36 std::cout << "Usage: ";
39 std::cout << service_path.BaseName().value(); 37 std::cout << service_path.BaseName().value();
40 std::cout << " ["; 38 std::cout << " [";
41 std::cout << "["; 39 std::cout << "[";
(...skipping 64 matching lines...) Expand 10 before | Expand all | Expand 10 after
106 if (input.empty() || input == "y") { 104 if (input.empty() || input == "y") {
107 return true; 105 return true;
108 } else if (input == "n") { 106 } else if (input == "n") {
109 return false; 107 return false;
110 } 108 }
111 } 109 }
112 } 110 }
113 111
114 } // namespace 112 } // namespace
115 113
114
116 class CloudPrintServiceModule 115 class CloudPrintServiceModule
117 : public ATL::CAtlServiceModuleT<CloudPrintServiceModule, IDS_SERVICENAME> { 116 : public ATL::CAtlServiceModuleT<CloudPrintServiceModule, IDS_SERVICENAME> {
118 public: 117 public:
119 typedef ATL::CAtlServiceModuleT<CloudPrintServiceModule, 118 typedef ATL::CAtlServiceModuleT<CloudPrintServiceModule,
120 IDS_SERVICENAME> Base; 119 IDS_SERVICENAME> Base;
121 120
122 CloudPrintServiceModule() 121 CloudPrintServiceModule()
123 : check_requirements_(false), 122 : check_requirements_(false),
124 controller_(new ServiceController(m_szServiceName)) { 123 controller_(new ServiceController(m_szServiceName)) {
125 } 124 }
(...skipping 20 matching lines...) Expand all
146 } 145 }
147 return is_service; 146 return is_service;
148 } 147 }
149 148
150 HRESULT PreMessageLoop(int nShowCmd) { 149 HRESULT PreMessageLoop(int nShowCmd) {
151 HRESULT hr = Base::PreMessageLoop(nShowCmd); 150 HRESULT hr = Base::PreMessageLoop(nShowCmd);
152 if (FAILED(hr)) 151 if (FAILED(hr))
153 return hr; 152 return hr;
154 153
155 if (check_requirements_) { 154 if (check_requirements_) {
156 hr = CheckRequirements(); 155 CheckRequirements();
157 if (FAILED(hr))
158 return hr;
159 // Don't run message loop and stop service.
160 return S_FALSE;
161 } else { 156 } else {
162 hr = StartConnector(); 157 HRESULT hr = StartConnector();
163 if (FAILED(hr)) 158 if (FAILED(hr))
164 return hr; 159 return hr;
165 } 160 }
166 161
167 LogEvent(_T("Service started/resumed")); 162 LogEvent(_T("Service started/resumed"));
168 SetServiceStatus(SERVICE_RUNNING); 163 SetServiceStatus(SERVICE_RUNNING);
169 164
170 return hr; 165 return hr;
171 } 166 }
172 167
173 HRESULT PostMessageLoop() { 168 HRESULT PostMessageLoop() {
174 StopConnector(); 169 StopConnector();
170 setup_listener_.reset();
175 return Base::PostMessageLoop(); 171 return Base::PostMessageLoop();
176 } 172 }
177 173
178 private: 174 private:
179 HRESULT ParseCommandLine(const CommandLine& command_line, bool* is_service) { 175 HRESULT ParseCommandLine(const CommandLine& command_line, bool* is_service) {
180 if (!is_service) 176 if (!is_service)
181 return E_INVALIDARG; 177 return E_INVALIDARG;
182 *is_service = false; 178 *is_service = false;
183 179
184 user_data_dir_ = command_line.GetSwitchValuePath(kUserDataDirSwitch); 180 user_data_dir_ = command_line.GetSwitchValuePath(kUserDataDirSwitch);
(...skipping 11 matching lines...) Expand all
196 192
197 string16 run_as_user; 193 string16 run_as_user;
198 string16 run_as_password; 194 string16 run_as_password;
199 SelectWindowsAccount(&run_as_user, &run_as_password); 195 SelectWindowsAccount(&run_as_user, &run_as_password);
200 196
201 HRESULT hr = SetupServiceState(); 197 HRESULT hr = SetupServiceState();
202 if (FAILED(hr)) 198 if (FAILED(hr))
203 return hr; 199 return hr;
204 200
205 hr = controller_->InstallService(run_as_user, run_as_password, 201 hr = controller_->InstallService(run_as_user, run_as_password,
206 kServiceSwitch, user_data_dir_); 202 kServiceSwitch, user_data_dir_, true);
207 if (SUCCEEDED(hr) && command_line.HasSwitch(kStartSwitch)) 203 if (SUCCEEDED(hr) && command_line.HasSwitch(kStartSwitch))
208 return controller_->StartService(); 204 return controller_->StartService();
209 205
210 return hr; 206 return hr;
211 } 207 }
212 208
213 if (command_line.HasSwitch(kStartSwitch)) 209 if (command_line.HasSwitch(kStartSwitch))
214 return controller_->StartService(); 210 return controller_->StartService();
215 211
212 if (command_line.HasSwitch(kConsoleSwitch)) {
213 check_requirements_ = command_line.HasSwitch(kRequirementsSwitch);
214 ::SetConsoleCtrlHandler(&ConsoleCtrlHandler, TRUE);
215 HRESULT hr = Run();
216 ::SetConsoleCtrlHandler(NULL, FALSE);
217 return hr;
218 }
219
216 if (command_line.HasSwitch(kServiceSwitch) || 220 if (command_line.HasSwitch(kServiceSwitch) ||
217 command_line.HasSwitch(kRequirementsSwitch)) { 221 command_line.HasSwitch(kRequirementsSwitch)) {
218 *is_service = true; 222 *is_service = true;
219 check_requirements_ = command_line.HasSwitch(kRequirementsSwitch); 223 check_requirements_ = command_line.HasSwitch(kRequirementsSwitch);
220 return S_OK; 224 return S_OK;
221 } 225 }
222 226
223 if (command_line.HasSwitch(kConsoleSwitch)) {
224 ::SetConsoleCtrlHandler(&ConsoleCtrlHandler, TRUE);
225 HRESULT hr = Run();
226 ::SetConsoleCtrlHandler(NULL, FALSE);
227 return hr;
228 }
229 227
230 InvalidUsage(); 228 InvalidUsage();
231 return S_FALSE; 229 return S_FALSE;
232 } 230 }
233 231
234 void SelectWindowsAccount(string16* run_as_user, string16* run_as_password) { 232 void SelectWindowsAccount(string16* run_as_user, string16* run_as_password) {
235 *run_as_user = GetCurrentUserName(); 233 *run_as_user = GetCurrentUserName();
236 for (;;) { 234 for (;;) {
237 std::cout << "\nPlease provide Windows account to run service.\n"; 235 std::cout << "\nPlease provide Windows account to run service.\n";
238 *run_as_user = ASCIIToWide(GetOption("Account as DOMAIN\\USERNAME", 236 *run_as_user = ASCIIToWide(GetOption("Account as DOMAIN\\USERNAME",
239 WideToASCII(*run_as_user), false)); 237 WideToASCII(*run_as_user), false));
240 *run_as_password = ASCIIToWide(GetOption("Password", "", true)); 238 *run_as_password = ASCIIToWide(GetOption("Password", "", true));
241 239
242 base::FilePath requirements_filename(user_data_dir_); 240 SetupListener setup(*run_as_user);
243 requirements_filename = 241 if (FAILED(controller_->InstallService(*run_as_user, *run_as_password,
244 requirements_filename.Append(kRequirementsFileName); 242 kRequirementsSwitch,
245 243 user_data_dir_, false))) {
246 file_util::Delete(requirements_filename, false); 244 LOG(ERROR) << "Failed to install service as " << *run_as_user << ".";
247 if (file_util::PathExists(requirements_filename)) {
248 LOG(ERROR) << "Unable to delete " <<
249 requirements_filename.value() << ".";
250 continue; 245 continue;
251 } 246 }
252 if (FAILED(controller_->InstallService(*run_as_user, *run_as_password, 247
253 kRequirementsSwitch, 248 bool service_started = SUCCEEDED(controller_->StartService());
254 user_data_dir_))) { 249
255 continue; 250 if (service_started &&
251 !setup.WaitResponce(base::TimeDelta::FromSeconds(30))) {
252 LOG(ERROR) << "Failed to check environment for user " << *run_as_user
253 << ".";
256 } 254 }
257 bool service_started = SUCCEEDED(controller_->StartService()); 255
258 controller_->UninstallService(); 256 controller_->UninstallService();
259 if (!service_started) { 257 if (!service_started) {
260 LOG(ERROR) << "Failed to start service as " << *run_as_user << "."; 258 LOG(ERROR) << "Failed to start service as " << *run_as_user << ".";
261 continue; 259 continue;
262 } 260 }
263 std::string printers; 261 if (setup.user_data_dir().empty()) {
264 if (!file_util::PathExists(requirements_filename) || 262 LOG(ERROR) << "Service can't access " << user_data_dir_.value() << ".";
265 !file_util::ReadFileToString(requirements_filename, &printers)) {
266 LOG(ERROR) << "Service can't create " << requirements_filename.value();
267 continue; 263 continue;
268 } 264 }
269 265 if (setup.chrome_path().empty()) {
270 if (EndsWith(printers, kChromeIsNotAvalible, true)) { 266 LOG(ERROR) << "Chrome is not available for " << *run_as_user << ".";
271 LOG(ERROR) << kChromeIsNotAvalible << " for " << *run_as_user << "."; 267 continue;
268 }
269 if (!setup.is_xps_availible()) {
270 LOG(ERROR) << "XPS pack is not installed.";
272 continue; 271 continue;
273 } 272 }
274 273
275 std::cout << "\nService requirements check result: \n"; 274 std::cout << "\nService requirements check result: \n";
276 std::cout << printers << "\n"; 275 std::cout << "Username: " << setup.user_name()<< "\n";
277 file_util::Delete(requirements_filename, false); 276 std::cout << "Chrome: " << setup.chrome_path().value()<< "\n";
277 std::cout << "Printers:\n ";
278 std::ostream_iterator<std::string> cout_it(std::cout, "\n ");
279 std::copy(setup.printers().begin(), setup.printers().end(), cout_it);
280 std::cout << "\n";
278 281
279 if (AskUser("Do you want to use " + WideToASCII(*run_as_user) + "?")) 282 if (AskUser("Do you want to use " + WideToASCII(*run_as_user) + "?"))
280 return; 283 return;
281 } 284 }
282 } 285 }
283 286
284 HRESULT SetupServiceState() { 287 HRESULT SetupServiceState() {
285 base::FilePath file = user_data_dir_.Append(kServiceStateFileName); 288 base::FilePath file = user_data_dir_.Append(kServiceStateFileName);
286 289
287 for (;;) { 290 for (;;) {
(...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after
325 return last_error ? HRESULT_FROM_WIN32(last_error) : E_FAIL; 328 return last_error ? HRESULT_FROM_WIN32(last_error) : E_FAIL;
326 } 329 }
327 } 330 }
328 } 331 }
329 } 332 }
330 } 333 }
331 334
332 return S_OK; 335 return S_OK;
333 } 336 }
334 337
335 HRESULT CheckRequirements() { 338 void CheckRequirements() {
336 base::FilePath requirements_filename(user_data_dir_); 339 setup_listener_.reset(new ServiceListener(user_data_dir_));
337 requirements_filename = requirements_filename.Append(kRequirementsFileName);
338 std::string output;
339 output.append("Printers available for " +
340 WideToASCII(GetCurrentUserName()) + ":\n");
341 scoped_refptr<printing::PrintBackend> backend(
342 printing::PrintBackend::CreateInstance(NULL));
343 printing::PrinterList printer_list;
344 backend->EnumeratePrinters(&printer_list);
345 for (size_t i = 0; i < printer_list.size(); ++i) {
346 output += " ";
347 output += printer_list[i].printer_name;
348 output += "\n";
349 }
350 base::FilePath chrome = chrome_launcher_support::GetAnyChromePath();
351 output.append(chrome.empty() ? kChromeIsNotAvalible : kChromeIsAvalible);
352 file_util::WriteFile(requirements_filename, output.c_str(), output.size());
353 return S_OK;
354 } 340 }
355 341
356 HRESULT StartConnector() { 342 HRESULT StartConnector() {
357 chrome_.reset(new ChromeLauncher(user_data_dir_)); 343 chrome_.reset(new ChromeLauncher(user_data_dir_));
358 return chrome_->Start() ? S_OK : E_FAIL; 344 return chrome_->Start() ? S_OK : E_FAIL;
359 } 345 }
360 346
361 void StopConnector() { 347 void StopConnector() {
362 if (chrome_.get()) { 348 if (chrome_.get()) {
363 chrome_->Stop(); 349 chrome_->Stop();
364 chrome_.reset(); 350 chrome_.reset();
365 } 351 }
366 } 352 }
367 353
368 static BOOL WINAPI ConsoleCtrlHandler(DWORD type); 354 static BOOL WINAPI ConsoleCtrlHandler(DWORD type);
369 355
370 bool check_requirements_; 356 bool check_requirements_;
371 base::FilePath user_data_dir_; 357 base::FilePath user_data_dir_;
372 scoped_ptr<ChromeLauncher> chrome_; 358 scoped_ptr<ChromeLauncher> chrome_;
373 scoped_ptr<ServiceController> controller_; 359 scoped_ptr<ServiceController> controller_;
360 scoped_ptr<ServiceListener> setup_listener_;
374 }; 361 };
375 362
376 CloudPrintServiceModule _AtlModule; 363 CloudPrintServiceModule _AtlModule;
377 364
378 BOOL CloudPrintServiceModule::ConsoleCtrlHandler(DWORD type) { 365 BOOL CloudPrintServiceModule::ConsoleCtrlHandler(DWORD type) {
379 PostThreadMessage(_AtlModule.m_dwThreadID, WM_QUIT, 0, 0); 366 PostThreadMessage(_AtlModule.m_dwThreadID, WM_QUIT, 0, 0);
380 return TRUE; 367 return TRUE;
381 } 368 }
382 369
383 int main() { 370 int main() {
384 base::AtExitManager at_exit; 371 base::AtExitManager at_exit;
385 return _AtlModule.WinMain(0); 372 return _AtlModule.WinMain(0);
386 } 373 }
387 374
OLDNEW
« no previous file with comments | « cloud_print/service/service.gyp ('k') | cloud_print/service/win/cloud_print_service.rc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698