diff options
author | sanjeevr@chromium.org <sanjeevr@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2011-01-24 23:47:41 +0000 |
---|---|---|
committer | sanjeevr@chromium.org <sanjeevr@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2011-01-24 23:47:41 +0000 |
commit | 402197a5a7eb74fbc1fe9317abe94b1812af5c92 (patch) | |
tree | 2a38f1ba579d385eeacce4adbb52fbe52f2678c8 | |
parent | 2c81bcd1677ef4237c84462cbf2c5ff02301a46f (diff) | |
download | chromium_src-402197a5a7eb74fbc1fe9317abe94b1812af5c92.zip chromium_src-402197a5a7eb74fbc1fe9317abe94b1812af5c92.tar.gz chromium_src-402197a5a7eb74fbc1fe9317abe94b1812af5c92.tar.bz2 |
Added a diagnostic user message when enumerating printers fails. Also tweaked some of the strings.
BUG=None
TEST=Test Cloud Print Proxy.
Review URL: http://codereview.chromium.org/6356007
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@72422 0039d316-1c4b-4281-b951-d872f2087c98
-rw-r--r-- | chrome/app/generated_resources.grd | 5 | ||||
-rw-r--r-- | chrome/service/cloud_print/cloud_print_consts.cc | 2 | ||||
-rw-r--r-- | chrome/service/cloud_print/cloud_print_consts.h | 1 | ||||
-rw-r--r-- | chrome/service/cloud_print/cloud_print_proxy_backend.cc | 119 | ||||
-rw-r--r-- | chrome/service/cloud_print/print_system.h | 3 | ||||
-rw-r--r-- | chrome/service/cloud_print/print_system_cups.cc | 20 | ||||
-rw-r--r-- | chrome/service/cloud_print/print_system_win.cc | 9 | ||||
-rw-r--r-- | chrome/service/cloud_print/printer_job_handler.cc | 9 | ||||
-rw-r--r-- | chrome/service/cloud_print/printer_job_handler.h | 5 | ||||
-rw-r--r-- | printing/backend/print_backend.h | 2 | ||||
-rw-r--r-- | printing/backend/print_backend_cups.cc | 7 | ||||
-rw-r--r-- | printing/backend/print_backend_win.cc | 52 |
12 files changed, 158 insertions, 76 deletions
diff --git a/chrome/app/generated_resources.grd b/chrome/app/generated_resources.grd index 25ad9e5..dab464d 100644 --- a/chrome/app/generated_resources.grd +++ b/chrome/app/generated_resources.grd @@ -5371,8 +5371,11 @@ Keep your key file in a safe place. You will need it to create new versions of y An error occurred while retrieving printer capabilities for printer <ph name="PRINTER_NAME">$1<ex>HP Laserjet 7900</ex></ph>. This printer could not be registered with <ph name="CLOUD_PRINT_NAME">Google Cloud Print</ph>. </message> <message name="IDS_CLOUD_PRINT_XPS_UNAVAILABLE" desc="Status message to be sent to the Cloud Print server when the XPS framework is missing."> - The Microsoft XML Paper Specification Essentials Pack is not installed on the machine running the Google Cloud Print connector. + The <ph name="CLOUD_PRINT_NAME">Google Cloud Print</ph> connector requires that the Microsoft XML Paper Specification Essentials Pack be installed. </message> + <message name="IDS_CLOUD_PRINT_ENUM_FAILED" desc="Status message to be sent to the Cloud Print server when enumerating printers failed."> + There was a problem listing printers. Some of your printers may not have registered successfully with <ph name="CLOUD_PRINT_NAME">Google Cloud Print</ph>. + </message> <!-- Print Preview --> <message name="IDS_PRINT_PREVIEW_TITLE" desc="Title for print preview page "> diff --git a/chrome/service/cloud_print/cloud_print_consts.cc b/chrome/service/cloud_print/cloud_print_consts.cc index 1654844..4481384 100644 --- a/chrome/service/cloud_print/cloud_print_consts.cc +++ b/chrome/service/cloud_print/cloud_print_consts.cc @@ -57,4 +57,4 @@ const char kJobFetchReasonQueryMore[] = "querymore"; // Short message ids for diagnostic messages sent to the server. const char kPrintSystemFailedMessageId[] = "printsystemfail"; const char kGetPrinterCapsFailedMessageId[] = "getprncapsfail"; - +const char kEnumPrintersFailedMessageId[] = "enumfail"; diff --git a/chrome/service/cloud_print/cloud_print_consts.h b/chrome/service/cloud_print/cloud_print_consts.h index 409eb72..160f20f 100644 --- a/chrome/service/cloud_print/cloud_print_consts.h +++ b/chrome/service/cloud_print/cloud_print_consts.h @@ -45,6 +45,7 @@ extern const char kJobFetchReasonNotified[]; extern const char kJobFetchReasonQueryMore[]; extern const char kPrintSystemFailedMessageId[]; extern const char kGetPrinterCapsFailedMessageId[]; +extern const char kEnumPrintersFailedMessageId[]; // Max retry count for job data fetch requests. const int kJobDataMaxRetryCount = 5; diff --git a/chrome/service/cloud_print/cloud_print_proxy_backend.cc b/chrome/service/cloud_print/cloud_print_proxy_backend.cc index eae43bc..3d0ac29 100644 --- a/chrome/service/cloud_print/cloud_print_proxy_backend.cc +++ b/chrome/service/cloud_print/cloud_print_proxy_backend.cc @@ -80,6 +80,8 @@ class CloudPrintProxyBackend::Core virtual void OnPrinterJobHandlerShutdown(PrinterJobHandler* job_handler, const std::string& printer_id); virtual void OnAuthError(); + virtual void OnPrinterNotFound(const std::string& printer_name, + bool* delete_from_server); // notifier::TalkMediator::Delegate implementation. virtual void OnNotificationStateChange( @@ -115,7 +117,13 @@ class CloudPrintProxyBackend::Core DictionaryValue* json_data, bool succeeded); -CloudPrintURLFetcher::ResponseAction HandlePrintSystemUnavailableResponse( + CloudPrintURLFetcher::ResponseAction HandlePrintSystemUnavailableResponse( + const URLFetcher* source, + const GURL& url, + DictionaryValue* json_data, + bool succeeded); + + CloudPrintURLFetcher::ResponseAction HandleEnumPrintersFailedResponse( const URLFetcher* source, const GURL& url, DictionaryValue* json_data, @@ -150,9 +158,10 @@ CloudPrintURLFetcher::ResponseAction HandlePrintSystemUnavailableResponse( // handler is responsible for checking for pending print jobs for this // printer and print them. void InitJobHandlerForPrinter(DictionaryValue* printer_data); - // Sends a diagnostic message to the cloud print server that the print - // system failed to initialize. - void ReportPrintSystemUnavailable(const std::string& failure_message); + // Reports a diagnostic message to the server. + void ReportUserMessage(const std::string& message_id, + const std::string& failure_message, + ResponseHandler handler); // Callback method for GetPrinterCapsAndDefaults. void OnReceivePrinterCaps( @@ -181,6 +190,9 @@ CloudPrintURLFetcher::ResponseAction HandlePrintSystemUnavailableResponse( // user a chance to further trim the list. When the frontend gives us the // final list we make a copy into this so that we can start registering. printing::PrinterList printer_list_; + // Indicates whether the printers in printer_list_ is the complete set of + // printers to be registered for this proxy. + bool complete_list_available_; // The CloudPrintURLFetcher instance for the current request. scoped_refptr<CloudPrintURLFetcher> request_; // The index of the nex printer to be uploaded. @@ -280,6 +292,7 @@ CloudPrintProxyBackend::Core::Core(CloudPrintProxyBackend* backend, const DictionaryValue* print_system_settings) : backend_(backend), cloud_print_server_url_(cloud_print_server_url), + complete_list_available_(false), next_upload_index_(0), next_response_handler_(NULL), new_printers_available_(false), @@ -382,17 +395,33 @@ void CloudPrintProxyBackend::Core::DoInitializeWithToken( StartRegistration(); } else { // We could not initialize the print system. We need to notify the server. - ReportPrintSystemUnavailable(result.message()); + ReportUserMessage( + kPrintSystemFailedMessageId, + result.message(), + &CloudPrintProxyBackend::Core::HandlePrintSystemUnavailableResponse); } } void CloudPrintProxyBackend::Core::StartRegistration() { DCHECK(MessageLoop::current() == backend_->core_thread_.message_loop()); printer_list_.clear(); - print_system_->EnumeratePrinters(&printer_list_); - // Now we need to ask the server about printers that were registered on the - // server so that we can trim this list. - GetRegisteredPrinters(); + cloud_print::PrintSystem::PrintSystemResult result = + print_system_->EnumeratePrinters(&printer_list_); + complete_list_available_ = result.succeeded(); + if (!result.succeeded()) { + std::string message = result.message(); + if (message.empty()) + message = l10n_util::GetStringUTF8(IDS_CLOUD_PRINT_ENUM_FAILED); + // There was a failure enumerating printers. Send a message to the server. + ReportUserMessage( + kEnumPrintersFailedMessageId, + message, + &CloudPrintProxyBackend::Core::HandleEnumPrintersFailedResponse); + } else { + // Now we need to ask the server about printers that were registered on the + // server so that we can trim this list. + GetRegisteredPrinters(); + } } void CloudPrintProxyBackend::Core::EndRegistration() { @@ -478,10 +507,6 @@ void CloudPrintProxyBackend::Core::OnReceivePrinterCaps( const std::string& printer_name, const printing::PrinterCapsAndDefaults& caps_and_defaults) { DCHECK(next_upload_index_ < printer_list_.size()); - std::string mime_boundary; - CloudPrintHelpers::CreateMimeBoundaryForUpload(&mime_boundary); - std::string post_data; - GURL post_url; if (succeeded) { const printing::PrinterBasicInfo& info = printer_list_.at(next_upload_index_); @@ -489,6 +514,10 @@ void CloudPrintProxyBackend::Core::OnReceivePrinterCaps( last_uploaded_printer_name_ = info.printer_name; last_uploaded_printer_info_ = caps_and_defaults; + std::string mime_boundary; + CloudPrintHelpers::CreateMimeBoundaryForUpload(&mime_boundary); + std::string post_data; + CloudPrintHelpers::AddMultipartValueForUpload(kProxyIdValue, proxy_id_, mime_boundary, std::string(), &post_data); @@ -522,38 +551,32 @@ void CloudPrintProxyBackend::Core::OnReceivePrinterCaps( kPrinterCapsHashValue, MD5String(last_uploaded_printer_info_.printer_capabilities), mime_boundary, std::string(), &post_data); - post_url = CloudPrintHelpers::GetUrlForPrinterRegistration( + GURL post_url = CloudPrintHelpers::GetUrlForPrinterRegistration( cloud_print_server_url_); next_response_handler_ = &CloudPrintProxyBackend::Core::HandleRegisterPrinterResponse; + // Terminate the request body + post_data.append("--" + mime_boundary + "--\r\n"); + std::string mime_type("multipart/form-data; boundary="); + mime_type += mime_boundary; + request_ = new CloudPrintURLFetcher; + request_->StartPostRequest(post_url, this, auth_token_, + kCloudPrintAPIMaxRetryCount, mime_type, + post_data); } else { LOG(ERROR) << "CP_PROXY: Failed to get printer info for: " << printer_name; // This printer failed to register, notify the server of this failure. - post_url = CloudPrintHelpers::GetUrlForUserMessage( - cloud_print_server_url_, - kGetPrinterCapsFailedMessageId); string16 printer_name_utf16 = UTF8ToUTF16(printer_name); std::string status_message = l10n_util::GetStringFUTF8( IDS_CLOUD_PRINT_REGISTER_PRINTER_FAILED, printer_name_utf16); - CloudPrintHelpers::AddMultipartValueForUpload(kMessageTextValue, - status_message, - mime_boundary, - std::string(), - &post_data); - next_response_handler_ = - &CloudPrintProxyBackend::Core::HandleRegisterFailedStatusResponse; + ReportUserMessage( + kGetPrinterCapsFailedMessageId, + status_message, + &CloudPrintProxyBackend::Core::HandleRegisterFailedStatusResponse); } - // Terminate the request body - post_data.append("--" + mime_boundary + "--\r\n"); - std::string mime_type("multipart/form-data; boundary="); - mime_type += mime_boundary; - request_ = new CloudPrintURLFetcher; - request_->StartPostRequest(post_url, this, auth_token_, - kCloudPrintAPIMaxRetryCount, mime_type, - post_data); } void CloudPrintProxyBackend::Core::HandlePrinterNotification( @@ -725,22 +748,23 @@ void CloudPrintProxyBackend::Core::InitJobHandlerForPrinter( } } -void CloudPrintProxyBackend::Core::ReportPrintSystemUnavailable( - const std::string& failure_message) { +void CloudPrintProxyBackend::Core::ReportUserMessage( + const std::string& message_id, + const std::string& failure_message, + ResponseHandler handler) { DCHECK(MessageLoop::current() == backend_->core_thread_.message_loop()); std::string mime_boundary; CloudPrintHelpers::CreateMimeBoundaryForUpload(&mime_boundary); GURL post_url = CloudPrintHelpers::GetUrlForUserMessage( cloud_print_server_url_, - kPrintSystemFailedMessageId); + message_id); std::string post_data; CloudPrintHelpers::AddMultipartValueForUpload(kMessageTextValue, failure_message, mime_boundary, std::string(), &post_data); - next_response_handler_ = - &CloudPrintProxyBackend::Core::HandlePrintSystemUnavailableResponse; + next_response_handler_ = handler; // Terminate the request body post_data.append("--" + mime_boundary + "--\r\n"); std::string mime_type("multipart/form-data; boundary="); @@ -807,6 +831,19 @@ CloudPrintProxyBackend::Core::HandlePrintSystemUnavailableResponse( return CloudPrintURLFetcher::STOP_PROCESSING; } +CloudPrintURLFetcher::ResponseAction +CloudPrintProxyBackend::Core::HandleEnumPrintersFailedResponse( + const URLFetcher* source, + const GURL& url, + DictionaryValue* json_data, + bool succeeded) { + DCHECK(MessageLoop::current() == backend_->core_thread_.message_loop()); + // Now proceed with printer registration. + GetRegisteredPrinters(); + return CloudPrintURLFetcher::STOP_PROCESSING; +} + + bool CloudPrintProxyBackend::Core::RemovePrinterFromList( const std::string& printer_name) { DCHECK(MessageLoop::current() == backend_->core_thread_.message_loop()); @@ -883,3 +920,11 @@ void CloudPrintProxyBackend::Core::OnAuthError() { backend_->frontend_loop_->PostTask(FROM_HERE, NewRunnableMethod(this, &Core::NotifyAuthenticationFailed)); } + +void CloudPrintProxyBackend::Core::OnPrinterNotFound( + const std::string& printer_name, + bool* delete_from_server) { + // If we have a complete list of local printers, then this needs to be deleted + // from the server. + *delete_from_server = complete_list_available_; +} diff --git a/chrome/service/cloud_print/print_system.h b/chrome/service/cloud_print/print_system.h index 32fa8f8..d3de6bc9 100644 --- a/chrome/service/cloud_print/print_system.h +++ b/chrome/service/cloud_print/print_system.h @@ -158,7 +158,8 @@ class PrintSystem : public base::RefCountedThreadSafe<PrintSystem> { virtual PrintSystemResult Init() = 0; // Enumerates the list of installed local and network printers. - virtual void EnumeratePrinters(printing::PrinterList* printer_list) = 0; + virtual PrintSystemResult EnumeratePrinters( + printing::PrinterList* printer_list) = 0; // Gets the capabilities and defaults for a specific printer asynchronously. virtual void GetPrinterCapsAndDefaults( diff --git a/chrome/service/cloud_print/print_system_cups.cc b/chrome/service/cloud_print/print_system_cups.cc index 1e10ccd..0e40dff 100644 --- a/chrome/service/cloud_print/print_system_cups.cc +++ b/chrome/service/cloud_print/print_system_cups.cc @@ -28,9 +28,11 @@ #include "chrome/service/cloud_print/cloud_print_consts.h" #include "chrome/service/cloud_print/cloud_print_helpers.h" #include "googleurl/src/gurl.h" +#include "grit/generated_resources.h" #include "printing/backend/cups_helper.h" #include "printing/backend/print_backend.h" #include "printing/backend/print_backend_consts.h" +#include "ui/base/l10n/l10n_util.h" namespace { static const char kCUPSPrinterInfoOpt[] = "printer-info"; @@ -73,7 +75,8 @@ class PrintSystemCUPS : public PrintSystem { // PrintSystem implementation. virtual PrintSystemResult Init(); - virtual void EnumeratePrinters(printing::PrinterList* printer_list); + virtual PrintSystem::PrintSystemResult EnumeratePrinters( + printing::PrinterList* printer_list); virtual void GetPrinterCapsAndDefaults( const std::string& printer_name, @@ -151,6 +154,7 @@ class PrintSystemCUPS : public PrintSystem { int update_timeout_; bool initialized_; + bool printer_enum_succeeded_; }; class PrintServerWatcherCUPS @@ -358,7 +362,9 @@ class JobSpoolerCUPS : public PrintSystem::JobSpooler { }; PrintSystemCUPS::PrintSystemCUPS(const DictionaryValue* print_system_settings) - : update_timeout_(kCheckForPrinterUpdatesMs), initialized_(false) { + : update_timeout_(kCheckForPrinterUpdatesMs), + initialized_(false), + printer_enum_succeeded_(false) { if (print_system_settings) { int timeout; if (print_system_settings->GetInteger(kCUPSUpdateTimeoutMs, &timeout)) @@ -412,8 +418,10 @@ PrintSystem::PrintSystemResult PrintSystemCUPS::Init() { void PrintSystemCUPS::UpdatePrinters() { PrintServerList::iterator it; + printer_enum_succeeded_ = true; for (it = print_servers_.begin(); it != print_servers_.end(); ++it) { - it->backend->EnumeratePrinters(&it->printers); + if (!it->backend->EnumeratePrinters(&it->printers)) + printer_enum_succeeded_ = false; it->caps_cache.clear(); printing::PrinterList::iterator printer_it; for (printer_it = it->printers.begin(); @@ -431,7 +439,8 @@ void PrintSystemCUPS::UpdatePrinters() { GetUpdateTimeoutMs()); } -void PrintSystemCUPS::EnumeratePrinters(printing::PrinterList* printer_list) { +PrintSystem::PrintSystemResult PrintSystemCUPS::EnumeratePrinters( + printing::PrinterList* printer_list) { DCHECK(initialized_); printer_list->clear(); PrintServerList::iterator it; @@ -440,6 +449,9 @@ void PrintSystemCUPS::EnumeratePrinters(printing::PrinterList* printer_list) { it->printers.begin(), it->printers.end()); } VLOG(1) << "CUPS: Total " << printer_list->size() << " printers enumerated."; + // TODO(sanjeevr): Maybe some day we want to report the actual server names + // for which the enumeration failed. + return PrintSystemResult(printer_enum_succeeded_, std::string()); } void PrintSystemCUPS::GetPrinterCapsAndDefaults( diff --git a/chrome/service/cloud_print/print_system_win.cc b/chrome/service/cloud_print/print_system_win.cc index 4144090..5ac4650 100644 --- a/chrome/service/cloud_print/print_system_win.cc +++ b/chrome/service/cloud_print/print_system_win.cc @@ -250,7 +250,8 @@ class PrintSystemWin : public PrintSystem { // PrintSystem implementation. virtual PrintSystemResult Init(); - virtual void EnumeratePrinters(printing::PrinterList* printer_list); + virtual PrintSystem::PrintSystemResult EnumeratePrinters( + printing::PrinterList* printer_list); virtual void GetPrinterCapsAndDefaults( const std::string& printer_name, @@ -605,8 +606,10 @@ PrintSystem::PrintSystemResult PrintSystemWin::Init() { return PrintSystemResult(true, std::string()); } -void PrintSystemWin::EnumeratePrinters(printing::PrinterList* printer_list) { - print_backend_->EnumeratePrinters(printer_list); +PrintSystem::PrintSystemResult PrintSystemWin::EnumeratePrinters( + printing::PrinterList* printer_list) { + bool ret = print_backend_->EnumeratePrinters(printer_list); + return PrintSystemResult(ret, std::string()); } void PrintSystemWin::GetPrinterCapsAndDefaults( diff --git a/chrome/service/cloud_print/printer_job_handler.cc b/chrome/service/cloud_print/printer_job_handler.cc index 6013411..c99d1b6 100644 --- a/chrome/service/cloud_print/printer_job_handler.cc +++ b/chrome/service/cloud_print/printer_job_handler.cc @@ -65,8 +65,13 @@ bool PrinterJobHandler::Initialize() { printer_watcher_->StartWatching(this); CheckForJobs(kJobFetchReasonStartup); } else { - // This printer does not exist any more. Delete it from the server. - OnPrinterDeleted(); + // This printer does not exist any more. Check if we should delete it from + // the server. + bool delete_from_server = false; + delegate_->OnPrinterNotFound(printer_info_.printer_name, + &delete_from_server); + if (delete_from_server) + OnPrinterDeleted(); } return true; } diff --git a/chrome/service/cloud_print/printer_job_handler.h b/chrome/service/cloud_print/printer_job_handler.h index 4fb5e85..ee2e8cc 100644 --- a/chrome/service/cloud_print/printer_job_handler.h +++ b/chrome/service/cloud_print/printer_job_handler.h @@ -91,6 +91,11 @@ class PrinterJobHandler : public base::RefCountedThreadSafe<PrinterJobHandler>, virtual void OnPrinterJobHandlerShutdown( PrinterJobHandler* job_handler, const std::string& printer_id) = 0; virtual void OnAuthError() = 0; + // Called when the PrinterJobHandler cannot find the printer locally. The + // delegate returns |delete_from_server| to true if the printer should be + // deleted from the server,false otherwise. + virtual void OnPrinterNotFound(const std::string& printer_name, + bool* delete_from_server) = 0; protected: virtual ~Delegate() {} diff --git a/printing/backend/print_backend.h b/printing/backend/print_backend.h index 3b55268..63c00c9 100644 --- a/printing/backend/print_backend.h +++ b/printing/backend/print_backend.h @@ -48,7 +48,7 @@ class PrintBackend : public base::RefCountedThreadSafe<PrintBackend> { virtual ~PrintBackend(); // Enumerates the list of installed local and network printers. - virtual void EnumeratePrinters(PrinterList* printer_list) = 0; + virtual bool EnumeratePrinters(PrinterList* printer_list) = 0; // Gets the capabilities and defaults for a specific printer. virtual bool GetPrinterCapsAndDefaults( diff --git a/printing/backend/print_backend_cups.cc b/printing/backend/print_backend_cups.cc index 01aa18d..3b38c3f 100644 --- a/printing/backend/print_backend_cups.cc +++ b/printing/backend/print_backend_cups.cc @@ -84,7 +84,7 @@ class PrintBackendCUPS : public PrintBackend { virtual ~PrintBackendCUPS() {} // PrintBackend implementation. - virtual void EnumeratePrinters(PrinterList* printer_list); + virtual bool EnumeratePrinters(PrinterList* printer_list); virtual bool GetPrinterCapsAndDefaults(const std::string& printer_name, PrinterCapsAndDefaults* printer_info); @@ -107,12 +107,14 @@ PrintBackendCUPS::PrintBackendCUPS(const GURL& print_server_url, bool blocking) : print_server_url_(print_server_url), blocking_(blocking) { } -void PrintBackendCUPS::EnumeratePrinters(PrinterList* printer_list) { +bool PrintBackendCUPS::EnumeratePrinters(PrinterList* printer_list) { DCHECK(printer_list); printer_list->clear(); cups_dest_t* destinations = NULL; int num_dests = GetDests(&destinations); + // TODO(gene): Figure out how to get an error code from cupsGetDests so we can + // differentiate between the enumeration failing and there being 0 printers. for (int printer_index = 0; printer_index < num_dests; printer_index++) { const cups_dest_t& printer = destinations[printer_index]; @@ -142,6 +144,7 @@ void PrintBackendCUPS::EnumeratePrinters(PrinterList* printer_list) { cupsFreeDests(num_dests, destinations); VLOG(1) << "CUPS: Enumerated " << printer_list->size() << " printers."; + return true; } bool PrintBackendCUPS::GetPrinterCapsAndDefaults( diff --git a/printing/backend/print_backend_win.cc b/printing/backend/print_backend_win.cc index 41d9ee3..3b7608c 100644 --- a/printing/backend/print_backend_win.cc +++ b/printing/backend/print_backend_win.cc @@ -43,7 +43,7 @@ class PrintBackendWin : public PrintBackend { PrintBackendWin() {} virtual ~PrintBackendWin() {} - virtual void EnumeratePrinters(PrinterList* printer_list); + virtual bool EnumeratePrinters(PrinterList* printer_list); virtual bool GetPrinterCapsAndDefaults(const std::string& printer_name, PrinterCapsAndDefaults* printer_info); @@ -51,35 +51,39 @@ class PrintBackendWin : public PrintBackend { virtual bool IsValidPrinter(const std::string& printer_name); }; -void PrintBackendWin::EnumeratePrinters(PrinterList* printer_list) { +bool PrintBackendWin::EnumeratePrinters(PrinterList* printer_list) { DCHECK(printer_list); DWORD bytes_needed = 0; DWORD count_returned = 0; BOOL ret = EnumPrinters(PRINTER_ENUM_LOCAL|PRINTER_ENUM_CONNECTIONS, NULL, 2, NULL, 0, &bytes_needed, &count_returned); - if (0 != bytes_needed) { - scoped_ptr<BYTE> printer_info_buffer(new BYTE[bytes_needed]); - ret = EnumPrinters(PRINTER_ENUM_LOCAL|PRINTER_ENUM_CONNECTIONS, NULL, 2, - printer_info_buffer.get(), bytes_needed, &bytes_needed, - &count_returned); - DCHECK(ret); - PRINTER_INFO_2* printer_info = - reinterpret_cast<PRINTER_INFO_2*>(printer_info_buffer.get()); - for (DWORD index = 0; index < count_returned; index++) { - PrinterBasicInfo info; - info.printer_name = WideToUTF8(printer_info[index].pPrinterName); - if (printer_info[index].pComment) - info.printer_description = WideToUTF8(printer_info[index].pComment); - info.printer_status = printer_info[index].Status; - if (printer_info[index].pLocation) - info.options[kLocationTagName] = - WideToUTF8(printer_info[index].pLocation); - if (printer_info[index].pDriverName) - info.options[kDriverNameTagName] = - WideToUTF8(printer_info[index].pDriverName); - printer_list->push_back(info); - } + if (!bytes_needed) + return false; + scoped_ptr<BYTE> printer_info_buffer(new BYTE[bytes_needed]); + ret = EnumPrinters(PRINTER_ENUM_LOCAL|PRINTER_ENUM_CONNECTIONS, NULL, 2, + printer_info_buffer.get(), bytes_needed, &bytes_needed, + &count_returned); + DCHECK(ret); + if (!ret) + return false; + + PRINTER_INFO_2* printer_info = + reinterpret_cast<PRINTER_INFO_2*>(printer_info_buffer.get()); + for (DWORD index = 0; index < count_returned; index++) { + PrinterBasicInfo info; + info.printer_name = WideToUTF8(printer_info[index].pPrinterName); + if (printer_info[index].pComment) + info.printer_description = WideToUTF8(printer_info[index].pComment); + info.printer_status = printer_info[index].Status; + if (printer_info[index].pLocation) + info.options[kLocationTagName] = + WideToUTF8(printer_info[index].pLocation); + if (printer_info[index].pDriverName) + info.options[kDriverNameTagName] = + WideToUTF8(printer_info[index].pDriverName); + printer_list->push_back(info); } + return true; } bool PrintBackendWin::GetPrinterCapsAndDefaults( |