Index: printing/backend/win_helper.cc |
diff --git a/printing/backend/win_helper.cc b/printing/backend/win_helper.cc |
index b163a65ece970a3c25d139d63ef5ebf73acdfb5b..b58592e29f2245368a5b6535e467ac58ed10934e 100644 |
--- a/printing/backend/win_helper.cc |
+++ b/printing/backend/win_helper.cc |
@@ -4,7 +4,14 @@ |
#include "printing/backend/win_helper.h" |
+#include <algorithm> |
+ |
+#include "base/file_path.h" |
+#include "base/file_version_info.h" |
#include "base/logging.h" |
+#include "base/utf_string_conversions.h" |
+#include "printing/backend/print_backend.h" |
+#include "printing/backend/print_backend_consts.h" |
namespace { |
typedef HRESULT (WINAPI *PTOpenProviderProc)(PCWSTR printer_name, |
@@ -57,6 +64,49 @@ PTMergeAndValidatePrintTicketProc g_merge_and_validate_print_ticket_proc = NULL; |
PTReleaseMemoryProc g_release_memory_proc = NULL; |
PTCloseProviderProc g_close_provider_proc = NULL; |
StartXpsPrintJobProc g_start_xps_print_job_proc = NULL; |
+ |
+// Returns pointer to structure allocated in |buffer|. So pointer is only valide |
+// until |buffer| is destroyed. |
+const PRINTER_INFO_2* GetPrinterInfo2(HANDLE printer, |
+ scoped_array<BYTE>* buffer) { |
+ DCHECK(printer); |
+ DCHECK(buffer); |
+ DWORD bytes_needed = 0; |
+ const DWORD kLevel = 2; |
+ ::GetPrinter(printer, kLevel, NULL, 0, &bytes_needed); |
+ if (!bytes_needed) |
+ return NULL; |
+ buffer->reset(new BYTE[bytes_needed]); |
+ if (!buffer->get()) |
+ return NULL; |
+ if (!::GetPrinter(printer, kLevel, buffer->get(), bytes_needed, |
+ &bytes_needed)) { |
+ return NULL; |
+ } |
+ return reinterpret_cast<const PRINTER_INFO_2*>(buffer->get()); |
+} |
+ |
+// Returns pointer to structure allocated in |buffer|. So pointer is only valide |
+// until |buffer| is destroyed. |
+const DRIVER_INFO_6* GetDriverInfo6(HANDLE printer, |
+ scoped_array<BYTE>* buffer) { |
+ DCHECK(printer); |
+ DCHECK(buffer); |
+ DWORD bytes_needed = 0; |
+ const DWORD kLevel = 6; |
+ ::GetPrinterDriver(printer, NULL, kLevel, NULL, 0, &bytes_needed); |
+ if (!bytes_needed) |
+ return NULL; |
+ buffer->reset(new BYTE[bytes_needed]); |
+ if (!buffer->get()) |
+ return NULL; |
+ if (!::GetPrinterDriver(printer, NULL, kLevel, buffer->get(), bytes_needed, |
+ &bytes_needed)) { |
+ return NULL; |
+ } |
+ return reinterpret_cast<const DRIVER_INFO_6*>(buffer->get()); |
+} |
+ |
} |
namespace printing { |
@@ -260,4 +310,66 @@ HRESULT XPSPrintModule::StartXpsPrintJob( |
print_ticket_stream); |
} |
+bool InitBasicPrinterInfo(HANDLE printer, PrinterBasicInfo* printer_info) { |
+ DCHECK(printer); |
+ DCHECK(printer_info); |
+ if (!printer) |
+ return false; |
+ |
+ scoped_array<BYTE> printer_info_buffer; |
+ const PRINTER_INFO_2* info2 = GetPrinterInfo2(printer, &printer_info_buffer); |
+ |
+ if (!info2) |
+ return false; |
+ printer_info->printer_name = WideToUTF8(info2->pPrinterName); |
+ if (info2->pComment) |
+ printer_info->printer_description = |
+ WideToUTF8(info2->pComment); |
+ if (info2->pLocation) |
+ printer_info->options[kLocationTagName] = |
+ WideToUTF8(info2->pLocation); |
+ if (info2->pDriverName) |
+ printer_info->options[kDriverNameTagName] = |
+ WideToUTF8(info2->pDriverName); |
+ printer_info->printer_status = info2->Status; |
+ |
+ std::string driver_info = GetDriverInfo(printer); |
+ if (!driver_info.empty()) |
+ printer_info->options[kDriverInfoTagName] = driver_info; |
+ return true; |
+} |
+ |
+std::string GetDriverInfo(HANDLE printer) { |
+ DCHECK(printer); |
+ std::string driver_info; |
+ |
+ if (!printer) |
+ return driver_info; |
+ |
+ scoped_array<BYTE> driver_info_buffer; |
+ const DRIVER_INFO_6* driver = GetDriverInfo6(printer, &driver_info_buffer); |
+ if (!driver) |
+ return driver_info; |
+ |
+ std::string info[4]; |
+ if (driver->pName) |
+ info[0] = WideToUTF8(driver->pName); |
+ |
+ if (driver->pDriverPath) { |
+ scoped_ptr<FileVersionInfo> version_info( |
+ FileVersionInfo::CreateFileVersionInfo( |
+ FilePath(driver->pDriverPath))); |
+ info[1] = WideToUTF8(version_info->file_version()); |
+ info[2] = WideToUTF8(version_info->product_name()); |
+ info[3] = WideToUTF8(version_info->product_version()); |
+ } |
+ |
+ for (size_t i = 0; i < arraysize(info); ++i) { |
+ std::replace(info[i].begin(), info[i].end(), ';', ','); |
+ driver_info.append(info[i]); |
+ driver_info.append(";"); |
+ } |
+ return driver_info; |
+} |
+ |
} // namespace printing |