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"
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
;
22 nsPrintSettingsServiceWin::SerializeToPrintData(nsIPrintSettings
* aSettings
,
24 nsresult rv
= nsPrintSettingsService::SerializeToPrintData(aSettings
, data
);
25 NS_ENSURE_SUCCESS(rv
, rv
);
27 nsCOMPtr
<nsIPrintSettingsWin
> psWin
= do_QueryInterface(aSettings
);
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
53 nsAutoDevMode
devMode(devModeRaw
);
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
);
76 nsPrintSettingsServiceWin::DeserializeToPrintSettings(
77 const PrintData
& data
, nsIPrintSettings
* settings
) {
79 nsPrintSettingsService::DeserializeToPrintSettings(data
, settings
);
80 NS_ENSURE_SUCCESS(rv
, rv
);
82 nsCOMPtr
<nsIPrintSettingsWin
> psWin
= do_QueryInterface(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);
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
117 nsresult
nsPrintSettingsServiceWin::_CreatePrintSettings(
118 nsIPrintSettings
** _retval
) {
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