blob: 088873614d2e31d9bef988a265da5cdf3e698e0c [file] [log] [blame]
[email protected]128bec3c2011-01-20 22:57:351// Copyright (c) 2011 The Chromium Authors. All rights reserved.
license.botbf09a502008-08-24 00:55:552// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
initial.commit09911bf2008-07-26 23:55:294
[email protected]51e8d9352010-10-06 22:21:175#include "printing/printing_context_win.h"
vitalybuka92ab8ce2014-08-26 23:41:456
avi126e93c2015-12-21 21:48:167#include <stddef.h>
8#include <stdint.h>
9
vitalybukaf9d0c0c2014-09-09 19:53:3310#include "base/bind.h"
11#include "base/message_loop/message_loop.h"
thakise03b42a2015-07-14 18:44:1012#include "base/win/scoped_handle.h"
13#include "base/win/scoped_hdc.h"
vitalybukaf9d0c0c2014-09-09 19:53:3314#include "printing/backend/printing_info_win.h"
15#include "printing/backend/win_helper.h"
[email protected]8ff1d422009-07-07 21:31:3916#include "printing/print_settings.h"
vitalybukaf9d0c0c2014-09-09 19:53:3317#include "printing/printing_context_system_dialog_win.h"
18#include "printing/printing_test.h"
initial.commit09911bf2008-07-26 23:55:2919#include "testing/gtest/include/gtest/gtest.h"
initial.commit09911bf2008-07-26 23:55:2920
[email protected]1b248882014-02-25 04:39:1421namespace printing {
22
initial.commit09911bf2008-07-26 23:55:2923// This test is automatically disabled if no printer is available.
Vitaly Bukabd7c9812014-08-26 08:57:5424class PrintingContextTest : public PrintingTest<testing::Test>,
25 public PrintingContext::Delegate {
[email protected]b7191422010-09-21 19:18:0526 public:
[email protected]1b248882014-02-25 04:39:1427 void PrintSettingsCallback(PrintingContext::Result result) {
[email protected]b7191422010-09-21 19:18:0528 result_ = result;
29 }
30
Vitaly Bukabd7c9812014-08-26 08:57:5431 // PrintingContext::Delegate methods.
nickbc761612015-04-27 23:30:4632 gfx::NativeView GetParentView() override { return NULL; }
33 std::string GetAppLocale() override { return std::string(); }
Vitaly Bukabd7c9812014-08-26 08:57:5434
[email protected]b7191422010-09-21 19:18:0535 protected:
[email protected]1b248882014-02-25 04:39:1436 PrintingContext::Result result() const { return result_; }
[email protected]b7191422010-09-21 19:18:0537
38 private:
[email protected]1b248882014-02-25 04:39:1439 PrintingContext::Result result_;
initial.commit09911bf2008-07-26 23:55:2940};
41
thakise03b42a2015-07-14 18:44:1042namespace {
thestige85e6b62016-08-25 00:00:0643
thakise03b42a2015-07-14 18:44:1044struct FreeHandleTraits {
45 typedef HANDLE Handle;
46 static void CloseHandle(HANDLE handle) { GlobalFree(handle); }
47 static bool IsHandleValid(HANDLE handle) { return handle != NULL; }
48 static HANDLE NullHandle() { return NULL; }
49};
50typedef base::win::GenericScopedHandle<FreeHandleTraits,
51 base::win::DummyVerifierTraits>
52 ScopedGlobalAlloc;
thakise03b42a2015-07-14 18:44:1053
thestige85e6b62016-08-25 00:00:0654} // namespace
55
56class MockPrintingContextWin : public PrintingContextSystemDialogWin {
vitalybukaf9d0c0c2014-09-09 19:53:3357 public:
thestige85e6b62016-08-25 00:00:0658 explicit MockPrintingContextWin(Delegate* delegate)
59 : PrintingContextSystemDialogWin(delegate) {}
vitalybukaf9d0c0c2014-09-09 19:53:3360
61 protected:
62 // This is a fake PrintDlgEx implementation that sets the right fields in
63 // |lppd| to trigger a bug in older revisions of PrintingContext.
anujk.sharma263c3132014-10-07 07:29:4264 HRESULT ShowPrintDialog(PRINTDLGEX* lppd) override {
vitalybukaf9d0c0c2014-09-09 19:53:3365 // The interesting bits:
66 // Pretend the user hit print
67 lppd->dwResultAction = PD_RESULT_PRINT;
68
69 // Pretend the page range is 1-5, but since lppd->Flags does not have
70 // PD_SELECTION set, this really shouldn't matter.
71 lppd->nPageRanges = 1;
72 lppd->lpPageRanges[0].nFromPage = 1;
73 lppd->lpPageRanges[0].nToPage = 5;
74
75 base::string16 printer_name = PrintingContextTest::GetDefaultPrinter();
76 ScopedPrinterHandle printer;
77 if (!printer.OpenPrinter(printer_name.c_str()))
78 return E_FAIL;
79
vitalybukaf9d0c0c2014-09-09 19:53:3380 const DEVMODE* dev_mode = NULL;
vitalybukaf9d0c0c2014-09-09 19:53:3381 lppd->hDC = NULL;
82 lppd->hDevMode = NULL;
83 lppd->hDevNames = NULL;
84
85 PrinterInfo2 info_2;
thakise03b42a2015-07-14 18:44:1086 if (info_2.Init(printer.Get()))
vitalybukaf9d0c0c2014-09-09 19:53:3387 dev_mode = info_2.get()->pDevMode;
thakise03b42a2015-07-14 18:44:1088 if (!dev_mode)
89 return E_FAIL;
vitalybukaf9d0c0c2014-09-09 19:53:3390
thakise03b42a2015-07-14 18:44:1091 base::win::ScopedCreateDC hdc(
92 CreateDC(L"WINSPOOL", printer_name.c_str(), NULL, dev_mode));
93 if (!hdc.Get())
94 return E_FAIL;
vitalybukaf9d0c0c2014-09-09 19:53:3395
96 size_t dev_mode_size = dev_mode->dmSize + dev_mode->dmDriverExtra;
thakise03b42a2015-07-14 18:44:1097 ScopedGlobalAlloc dev_mode_mem(GlobalAlloc(GMEM_MOVEABLE, dev_mode_size));
98 if (!dev_mode_mem.Get())
99 return E_FAIL;
100 void* dev_mode_ptr = GlobalLock(dev_mode_mem.Get());
101 if (!dev_mode_ptr)
102 return E_FAIL;
vitalybukaf9d0c0c2014-09-09 19:53:33103 memcpy(dev_mode_ptr, dev_mode, dev_mode_size);
thakise03b42a2015-07-14 18:44:10104 GlobalUnlock(dev_mode_mem.Get());
vitalybukaf9d0c0c2014-09-09 19:53:33105 dev_mode_ptr = NULL;
106
107 size_t driver_size =
108 2 + sizeof(wchar_t) * lstrlen(info_2.get()->pDriverName);
109 size_t printer_size =
110 2 + sizeof(wchar_t) * lstrlen(info_2.get()->pPrinterName);
111 size_t port_size = 2 + sizeof(wchar_t) * lstrlen(info_2.get()->pPortName);
112 size_t dev_names_size =
113 sizeof(DEVNAMES) + driver_size + printer_size + port_size;
thakise03b42a2015-07-14 18:44:10114 ScopedGlobalAlloc dev_names_mem(GlobalAlloc(GHND, dev_names_size));
115 if (!dev_names_mem.Get())
116 return E_FAIL;
117 void* dev_names_ptr = GlobalLock(dev_names_mem.Get());
118 if (!dev_names_ptr)
119 return E_FAIL;
vitalybukaf9d0c0c2014-09-09 19:53:33120 DEVNAMES* dev_names = reinterpret_cast<DEVNAMES*>(dev_names_ptr);
121 dev_names->wDefault = 1;
122 dev_names->wDriverOffset = sizeof(DEVNAMES) / sizeof(wchar_t);
avi126e93c2015-12-21 21:48:16123 memcpy(reinterpret_cast<uint8_t*>(dev_names_ptr) + dev_names->wDriverOffset,
124 info_2.get()->pDriverName, driver_size);
brucedawsonc8e9e0d002015-12-03 01:54:27125 dev_names->wDeviceOffset = base::checked_cast<WORD>(
126 dev_names->wDriverOffset + driver_size / sizeof(wchar_t));
avi126e93c2015-12-21 21:48:16127 memcpy(reinterpret_cast<uint8_t*>(dev_names_ptr) + dev_names->wDeviceOffset,
128 info_2.get()->pPrinterName, printer_size);
brucedawsonc8e9e0d002015-12-03 01:54:27129 dev_names->wOutputOffset = base::checked_cast<WORD>(
130 dev_names->wDeviceOffset + printer_size / sizeof(wchar_t));
avi126e93c2015-12-21 21:48:16131 memcpy(reinterpret_cast<uint8_t*>(dev_names_ptr) + dev_names->wOutputOffset,
132 info_2.get()->pPortName, port_size);
thakise03b42a2015-07-14 18:44:10133 GlobalUnlock(dev_names_mem.Get());
vitalybukaf9d0c0c2014-09-09 19:53:33134 dev_names_ptr = NULL;
135
thakise03b42a2015-07-14 18:44:10136 lppd->hDC = hdc.Take();
137 lppd->hDevMode = dev_mode_mem.Take();
138 lppd->hDevNames = dev_names_mem.Take();
139 return S_OK;
vitalybukaf9d0c0c2014-09-09 19:53:33140 }
141};
142
143TEST_F(PrintingContextTest, PrintAll) {
144 base::MessageLoop message_loop;
145 if (IsTestCaseDisabled())
146 return;
147
148 MockPrintingContextWin context(this);
149 context.AskUserForSettings(
150 123,
151 false,
dgn4c172eea2014-12-15 21:11:23152 false,
vitalybukaf9d0c0c2014-09-09 19:53:33153 base::Bind(&PrintingContextTest::PrintSettingsCallback,
154 base::Unretained(this)));
155 EXPECT_EQ(PrintingContext::OK, result());
156 PrintSettings settings = context.settings();
thakis6ef917b2015-12-10 19:29:57157 EXPECT_EQ(0u, settings.ranges().size());
vitalybukaf9d0c0c2014-09-09 19:53:33158}
159
[email protected]e055fe2b2010-12-01 02:05:39160TEST_F(PrintingContextTest, Base) {
[email protected]e055fe2b2010-12-01 02:05:39161 if (IsTestCaseDisabled())
162 return;
initial.commit09911bf2008-07-26 23:55:29163
[email protected]1b248882014-02-25 04:39:14164 PrintSettings settings;
initial.commit09911bf2008-07-26 23:55:29165 settings.set_device_name(GetDefaultPrinter());
166 // Initialize it.
dchengc3df9ba2016-04-07 23:09:32167 std::unique_ptr<PrintingContext> context(PrintingContext::Create(this));
[email protected]1b248882014-02-25 04:39:14168 EXPECT_EQ(PrintingContext::OK, context->InitWithSettings(settings));
initial.commit09911bf2008-07-26 23:55:29169
initial.commit09911bf2008-07-26 23:55:29170 // The print may lie to use and may not support world transformation.
171 // Verify right now.
172 XFORM random_matrix = { 1, 0.1f, 0, 1.5f, 0, 1 };
[email protected]51e8d9352010-10-06 22:21:17173 EXPECT_TRUE(SetWorldTransform(context->context(), &random_matrix));
174 EXPECT_TRUE(ModifyWorldTransform(context->context(), NULL, MWT_IDENTITY));
initial.commit09911bf2008-07-26 23:55:29175}
[email protected]d8254622010-08-13 19:15:46176
[email protected]1b248882014-02-25 04:39:14177} // namespace printing