OLD | NEW |
1 // Copyright (c) 2010 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2010 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 "chrome/service/cloud_print/print_system.h" | 5 #include "chrome/service/cloud_print/print_system.h" |
6 | 6 |
7 #include <windows.h> | |
8 #include <objidl.h> | 7 #include <objidl.h> |
9 #include <ocidl.h> | |
10 #include <olectl.h> | |
11 #include <prntvpt.h> | 8 #include <prntvpt.h> |
12 #include <winspool.h> | 9 #include <winspool.h> |
13 | 10 |
14 #include "base/lock.h" | 11 #include "base/file_path.h" |
15 #include "base/file_util.h" | |
16 #include "base/object_watcher.h" | 12 #include "base/object_watcher.h" |
17 #include "base/scoped_ptr.h" | 13 #include "base/scoped_ptr.h" |
18 #include "base/utf_string_conversions.h" | 14 #include "base/utf_string_conversions.h" |
19 #include "base/win/scoped_bstr.h" | 15 #include "base/win/scoped_bstr.h" |
20 #include "base/win/scoped_comptr.h" | 16 #include "base/win/scoped_comptr.h" |
21 #include "chrome/service/cloud_print/cloud_print_consts.h" | 17 #include "chrome/service/cloud_print/cloud_print_consts.h" |
22 #include "chrome/service/service_process.h" | 18 #include "chrome/service/service_process.h" |
23 #include "chrome/service/service_utility_process_host.h" | 19 #include "chrome/service/service_utility_process_host.h" |
24 #include "gfx/rect.h" | 20 #include "gfx/rect.h" |
| 21 #include "printing/backend/print_backend.h" |
| 22 #include "printing/backend/print_backend_consts.h" |
| 23 #include "printing/backend/win_helper.h" |
25 #include "printing/native_metafile.h" | 24 #include "printing/native_metafile.h" |
26 #include "printing/page_range.h" | 25 #include "printing/page_range.h" |
27 | 26 |
28 #pragma comment(lib, "prntvpt.lib") | 27 #pragma comment(lib, "prntvpt.lib") |
29 #pragma comment(lib, "rpcrt4.lib") | |
30 | 28 |
31 using base::win::ScopedBstr; | 29 using base::win::ScopedBstr; |
32 using base::win::ScopedComPtr; | 30 using base::win::ScopedComPtr; |
33 | 31 |
34 namespace { | 32 namespace { |
35 | 33 |
36 class DevMode { | 34 class DevMode { |
37 public: | 35 public: |
38 DevMode() : dm_(NULL) {} | 36 DevMode() : dm_(NULL) {} |
39 ~DevMode() { Free(); } | 37 ~DevMode() { Free(); } |
40 | 38 |
41 void Allocate(int size) { | 39 void Allocate(int size) { |
42 Free(); | 40 Free(); |
43 dm_ = reinterpret_cast<DEVMODE*>(new char[size]); | 41 dm_ = reinterpret_cast<DEVMODE*>(new char[size]); |
44 } | 42 } |
45 | 43 |
46 void Free() { | 44 void Free() { |
47 if (dm_) | 45 if (dm_) |
48 delete [] dm_; | 46 delete [] dm_; |
49 dm_ = NULL; | 47 dm_ = NULL; |
50 } | 48 } |
51 | 49 |
52 DEVMODE* dm_; | 50 DEVMODE* dm_; |
53 | 51 |
54 private: | 52 private: |
55 DISALLOW_COPY_AND_ASSIGN(DevMode); | 53 DISALLOW_COPY_AND_ASSIGN(DevMode); |
56 }; | 54 }; |
57 | 55 |
58 bool InitXPSModule() { | |
59 HMODULE prntvpt_module = LoadLibrary(L"prntvpt.dll"); | |
60 return (NULL != prntvpt_module); | |
61 } | |
62 | |
63 inline HRESULT GetLastErrorHR() { | 56 inline HRESULT GetLastErrorHR() { |
64 LONG error = GetLastError(); | 57 LONG error = GetLastError(); |
65 return HRESULT_FROM_WIN32(error); | 58 return HRESULT_FROM_WIN32(error); |
66 } | 59 } |
67 | 60 |
68 HRESULT StreamFromPrintTicket(const std::string& print_ticket, | 61 HRESULT StreamFromPrintTicket(const std::string& print_ticket, |
69 IStream** stream) { | 62 IStream** stream) { |
70 DCHECK(stream); | 63 DCHECK(stream); |
71 HRESULT hr = CreateStreamOnHGlobal(NULL, TRUE, stream); | 64 HRESULT hr = CreateStreamOnHGlobal(NULL, TRUE, stream); |
72 if (FAILED(hr)) { | 65 if (FAILED(hr)) { |
73 return hr; | 66 return hr; |
74 } | 67 } |
75 ULONG bytes_written = 0; | 68 ULONG bytes_written = 0; |
76 (*stream)->Write(print_ticket.c_str(), print_ticket.length(), &bytes_written); | 69 (*stream)->Write(print_ticket.c_str(), print_ticket.length(), &bytes_written); |
77 DCHECK(bytes_written == print_ticket.length()); | 70 DCHECK(bytes_written == print_ticket.length()); |
78 LARGE_INTEGER pos = {0}; | 71 LARGE_INTEGER pos = {0}; |
79 ULARGE_INTEGER new_pos = {0}; | 72 ULARGE_INTEGER new_pos = {0}; |
80 (*stream)->Seek(pos, STREAM_SEEK_SET, &new_pos); | 73 (*stream)->Seek(pos, STREAM_SEEK_SET, &new_pos); |
81 return S_OK; | 74 return S_OK; |
82 } | 75 } |
83 | 76 |
84 HRESULT StreamOnHGlobalToString(IStream* stream, std::string* out) { | |
85 DCHECK(stream); | |
86 DCHECK(out); | |
87 HGLOBAL hdata = NULL; | |
88 HRESULT hr = GetHGlobalFromStream(stream, &hdata); | |
89 if (SUCCEEDED(hr)) { | |
90 DCHECK(hdata); | |
91 ScopedHGlobal<char> locked_data(hdata); | |
92 out->assign(locked_data.release(), locked_data.Size()); | |
93 } | |
94 return hr; | |
95 } | |
96 | |
97 HRESULT PrintTicketToDevMode(const std::string& printer_name, | 77 HRESULT PrintTicketToDevMode(const std::string& printer_name, |
98 const std::string& print_ticket, | 78 const std::string& print_ticket, |
99 DevMode* dev_mode) { | 79 DevMode* dev_mode) { |
100 DCHECK(dev_mode); | 80 DCHECK(dev_mode); |
101 | 81 |
102 ScopedComPtr<IStream> pt_stream; | 82 ScopedComPtr<IStream> pt_stream; |
103 HRESULT hr = StreamFromPrintTicket(print_ticket, pt_stream.Receive()); | 83 HRESULT hr = StreamFromPrintTicket(print_ticket, pt_stream.Receive()); |
104 if (FAILED(hr)) | 84 if (FAILED(hr)) |
105 return hr; | 85 return hr; |
106 | 86 |
(...skipping 95 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
202 } else if (change & PRINTER_CHANGE_SET_PRINTER) { | 182 } else if (change & PRINTER_CHANGE_SET_PRINTER) { |
203 delegate_->OnPrinterChanged(); | 183 delegate_->OnPrinterChanged(); |
204 } | 184 } |
205 if (change & PRINTER_CHANGE_JOB) { | 185 if (change & PRINTER_CHANGE_JOB) { |
206 delegate_->OnJobChanged(); | 186 delegate_->OnJobChanged(); |
207 } | 187 } |
208 } | 188 } |
209 watcher_.StartWatching(printer_change_, this); | 189 watcher_.StartWatching(printer_change_, this); |
210 } | 190 } |
211 | 191 |
212 bool GetCurrentPrinterInfo(PrinterBasicInfo* printer_info) { | 192 bool GetCurrentPrinterInfo(printing::PrinterBasicInfo* printer_info) { |
213 DCHECK(printer_info); | 193 DCHECK(printer_info); |
214 if (!printer_) | 194 if (!printer_) |
215 return false; | 195 return false; |
216 | 196 |
217 DWORD bytes_needed = 0; | 197 DWORD bytes_needed = 0; |
218 bool ret = false; | 198 bool ret = false; |
219 GetPrinter(printer_, 2, NULL, 0, &bytes_needed); | 199 GetPrinter(printer_, 2, NULL, 0, &bytes_needed); |
220 if (0 != bytes_needed) { | 200 if (0 != bytes_needed) { |
221 scoped_ptr<BYTE> printer_info_buffer(new BYTE[bytes_needed]); | 201 scoped_ptr<BYTE> printer_info_buffer(new BYTE[bytes_needed]); |
222 if (GetPrinter(printer_, 2, printer_info_buffer.get(), | 202 if (GetPrinter(printer_, 2, printer_info_buffer.get(), |
(...skipping 26 matching lines...) Expand all Loading... |
249 }; | 229 }; |
250 | 230 |
251 // This typedef is to workaround the issue with certain versions of | 231 // This typedef is to workaround the issue with certain versions of |
252 // Visual Studio where it gets confused between multiple Delegate. | 232 // Visual Studio where it gets confused between multiple Delegate. |
253 // In this case, some compilers get confused and inherit | 233 // In this case, some compilers get confused and inherit |
254 // PrintSystemWin watchers from wrong Delegate, giving C2664 and C2259 errors. | 234 // PrintSystemWin watchers from wrong Delegate, giving C2664 and C2259 errors. |
255 typedef PrintSystemWatcherWin::Delegate PrintSystemWatcherWinDelegate; | 235 typedef PrintSystemWatcherWin::Delegate PrintSystemWatcherWinDelegate; |
256 | 236 |
257 class PrintSystemWin : public PrintSystem { | 237 class PrintSystemWin : public PrintSystem { |
258 public: | 238 public: |
259 virtual void EnumeratePrinters(PrinterList* printer_list); | 239 PrintSystemWin(); |
260 | 240 |
261 virtual bool GetPrinterCapsAndDefaults(const std::string& printer_name, | 241 // PrintSystem implementation. |
262 PrinterCapsAndDefaults* printer_info); | 242 virtual printing::PrintBackend* GetPrintBackend(); |
263 | 243 |
264 virtual bool ValidatePrintTicket(const std::string& printer_name, | 244 virtual bool ValidatePrintTicket(const std::string& printer_name, |
265 const std::string& print_ticket_data); | 245 const std::string& print_ticket_data); |
266 | 246 |
267 virtual bool GetJobDetails(const std::string& printer_name, | 247 virtual bool GetJobDetails(const std::string& printer_name, |
268 PlatformJobId job_id, | 248 PlatformJobId job_id, |
269 PrintJobDetails *job_details); | 249 PrintJobDetails *job_details); |
270 | 250 |
271 virtual bool IsValidPrinter(const std::string& printer_name); | |
272 | |
273 class PrintServerWatcherWin | 251 class PrintServerWatcherWin |
274 : public PrintSystem::PrintServerWatcher, | 252 : public PrintSystem::PrintServerWatcher, |
275 public PrintSystemWatcherWinDelegate { | 253 public PrintSystemWatcherWinDelegate { |
276 public: | 254 public: |
277 PrintServerWatcherWin() {} | 255 PrintServerWatcherWin() {} |
278 | 256 |
279 // PrintSystem::PrintServerWatcher interface | 257 // PrintSystem::PrintServerWatcher interface |
280 virtual bool StartWatching( | 258 virtual bool StartWatching( |
281 PrintSystem::PrintServerWatcher::Delegate* delegate) { | 259 PrintSystem::PrintServerWatcher::Delegate* delegate) { |
282 delegate_ = delegate; | 260 delegate_ = delegate; |
(...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
316 virtual bool StartWatching( | 294 virtual bool StartWatching( |
317 PrintSystem::PrinterWatcher::Delegate* delegate) { | 295 PrintSystem::PrinterWatcher::Delegate* delegate) { |
318 delegate_ = delegate; | 296 delegate_ = delegate; |
319 return watcher_.Start(printer_name_, this); | 297 return watcher_.Start(printer_name_, this); |
320 } | 298 } |
321 virtual bool StopWatching() { | 299 virtual bool StopWatching() { |
322 bool ret = watcher_.Stop(); | 300 bool ret = watcher_.Stop(); |
323 delegate_ = NULL; | 301 delegate_ = NULL; |
324 return ret; | 302 return ret; |
325 } | 303 } |
326 virtual bool GetCurrentPrinterInfo(PrinterBasicInfo* printer_info) { | 304 virtual bool GetCurrentPrinterInfo( |
| 305 printing::PrinterBasicInfo* printer_info) { |
327 return watcher_.GetCurrentPrinterInfo(printer_info); | 306 return watcher_.GetCurrentPrinterInfo(printer_info); |
328 } | 307 } |
329 | 308 |
330 // PrintSystemWatcherWin::Delegate interface | 309 // PrintSystemWatcherWin::Delegate interface |
331 virtual void OnPrinterAdded() { | 310 virtual void OnPrinterAdded() { |
332 NOTREACHED(); | 311 NOTREACHED(); |
333 } | 312 } |
334 virtual void OnPrinterDeleted() { | 313 virtual void OnPrinterDeleted() { |
335 delegate_->OnPrinterDeleted(); | 314 delegate_->OnPrinterDeleted(); |
336 } | 315 } |
(...skipping 46 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
383 NOTREACHED(); | 362 NOTREACHED(); |
384 return false; | 363 return false; |
385 } | 364 } |
386 last_page_printed_ = -1; | 365 last_page_printed_ = -1; |
387 // We only support PDFs for now. | 366 // We only support PDFs for now. |
388 if (print_data_mime_type != "application/pdf") { | 367 if (print_data_mime_type != "application/pdf") { |
389 NOTREACHED(); | 368 NOTREACHED(); |
390 return false; | 369 return false; |
391 } | 370 } |
392 | 371 |
393 if (!InitXPSModule()) { | 372 if (!printing::InitXPSModule()) { |
394 // TODO(sanjeevr): Handle legacy proxy case (with no prntvpt.dll) | 373 // TODO(sanjeevr): Handle legacy proxy case (with no prntvpt.dll) |
395 return false; | 374 return false; |
396 } | 375 } |
397 DevMode pt_dev_mode; | 376 DevMode pt_dev_mode; |
398 HRESULT hr = PrintTicketToDevMode(printer_name, print_ticket, | 377 HRESULT hr = PrintTicketToDevMode(printer_name, print_ticket, |
399 &pt_dev_mode); | 378 &pt_dev_mode); |
400 if (FAILED(hr)) { | 379 if (FAILED(hr)) { |
401 NOTREACHED(); | 380 NOTREACHED(); |
402 return false; | 381 return false; |
403 } | 382 } |
(...skipping 116 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
520 DISALLOW_COPY_AND_ASSIGN(JobSpoolerWin::Core); | 499 DISALLOW_COPY_AND_ASSIGN(JobSpoolerWin::Core); |
521 }; | 500 }; |
522 scoped_refptr<Core> core_; | 501 scoped_refptr<Core> core_; |
523 DISALLOW_COPY_AND_ASSIGN(JobSpoolerWin); | 502 DISALLOW_COPY_AND_ASSIGN(JobSpoolerWin); |
524 }; | 503 }; |
525 | 504 |
526 virtual PrintSystem::PrintServerWatcher* CreatePrintServerWatcher(); | 505 virtual PrintSystem::PrintServerWatcher* CreatePrintServerWatcher(); |
527 virtual PrintSystem::PrinterWatcher* CreatePrinterWatcher( | 506 virtual PrintSystem::PrinterWatcher* CreatePrinterWatcher( |
528 const std::string& printer_name); | 507 const std::string& printer_name); |
529 virtual PrintSystem::JobSpooler* CreateJobSpooler(); | 508 virtual PrintSystem::JobSpooler* CreateJobSpooler(); |
| 509 |
| 510 private: |
| 511 void Init(); |
| 512 |
| 513 scoped_refptr<printing::PrintBackend> print_backend_; |
530 }; | 514 }; |
531 | 515 |
532 void PrintSystemWin::EnumeratePrinters(PrinterList* printer_list) { | 516 PrintSystemWin::PrintSystemWin() { |
533 DCHECK(printer_list); | 517 Init(); |
534 DWORD bytes_needed = 0; | |
535 DWORD count_returned = 0; | |
536 BOOL ret = EnumPrinters(PRINTER_ENUM_LOCAL|PRINTER_ENUM_CONNECTIONS, NULL, 2, | |
537 NULL, 0, &bytes_needed, &count_returned); | |
538 if (0 != bytes_needed) { | |
539 scoped_ptr<BYTE> printer_info_buffer(new BYTE[bytes_needed]); | |
540 ret = EnumPrinters(PRINTER_ENUM_LOCAL|PRINTER_ENUM_CONNECTIONS, NULL, 2, | |
541 printer_info_buffer.get(), bytes_needed, &bytes_needed, | |
542 &count_returned); | |
543 DCHECK(ret); | |
544 PRINTER_INFO_2* printer_info = | |
545 reinterpret_cast<PRINTER_INFO_2*>(printer_info_buffer.get()); | |
546 for (DWORD index = 0; index < count_returned; index++) { | |
547 PrinterBasicInfo info; | |
548 info.printer_name = WideToUTF8(printer_info[index].pPrinterName); | |
549 if (printer_info[index].pComment) | |
550 info.printer_description = WideToUTF8(printer_info[index].pComment); | |
551 info.printer_status = printer_info[index].Status; | |
552 if (printer_info[index].pLocation) | |
553 info.options[kLocationTagName] = | |
554 WideToUTF8(printer_info[index].pLocation); | |
555 if (printer_info[index].pDriverName) | |
556 info.options[kDriverNameTagName] = | |
557 WideToUTF8(printer_info[index].pDriverName); | |
558 printer_list->push_back(info); | |
559 } | |
560 } | |
561 } | 518 } |
562 | 519 |
563 bool PrintSystemWin::GetPrinterCapsAndDefaults( | 520 void PrintSystemWin::Init() { |
564 const std::string& printer_name, | 521 print_backend_ = printing::PrintBackend::CreateInstance(NULL); |
565 PrinterCapsAndDefaults* printer_info) { | 522 } |
566 if (!InitXPSModule()) { | 523 |
567 // TODO(sanjeevr): Handle legacy proxy case (with no prntvpt.dll) | 524 printing::PrintBackend* PrintSystemWin::GetPrintBackend() { |
568 return false; | 525 return print_backend_; |
569 } | |
570 if (!IsValidPrinter(printer_name)) { | |
571 return false; | |
572 } | |
573 DCHECK(printer_info); | |
574 HPTPROVIDER provider = NULL; | |
575 std::wstring printer_name_wide = UTF8ToWide(printer_name); | |
576 HRESULT hr = PTOpenProvider(printer_name_wide.c_str(), 1, &provider); | |
577 DCHECK(SUCCEEDED(hr)); | |
578 if (provider) { | |
579 ScopedComPtr<IStream> print_capabilities_stream; | |
580 hr = CreateStreamOnHGlobal(NULL, TRUE, | |
581 print_capabilities_stream.Receive()); | |
582 DCHECK(SUCCEEDED(hr)); | |
583 if (print_capabilities_stream) { | |
584 ScopedBstr error; | |
585 hr = PTGetPrintCapabilities(provider, NULL, print_capabilities_stream, | |
586 error.Receive()); | |
587 DCHECK(SUCCEEDED(hr)); | |
588 if (FAILED(hr)) { | |
589 return false; | |
590 } | |
591 hr = StreamOnHGlobalToString(print_capabilities_stream.get(), | |
592 &printer_info->printer_capabilities); | |
593 DCHECK(SUCCEEDED(hr)); | |
594 printer_info->caps_mime_type = "text/xml"; | |
595 } | |
596 // TODO(sanjeevr): Add ScopedPrinterHandle | |
597 HANDLE printer_handle = NULL; | |
598 OpenPrinter(const_cast<LPTSTR>(printer_name_wide.c_str()), &printer_handle, | |
599 NULL); | |
600 DCHECK(printer_handle); | |
601 if (printer_handle) { | |
602 DWORD devmode_size = DocumentProperties( | |
603 NULL, printer_handle, const_cast<LPTSTR>(printer_name_wide.c_str()), | |
604 NULL, NULL, 0); | |
605 DCHECK(0 != devmode_size); | |
606 scoped_ptr<BYTE> devmode_out_buffer(new BYTE[devmode_size]); | |
607 DEVMODE* devmode_out = | |
608 reinterpret_cast<DEVMODE*>(devmode_out_buffer.get()); | |
609 DocumentProperties( | |
610 NULL, printer_handle, const_cast<LPTSTR>(printer_name_wide.c_str()), | |
611 devmode_out, NULL, DM_OUT_BUFFER); | |
612 ScopedComPtr<IStream> printer_defaults_stream; | |
613 hr = CreateStreamOnHGlobal(NULL, TRUE, | |
614 printer_defaults_stream.Receive()); | |
615 DCHECK(SUCCEEDED(hr)); | |
616 if (printer_defaults_stream) { | |
617 hr = PTConvertDevModeToPrintTicket(provider, devmode_size, | |
618 devmode_out, kPTJobScope, | |
619 printer_defaults_stream); | |
620 DCHECK(SUCCEEDED(hr)); | |
621 if (SUCCEEDED(hr)) { | |
622 hr = StreamOnHGlobalToString(printer_defaults_stream.get(), | |
623 &printer_info->printer_defaults); | |
624 DCHECK(SUCCEEDED(hr)); | |
625 printer_info->defaults_mime_type = "text/xml"; | |
626 } | |
627 } | |
628 ClosePrinter(printer_handle); | |
629 } | |
630 PTCloseProvider(provider); | |
631 } | |
632 return true; | |
633 } | 526 } |
634 | 527 |
635 bool PrintSystemWin::ValidatePrintTicket( | 528 bool PrintSystemWin::ValidatePrintTicket( |
636 const std::string& printer_name, | 529 const std::string& printer_name, |
637 const std::string& print_ticket_data) { | 530 const std::string& print_ticket_data) { |
638 if (!InitXPSModule()) { | 531 if (!printing::InitXPSModule()) { |
639 // TODO(sanjeevr): Handle legacy proxy case (with no prntvpt.dll) | 532 // TODO(sanjeevr): Handle legacy proxy case (with no prntvpt.dll) |
640 return false; | 533 return false; |
641 } | 534 } |
642 bool ret = false; | 535 bool ret = false; |
643 HPTPROVIDER provider = NULL; | 536 HPTPROVIDER provider = NULL; |
644 PTOpenProvider(UTF8ToWide(printer_name.c_str()).c_str(), 1, &provider); | 537 PTOpenProvider(UTF8ToWide(printer_name.c_str()).c_str(), 1, &provider); |
645 if (provider) { | 538 if (provider) { |
646 ScopedComPtr<IStream> print_ticket_stream; | 539 ScopedComPtr<IStream> print_ticket_stream; |
647 CreateStreamOnHGlobal(NULL, TRUE, print_ticket_stream.Receive()); | 540 CreateStreamOnHGlobal(NULL, TRUE, print_ticket_stream.Receive()); |
648 ULONG bytes_written = 0; | 541 ULONG bytes_written = 0; |
(...skipping 56 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
705 job_details->total_pages = job_info->TotalPages; | 598 job_details->total_pages = job_info->TotalPages; |
706 job_details->pages_printed = job_info->PagesPrinted; | 599 job_details->pages_printed = job_info->PagesPrinted; |
707 ret = true; | 600 ret = true; |
708 } | 601 } |
709 } | 602 } |
710 ClosePrinter(printer_handle); | 603 ClosePrinter(printer_handle); |
711 } | 604 } |
712 return ret; | 605 return ret; |
713 } | 606 } |
714 | 607 |
715 bool PrintSystemWin::IsValidPrinter(const std::string& printer_name) { | |
716 std::wstring printer_name_wide = UTF8ToWide(printer_name); | |
717 HANDLE printer_handle = NULL; | |
718 OpenPrinter(const_cast<LPTSTR>(printer_name_wide.c_str()), &printer_handle, | |
719 NULL); | |
720 bool ret = false; | |
721 if (printer_handle) { | |
722 ret = true; | |
723 ClosePrinter(printer_handle); | |
724 } | |
725 return ret; | |
726 } | |
727 | |
728 PrintSystem::PrintServerWatcher* | 608 PrintSystem::PrintServerWatcher* |
729 PrintSystemWin::CreatePrintServerWatcher() { | 609 PrintSystemWin::CreatePrintServerWatcher() { |
730 return new PrintServerWatcherWin(); | 610 return new PrintServerWatcherWin(); |
731 } | 611 } |
732 | 612 |
733 PrintSystem::PrinterWatcher* PrintSystemWin::CreatePrinterWatcher( | 613 PrintSystem::PrinterWatcher* PrintSystemWin::CreatePrinterWatcher( |
734 const std::string& printer_name) { | 614 const std::string& printer_name) { |
735 DCHECK(!printer_name.empty()); | 615 DCHECK(!printer_name.empty()); |
736 return new PrinterWatcherWin(printer_name); | 616 return new PrinterWatcherWin(printer_name); |
737 } | 617 } |
(...skipping 15 matching lines...) Expand all Loading... |
753 RpcStringFree(reinterpret_cast<RPC_WSTR *>(&proxy_id_as_string)); | 633 RpcStringFree(reinterpret_cast<RPC_WSTR *>(&proxy_id_as_string)); |
754 return ret; | 634 return ret; |
755 } | 635 } |
756 | 636 |
757 scoped_refptr<PrintSystem> PrintSystem::CreateInstance( | 637 scoped_refptr<PrintSystem> PrintSystem::CreateInstance( |
758 const DictionaryValue* print_system_settings) { | 638 const DictionaryValue* print_system_settings) { |
759 return new PrintSystemWin; | 639 return new PrintSystemWin; |
760 } | 640 } |
761 | 641 |
762 } // namespace cloud_print | 642 } // namespace cloud_print |
763 | |
OLD | NEW |