Backed out changeset b71c8c052463 (bug 1943846) for causing mass failures. CLOSED...
[gecko.git] / widget / windows / nsPrintSettingsServiceWin.cpp
blobcbc99441ab37c1c7511a708d437bb164d7158629
1 /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
2 /* This Source Code Form is subject to the terms of the Mozilla Public
3 * License, v. 2.0. If a copy of the MPL was not distributed with this
4 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
6 #include "nsPrintSettingsServiceWin.h"
8 #include "nsCOMPtr.h"
9 #include "nsPrintSettingsWin.h"
10 #include "nsPrintDialogUtil.h"
12 #include "nsGfxCIID.h"
13 #include "nsIServiceManager.h"
14 #include "nsWindowsHelpers.h"
15 #include "ipc/IPCMessageUtils.h"
16 #include "chrome/common/ipc_channel.h"
17 #include "mozilla/embedding/PPrintingTypes.h"
19 using namespace mozilla::embedding;
21 NS_IMETHODIMP
22 nsPrintSettingsServiceWin::SerializeToPrintData(nsIPrintSettings* aSettings,
23 PrintData* data) {
24 nsresult rv = nsPrintSettingsService::SerializeToPrintData(aSettings, data);
25 NS_ENSURE_SUCCESS(rv, rv);
27 nsCOMPtr<nsIPrintSettingsWin> psWin = do_QueryInterface(aSettings);
28 if (!psWin) {
29 return NS_ERROR_FAILURE;
32 nsAutoString deviceName;
33 nsAutoString driverName;
35 psWin->GetDeviceName(deviceName);
36 psWin->GetDriverName(driverName);
38 data->deviceName().Assign(deviceName);
39 data->driverName().Assign(driverName);
41 // When creating the print dialog on Windows, we only need to send certain
42 // print settings information from the parent to the child not vice versa.
43 if (XRE_IsParentProcess()) {
44 // A DEVMODE can actually be of arbitrary size. If it turns out that it'll
45 // make our IPC message larger than the limit, then we'll error out.
46 LPDEVMODEW devModeRaw;
47 psWin->GetDevMode(&devModeRaw); // This actually allocates a copy of the
48 // the nsIPrintSettingsWin DEVMODE, so
49 // we're now responsible for deallocating
50 // it. We'll use an nsAutoDevMode helper
51 // to do this.
52 if (devModeRaw) {
53 nsAutoDevMode devMode(devModeRaw);
54 devModeRaw = nullptr;
56 size_t devModeTotalSize = devMode->dmSize + devMode->dmDriverExtra;
57 size_t msgTotalSize = sizeof(PrintData) + devModeTotalSize;
59 if (msgTotalSize > IPC::Channel::kMaximumMessageSize / 2) {
60 return NS_ERROR_FAILURE;
63 // Instead of reaching in and manually reading each member, we'll just
64 // copy the bits over.
65 const char* devModeData = reinterpret_cast<const char*>(devMode.get());
66 nsTArray<uint8_t> arrayBuf;
67 arrayBuf.AppendElements(devModeData, devModeTotalSize);
68 data->devModeData() = std::move(arrayBuf);
72 return NS_OK;
75 NS_IMETHODIMP
76 nsPrintSettingsServiceWin::DeserializeToPrintSettings(
77 const PrintData& data, nsIPrintSettings* settings) {
78 nsresult rv =
79 nsPrintSettingsService::DeserializeToPrintSettings(data, settings);
80 NS_ENSURE_SUCCESS(rv, rv);
82 nsCOMPtr<nsIPrintSettingsWin> psWin = do_QueryInterface(settings);
83 if (!settings) {
84 return NS_ERROR_FAILURE;
87 if (XRE_IsContentProcess()) {
88 psWin->SetDeviceName(data.deviceName());
89 psWin->SetDriverName(data.driverName());
91 if (data.devModeData().IsEmpty()) {
92 psWin->SetDevMode(nullptr);
93 } else {
94 // Check minimum length of DEVMODE data.
95 auto devModeDataLength = data.devModeData().Length();
96 if (devModeDataLength < sizeof(DEVMODEW)) {
97 NS_WARNING("DEVMODE data is too short.");
98 return NS_ERROR_FAILURE;
101 DEVMODEW* devMode = reinterpret_cast<DEVMODEW*>(
102 const_cast<uint8_t*>(data.devModeData().Elements()));
104 // Check actual length of DEVMODE data.
105 if ((devMode->dmSize + devMode->dmDriverExtra) != devModeDataLength) {
106 NS_WARNING("DEVMODE length is incorrect.");
107 return NS_ERROR_FAILURE;
110 psWin->SetDevMode(devMode); // Copies
114 return NS_OK;
117 nsresult nsPrintSettingsServiceWin::_CreatePrintSettings(
118 nsIPrintSettings** _retval) {
119 *_retval = nullptr;
120 nsPrintSettingsWin* printSettings =
121 new nsPrintSettingsWin(); // does not initially ref count
122 NS_ENSURE_TRUE(printSettings, NS_ERROR_OUT_OF_MEMORY);
124 NS_ADDREF(*_retval = printSettings); // ref count
126 return NS_OK;