| 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 "printing/backend/win_helper.h" | 5 #include "printing/backend/win_helper.h" |
| 6 | 6 |
| 7 #include <algorithm> | 7 #include <algorithm> |
| 8 | 8 |
| 9 #include "base/file_version_info.h" | 9 #include "base/file_version_info.h" |
| 10 #include "base/files/file_path.h" | 10 #include "base/files/file_path.h" |
| (...skipping 367 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 378 | 378 |
| 379 for (size_t i = 0; i < arraysize(info); ++i) { | 379 for (size_t i = 0; i < arraysize(info); ++i) { |
| 380 std::replace(info[i].begin(), info[i].end(), ';', ','); | 380 std::replace(info[i].begin(), info[i].end(), ';', ','); |
| 381 driver_info.append(info[i]); | 381 driver_info.append(info[i]); |
| 382 if (i < arraysize(info) - 1) | 382 if (i < arraysize(info) - 1) |
| 383 driver_info.append(";"); | 383 driver_info.append(";"); |
| 384 } | 384 } |
| 385 return driver_info; | 385 return driver_info; |
| 386 } | 386 } |
| 387 | 387 |
| 388 scoped_ptr<DEVMODE[]> XpsTicketToDevMode(const base::string16& printer_name, | 388 scoped_ptr<DEVMODE, base::FreeDeleter> XpsTicketToDevMode( |
| 389 const std::string& print_ticket) { | 389 const base::string16& printer_name, |
| 390 scoped_ptr<DEVMODE[]> scoped_dev_mode; | 390 const std::string& print_ticket) { |
| 391 scoped_ptr<DEVMODE, base::FreeDeleter> dev_mode; |
| 391 printing::ScopedXPSInitializer xps_initializer; | 392 printing::ScopedXPSInitializer xps_initializer; |
| 392 if (!xps_initializer.initialized()) { | 393 if (!xps_initializer.initialized()) { |
| 393 // TODO(sanjeevr): Handle legacy proxy case (with no prntvpt.dll) | 394 // TODO(sanjeevr): Handle legacy proxy case (with no prntvpt.dll) |
| 394 return scoped_dev_mode.Pass(); | 395 return dev_mode.Pass(); |
| 395 } | 396 } |
| 396 | 397 |
| 397 printing::ScopedPrinterHandle printer; | 398 printing::ScopedPrinterHandle printer; |
| 398 if (!printer.OpenPrinter(printer_name.c_str())) | 399 if (!printer.OpenPrinter(printer_name.c_str())) |
| 399 return scoped_dev_mode.Pass(); | 400 return dev_mode.Pass(); |
| 400 | 401 |
| 401 base::win::ScopedComPtr<IStream> pt_stream; | 402 base::win::ScopedComPtr<IStream> pt_stream; |
| 402 HRESULT hr = StreamFromPrintTicket(print_ticket, pt_stream.Receive()); | 403 HRESULT hr = StreamFromPrintTicket(print_ticket, pt_stream.Receive()); |
| 403 if (FAILED(hr)) | 404 if (FAILED(hr)) |
| 404 return scoped_dev_mode.Pass(); | 405 return dev_mode.Pass(); |
| 405 | 406 |
| 406 HPTPROVIDER provider = NULL; | 407 HPTPROVIDER provider = NULL; |
| 407 hr = printing::XPSModule::OpenProvider(printer_name, 1, &provider); | 408 hr = printing::XPSModule::OpenProvider(printer_name, 1, &provider); |
| 408 if (SUCCEEDED(hr)) { | 409 if (SUCCEEDED(hr)) { |
| 409 ULONG size = 0; | 410 ULONG size = 0; |
| 410 DEVMODE* dm = NULL; | 411 DEVMODE* dm = NULL; |
| 411 // Use kPTJobScope, because kPTDocumentScope breaks duplex. | 412 // Use kPTJobScope, because kPTDocumentScope breaks duplex. |
| 412 hr = printing::XPSModule::ConvertPrintTicketToDevMode(provider, | 413 hr = printing::XPSModule::ConvertPrintTicketToDevMode(provider, |
| 413 pt_stream, | 414 pt_stream, |
| 414 kUserDefaultDevmode, | 415 kUserDefaultDevmode, |
| 415 kPTJobScope, | 416 kPTJobScope, |
| 416 &size, | 417 &size, |
| 417 &dm, | 418 &dm, |
| 418 NULL); | 419 NULL); |
| 419 if (SUCCEEDED(hr)) { | 420 if (SUCCEEDED(hr)) { |
| 420 // Correct DEVMODE using DocumentProperties. See documentation for | 421 // Correct DEVMODE using DocumentProperties. See documentation for |
| 421 // PTConvertPrintTicketToDevMode. | 422 // PTConvertPrintTicketToDevMode. |
| 422 scoped_dev_mode = CreateDevMode(printer, dm); | 423 dev_mode = CreateDevMode(printer, dm); |
| 423 printing::XPSModule::ReleaseMemory(dm); | 424 printing::XPSModule::ReleaseMemory(dm); |
| 424 } | 425 } |
| 425 printing::XPSModule::CloseProvider(provider); | 426 printing::XPSModule::CloseProvider(provider); |
| 426 } | 427 } |
| 427 return scoped_dev_mode.Pass(); | 428 return dev_mode.Pass(); |
| 428 } | 429 } |
| 429 | 430 |
| 430 scoped_ptr<DEVMODE[]> CreateDevModeWithColor(HANDLE printer, | 431 scoped_ptr<DEVMODE, base::FreeDeleter> CreateDevModeWithColor( |
| 431 const base::string16& printer_name, | 432 HANDLE printer, |
| 432 bool color) { | 433 const base::string16& printer_name, |
| 433 scoped_ptr<DEVMODE[]> default = CreateDevMode(printer, NULL); | 434 bool color) { |
| 435 scoped_ptr<DEVMODE, base::FreeDeleter> default = CreateDevMode(printer, NULL); |
| 434 if (!default) | 436 if (!default) |
| 435 return default.Pass(); | 437 return default.Pass(); |
| 436 | 438 |
| 437 if ((default.get()->dmFields & DM_COLOR) && | 439 if ((default->dmFields & DM_COLOR) && |
| 438 ((default.get()->dmColor == DMCOLOR_COLOR) == color)) { | 440 ((default->dmColor == DMCOLOR_COLOR) == color)) { |
| 439 return default.Pass(); | 441 return default.Pass(); |
| 440 } | 442 } |
| 441 | 443 |
| 442 default.get()->dmFields |= DM_COLOR; | 444 default->dmFields |= DM_COLOR; |
| 443 default.get()->dmColor = color ? DMCOLOR_COLOR : DMCOLOR_MONOCHROME; | 445 default->dmColor = color ? DMCOLOR_COLOR : DMCOLOR_MONOCHROME; |
| 444 | 446 |
| 445 DriverInfo6 info_6; | 447 DriverInfo6 info_6; |
| 446 if (!info_6.Init(printer)) | 448 if (!info_6.Init(printer)) |
| 447 return default.Pass(); | 449 return default.Pass(); |
| 448 | 450 |
| 449 const DRIVER_INFO_6* p = info_6.get(); | 451 const DRIVER_INFO_6* p = info_6.get(); |
| 450 | 452 |
| 451 // Only HP known to have issues. | 453 // Only HP known to have issues. |
| 452 if (!p->pszMfgName || wcscmp(p->pszMfgName, L"HP") != 0) | 454 if (!p->pszMfgName || wcscmp(p->pszMfgName, L"HP") != 0) |
| 453 return default.Pass(); | 455 return default.Pass(); |
| 454 | 456 |
| 455 // Need XPS for this workaround. | 457 // Need XPS for this workaround. |
| 456 printing::ScopedXPSInitializer xps_initializer; | 458 printing::ScopedXPSInitializer xps_initializer; |
| 457 if (!xps_initializer.initialized()) | 459 if (!xps_initializer.initialized()) |
| 458 return default.Pass(); | 460 return default.Pass(); |
| 459 | 461 |
| 460 const char* xps_color = color ? kXpsTicketColor : kXpsTicketMonochrome; | 462 const char* xps_color = color ? kXpsTicketColor : kXpsTicketMonochrome; |
| 461 std::string xps_ticket = base::StringPrintf(kXpsTicketTemplate, xps_color); | 463 std::string xps_ticket = base::StringPrintf(kXpsTicketTemplate, xps_color); |
| 462 scoped_ptr<DEVMODE[]> ticket = printing::XpsTicketToDevMode(printer_name, | 464 scoped_ptr<DEVMODE, base::FreeDeleter> ticket = |
| 463 xps_ticket); | 465 printing::XpsTicketToDevMode(printer_name, xps_ticket); |
| 464 if (!ticket) | 466 if (!ticket) |
| 465 return default.Pass(); | 467 return default.Pass(); |
| 466 | 468 |
| 467 return ticket.Pass(); | 469 return ticket.Pass(); |
| 468 } | 470 } |
| 469 | 471 |
| 470 PRINTING_EXPORT scoped_ptr<DEVMODE[]> CreateDevMode(HANDLE printer, | 472 scoped_ptr<DEVMODE, base::FreeDeleter> CreateDevMode(HANDLE printer, |
| 471 DEVMODE* in) { | 473 DEVMODE* in) { |
| 472 LONG buffer_size = DocumentProperties(NULL, printer, L"", NULL, NULL, 0); | 474 LONG buffer_size = DocumentProperties(NULL, printer, L"", NULL, NULL, 0); |
| 473 if (buffer_size <= 0) | 475 if (buffer_size < static_cast<int>(sizeof(DEVMODE))) |
| 474 return scoped_ptr<DEVMODE[]>(); | 476 return scoped_ptr<DEVMODE, base::FreeDeleter>(); |
| 475 CHECK_GE(buffer_size, static_cast<int>(sizeof(DEVMODE))); | 477 scoped_ptr<DEVMODE, base::FreeDeleter> out( |
| 476 scoped_ptr<DEVMODE[]> out( | 478 reinterpret_cast<DEVMODE*>(malloc(buffer_size))); |
| 477 reinterpret_cast<DEVMODE*>(new uint8[buffer_size])); | |
| 478 DWORD flags = (in ? (DM_IN_BUFFER) : 0) | DM_OUT_BUFFER; | 479 DWORD flags = (in ? (DM_IN_BUFFER) : 0) | DM_OUT_BUFFER; |
| 479 if (DocumentProperties(NULL, printer, L"", out.get(), in, flags) != IDOK) | 480 if (DocumentProperties(NULL, printer, L"", out.get(), in, flags) != IDOK) |
| 480 return scoped_ptr<DEVMODE[]>(); | 481 return scoped_ptr<DEVMODE, base::FreeDeleter>(); |
| 481 CHECK_GE(buffer_size, out.get()->dmSize + out.get()->dmDriverExtra); | 482 CHECK_GE(buffer_size, out.get()->dmSize + out.get()->dmDriverExtra); |
| 482 return out.Pass(); | 483 return out.Pass(); |
| 483 } | 484 } |
| 484 | 485 |
| 485 } // namespace printing | 486 } // namespace printing |
| OLD | NEW |