Code:
/ Dotnetfx_Win7_3.5.1 / Dotnetfx_Win7_3.5.1 / 3.5.1 / DEVDIV / depot / DevDiv / releases / Orcas / NetFXw7 / wpf / src / Framework / System / Windows / Controls / PrintDialog.cs / 1 / PrintDialog.cs
/*++ Copyright (C) 2004 - 2005 Microsoft Corporation. All rights reserved. Module Name: PrintDialog.cs Abstract: This file contains the implementation of the PrintDialog class and its supporting enums. Author: Robert Anderson (robertan) 9-May-2005 --*/ using System; using System.Collections; using System.Collections.Generic; using System.ComponentModel; using System.Printing; using System.Security; using System.Security.Permissions; using System.Windows; using System.Windows.Controls; using System.Windows.Interop; using System.Windows.Media; using System.Windows.Shapes; using System.Windows.Xps; using System.Xml; using MS.Internal.Printing; using MS.Internal; using System.Windows.Xps.Serialization; using System.Windows.Documents; using System.Windows.Documents.Serialization; // WritingCompletedEventArgs using System.Drawing.Printing; using MS.Internal.PresentationFramework; namespace System.Windows.Controls { ////// This class is used to show a print which will configure a /// user PrintTicket and Printer based on user input. This /// PrintTicket and Printer is then used to perform a print job. /// public class PrintDialog { #region Constructors ////// Instantiates an instance of the Print Dialog. /// ////// Critical: - setting critical data (_printQueue, _printTicket, _dialogInvoked) /// PublicOk: - We are setting these to "known" values of null. There /// is no data exposure here. /// [SecurityCritical] public PrintDialog( ) { _dialogInvoked = false; _printQueue = null; _printTicket = null; _isPrintableAreaWidthUpdated = false; _isPrintableAreaHeightUpdated = false; _pageRangeSelection = PageRangeSelection.AllPages; _minPage = 1; _maxPage = 9999; _userPageRangeEnabled = false; } #endregion Constructors #region Public properties ////// Gets or Sets the PageRangeSelection option for the print dialog. /// public PageRangeSelection PageRangeSelection { get { return _pageRangeSelection; } set { _pageRangeSelection = value; } } ////// Gets or sets a PageRange objects used when the PageRangeSelection /// option is set to UserPages. /// public PageRange PageRange { get { return _pageRange; } set { if ((value.PageTo <= 0) || (value.PageFrom <= 0)) { throw new System.ArgumentException(SR.Get(SRID.PrintDialogInvalidPageRange), "PageRange"); } _pageRange = value; if (_pageRange.PageFrom > _pageRange.PageTo) { int temp = _pageRange.PageFrom; _pageRange.PageFrom = _pageRange.PageTo; _pageRange.PageTo = temp; } } } ////// Gets or a sets a flag to enable/disable the user page range support on /// the print dialog. /// public bool UserPageRangeEnabled { get { return _userPageRangeEnabled; } set { _userPageRangeEnabled = value; } } // the following two properties return non CLS-compliant type UInt32 (bug 1788246) #pragma warning disable 3003 ////// Gets or sets the minimum page number allowed in the page ranges. /// public UInt32 MinPage { get { return _minPage; } set { if (_minPage <= 0) { throw new System.ArgumentException(SR.Get(SRID.PrintDialogZeroNotAllowed, "MinPage")); } _minPage = value; } } ////// Gets or sets the maximum page number allowed in the page ranges. /// public UInt32 MaxPage { get { return _maxPage; } set { if (_maxPage <= 0) { throw new System.ArgumentException(SR.Get(SRID.PrintDialogZeroNotAllowed, "MaxPage")); } _maxPage = value; } } #pragma warning restore 3003 ////// Gets or sets the printer selection. /// ////// Critical: - The getter is critical since it accesses critical data in web application mode. /// - The getter is calling critical code (AcquireDefaultPrintQueue). /// - The setter is critical since it is returning critical data. /// PublicOk: - A demand is made for default printing before returning the print queue. This /// would be the same permission required to get the print queue in the first place. /// - We also demand before setting the print queue object. If they can satisfy the /// the demand then they are safe to print anyways. /// public PrintQueue PrintQueue { [SecurityCritical] get { SecurityHelper.DemandPrintDialogPermissions(); if (_printQueue == null) { _printQueue = AcquireDefaultPrintQueue(); } return _printQueue; } [SecurityCritical] set { SecurityHelper.DemandPrintDialogPermissions(); _printQueue = value; } } ////// Get or sets the current PrintTicket object. /// ////// Critical: - The getter is critical since it accesses critical data. /// - The getter is calling critical code (AcquireDefaultPrintTicket). /// - The setter is critical since it is returning critical data. /// PublicOk: - A demand is made for default printing before returning the print ticket. This /// would be the same permission required to get the print ticket in the first place. /// - We also demand before setting the print ticket object. If they can satisfy the /// the demand then they are safe to print anyways. /// public PrintTicket PrintTicket { [SecurityCritical] get { SecurityHelper.DemandPrintDialogPermissions(); if (_printTicket == null) { _printTicket = AcquireDefaultPrintTicket(this.PrintQueue); } return _printTicket; } [SecurityCritical] set { SecurityHelper.DemandPrintDialogPermissions(); _printTicket = value; } } ////// Get the Width of the area on paper to which the application can print /// public double PrintableAreaWidth { get { if( ((_isPrintableAreaWidthUpdated == false) && (_isPrintableAreaHeightUpdated == false)) || ((_isPrintableAreaWidthUpdated == true) && (_isPrintableAreaHeightUpdated == false))) { _isPrintableAreaWidthUpdated = true; _isPrintableAreaHeightUpdated = false; UpdatePrintableAreaSize(); } return _printableAreaWidth; } } ////// Get the Height of the area on paper to which the application can print /// public double PrintableAreaHeight { get { if( ((_isPrintableAreaWidthUpdated == false) && (_isPrintableAreaHeightUpdated == false)) || ((_isPrintableAreaWidthUpdated == false) && (_isPrintableAreaHeightUpdated == true))) { _isPrintableAreaWidthUpdated = false; _isPrintableAreaHeightUpdated = true; UpdatePrintableAreaSize(); } return _printableAreaHeight; } } #endregion Public properties #region Public methods ////// Pops the dialog up to the user in a modal form. /// ////// Critical: - Accesses and sets critical data. /// PublicOk: - Data is internal to this dialog and can only be retrieved /// by other critical code. No information leaves this method. /// [SecurityCritical] public NullableShowDialog() { // // Reset this flag as we have not displayed the dialog yet. // _dialogInvoked = false; Win32PrintDialog dlg = new Win32PrintDialog(); // // Setup the old values if any exist. // dlg.PrintTicket = _printTicket; dlg.PrintQueue = _printQueue; dlg.MinPage = Math.Max(1, Math.Min(_minPage, _maxPage)); dlg.MaxPage = Math.Max(dlg.MinPage, Math.Max(_minPage, _maxPage)); dlg.PageRangeEnabled = _userPageRangeEnabled; dlg.PageRange = new PageRange( Math.Max((int)dlg.MinPage, _pageRange.PageFrom), Math.Min((int)dlg.MaxPage, _pageRange.PageTo)); dlg.PageRangeSelection = _pageRangeSelection; // // Invoke the Win32 dialog // UInt32 dialogResult = dlg.ShowDialog(); if ((dialogResult == MS.Internal.Printing.NativeMethods.PD_RESULT_APPLY) || (dialogResult == MS.Internal.Printing.NativeMethods.PD_RESULT_PRINT)) { _printTicket = dlg.PrintTicket; _printQueue = dlg.PrintQueue; _pageRange = dlg.PageRange; _pageRangeSelection = dlg.PageRangeSelection; _dialogInvoked = true; } return (dialogResult == MS.Internal.Printing.NativeMethods.PD_RESULT_PRINT); } /// /// Prints a Visual to the currently selected Print Queue. /// /// /// The visual to be printed. /// /// /// Description of the job to be printed. This shows in the Printer UI /// ////// Critical: - Sets a critical data property. /// PublicOk: - The critical data is a flag that needs to be reset for each print /// job to enforce the dialog invocation on every print operation. Without /// this method resetting this flag we would not be honoring the security /// goal of displaying the dialog once per print job. /// [SecurityCritical] public void PrintVisual( Visual visual, String description ) { if (visual == null) { throw new ArgumentNullException("visual"); } XpsDocumentWriter writer = CreateWriter(description); writer.Write(visual); _printableAreaWidth = 0; _printableAreaHeight = 0; _isPrintableAreaWidthUpdated = false; _isPrintableAreaHeightUpdated = false; _dialogInvoked = false; } ////// Prints an DocumentPaginator based document to the currently selected Print Queue. /// /// /// The DocumentPaginator to be printed. /// /// /// Description of the job to be printed. This shows in the Printer UI /// ////// Critical: - Sets a critical data property. /// PublicOk: - The critical data is a flag that needs to be reset for each print /// job to enforce the dialog invocation on every print operation. Without /// this method resetting this flag we would not be honoring the security /// goal of displaying the dialog once per print job. /// [SecurityCritical] public void PrintDocument( DocumentPaginator documentPaginator, String description ) { if (documentPaginator == null) { throw new ArgumentNullException("documentPaginator"); } XpsDocumentWriter writer = CreateWriter(description); writer.Write(documentPaginator); _printableAreaWidth = 0; _printableAreaHeight = 0; _isPrintableAreaWidthUpdated = false; _isPrintableAreaHeightUpdated = false; _dialogInvoked = false; } #endregion Public methods #region Private methods ////// Critical: - Asserts to obtain the default print queue from the local server. /// [SecurityCritical] private PrintQueue AcquireDefaultPrintQueue() { PrintQueue printQueue = null; (new PrintingPermission(PrintingPermissionLevel.DefaultPrinting)).Assert(); //BlessedAssert try { try { LocalPrintServer server = new LocalPrintServer(); printQueue = server.DefaultPrintQueue; } catch (PrintSystemException) { // // It is entirely possible for there to be no "default" printer. In this case, // the printing system throws an exception. We do not want this to propagate // up. Instead, returning null is fine. // printQueue = null; } } finally { PrintingPermission.RevertAssert(); } return printQueue; } ////// Critical: - Asserts to obtain the PrintTicket from the specified PrintQueue /// object or create a blank PrintTicket object (i.e. PrintTicket::ctor). /// [SecurityCritical] private PrintTicket AcquireDefaultPrintTicket( PrintQueue printQueue ) { PrintTicket printTicket = null; (new PrintingPermission(PrintingPermissionLevel.DefaultPrinting)).Assert(); //BlessedAssert try { try { if (printQueue != null) { printTicket = printQueue.UserPrintTicket; if (printTicket == null) { printTicket = printQueue.DefaultPrintTicket; } } } catch (PrintSystemException) { // // The printing subsystem can throw an exception in certain cases when // the print ticket is unavailable. If it does we will handle this // below. There is no real need to bubble this up to the application. // printTicket = null; } } finally { PrintingPermission.RevertAssert(); } // // If the printing subsystem could not give us a print ticket either due to // a failure or because a user/system default was not available, then just // create a blank/empty one. // if (printTicket == null) { printTicket = new PrintTicket(); } return printTicket; } ////// Critical: - Invokes a critical method (PickCorrectPrintingEnvironment). /// TreatAsSafe: - Critical data returned from above method is internal and does /// not leave the scope of this method. It is only used to calculate /// non-critical values. /// [SecurityCritical, SecurityTreatAsSafe] private void UpdatePrintableAreaSize( ) { PrintQueue printQueue = null; PrintTicket printTicket = null; PickCorrectPrintingEnvironment(ref printQueue, ref printTicket); PrintCapabilities printCap = null; if (printQueue != null) { printCap = printQueue.GetPrintCapabilities(printTicket); } // PrintCapabilities OrientedPageMediaWidth/Height are Nullable if ((printCap != null) && (printCap.OrientedPageMediaWidth != null) && (printCap.OrientedPageMediaHeight != null)) { _printableAreaWidth = (double)printCap.OrientedPageMediaWidth; _printableAreaHeight = (double)printCap.OrientedPageMediaHeight; } else { // Initialize page size to portrait Letter size. // This is our fallback if PrintTicket doesn't specify the page size. _printableAreaWidth = 816; _printableAreaHeight = 1056; // PrintTicket's PageMediaSize could be null and PageMediaSize Width/Height are Nullable if ((printTicket.PageMediaSize != null) && (printTicket.PageMediaSize.Width != null) && (printTicket.PageMediaSize.Height != null)) { _printableAreaWidth = (double)printTicket.PageMediaSize.Width; _printableAreaHeight = (double)printTicket.PageMediaSize.Height; } // If we are using PrintTicket's PageMediaSize dimensions to populate the widht/height values, // we need to adjust them based on current orientation. PrintTicket's PageOrientation is Nullable. if (printTicket.PageOrientation != null) { PageOrientation orientation = (PageOrientation)printTicket.PageOrientation; // need to swap width/height in landscape orientation if ((orientation == PageOrientation.Landscape) || (orientation == PageOrientation.ReverseLandscape)) { double t = _printableAreaWidth; _printableAreaWidth = _printableAreaHeight; _printableAreaHeight = t; } } } } ////// Critical: - Asserts for PrintingPermissionLevel.DefaultPrinting /// to be able to use the printQueue to create the /// XpsDocumentWriter. /// TreatAsSafe: - The assert is only done after ensuring that the user /// has conciously made a decision to print by successfully /// dismissing the Print Dialog. This logic of a dialog /// being required is only needed for partial trust applications. /// The logic of checking this criteria is contained within the /// PickCorrectPrintingEnvironment method. /// - The XpsDocumentWriter instance returned from this method /// is not unsafe since the application is either full trust /// or the user chose to print. It is okay for the application /// to use the XpsDocumentWriter to print at this point. /// [SecurityCritical, SecurityTreatAsSafe] private XpsDocumentWriter CreateWriter( String description ) { PrintQueue printQueue = null; PrintTicket printTicket = null; XpsDocumentWriter writer = null; PickCorrectPrintingEnvironment(ref printQueue, ref printTicket); (new PrintingPermission(PrintingPermissionLevel.DefaultPrinting)).Assert(); //BlessedAssert try { if(printQueue != null) { printQueue.CurrentJobSettings.Description = description; } writer = PrintQueue.CreateXpsDocumentWriter(printQueue); PrintDlgPrintTicketEventHandler eventHandler = new PrintDlgPrintTicketEventHandler(printTicket); writer.WritingPrintTicketRequired += new WritingPrintTicketRequiredEventHandler(eventHandler.SetPrintTicket); } finally { PrintingPermission.RevertAssert(); } return writer; } ////// Critical: - Accesses critical data and returns it to the caller. /// - Calls critical code (AcquireDefaultPrintQueue/AcquireDefaultPrintTicket) /// - Detects whether a caller is allowed to acquire this data /// based on a demand. This demand is only performed if the /// dialog was not invoked already. It is fine to return the /// data if the dialog was invoked, however, the data is still /// critical. /// /// NOTE: This method validates that a dialog was invoked prior to returning the /// PrintQueue and PrintTicket for the case of web applications. If the /// dialog was not invoked then an exception is thrown. /// [SecurityCritical] private void PickCorrectPrintingEnvironment( ref PrintQueue printQueue, ref PrintTicket printTicket ) { if (_dialogInvoked == false) { // // If the dialog has not been invoked then the user needs printing permissions. // If the demand succeeds then they can print. If the demand fails, then we // tell them that the print dialog must be displayed first by throwing a dialog // exception. // try { SecurityHelper.DemandPrintDialogPermissions(); } catch (SecurityException) { throw new PrintDialogException(SR.Get(SRID.PartialTrustPrintDialogMustBeInvoked)); } } // // If the default print queue and print ticket have not already // been selected then update them now since we need them. // // NOTE: If this code gets called then we know the dialog has never // been invoked but the above demand was satisfied. In this // case we want to just pickup the user defaults. // if (_printQueue == null) { _printQueue = AcquireDefaultPrintQueue(); } if (_printTicket == null) { _printTicket = AcquireDefaultPrintTicket(_printQueue); } // // We should have valid print queue and print ticket objects to // return now. As a note, a null PrintQueue is valid for this // since the dialog will automatically pick up the user default // printer for us. // printQueue = _printQueue; printTicket = _printTicket; } #endregion Private methods #region Private data ////// The PrintTicket is critical and not obtainable from a partial /// trust application unless they can satisfy a printing permission /// demand. /// [SecurityCritical] private PrintTicket _printTicket; ////// The PrintQueue is critical and not obtainable from a partial /// trust application unless they can satisfy a printing permission /// demand. /// [SecurityCritical] private PrintQueue _printQueue; ////// This variable is used to determine whether a user actually invoked /// and dismissed the dialog prior to printing. In a partial trust app, /// we can safely perform the necessary asserts to print as long as the /// user said printing was okay. /// [SecurityCritical] private bool _dialogInvoked; private PageRangeSelection _pageRangeSelection; private PageRange _pageRange; private bool _userPageRangeEnabled; private UInt32 _minPage; private UInt32 _maxPage; private double _printableAreaWidth; private double _printableAreaHeight; private bool _isPrintableAreaWidthUpdated; private bool _isPrintableAreaHeightUpdated; #endregion Private data #region Internal classes internal class PrintDlgPrintTicketEventHandler { #region Constructor public PrintDlgPrintTicketEventHandler( PrintTicket printTicket ) { _printTicket = printTicket; } #endregion Constructor #region Public Methods public void SetPrintTicket( Object sender, WritingPrintTicketRequiredEventArgs args ) { if (args.CurrentPrintTicketLevel == PrintTicketLevel.FixedDocumentSequencePrintTicket) { args.CurrentPrintTicket = _printTicket; } } #endregion Public Methods #region Private Data private PrintTicket _printTicket; #endregion Private Data }; #endregion Internal classes } } // File provided for Reference Use Only by Microsoft Corporation (c) 2007. // Copyright (c) Microsoft Corporation. All rights reserved. /*++ Copyright (C) 2004 - 2005 Microsoft Corporation. All rights reserved. Module Name: PrintDialog.cs Abstract: This file contains the implementation of the PrintDialog class and its supporting enums. Author: Robert Anderson (robertan) 9-May-2005 --*/ using System; using System.Collections; using System.Collections.Generic; using System.ComponentModel; using System.Printing; using System.Security; using System.Security.Permissions; using System.Windows; using System.Windows.Controls; using System.Windows.Interop; using System.Windows.Media; using System.Windows.Shapes; using System.Windows.Xps; using System.Xml; using MS.Internal.Printing; using MS.Internal; using System.Windows.Xps.Serialization; using System.Windows.Documents; using System.Windows.Documents.Serialization; // WritingCompletedEventArgs using System.Drawing.Printing; using MS.Internal.PresentationFramework; namespace System.Windows.Controls { ////// This class is used to show a print which will configure a /// user PrintTicket and Printer based on user input. This /// PrintTicket and Printer is then used to perform a print job. /// public class PrintDialog { #region Constructors ////// Instantiates an instance of the Print Dialog. /// ////// Critical: - setting critical data (_printQueue, _printTicket, _dialogInvoked) /// PublicOk: - We are setting these to "known" values of null. There /// is no data exposure here. /// [SecurityCritical] public PrintDialog( ) { _dialogInvoked = false; _printQueue = null; _printTicket = null; _isPrintableAreaWidthUpdated = false; _isPrintableAreaHeightUpdated = false; _pageRangeSelection = PageRangeSelection.AllPages; _minPage = 1; _maxPage = 9999; _userPageRangeEnabled = false; } #endregion Constructors #region Public properties ////// Gets or Sets the PageRangeSelection option for the print dialog. /// public PageRangeSelection PageRangeSelection { get { return _pageRangeSelection; } set { _pageRangeSelection = value; } } ////// Gets or sets a PageRange objects used when the PageRangeSelection /// option is set to UserPages. /// public PageRange PageRange { get { return _pageRange; } set { if ((value.PageTo <= 0) || (value.PageFrom <= 0)) { throw new System.ArgumentException(SR.Get(SRID.PrintDialogInvalidPageRange), "PageRange"); } _pageRange = value; if (_pageRange.PageFrom > _pageRange.PageTo) { int temp = _pageRange.PageFrom; _pageRange.PageFrom = _pageRange.PageTo; _pageRange.PageTo = temp; } } } ////// Gets or a sets a flag to enable/disable the user page range support on /// the print dialog. /// public bool UserPageRangeEnabled { get { return _userPageRangeEnabled; } set { _userPageRangeEnabled = value; } } // the following two properties return non CLS-compliant type UInt32 (bug 1788246) #pragma warning disable 3003 ////// Gets or sets the minimum page number allowed in the page ranges. /// public UInt32 MinPage { get { return _minPage; } set { if (_minPage <= 0) { throw new System.ArgumentException(SR.Get(SRID.PrintDialogZeroNotAllowed, "MinPage")); } _minPage = value; } } ////// Gets or sets the maximum page number allowed in the page ranges. /// public UInt32 MaxPage { get { return _maxPage; } set { if (_maxPage <= 0) { throw new System.ArgumentException(SR.Get(SRID.PrintDialogZeroNotAllowed, "MaxPage")); } _maxPage = value; } } #pragma warning restore 3003 ////// Gets or sets the printer selection. /// ////// Critical: - The getter is critical since it accesses critical data in web application mode. /// - The getter is calling critical code (AcquireDefaultPrintQueue). /// - The setter is critical since it is returning critical data. /// PublicOk: - A demand is made for default printing before returning the print queue. This /// would be the same permission required to get the print queue in the first place. /// - We also demand before setting the print queue object. If they can satisfy the /// the demand then they are safe to print anyways. /// public PrintQueue PrintQueue { [SecurityCritical] get { SecurityHelper.DemandPrintDialogPermissions(); if (_printQueue == null) { _printQueue = AcquireDefaultPrintQueue(); } return _printQueue; } [SecurityCritical] set { SecurityHelper.DemandPrintDialogPermissions(); _printQueue = value; } } ////// Get or sets the current PrintTicket object. /// ////// Critical: - The getter is critical since it accesses critical data. /// - The getter is calling critical code (AcquireDefaultPrintTicket). /// - The setter is critical since it is returning critical data. /// PublicOk: - A demand is made for default printing before returning the print ticket. This /// would be the same permission required to get the print ticket in the first place. /// - We also demand before setting the print ticket object. If they can satisfy the /// the demand then they are safe to print anyways. /// public PrintTicket PrintTicket { [SecurityCritical] get { SecurityHelper.DemandPrintDialogPermissions(); if (_printTicket == null) { _printTicket = AcquireDefaultPrintTicket(this.PrintQueue); } return _printTicket; } [SecurityCritical] set { SecurityHelper.DemandPrintDialogPermissions(); _printTicket = value; } } ////// Get the Width of the area on paper to which the application can print /// public double PrintableAreaWidth { get { if( ((_isPrintableAreaWidthUpdated == false) && (_isPrintableAreaHeightUpdated == false)) || ((_isPrintableAreaWidthUpdated == true) && (_isPrintableAreaHeightUpdated == false))) { _isPrintableAreaWidthUpdated = true; _isPrintableAreaHeightUpdated = false; UpdatePrintableAreaSize(); } return _printableAreaWidth; } } ////// Get the Height of the area on paper to which the application can print /// public double PrintableAreaHeight { get { if( ((_isPrintableAreaWidthUpdated == false) && (_isPrintableAreaHeightUpdated == false)) || ((_isPrintableAreaWidthUpdated == false) && (_isPrintableAreaHeightUpdated == true))) { _isPrintableAreaWidthUpdated = false; _isPrintableAreaHeightUpdated = true; UpdatePrintableAreaSize(); } return _printableAreaHeight; } } #endregion Public properties #region Public methods ////// Pops the dialog up to the user in a modal form. /// ////// Critical: - Accesses and sets critical data. /// PublicOk: - Data is internal to this dialog and can only be retrieved /// by other critical code. No information leaves this method. /// [SecurityCritical] public NullableShowDialog() { // // Reset this flag as we have not displayed the dialog yet. // _dialogInvoked = false; Win32PrintDialog dlg = new Win32PrintDialog(); // // Setup the old values if any exist. // dlg.PrintTicket = _printTicket; dlg.PrintQueue = _printQueue; dlg.MinPage = Math.Max(1, Math.Min(_minPage, _maxPage)); dlg.MaxPage = Math.Max(dlg.MinPage, Math.Max(_minPage, _maxPage)); dlg.PageRangeEnabled = _userPageRangeEnabled; dlg.PageRange = new PageRange( Math.Max((int)dlg.MinPage, _pageRange.PageFrom), Math.Min((int)dlg.MaxPage, _pageRange.PageTo)); dlg.PageRangeSelection = _pageRangeSelection; // // Invoke the Win32 dialog // UInt32 dialogResult = dlg.ShowDialog(); if ((dialogResult == MS.Internal.Printing.NativeMethods.PD_RESULT_APPLY) || (dialogResult == MS.Internal.Printing.NativeMethods.PD_RESULT_PRINT)) { _printTicket = dlg.PrintTicket; _printQueue = dlg.PrintQueue; _pageRange = dlg.PageRange; _pageRangeSelection = dlg.PageRangeSelection; _dialogInvoked = true; } return (dialogResult == MS.Internal.Printing.NativeMethods.PD_RESULT_PRINT); } /// /// Prints a Visual to the currently selected Print Queue. /// /// /// The visual to be printed. /// /// /// Description of the job to be printed. This shows in the Printer UI /// ////// Critical: - Sets a critical data property. /// PublicOk: - The critical data is a flag that needs to be reset for each print /// job to enforce the dialog invocation on every print operation. Without /// this method resetting this flag we would not be honoring the security /// goal of displaying the dialog once per print job. /// [SecurityCritical] public void PrintVisual( Visual visual, String description ) { if (visual == null) { throw new ArgumentNullException("visual"); } XpsDocumentWriter writer = CreateWriter(description); writer.Write(visual); _printableAreaWidth = 0; _printableAreaHeight = 0; _isPrintableAreaWidthUpdated = false; _isPrintableAreaHeightUpdated = false; _dialogInvoked = false; } ////// Prints an DocumentPaginator based document to the currently selected Print Queue. /// /// /// The DocumentPaginator to be printed. /// /// /// Description of the job to be printed. This shows in the Printer UI /// ////// Critical: - Sets a critical data property. /// PublicOk: - The critical data is a flag that needs to be reset for each print /// job to enforce the dialog invocation on every print operation. Without /// this method resetting this flag we would not be honoring the security /// goal of displaying the dialog once per print job. /// [SecurityCritical] public void PrintDocument( DocumentPaginator documentPaginator, String description ) { if (documentPaginator == null) { throw new ArgumentNullException("documentPaginator"); } XpsDocumentWriter writer = CreateWriter(description); writer.Write(documentPaginator); _printableAreaWidth = 0; _printableAreaHeight = 0; _isPrintableAreaWidthUpdated = false; _isPrintableAreaHeightUpdated = false; _dialogInvoked = false; } #endregion Public methods #region Private methods ////// Critical: - Asserts to obtain the default print queue from the local server. /// [SecurityCritical] private PrintQueue AcquireDefaultPrintQueue() { PrintQueue printQueue = null; (new PrintingPermission(PrintingPermissionLevel.DefaultPrinting)).Assert(); //BlessedAssert try { try { LocalPrintServer server = new LocalPrintServer(); printQueue = server.DefaultPrintQueue; } catch (PrintSystemException) { // // It is entirely possible for there to be no "default" printer. In this case, // the printing system throws an exception. We do not want this to propagate // up. Instead, returning null is fine. // printQueue = null; } } finally { PrintingPermission.RevertAssert(); } return printQueue; } ////// Critical: - Asserts to obtain the PrintTicket from the specified PrintQueue /// object or create a blank PrintTicket object (i.e. PrintTicket::ctor). /// [SecurityCritical] private PrintTicket AcquireDefaultPrintTicket( PrintQueue printQueue ) { PrintTicket printTicket = null; (new PrintingPermission(PrintingPermissionLevel.DefaultPrinting)).Assert(); //BlessedAssert try { try { if (printQueue != null) { printTicket = printQueue.UserPrintTicket; if (printTicket == null) { printTicket = printQueue.DefaultPrintTicket; } } } catch (PrintSystemException) { // // The printing subsystem can throw an exception in certain cases when // the print ticket is unavailable. If it does we will handle this // below. There is no real need to bubble this up to the application. // printTicket = null; } } finally { PrintingPermission.RevertAssert(); } // // If the printing subsystem could not give us a print ticket either due to // a failure or because a user/system default was not available, then just // create a blank/empty one. // if (printTicket == null) { printTicket = new PrintTicket(); } return printTicket; } ////// Critical: - Invokes a critical method (PickCorrectPrintingEnvironment). /// TreatAsSafe: - Critical data returned from above method is internal and does /// not leave the scope of this method. It is only used to calculate /// non-critical values. /// [SecurityCritical, SecurityTreatAsSafe] private void UpdatePrintableAreaSize( ) { PrintQueue printQueue = null; PrintTicket printTicket = null; PickCorrectPrintingEnvironment(ref printQueue, ref printTicket); PrintCapabilities printCap = null; if (printQueue != null) { printCap = printQueue.GetPrintCapabilities(printTicket); } // PrintCapabilities OrientedPageMediaWidth/Height are Nullable if ((printCap != null) && (printCap.OrientedPageMediaWidth != null) && (printCap.OrientedPageMediaHeight != null)) { _printableAreaWidth = (double)printCap.OrientedPageMediaWidth; _printableAreaHeight = (double)printCap.OrientedPageMediaHeight; } else { // Initialize page size to portrait Letter size. // This is our fallback if PrintTicket doesn't specify the page size. _printableAreaWidth = 816; _printableAreaHeight = 1056; // PrintTicket's PageMediaSize could be null and PageMediaSize Width/Height are Nullable if ((printTicket.PageMediaSize != null) && (printTicket.PageMediaSize.Width != null) && (printTicket.PageMediaSize.Height != null)) { _printableAreaWidth = (double)printTicket.PageMediaSize.Width; _printableAreaHeight = (double)printTicket.PageMediaSize.Height; } // If we are using PrintTicket's PageMediaSize dimensions to populate the widht/height values, // we need to adjust them based on current orientation. PrintTicket's PageOrientation is Nullable. if (printTicket.PageOrientation != null) { PageOrientation orientation = (PageOrientation)printTicket.PageOrientation; // need to swap width/height in landscape orientation if ((orientation == PageOrientation.Landscape) || (orientation == PageOrientation.ReverseLandscape)) { double t = _printableAreaWidth; _printableAreaWidth = _printableAreaHeight; _printableAreaHeight = t; } } } } ////// Critical: - Asserts for PrintingPermissionLevel.DefaultPrinting /// to be able to use the printQueue to create the /// XpsDocumentWriter. /// TreatAsSafe: - The assert is only done after ensuring that the user /// has conciously made a decision to print by successfully /// dismissing the Print Dialog. This logic of a dialog /// being required is only needed for partial trust applications. /// The logic of checking this criteria is contained within the /// PickCorrectPrintingEnvironment method. /// - The XpsDocumentWriter instance returned from this method /// is not unsafe since the application is either full trust /// or the user chose to print. It is okay for the application /// to use the XpsDocumentWriter to print at this point. /// [SecurityCritical, SecurityTreatAsSafe] private XpsDocumentWriter CreateWriter( String description ) { PrintQueue printQueue = null; PrintTicket printTicket = null; XpsDocumentWriter writer = null; PickCorrectPrintingEnvironment(ref printQueue, ref printTicket); (new PrintingPermission(PrintingPermissionLevel.DefaultPrinting)).Assert(); //BlessedAssert try { if(printQueue != null) { printQueue.CurrentJobSettings.Description = description; } writer = PrintQueue.CreateXpsDocumentWriter(printQueue); PrintDlgPrintTicketEventHandler eventHandler = new PrintDlgPrintTicketEventHandler(printTicket); writer.WritingPrintTicketRequired += new WritingPrintTicketRequiredEventHandler(eventHandler.SetPrintTicket); } finally { PrintingPermission.RevertAssert(); } return writer; } ////// Critical: - Accesses critical data and returns it to the caller. /// - Calls critical code (AcquireDefaultPrintQueue/AcquireDefaultPrintTicket) /// - Detects whether a caller is allowed to acquire this data /// based on a demand. This demand is only performed if the /// dialog was not invoked already. It is fine to return the /// data if the dialog was invoked, however, the data is still /// critical. /// /// NOTE: This method validates that a dialog was invoked prior to returning the /// PrintQueue and PrintTicket for the case of web applications. If the /// dialog was not invoked then an exception is thrown. /// [SecurityCritical] private void PickCorrectPrintingEnvironment( ref PrintQueue printQueue, ref PrintTicket printTicket ) { if (_dialogInvoked == false) { // // If the dialog has not been invoked then the user needs printing permissions. // If the demand succeeds then they can print. If the demand fails, then we // tell them that the print dialog must be displayed first by throwing a dialog // exception. // try { SecurityHelper.DemandPrintDialogPermissions(); } catch (SecurityException) { throw new PrintDialogException(SR.Get(SRID.PartialTrustPrintDialogMustBeInvoked)); } } // // If the default print queue and print ticket have not already // been selected then update them now since we need them. // // NOTE: If this code gets called then we know the dialog has never // been invoked but the above demand was satisfied. In this // case we want to just pickup the user defaults. // if (_printQueue == null) { _printQueue = AcquireDefaultPrintQueue(); } if (_printTicket == null) { _printTicket = AcquireDefaultPrintTicket(_printQueue); } // // We should have valid print queue and print ticket objects to // return now. As a note, a null PrintQueue is valid for this // since the dialog will automatically pick up the user default // printer for us. // printQueue = _printQueue; printTicket = _printTicket; } #endregion Private methods #region Private data ////// The PrintTicket is critical and not obtainable from a partial /// trust application unless they can satisfy a printing permission /// demand. /// [SecurityCritical] private PrintTicket _printTicket; ////// The PrintQueue is critical and not obtainable from a partial /// trust application unless they can satisfy a printing permission /// demand. /// [SecurityCritical] private PrintQueue _printQueue; ////// This variable is used to determine whether a user actually invoked /// and dismissed the dialog prior to printing. In a partial trust app, /// we can safely perform the necessary asserts to print as long as the /// user said printing was okay. /// [SecurityCritical] private bool _dialogInvoked; private PageRangeSelection _pageRangeSelection; private PageRange _pageRange; private bool _userPageRangeEnabled; private UInt32 _minPage; private UInt32 _maxPage; private double _printableAreaWidth; private double _printableAreaHeight; private bool _isPrintableAreaWidthUpdated; private bool _isPrintableAreaHeightUpdated; #endregion Private data #region Internal classes internal class PrintDlgPrintTicketEventHandler { #region Constructor public PrintDlgPrintTicketEventHandler( PrintTicket printTicket ) { _printTicket = printTicket; } #endregion Constructor #region Public Methods public void SetPrintTicket( Object sender, WritingPrintTicketRequiredEventArgs args ) { if (args.CurrentPrintTicketLevel == PrintTicketLevel.FixedDocumentSequencePrintTicket) { args.CurrentPrintTicket = _printTicket; } } #endregion Public Methods #region Private Data private PrintTicket _printTicket; #endregion Private Data }; #endregion Internal classes } } // File provided for Reference Use Only by Microsoft Corporation (c) 2007. // Copyright (c) Microsoft Corporation. All rights reserved.
Link Menu
This book is available now!
Buy at Amazon US or
Buy at Amazon UK
- DelegatingHeader.cs
- FileLevelControlBuilderAttribute.cs
- RMPublishingDialog.cs
- ButtonChrome.cs
- LineUtil.cs
- SecurityContextKeyIdentifierClause.cs
- EventMappingSettings.cs
- Repeater.cs
- uribuilder.cs
- WebPartRestoreVerb.cs
- CreateUserWizardStep.cs
- NameNode.cs
- ButtonField.cs
- EditorZoneBase.cs
- UrlPropertyAttribute.cs
- COM2TypeInfoProcessor.cs
- DllHostInitializer.cs
- HelpInfo.cs
- Pen.cs
- Utils.cs
- ColumnHeaderCollectionEditor.cs
- WindowsGraphics.cs
- OracleConnection.cs
- HtmlHead.cs
- UnderstoodHeaders.cs
- DefaultTextStore.cs
- Triplet.cs
- TextTreeInsertElementUndoUnit.cs
- SafeWaitHandle.cs
- DataMemberConverter.cs
- DataObjectCopyingEventArgs.cs
- AssertSection.cs
- HWStack.cs
- TablePatternIdentifiers.cs
- TypeLibConverter.cs
- MetadataCache.cs
- SelectionChangedEventArgs.cs
- ControlAdapter.cs
- ThreadPoolTaskScheduler.cs
- ProfileService.cs
- Formatter.cs
- DupHandleConnectionReader.cs
- RtfControls.cs
- HttpProcessUtility.cs
- CommandEventArgs.cs
- ZipIOExtraFieldZip64Element.cs
- XmlCharCheckingReader.cs
- DataSourceHelper.cs
- ResourceExpression.cs
- BroadcastEventHelper.cs
- SqlNodeAnnotation.cs
- MatchingStyle.cs
- ExpandedWrapper.cs
- XmlSortKeyAccumulator.cs
- UrlPath.cs
- SocketAddress.cs
- UriSchemeKeyedCollection.cs
- UpdateException.cs
- BamlStream.cs
- WebPartChrome.cs
- ExpressionVisitor.cs
- Match.cs
- SystemBrushes.cs
- ArglessEventHandlerProxy.cs
- Preprocessor.cs
- EventKeyword.cs
- BitmapEffectCollection.cs
- ClientUtils.cs
- WebEvents.cs
- ScriptBehaviorDescriptor.cs
- EdmComplexPropertyAttribute.cs
- XmlEntityReference.cs
- FragmentNavigationEventArgs.cs
- XmlAnyElementAttributes.cs
- GridView.cs
- CurrentTimeZone.cs
- BaseValidator.cs
- CodeTryCatchFinallyStatement.cs
- SerialStream.cs
- DataGridCaption.cs
- XpsS0ValidatingLoader.cs
- InProcStateClientManager.cs
- XmlEntity.cs
- DummyDataSource.cs
- CharStorage.cs
- Visitor.cs
- ToolStripContentPanel.cs
- FormViewModeEventArgs.cs
- QuaternionAnimationBase.cs
- PropertyStore.cs
- Matrix3DValueSerializer.cs
- ProjectionNode.cs
- GridViewSortEventArgs.cs
- UnsafeNativeMethods.cs
- EdmSchemaAttribute.cs
- TextElement.cs
- SessionStateUtil.cs
- ApplicationDirectory.cs
- ExpressionEditorAttribute.cs
- TextSpanModifier.cs