Bug 1324064: Stop accessing printer devices in the child when printing via parent. r=jimm

This should remove all access to printer devices on Windows, there might by some other OS specific code which still does.
This commit is contained in:
Bob Owen 2017-01-06 11:29:11 +00:00
Родитель 73e99c3caa
Коммит 554feff78a
7 изменённых файлов: 72 добавлений и 27 удалений

Просмотреть файл

@ -29,7 +29,7 @@ parent:
nsresult rv);
async ShowPrintDialog(PPrintSettingsDialog dialog,
PBrowser browser,
nullable PBrowser browser,
PrintData settings);
async PPrintProgressDialog();

Просмотреть файл

@ -84,9 +84,15 @@ PrintingParent::ShowPrintDialog(PBrowserParent* aParent,
const PrintData& aData,
PrintData* aResult)
{
nsCOMPtr<nsPIDOMWindowOuter> parentWin = DOMWindowFromBrowserParent(aParent);
if (!parentWin) {
return NS_ERROR_FAILURE;
// If aParent is null this call is just being used to get print settings from
// the printer for print preview.
bool isPrintPreview = !aParent;
nsCOMPtr<nsPIDOMWindowOuter> parentWin;
if (aParent) {
parentWin = DOMWindowFromBrowserParent(aParent);
if (!parentWin) {
return NS_ERROR_FAILURE;
}
}
nsCOMPtr<nsIPrintingPromptService> pps(do_GetService("@mozilla.org/embedcomp/printingprompt-service;1"));
@ -123,9 +129,9 @@ PrintingParent::ShowPrintDialog(PBrowserParent* aParent,
rv = settings->SetPrintSilent(printSilently);
NS_ENSURE_SUCCESS(rv, rv);
// If we are printing silently then we just need to initialize the print
// settings with anything specific from the printer.
if (printSilently ||
// If this is for print preview or we are printing silently then we just need
// to initialize the print settings with anything specific from the printer.
if (isPrintPreview || printSilently ||
Preferences::GetBool("print.always_print_silent", printSilently)) {
nsXPIDLString printerName;
rv = settings->GetPrinterName(getter_Copies(printerName));
@ -138,8 +144,13 @@ PrintingParent::ShowPrintDialog(PBrowserParent* aParent,
NS_ENSURE_SUCCESS(rv, rv);
}
rv = SerializeAndEnsureRemotePrintJob(settings, nullptr, remotePrintJob,
aResult);
if (isPrintPreview) {
// For print preview we don't want a RemotePrintJob just the settings.
rv = mPrintSettingsSvc->SerializeToPrintData(settings, nullptr, aResult);
} else {
rv = SerializeAndEnsureRemotePrintJob(settings, nullptr, remotePrintJob,
aResult);
}
return rv;
}

Просмотреть файл

@ -72,21 +72,25 @@ nsPrintingProxy::ShowPrintDialog(mozIDOMWindowProxy *parent,
nsIWebBrowserPrint *webBrowserPrint,
nsIPrintSettings *printSettings)
{
NS_ENSURE_ARG(parent);
NS_ENSURE_ARG(webBrowserPrint);
NS_ENSURE_ARG(printSettings);
// Get the TabChild for this nsIDOMWindow, which we can then pass up to
// the parent.
nsCOMPtr<nsPIDOMWindowOuter> pwin = nsPIDOMWindowOuter::From(parent);
NS_ENSURE_STATE(pwin);
nsCOMPtr<nsIDocShell> docShell = pwin->GetDocShell();
NS_ENSURE_STATE(docShell);
// If parent is null we are just being called to retrieve the print settings
// from the printer in the parent for print preview.
TabChild* pBrowser = nullptr;
if (parent) {
// Get the TabChild for this nsIDOMWindow, which we can then pass up to
// the parent.
nsCOMPtr<nsPIDOMWindowOuter> pwin = nsPIDOMWindowOuter::From(parent);
NS_ENSURE_STATE(pwin);
nsCOMPtr<nsIDocShell> docShell = pwin->GetDocShell();
NS_ENSURE_STATE(docShell);
nsCOMPtr<nsITabChild> tabchild = docShell->GetTabChild();
NS_ENSURE_STATE(tabchild);
nsCOMPtr<nsITabChild> tabchild = docShell->GetTabChild();
NS_ENSURE_STATE(tabchild);
TabChild* pBrowser = static_cast<TabChild*>(tabchild.get());
pBrowser = static_cast<TabChild*>(tabchild.get());
}
// Next, serialize the nsIWebBrowserPrint and nsIPrintSettings we were given.
nsresult rv = NS_OK;

Просмотреть файл

@ -562,7 +562,11 @@ nsPrintEngine::DoCommonPrint(bool aIsPrintPreview,
}
nsScriptSuppressor scriptSuppressor(this);
if (!aIsPrintPreview) {
// If printing via parent we still call ShowPrintDialog even for print preview
// because we use that to retrieve the print settings from the printer.
// The dialog is not shown, but this means we don't need to access the printer
// driver from the child, which causes sandboxing issues.
if (!aIsPrintPreview || printingViaParent) {
#ifdef DEBUG
mPrt->mDebugFilePtr = mDebugFile;
#endif
@ -583,8 +587,12 @@ nsPrintEngine::DoCommonPrint(bool aIsPrintPreview,
if (!printSilently || printingViaParent) {
nsCOMPtr<nsIPrintingPromptService> printPromptService(do_GetService(kPrintingPromptService));
if (printPromptService) {
nsPIDOMWindowOuter* domWin = mDocument->GetWindow();
NS_ENSURE_TRUE(domWin, NS_ERROR_FAILURE);
nsPIDOMWindowOuter* domWin = nullptr;
// We leave domWin as nullptr to indicate a call for print preview.
if (!aIsPrintPreview) {
domWin = mDocument->GetWindow();
NS_ENSURE_TRUE(domWin, NS_ERROR_FAILURE);
}
// Platforms not implementing a given dialog for the service may
// return NS_ERROR_NOT_IMPLEMENTED or an error code.
@ -608,7 +616,7 @@ nsPrintEngine::DoCommonPrint(bool aIsPrintPreview,
// are telling GFX we want to print silent
printSilently = true;
if (mPrt->mPrintSettings) {
if (mPrt->mPrintSettings && !aIsPrintPreview) {
// The user might have changed shrink-to-fit in the print dialog, so update our copy of its state
mPrt->mPrintSettings->GetShrinkToFit(&mPrt->mShrinkToFit);

Просмотреть файл

@ -39,7 +39,7 @@ nsDeviceContextSpecProxy::Init(nsIWidget* aWidget,
return rv;
}
mRealDeviceContextSpec->Init(nullptr, aPrintSettings, false);
mRealDeviceContextSpec->Init(nullptr, aPrintSettings, aIsPrintPreview);
if (NS_WARN_IF(NS_FAILED(rv))) {
mRealDeviceContextSpec = nullptr;
return rv;

Просмотреть файл

@ -1030,6 +1030,12 @@ NS_IMETHODIMP
nsPrintOptions::InitPrintSettingsFromPrinter(const char16_t *aPrinterName,
nsIPrintSettings *aPrintSettings)
{
// Don't get print settings from the printer in the child when printing via
// parent, these will be retrieved in the parent later in the print process.
if (XRE_IsContentProcess() && Preferences::GetBool("print.print_via_parent")) {
return NS_OK;
}
NS_ENSURE_ARG_POINTER(aPrintSettings);
NS_ENSURE_ARG_POINTER(aPrinterName);

Просмотреть файл

@ -3,13 +3,15 @@
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
#include "nsDeviceContextSpecWin.h"
#include "mozilla/ArrayUtils.h"
#include "mozilla/gfx/PrintTargetPDF.h"
#include "mozilla/gfx/PrintTargetWindows.h"
#include "mozilla/Logging.h"
#include "mozilla/Preferences.h"
#include "mozilla/RefPtr.h"
#include "nsDeviceContextSpecWin.h"
#include "prmem.h"
#include <winspool.h>
@ -34,7 +36,6 @@
#include "mozilla/gfx/Logging.h"
#include "mozilla/Logging.h"
static mozilla::LazyLogModule kWidgetPrintingLogMod("printing-widget");
#define PR_PL(_p1) MOZ_LOG(kWidgetPrintingLogMod, mozilla::LogLevel::Debug, _p1)
@ -132,6 +133,15 @@ NS_IMETHODIMP nsDeviceContextSpecWin::Init(nsIWidget* aWidget,
nsresult rv = NS_ERROR_GFX_PRINTER_NO_PRINTER_AVAILABLE;
if (aPrintSettings) {
// If we're in the child and printing via the parent or we're printing to
// PDF we only need information from the print settings.
mPrintSettings->GetOutputFormat(&mOutputFormat);
if ((XRE_IsContentProcess() &&
Preferences::GetBool("print.print_via_parent")) ||
mOutputFormat == nsIPrintSettings::kOutputFormatPDF) {
return NS_OK;
}
nsCOMPtr<nsIPrintSettingsWin> psWin(do_QueryInterface(aPrintSettings));
if (psWin) {
char16_t* deviceName;
@ -177,7 +187,6 @@ NS_IMETHODIMP nsDeviceContextSpecWin::Init(nsIWidget* aWidget,
char16_t * printerName = nullptr;
if (mPrintSettings) {
mPrintSettings->GetPrinterName(&printerName);
mPrintSettings->GetOutputFormat(&mOutputFormat);
}
// If there is no name then use the default printer
@ -441,6 +450,13 @@ nsPrinterEnumeratorWin::InitPrintSettingsFromPrinter(const char16_t *aPrinterNam
return NS_OK;
}
// When printing to PDF on Windows there is no associated printer driver.
int16_t outputFormat;
aPrintSettings->GetOutputFormat(&outputFormat);
if (outputFormat == nsIPrintSettings::kOutputFormatPDF) {
return NS_OK;
}
RefPtr<nsDeviceContextSpecWin> devSpecWin = new nsDeviceContextSpecWin();
if (!devSpecWin) return NS_ERROR_OUT_OF_MEMORY;