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

Side by Side Diff: chrome/service/cloud_print/print_system_win.cc

Issue 9569029: Improved resource management (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Review Created 8 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 | « no previous file | printing/backend/print_backend_win.cc » ('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 "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
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
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
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
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
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
OLDNEW
« no previous file with comments | « no previous file | printing/backend/print_backend_win.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698