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); nsresult rv);
async ShowPrintDialog(PPrintSettingsDialog dialog, async ShowPrintDialog(PPrintSettingsDialog dialog,
PBrowser browser, nullable PBrowser browser,
PrintData settings); PrintData settings);
async PPrintProgressDialog(); async PPrintProgressDialog();

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

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

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

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

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

@ -562,7 +562,11 @@ nsPrintEngine::DoCommonPrint(bool aIsPrintPreview,
} }
nsScriptSuppressor scriptSuppressor(this); 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 #ifdef DEBUG
mPrt->mDebugFilePtr = mDebugFile; mPrt->mDebugFilePtr = mDebugFile;
#endif #endif
@ -583,8 +587,12 @@ nsPrintEngine::DoCommonPrint(bool aIsPrintPreview,
if (!printSilently || printingViaParent) { if (!printSilently || printingViaParent) {
nsCOMPtr<nsIPrintingPromptService> printPromptService(do_GetService(kPrintingPromptService)); nsCOMPtr<nsIPrintingPromptService> printPromptService(do_GetService(kPrintingPromptService));
if (printPromptService) { if (printPromptService) {
nsPIDOMWindowOuter* domWin = mDocument->GetWindow(); nsPIDOMWindowOuter* domWin = nullptr;
NS_ENSURE_TRUE(domWin, NS_ERROR_FAILURE); // 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 // Platforms not implementing a given dialog for the service may
// return NS_ERROR_NOT_IMPLEMENTED or an error code. // 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 // are telling GFX we want to print silent
printSilently = true; 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 // The user might have changed shrink-to-fit in the print dialog, so update our copy of its state
mPrt->mPrintSettings->GetShrinkToFit(&mPrt->mShrinkToFit); mPrt->mPrintSettings->GetShrinkToFit(&mPrt->mShrinkToFit);

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

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

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

@ -1030,6 +1030,12 @@ NS_IMETHODIMP
nsPrintOptions::InitPrintSettingsFromPrinter(const char16_t *aPrinterName, nsPrintOptions::InitPrintSettingsFromPrinter(const char16_t *aPrinterName,
nsIPrintSettings *aPrintSettings) 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(aPrintSettings);
NS_ENSURE_ARG_POINTER(aPrinterName); NS_ENSURE_ARG_POINTER(aPrinterName);

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

@ -3,13 +3,15 @@
* License, v. 2.0. If a copy of the MPL was not distributed with this * 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/. */ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
#include "nsDeviceContextSpecWin.h"
#include "mozilla/ArrayUtils.h" #include "mozilla/ArrayUtils.h"
#include "mozilla/gfx/PrintTargetPDF.h" #include "mozilla/gfx/PrintTargetPDF.h"
#include "mozilla/gfx/PrintTargetWindows.h" #include "mozilla/gfx/PrintTargetWindows.h"
#include "mozilla/Logging.h" #include "mozilla/Logging.h"
#include "mozilla/Preferences.h"
#include "mozilla/RefPtr.h" #include "mozilla/RefPtr.h"
#include "nsDeviceContextSpecWin.h"
#include "prmem.h" #include "prmem.h"
#include <winspool.h> #include <winspool.h>
@ -34,7 +36,6 @@
#include "mozilla/gfx/Logging.h" #include "mozilla/gfx/Logging.h"
#include "mozilla/Logging.h"
static mozilla::LazyLogModule kWidgetPrintingLogMod("printing-widget"); static mozilla::LazyLogModule kWidgetPrintingLogMod("printing-widget");
#define PR_PL(_p1) MOZ_LOG(kWidgetPrintingLogMod, mozilla::LogLevel::Debug, _p1) #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; nsresult rv = NS_ERROR_GFX_PRINTER_NO_PRINTER_AVAILABLE;
if (aPrintSettings) { 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)); nsCOMPtr<nsIPrintSettingsWin> psWin(do_QueryInterface(aPrintSettings));
if (psWin) { if (psWin) {
char16_t* deviceName; char16_t* deviceName;
@ -177,7 +187,6 @@ NS_IMETHODIMP nsDeviceContextSpecWin::Init(nsIWidget* aWidget,
char16_t * printerName = nullptr; char16_t * printerName = nullptr;
if (mPrintSettings) { if (mPrintSettings) {
mPrintSettings->GetPrinterName(&printerName); mPrintSettings->GetPrinterName(&printerName);
mPrintSettings->GetOutputFormat(&mOutputFormat);
} }
// If there is no name then use the default printer // If there is no name then use the default printer
@ -441,6 +450,13 @@ nsPrinterEnumeratorWin::InitPrintSettingsFromPrinter(const char16_t *aPrinterNam
return NS_OK; 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(); RefPtr<nsDeviceContextSpecWin> devSpecWin = new nsDeviceContextSpecWin();
if (!devSpecWin) return NS_ERROR_OUT_OF_MEMORY; if (!devSpecWin) return NS_ERROR_OUT_OF_MEMORY;