| 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 <stddef.h> | 7 #include <stddef.h> |
| 8 | 8 |
| 9 #include <algorithm> | 9 #include <algorithm> |
| 10 #include <memory> |
| 10 | 11 |
| 11 #include "base/file_version_info.h" | 12 #include "base/file_version_info.h" |
| 12 #include "base/files/file_path.h" | 13 #include "base/files/file_path.h" |
| 13 #include "base/logging.h" | 14 #include "base/logging.h" |
| 14 #include "base/macros.h" | 15 #include "base/macros.h" |
| 15 #include "base/memory/free_deleter.h" | 16 #include "base/memory/free_deleter.h" |
| 16 #include "base/memory/scoped_ptr.h" | |
| 17 #include "base/numerics/safe_conversions.h" | 17 #include "base/numerics/safe_conversions.h" |
| 18 #include "base/strings/string_util.h" | 18 #include "base/strings/string_util.h" |
| 19 #include "base/strings/stringprintf.h" | 19 #include "base/strings/stringprintf.h" |
| 20 #include "base/strings/utf_string_conversions.h" | 20 #include "base/strings/utf_string_conversions.h" |
| 21 #include "base/win/scoped_comptr.h" | 21 #include "base/win/scoped_comptr.h" |
| 22 #include "printing/backend/print_backend.h" | 22 #include "printing/backend/print_backend.h" |
| 23 #include "printing/backend/print_backend_consts.h" | 23 #include "printing/backend/print_backend_consts.h" |
| 24 #include "printing/backend/printing_info_win.h" | 24 #include "printing/backend/printing_info_win.h" |
| 25 | 25 |
| 26 namespace { | 26 namespace { |
| (...skipping 336 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 363 | 363 |
| 364 DriverInfo6 info_6; | 364 DriverInfo6 info_6; |
| 365 if (!info_6.Init(printer)) | 365 if (!info_6.Init(printer)) |
| 366 return driver_info; | 366 return driver_info; |
| 367 | 367 |
| 368 std::string info[4]; | 368 std::string info[4]; |
| 369 if (info_6.get()->pName) | 369 if (info_6.get()->pName) |
| 370 info[0] = base::WideToUTF8(info_6.get()->pName); | 370 info[0] = base::WideToUTF8(info_6.get()->pName); |
| 371 | 371 |
| 372 if (info_6.get()->pDriverPath) { | 372 if (info_6.get()->pDriverPath) { |
| 373 scoped_ptr<FileVersionInfo> version_info( | 373 std::unique_ptr<FileVersionInfo> version_info( |
| 374 FileVersionInfo::CreateFileVersionInfo( | 374 FileVersionInfo::CreateFileVersionInfo( |
| 375 base::FilePath(info_6.get()->pDriverPath))); | 375 base::FilePath(info_6.get()->pDriverPath))); |
| 376 if (version_info.get()) { | 376 if (version_info.get()) { |
| 377 info[1] = base::WideToUTF8(version_info->file_version()); | 377 info[1] = base::WideToUTF8(version_info->file_version()); |
| 378 info[2] = base::WideToUTF8(version_info->product_name()); | 378 info[2] = base::WideToUTF8(version_info->product_name()); |
| 379 info[3] = base::WideToUTF8(version_info->product_version()); | 379 info[3] = base::WideToUTF8(version_info->product_version()); |
| 380 } | 380 } |
| 381 } | 381 } |
| 382 | 382 |
| 383 for (size_t i = 0; i < arraysize(info); ++i) { | 383 for (size_t i = 0; i < arraysize(info); ++i) { |
| 384 std::replace(info[i].begin(), info[i].end(), ';', ','); | 384 std::replace(info[i].begin(), info[i].end(), ';', ','); |
| 385 driver_info.append(info[i]); | 385 driver_info.append(info[i]); |
| 386 if (i < arraysize(info) - 1) | 386 if (i < arraysize(info) - 1) |
| 387 driver_info.append(";"); | 387 driver_info.append(";"); |
| 388 } | 388 } |
| 389 return driver_info; | 389 return driver_info; |
| 390 } | 390 } |
| 391 | 391 |
| 392 scoped_ptr<DEVMODE, base::FreeDeleter> XpsTicketToDevMode( | 392 std::unique_ptr<DEVMODE, base::FreeDeleter> XpsTicketToDevMode( |
| 393 const base::string16& printer_name, | 393 const base::string16& printer_name, |
| 394 const std::string& print_ticket) { | 394 const std::string& print_ticket) { |
| 395 scoped_ptr<DEVMODE, base::FreeDeleter> dev_mode; | 395 std::unique_ptr<DEVMODE, base::FreeDeleter> dev_mode; |
| 396 printing::ScopedXPSInitializer xps_initializer; | 396 printing::ScopedXPSInitializer xps_initializer; |
| 397 if (!xps_initializer.initialized()) { | 397 if (!xps_initializer.initialized()) { |
| 398 // TODO(sanjeevr): Handle legacy proxy case (with no prntvpt.dll) | 398 // TODO(sanjeevr): Handle legacy proxy case (with no prntvpt.dll) |
| 399 return dev_mode; | 399 return dev_mode; |
| 400 } | 400 } |
| 401 | 401 |
| 402 printing::ScopedPrinterHandle printer; | 402 printing::ScopedPrinterHandle printer; |
| 403 if (!printer.OpenPrinter(printer_name.c_str())) | 403 if (!printer.OpenPrinter(printer_name.c_str())) |
| 404 return dev_mode; | 404 return dev_mode; |
| 405 | 405 |
| (...skipping 15 matching lines...) Expand all Loading... |
| 421 // Correct DEVMODE using DocumentProperties. See documentation for | 421 // Correct DEVMODE using DocumentProperties. See documentation for |
| 422 // PTConvertPrintTicketToDevMode. | 422 // PTConvertPrintTicketToDevMode. |
| 423 dev_mode = CreateDevMode(printer.Get(), dm); | 423 dev_mode = CreateDevMode(printer.Get(), dm); |
| 424 printing::XPSModule::ReleaseMemory(dm); | 424 printing::XPSModule::ReleaseMemory(dm); |
| 425 } | 425 } |
| 426 printing::XPSModule::CloseProvider(provider); | 426 printing::XPSModule::CloseProvider(provider); |
| 427 } | 427 } |
| 428 return dev_mode; | 428 return dev_mode; |
| 429 } | 429 } |
| 430 | 430 |
| 431 scoped_ptr<DEVMODE, base::FreeDeleter> CreateDevModeWithColor( | 431 std::unique_ptr<DEVMODE, base::FreeDeleter> CreateDevModeWithColor( |
| 432 HANDLE printer, | 432 HANDLE printer, |
| 433 const base::string16& printer_name, | 433 const base::string16& printer_name, |
| 434 bool color) { | 434 bool color) { |
| 435 scoped_ptr<DEVMODE, base::FreeDeleter> default_ticket = | 435 std::unique_ptr<DEVMODE, base::FreeDeleter> default_ticket = |
| 436 CreateDevMode(printer, NULL); | 436 CreateDevMode(printer, NULL); |
| 437 if (!default_ticket) | 437 if (!default_ticket) |
| 438 return default_ticket; | 438 return default_ticket; |
| 439 | 439 |
| 440 if ((default_ticket->dmFields & DM_COLOR) && | 440 if ((default_ticket->dmFields & DM_COLOR) && |
| 441 ((default_ticket->dmColor == DMCOLOR_COLOR) == color)) { | 441 ((default_ticket->dmColor == DMCOLOR_COLOR) == color)) { |
| 442 return default_ticket; | 442 return default_ticket; |
| 443 } | 443 } |
| 444 | 444 |
| 445 default_ticket->dmFields |= DM_COLOR; | 445 default_ticket->dmFields |= DM_COLOR; |
| 446 default_ticket->dmColor = color ? DMCOLOR_COLOR : DMCOLOR_MONOCHROME; | 446 default_ticket->dmColor = color ? DMCOLOR_COLOR : DMCOLOR_MONOCHROME; |
| 447 | 447 |
| 448 DriverInfo6 info_6; | 448 DriverInfo6 info_6; |
| 449 if (!info_6.Init(printer)) | 449 if (!info_6.Init(printer)) |
| 450 return default_ticket; | 450 return default_ticket; |
| 451 | 451 |
| 452 const DRIVER_INFO_6* p = info_6.get(); | 452 const DRIVER_INFO_6* p = info_6.get(); |
| 453 | 453 |
| 454 // Only HP known to have issues. | 454 // Only HP known to have issues. |
| 455 if (!p->pszMfgName || wcscmp(p->pszMfgName, L"HP") != 0) | 455 if (!p->pszMfgName || wcscmp(p->pszMfgName, L"HP") != 0) |
| 456 return default_ticket; | 456 return default_ticket; |
| 457 | 457 |
| 458 // Need XPS for this workaround. | 458 // Need XPS for this workaround. |
| 459 printing::ScopedXPSInitializer xps_initializer; | 459 printing::ScopedXPSInitializer xps_initializer; |
| 460 if (!xps_initializer.initialized()) | 460 if (!xps_initializer.initialized()) |
| 461 return default_ticket; | 461 return default_ticket; |
| 462 | 462 |
| 463 const char* xps_color = color ? kXpsTicketColor : kXpsTicketMonochrome; | 463 const char* xps_color = color ? kXpsTicketColor : kXpsTicketMonochrome; |
| 464 std::string xps_ticket = base::StringPrintf(kXpsTicketTemplate, xps_color); | 464 std::string xps_ticket = base::StringPrintf(kXpsTicketTemplate, xps_color); |
| 465 scoped_ptr<DEVMODE, base::FreeDeleter> ticket = | 465 std::unique_ptr<DEVMODE, base::FreeDeleter> ticket = |
| 466 printing::XpsTicketToDevMode(printer_name, xps_ticket); | 466 printing::XpsTicketToDevMode(printer_name, xps_ticket); |
| 467 if (!ticket) | 467 if (!ticket) |
| 468 return default_ticket; | 468 return default_ticket; |
| 469 | 469 |
| 470 return ticket; | 470 return ticket; |
| 471 } | 471 } |
| 472 | 472 |
| 473 scoped_ptr<DEVMODE, base::FreeDeleter> CreateDevMode(HANDLE printer, | 473 std::unique_ptr<DEVMODE, base::FreeDeleter> CreateDevMode(HANDLE printer, |
| 474 DEVMODE* in) { | 474 DEVMODE* in) { |
| 475 LONG buffer_size = DocumentProperties( | 475 LONG buffer_size = DocumentProperties( |
| 476 NULL, printer, const_cast<wchar_t*>(L""), NULL, NULL, 0); | 476 NULL, printer, const_cast<wchar_t*>(L""), NULL, NULL, 0); |
| 477 if (buffer_size < static_cast<int>(sizeof(DEVMODE))) | 477 if (buffer_size < static_cast<int>(sizeof(DEVMODE))) |
| 478 return scoped_ptr<DEVMODE, base::FreeDeleter>(); | 478 return std::unique_ptr<DEVMODE, base::FreeDeleter>(); |
| 479 | 479 |
| 480 // Some drivers request buffers with size smaller than dmSize + dmDriverExtra. | 480 // Some drivers request buffers with size smaller than dmSize + dmDriverExtra. |
| 481 // crbug.com/421402 | 481 // crbug.com/421402 |
| 482 buffer_size *= 2; | 482 buffer_size *= 2; |
| 483 | 483 |
| 484 scoped_ptr<DEVMODE, base::FreeDeleter> out( | 484 std::unique_ptr<DEVMODE, base::FreeDeleter> out( |
| 485 reinterpret_cast<DEVMODE*>(calloc(buffer_size, 1))); | 485 reinterpret_cast<DEVMODE*>(calloc(buffer_size, 1))); |
| 486 DWORD flags = (in ? (DM_IN_BUFFER) : 0) | DM_OUT_BUFFER; | 486 DWORD flags = (in ? (DM_IN_BUFFER) : 0) | DM_OUT_BUFFER; |
| 487 if (DocumentProperties( | 487 if (DocumentProperties( |
| 488 NULL, printer, const_cast<wchar_t*>(L""), out.get(), in, flags) != | 488 NULL, printer, const_cast<wchar_t*>(L""), out.get(), in, flags) != |
| 489 IDOK) { | 489 IDOK) { |
| 490 return scoped_ptr<DEVMODE, base::FreeDeleter>(); | 490 return std::unique_ptr<DEVMODE, base::FreeDeleter>(); |
| 491 } | 491 } |
| 492 int size = out->dmSize; | 492 int size = out->dmSize; |
| 493 int extra_size = out->dmDriverExtra; | 493 int extra_size = out->dmDriverExtra; |
| 494 CHECK_GE(buffer_size, size + extra_size); | 494 CHECK_GE(buffer_size, size + extra_size); |
| 495 return out; | 495 return out; |
| 496 } | 496 } |
| 497 | 497 |
| 498 scoped_ptr<DEVMODE, base::FreeDeleter> PromptDevMode( | 498 std::unique_ptr<DEVMODE, base::FreeDeleter> PromptDevMode( |
| 499 HANDLE printer, | 499 HANDLE printer, |
| 500 const base::string16& printer_name, | 500 const base::string16& printer_name, |
| 501 DEVMODE* in, | 501 DEVMODE* in, |
| 502 HWND window, | 502 HWND window, |
| 503 bool* canceled) { | 503 bool* canceled) { |
| 504 LONG buffer_size = | 504 LONG buffer_size = |
| 505 DocumentProperties(window, | 505 DocumentProperties(window, |
| 506 printer, | 506 printer, |
| 507 const_cast<wchar_t*>(printer_name.c_str()), | 507 const_cast<wchar_t*>(printer_name.c_str()), |
| 508 NULL, | 508 NULL, |
| 509 NULL, | 509 NULL, |
| 510 0); | 510 0); |
| 511 if (buffer_size < static_cast<int>(sizeof(DEVMODE))) | 511 if (buffer_size < static_cast<int>(sizeof(DEVMODE))) |
| 512 return scoped_ptr<DEVMODE, base::FreeDeleter>(); | 512 return std::unique_ptr<DEVMODE, base::FreeDeleter>(); |
| 513 | 513 |
| 514 // Some drivers request buffers with size smaller than dmSize + dmDriverExtra. | 514 // Some drivers request buffers with size smaller than dmSize + dmDriverExtra. |
| 515 // crbug.com/421402 | 515 // crbug.com/421402 |
| 516 buffer_size *= 2; | 516 buffer_size *= 2; |
| 517 | 517 |
| 518 scoped_ptr<DEVMODE, base::FreeDeleter> out( | 518 std::unique_ptr<DEVMODE, base::FreeDeleter> out( |
| 519 reinterpret_cast<DEVMODE*>(calloc(buffer_size, 1))); | 519 reinterpret_cast<DEVMODE*>(calloc(buffer_size, 1))); |
| 520 DWORD flags = (in ? (DM_IN_BUFFER) : 0) | DM_OUT_BUFFER | DM_IN_PROMPT; | 520 DWORD flags = (in ? (DM_IN_BUFFER) : 0) | DM_OUT_BUFFER | DM_IN_PROMPT; |
| 521 LONG result = DocumentProperties(window, | 521 LONG result = DocumentProperties(window, |
| 522 printer, | 522 printer, |
| 523 const_cast<wchar_t*>(printer_name.c_str()), | 523 const_cast<wchar_t*>(printer_name.c_str()), |
| 524 out.get(), | 524 out.get(), |
| 525 in, | 525 in, |
| 526 flags); | 526 flags); |
| 527 if (canceled) | 527 if (canceled) |
| 528 *canceled = (result == IDCANCEL); | 528 *canceled = (result == IDCANCEL); |
| 529 if (result != IDOK) | 529 if (result != IDOK) |
| 530 return scoped_ptr<DEVMODE, base::FreeDeleter>(); | 530 return std::unique_ptr<DEVMODE, base::FreeDeleter>(); |
| 531 int size = out->dmSize; | 531 int size = out->dmSize; |
| 532 int extra_size = out->dmDriverExtra; | 532 int extra_size = out->dmDriverExtra; |
| 533 CHECK_GE(buffer_size, size + extra_size); | 533 CHECK_GE(buffer_size, size + extra_size); |
| 534 return out; | 534 return out; |
| 535 } | 535 } |
| 536 | 536 |
| 537 } // namespace printing | 537 } // namespace printing |
| OLD | NEW |