| OLD | NEW |
| 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 "chrome/service/cloud_print/print_system.h" | 5 #include "chrome/service/cloud_print/print_system.h" |
| 6 | 6 |
| 7 #include <objidl.h> | 7 #include <objidl.h> |
| 8 #include <winspool.h> | 8 #include <winspool.h> |
| 9 #include <xpsprint.h> | 9 #include <xpsprint.h> |
| 10 | 10 |
| (...skipping 15 matching lines...) Expand all Loading... |
| 26 #include "printing/emf_win.h" | 26 #include "printing/emf_win.h" |
| 27 #include "printing/page_range.h" | 27 #include "printing/page_range.h" |
| 28 #include "printing/pdf_render_settings.h" | 28 #include "printing/pdf_render_settings.h" |
| 29 #include "ui/base/l10n/l10n_util.h" | 29 #include "ui/base/l10n/l10n_util.h" |
| 30 #include "ui/gfx/rect.h" | 30 #include "ui/gfx/rect.h" |
| 31 | 31 |
| 32 #pragma comment(lib, "rpcrt4.lib") // for UuidToString & Co. | 32 #pragma comment(lib, "rpcrt4.lib") // for UuidToString & Co. |
| 33 | 33 |
| 34 namespace { | 34 namespace { |
| 35 | 35 |
| 36 class PrinterChangeHandleTraits { |
| 37 public: |
| 38 static bool CloseHandle(HANDLE handle) { |
| 39 return ::FindClosePrinterChangeNotification(handle) != FALSE; |
| 40 } |
| 41 }; |
| 42 |
| 43 typedef base::win::GenericScopedHandle<PrinterChangeHandleTraits> |
| 44 ScopedPrinterChangeHandle; |
| 45 |
| 36 class DevMode { | 46 class DevMode { |
| 37 public: | 47 public: |
| 38 DevMode() : dm_(NULL) {} | 48 DevMode() : dm_(NULL) {} |
| 39 ~DevMode() { Free(); } | 49 ~DevMode() { Free(); } |
| 40 | 50 |
| 41 void Allocate(int size) { | 51 void Allocate(int size) { |
| 42 Free(); | 52 Free(); |
| 43 dm_ = reinterpret_cast<DEVMODE*>(new char[size]); | 53 dm_ = reinterpret_cast<DEVMODE*>(new char[size]); |
| 44 } | 54 } |
| 45 | 55 |
| (...skipping 69 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 115 return hr; | 125 return hr; |
| 116 } | 126 } |
| 117 | 127 |
| 118 } // namespace | 128 } // namespace |
| 119 | 129 |
| 120 namespace cloud_print { | 130 namespace cloud_print { |
| 121 | 131 |
| 122 class PrintSystemWatcherWin : public base::win::ObjectWatcher::Delegate { | 132 class PrintSystemWatcherWin : public base::win::ObjectWatcher::Delegate { |
| 123 public: | 133 public: |
| 124 PrintSystemWatcherWin() | 134 PrintSystemWatcherWin() |
| 125 : printer_(NULL), | 135 : delegate_(NULL), |
| 126 printer_change_(NULL), | |
| 127 delegate_(NULL), | |
| 128 did_signal_(false) { | 136 did_signal_(false) { |
| 129 } | 137 } |
| 130 ~PrintSystemWatcherWin() { | 138 ~PrintSystemWatcherWin() { |
| 131 Stop(); | 139 Stop(); |
| 132 } | 140 } |
| 133 | 141 |
| 134 class Delegate { | 142 class Delegate { |
| 135 public: | 143 public: |
| 136 virtual ~Delegate() {} | 144 virtual ~Delegate() {} |
| 137 virtual void OnPrinterAdded() = 0; | 145 virtual void OnPrinterAdded() = 0; |
| 138 virtual void OnPrinterDeleted() = 0; | 146 virtual void OnPrinterDeleted() = 0; |
| 139 virtual void OnPrinterChanged() = 0; | 147 virtual void OnPrinterChanged() = 0; |
| 140 virtual void OnJobChanged() = 0; | 148 virtual void OnJobChanged() = 0; |
| 141 }; | 149 }; |
| 142 | 150 |
| 143 bool Start(const std::string& printer_name, Delegate* delegate) { | 151 bool Start(const std::string& printer_name, Delegate* delegate) { |
| 144 delegate_ = delegate; | 152 delegate_ = delegate; |
| 145 // An empty printer name means watch the current server, we need to pass | 153 // An empty printer name means watch the current server, we need to pass |
| 146 // NULL to OpenPrinter. | 154 // NULL to OpenPrinter. |
| 147 LPTSTR printer_name_to_use = NULL; | 155 LPTSTR printer_name_to_use = NULL; |
| 148 std::wstring printer_name_wide; | 156 std::wstring printer_name_wide; |
| 149 if (!printer_name.empty()) { | 157 if (!printer_name.empty()) { |
| 150 printer_name_wide = UTF8ToWide(printer_name); | 158 printer_name_wide = UTF8ToWide(printer_name); |
| 151 printer_name_to_use = const_cast<LPTSTR>(printer_name_wide.c_str()); | 159 printer_name_to_use = const_cast<LPTSTR>(printer_name_wide.c_str()); |
| 152 } | 160 } |
| 153 bool ret = false; | 161 bool ret = false; |
| 154 OpenPrinter(printer_name_to_use, &printer_, NULL); | 162 OpenPrinter(printer_name_to_use, printer_.Receive(), NULL); |
| 155 if (printer_) { | 163 if (printer_.IsValid()) { |
| 156 printer_change_ = FindFirstPrinterChangeNotification( | 164 printer_change_.Set(FindFirstPrinterChangeNotification( |
| 157 printer_, PRINTER_CHANGE_PRINTER|PRINTER_CHANGE_JOB, 0, NULL); | 165 printer_, PRINTER_CHANGE_PRINTER|PRINTER_CHANGE_JOB, 0, NULL)); |
| 158 if (printer_change_) { | 166 if (printer_change_.IsValid()) { |
| 159 ret = watcher_.StartWatching(printer_change_, this); | 167 ret = watcher_.StartWatching(printer_change_, this); |
| 160 } | 168 } |
| 161 } | 169 } |
| 162 if (!ret) { | 170 if (!ret) { |
| 163 Stop(); | 171 Stop(); |
| 164 } | 172 } |
| 165 return ret; | 173 return ret; |
| 166 } | 174 } |
| 167 bool Stop() { | 175 bool Stop() { |
| 168 watcher_.StopWatching(); | 176 watcher_.StopWatching(); |
| 169 if (printer_) { | 177 printer_.Close(); |
| 170 ClosePrinter(printer_); | 178 printer_change_.Close(); |
| 171 printer_ = NULL; | |
| 172 } | |
| 173 if (printer_change_) { | |
| 174 FindClosePrinterChangeNotification(printer_change_); | |
| 175 printer_change_ = NULL; | |
| 176 } | |
| 177 return true; | 179 return true; |
| 178 } | 180 } |
| 179 | 181 |
| 180 // base::ObjectWatcher::Delegate method | 182 // base::ObjectWatcher::Delegate method |
| 181 virtual void OnObjectSignaled(HANDLE object) { | 183 virtual void OnObjectSignaled(HANDLE object) { |
| 182 DWORD change = 0; | 184 DWORD change = 0; |
| 183 FindNextPrinterChangeNotification(object, &change, NULL, NULL); | 185 FindNextPrinterChangeNotification(object, &change, NULL, NULL); |
| 184 | 186 |
| 185 if (change != ((PRINTER_CHANGE_PRINTER|PRINTER_CHANGE_JOB) & | 187 if (change != ((PRINTER_CHANGE_PRINTER|PRINTER_CHANGE_JOB) & |
| 186 (~PRINTER_CHANGE_FAILED_CONNECTION_PRINTER))) { | 188 (~PRINTER_CHANGE_FAILED_CONNECTION_PRINTER))) { |
| 187 // For printer connections, we get spurious change notifications with | 189 // For printer connections, we get spurious change notifications with |
| 188 // all flags set except PRINTER_CHANGE_FAILED_CONNECTION_PRINTER. | 190 // all flags set except PRINTER_CHANGE_FAILED_CONNECTION_PRINTER. |
| 189 // Ignore these. | 191 // Ignore these. |
| 190 if (change & PRINTER_CHANGE_ADD_PRINTER) { | 192 if (change & PRINTER_CHANGE_ADD_PRINTER) { |
| 191 delegate_->OnPrinterAdded(); | 193 delegate_->OnPrinterAdded(); |
| 192 } else if (change & PRINTER_CHANGE_DELETE_PRINTER) { | 194 } else if (change & PRINTER_CHANGE_DELETE_PRINTER) { |
| 193 delegate_->OnPrinterDeleted(); | 195 delegate_->OnPrinterDeleted(); |
| 194 } else if (change & PRINTER_CHANGE_SET_PRINTER) { | 196 } else if (change & PRINTER_CHANGE_SET_PRINTER) { |
| 195 delegate_->OnPrinterChanged(); | 197 delegate_->OnPrinterChanged(); |
| 196 } | 198 } |
| 197 if (change & PRINTER_CHANGE_JOB) { | 199 if (change & PRINTER_CHANGE_JOB) { |
| 198 delegate_->OnJobChanged(); | 200 delegate_->OnJobChanged(); |
| 199 } | 201 } |
| 200 } | 202 } |
| 201 watcher_.StartWatching(printer_change_, this); | 203 watcher_.StartWatching(printer_change_, this); |
| 202 } | 204 } |
| 203 | 205 |
| 204 bool GetCurrentPrinterInfo(printing::PrinterBasicInfo* printer_info) { | 206 bool GetCurrentPrinterInfo(printing::PrinterBasicInfo* printer_info) { |
| 205 DCHECK(printer_info); | 207 DCHECK(printer_info); |
| 206 if (!printer_) | 208 if (!printer_.IsValid()) |
| 207 return false; | 209 return false; |
| 208 | 210 |
| 209 DWORD bytes_needed = 0; | 211 DWORD bytes_needed = 0; |
| 210 bool ret = false; | 212 bool ret = false; |
| 211 GetPrinter(printer_, 2, NULL, 0, &bytes_needed); | 213 GetPrinter(printer_, 2, NULL, 0, &bytes_needed); |
| 212 if (0 != bytes_needed) { | 214 if (0 != bytes_needed) { |
| 213 scoped_array<BYTE> printer_info_buffer(new BYTE[bytes_needed]); | 215 scoped_array<BYTE> printer_info_buffer(new BYTE[bytes_needed]); |
| 214 if (GetPrinter(printer_, 2, printer_info_buffer.get(), | 216 if (GetPrinter(printer_, 2, printer_info_buffer.get(), |
| 215 bytes_needed, &bytes_needed)) { | 217 bytes_needed, &bytes_needed)) { |
| 216 PRINTER_INFO_2* printer_info_win = | 218 PRINTER_INFO_2* printer_info_win = |
| (...skipping 10 matching lines...) Expand all Loading... |
| 227 WideToUTF8(printer_info_win->pDriverName); | 229 WideToUTF8(printer_info_win->pDriverName); |
| 228 printer_info->printer_status = printer_info_win->Status; | 230 printer_info->printer_status = printer_info_win->Status; |
| 229 ret = true; | 231 ret = true; |
| 230 } | 232 } |
| 231 } | 233 } |
| 232 return ret; | 234 return ret; |
| 233 } | 235 } |
| 234 | 236 |
| 235 private: | 237 private: |
| 236 base::win::ObjectWatcher watcher_; | 238 base::win::ObjectWatcher watcher_; |
| 237 HANDLE printer_; // The printer being watched | 239 printing::ScopedPrinterHandle printer_; // The printer being watched |
| 238 HANDLE printer_change_; // Returned by FindFirstPrinterChangeNotifier | 240 // Returned by FindFirstPrinterChangeNotifier. |
| 239 Delegate* delegate_; // Delegate to notify | 241 ScopedPrinterChangeHandle printer_change_; |
| 240 bool did_signal_; // DoneWaiting was called | 242 Delegate* delegate_; // Delegate to notify |
| 243 bool did_signal_; // DoneWaiting was called |
| 241 }; | 244 }; |
| 242 | 245 |
| 243 // This typedef is to workaround the issue with certain versions of | 246 // This typedef is to workaround the issue with certain versions of |
| 244 // Visual Studio where it gets confused between multiple Delegate. | 247 // Visual Studio where it gets confused between multiple Delegate. |
| 245 // In this case, some compilers get confused and inherit | 248 // In this case, some compilers get confused and inherit |
| 246 // PrintSystemWin watchers from wrong Delegate, giving C2664 and C2259 errors. | 249 // PrintSystemWin watchers from wrong Delegate, giving C2664 and C2259 errors. |
| 247 typedef PrintSystemWatcherWin::Delegate PrintSystemWatcherWinDelegate; | 250 typedef PrintSystemWatcherWin::Delegate PrintSystemWatcherWinDelegate; |
| 248 | 251 |
| 249 class PrintSystemWin : public PrintSystem { | 252 class PrintSystemWin : public PrintSystem { |
| 250 public: | 253 public: |
| (...skipping 546 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 797 error.Receive())); | 800 error.Receive())); |
| 798 printing::XPSModule::CloseProvider(provider); | 801 printing::XPSModule::CloseProvider(provider); |
| 799 } | 802 } |
| 800 return ret; | 803 return ret; |
| 801 } | 804 } |
| 802 | 805 |
| 803 bool PrintSystemWin::GetJobDetails(const std::string& printer_name, | 806 bool PrintSystemWin::GetJobDetails(const std::string& printer_name, |
| 804 PlatformJobId job_id, | 807 PlatformJobId job_id, |
| 805 PrintJobDetails *job_details) { | 808 PrintJobDetails *job_details) { |
| 806 DCHECK(job_details); | 809 DCHECK(job_details); |
| 807 HANDLE printer_handle = NULL; | 810 printing::ScopedPrinterHandle printer_handle; |
| 808 std::wstring printer_name_wide = UTF8ToWide(printer_name); | 811 std::wstring printer_name_wide = UTF8ToWide(printer_name); |
| 809 OpenPrinter(const_cast<LPTSTR>(printer_name_wide.c_str()), &printer_handle, | 812 OpenPrinter(const_cast<LPTSTR>(printer_name_wide.c_str()), |
| 810 NULL); | 813 printer_handle.Receive(), NULL); |
| 811 DCHECK(printer_handle); | 814 DCHECK(printer_handle.IsValid()); |
| 812 bool ret = false; | 815 bool ret = false; |
| 813 if (printer_handle) { | 816 if (printer_handle.IsValid()) { |
| 814 DWORD bytes_needed = 0; | 817 DWORD bytes_needed = 0; |
| 815 GetJob(printer_handle, job_id, 1, NULL, 0, &bytes_needed); | 818 GetJob(printer_handle, job_id, 1, NULL, 0, &bytes_needed); |
| 816 DWORD last_error = GetLastError(); | 819 DWORD last_error = GetLastError(); |
| 817 if (ERROR_INVALID_PARAMETER != last_error) { | 820 if (ERROR_INVALID_PARAMETER != last_error) { |
| 818 // ERROR_INVALID_PARAMETER normally means that the job id is not valid. | 821 // ERROR_INVALID_PARAMETER normally means that the job id is not valid. |
| 819 DCHECK(last_error == ERROR_INSUFFICIENT_BUFFER); | 822 DCHECK(last_error == ERROR_INSUFFICIENT_BUFFER); |
| 820 scoped_array<BYTE> job_info_buffer(new BYTE[bytes_needed]); | 823 scoped_array<BYTE> job_info_buffer(new BYTE[bytes_needed]); |
| 821 if (GetJob(printer_handle, job_id, 1, job_info_buffer.get(), bytes_needed, | 824 if (GetJob(printer_handle, job_id, 1, job_info_buffer.get(), bytes_needed, |
| 822 &bytes_needed)) { | 825 &bytes_needed)) { |
| 823 JOB_INFO_1 *job_info = | 826 JOB_INFO_1 *job_info = |
| 824 reinterpret_cast<JOB_INFO_1 *>(job_info_buffer.get()); | 827 reinterpret_cast<JOB_INFO_1 *>(job_info_buffer.get()); |
| 825 if (job_info->pStatus) { | 828 if (job_info->pStatus) { |
| 826 WideToUTF8(job_info->pStatus, wcslen(job_info->pStatus), | 829 WideToUTF8(job_info->pStatus, wcslen(job_info->pStatus), |
| 827 &job_details->status_message); | 830 &job_details->status_message); |
| 828 } | 831 } |
| 829 job_details->platform_status_flags = job_info->Status; | 832 job_details->platform_status_flags = job_info->Status; |
| 830 if ((job_info->Status & JOB_STATUS_COMPLETE) || | 833 if ((job_info->Status & JOB_STATUS_COMPLETE) || |
| 831 (job_info->Status & JOB_STATUS_PRINTED)) { | 834 (job_info->Status & JOB_STATUS_PRINTED)) { |
| 832 job_details->status = PRINT_JOB_STATUS_COMPLETED; | 835 job_details->status = PRINT_JOB_STATUS_COMPLETED; |
| 833 } else if (job_info->Status & JOB_STATUS_ERROR) { | 836 } else if (job_info->Status & JOB_STATUS_ERROR) { |
| 834 job_details->status = PRINT_JOB_STATUS_ERROR; | 837 job_details->status = PRINT_JOB_STATUS_ERROR; |
| 835 } else { | 838 } else { |
| 836 job_details->status = PRINT_JOB_STATUS_IN_PROGRESS; | 839 job_details->status = PRINT_JOB_STATUS_IN_PROGRESS; |
| 837 } | 840 } |
| 838 job_details->total_pages = job_info->TotalPages; | 841 job_details->total_pages = job_info->TotalPages; |
| 839 job_details->pages_printed = job_info->PagesPrinted; | 842 job_details->pages_printed = job_info->PagesPrinted; |
| 840 ret = true; | 843 ret = true; |
| 841 } | 844 } |
| 842 } | 845 } |
| 843 ClosePrinter(printer_handle); | |
| 844 } | 846 } |
| 845 return ret; | 847 return ret; |
| 846 } | 848 } |
| 847 | 849 |
| 848 PrintSystem::PrintServerWatcher* | 850 PrintSystem::PrintServerWatcher* |
| 849 PrintSystemWin::CreatePrintServerWatcher() { | 851 PrintSystemWin::CreatePrintServerWatcher() { |
| 850 return new PrintServerWatcherWin(); | 852 return new PrintServerWatcherWin(); |
| 851 } | 853 } |
| 852 | 854 |
| 853 PrintSystem::PrinterWatcher* PrintSystemWin::CreatePrinterWatcher( | 855 PrintSystem::PrinterWatcher* PrintSystemWin::CreatePrinterWatcher( |
| (...skipping 26 matching lines...) Expand all Loading... |
| 880 RpcStringFree(reinterpret_cast<RPC_WSTR *>(&proxy_id_as_string)); | 882 RpcStringFree(reinterpret_cast<RPC_WSTR *>(&proxy_id_as_string)); |
| 881 return ret; | 883 return ret; |
| 882 } | 884 } |
| 883 | 885 |
| 884 scoped_refptr<PrintSystem> PrintSystem::CreateInstance( | 886 scoped_refptr<PrintSystem> PrintSystem::CreateInstance( |
| 885 const base::DictionaryValue* print_system_settings) { | 887 const base::DictionaryValue* print_system_settings) { |
| 886 return new PrintSystemWin; | 888 return new PrintSystemWin; |
| 887 } | 889 } |
| 888 | 890 |
| 889 } // namespace cloud_print | 891 } // namespace cloud_print |
| OLD | NEW |