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 454 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
465 | 465 |
466 return ticket.Pass(); | 466 return ticket.Pass(); |
467 } | 467 } |
468 | 468 |
469 scoped_ptr<DEVMODE, base::FreeDeleter> CreateDevMode(HANDLE printer, | 469 scoped_ptr<DEVMODE, base::FreeDeleter> CreateDevMode(HANDLE printer, |
470 DEVMODE* in) { | 470 DEVMODE* in) { |
471 LONG buffer_size = DocumentProperties( | 471 LONG buffer_size = DocumentProperties( |
472 NULL, printer, const_cast<wchar_t*>(L""), NULL, NULL, 0); | 472 NULL, printer, const_cast<wchar_t*>(L""), NULL, NULL, 0); |
473 if (buffer_size < static_cast<int>(sizeof(DEVMODE))) | 473 if (buffer_size < static_cast<int>(sizeof(DEVMODE))) |
474 return scoped_ptr<DEVMODE, base::FreeDeleter>(); | 474 return scoped_ptr<DEVMODE, base::FreeDeleter>(); |
| 475 |
| 476 // Some drivers request buffers with size smaller than dmSize + dmDriverExtra. |
| 477 // crbug.com/421402 |
| 478 buffer_size *= 2; |
| 479 |
475 scoped_ptr<DEVMODE, base::FreeDeleter> out( | 480 scoped_ptr<DEVMODE, base::FreeDeleter> out( |
476 reinterpret_cast<DEVMODE*>(calloc(buffer_size, 1))); | 481 reinterpret_cast<DEVMODE*>(calloc(buffer_size, 1))); |
477 DWORD flags = (in ? (DM_IN_BUFFER) : 0) | DM_OUT_BUFFER; | 482 DWORD flags = (in ? (DM_IN_BUFFER) : 0) | DM_OUT_BUFFER; |
478 if (DocumentProperties( | 483 if (DocumentProperties( |
479 NULL, printer, const_cast<wchar_t*>(L""), out.get(), in, flags) != | 484 NULL, printer, const_cast<wchar_t*>(L""), out.get(), in, flags) != |
480 IDOK) { | 485 IDOK) { |
481 return scoped_ptr<DEVMODE, base::FreeDeleter>(); | 486 return scoped_ptr<DEVMODE, base::FreeDeleter>(); |
482 } | 487 } |
483 int size = out->dmSize; | 488 int size = out->dmSize; |
484 int extra_size = out->dmDriverExtra; | 489 int extra_size = out->dmDriverExtra; |
485 CHECK_GE(buffer_size, size + extra_size); | 490 CHECK_GE(buffer_size, size + extra_size); |
486 return out.Pass(); | 491 return out.Pass(); |
487 } | 492 } |
488 | 493 |
489 scoped_ptr<DEVMODE, base::FreeDeleter> PromptDevMode( | 494 scoped_ptr<DEVMODE, base::FreeDeleter> PromptDevMode( |
490 HANDLE printer, | 495 HANDLE printer, |
491 const base::string16& printer_name, | 496 const base::string16& printer_name, |
492 DEVMODE* in, | 497 DEVMODE* in, |
493 HWND window, | 498 HWND window, |
494 bool* canceled) { | 499 bool* canceled) { |
495 LONG buffer_size = | 500 LONG buffer_size = |
496 DocumentProperties(window, | 501 DocumentProperties(window, |
497 printer, | 502 printer, |
498 const_cast<wchar_t*>(printer_name.c_str()), | 503 const_cast<wchar_t*>(printer_name.c_str()), |
499 NULL, | 504 NULL, |
500 NULL, | 505 NULL, |
501 0); | 506 0); |
502 if (buffer_size < static_cast<int>(sizeof(DEVMODE))) | 507 if (buffer_size < static_cast<int>(sizeof(DEVMODE))) |
503 return scoped_ptr<DEVMODE, base::FreeDeleter>(); | 508 return scoped_ptr<DEVMODE, base::FreeDeleter>(); |
| 509 |
| 510 // Some drivers request buffers with size smaller than dmSize + dmDriverExtra. |
| 511 // crbug.com/421402 |
| 512 buffer_size *= 2; |
| 513 |
504 scoped_ptr<DEVMODE, base::FreeDeleter> out( | 514 scoped_ptr<DEVMODE, base::FreeDeleter> out( |
505 reinterpret_cast<DEVMODE*>(calloc(buffer_size, 1))); | 515 reinterpret_cast<DEVMODE*>(calloc(buffer_size, 1))); |
506 DWORD flags = (in ? (DM_IN_BUFFER) : 0) | DM_OUT_BUFFER | DM_IN_PROMPT; | 516 DWORD flags = (in ? (DM_IN_BUFFER) : 0) | DM_OUT_BUFFER | DM_IN_PROMPT; |
507 LONG result = DocumentProperties(window, | 517 LONG result = DocumentProperties(window, |
508 printer, | 518 printer, |
509 const_cast<wchar_t*>(printer_name.c_str()), | 519 const_cast<wchar_t*>(printer_name.c_str()), |
510 out.get(), | 520 out.get(), |
511 in, | 521 in, |
512 flags); | 522 flags); |
513 if (canceled) | 523 if (canceled) |
514 *canceled = (result == IDCANCEL); | 524 *canceled = (result == IDCANCEL); |
515 if (result != IDOK) | 525 if (result != IDOK) |
516 return scoped_ptr<DEVMODE, base::FreeDeleter>(); | 526 return scoped_ptr<DEVMODE, base::FreeDeleter>(); |
517 int size = out->dmSize; | 527 int size = out->dmSize; |
518 int extra_size = out->dmDriverExtra; | 528 int extra_size = out->dmDriverExtra; |
519 CHECK_GE(buffer_size, size + extra_size); | 529 CHECK_GE(buffer_size, size + extra_size); |
520 return out.Pass(); | 530 return out.Pass(); |
521 } | 531 } |
522 | 532 |
523 } // namespace printing | 533 } // namespace printing |
OLD | NEW |