Example #1
0
        /// <summary>
        /// Merges delta PrintTicket with base PrintTicket and then validates the merged PrintTicket.
        /// </summary>
        /// <param name="basePrintTicket">The MemoryStream that contains base XML PrintTicket.</param>
        /// <param name="deltaPrintTicket">The MemoryStream that contains delta XML PrintTicket.</param>
        /// <param name="scope">scope that delta PrintTicket and result PrintTicket will be limited to</param>
        /// <param name="conflictStatus">The returned conflict resolving status.</param>
        /// <returns>MemoryStream that contains validated and merged PrintTicket XML.</returns>
        /// <exception cref="ObjectDisposedException">
        /// The PTProvider instance has already been disposed.
        /// </exception>
        /// <exception cref="ArgumentException">
        /// The base PrintTicket specified by <paramref name="basePrintTicket"/> is not well-formed,
        /// or delta PrintTicket specified by <paramref name="deltaPrintTicket"/> is not well-formed.
        /// </exception>
        /// <exception cref="PrintQueueException">
        /// The PTProvider instance failed to merge and validate the input PrintTicket(s).
        /// </exception>
        public override MemoryStream MergeAndValidatePrintTicket(MemoryStream basePrintTicket,
                                                                 MemoryStream deltaPrintTicket,
                                                                 PrintTicketScope scope,
                                                                 out ConflictStatus conflictStatus)
        {
            VerifyAccess();

            DevModeFields supportedFields = DevModeFields.All;
            DevMode       defaultDevMode  = GetDEVMODE(BaseDevModeType.PrinterDefault);

            InternalPrintTicket baseTicket  = (basePrintTicket != null) ? new InternalPrintTicket(basePrintTicket) : null;
            DevMode             baseDevMode = defaultDevMode.Clone();

            PrintTicketToDevMode(baseDevMode, baseTicket, scope, supportedFields);

            InternalPrintTicket deltaTicket  = (deltaPrintTicket != null) ? new InternalPrintTicket(deltaPrintTicket) : null;
            DevMode             deltaDevMode = defaultDevMode.Clone();

            PrintTicketToDevMode(deltaDevMode, deltaTicket, scope, supportedFields);

            // DevMode Merge - Copy fields set in baseDevMode but not set in deltaDevMode
            deltaDevMode.Copy(baseDevMode, baseDevMode.Fields & (~deltaDevMode.Fields));

            conflictStatus = Validate(deltaDevMode) ? ConflictStatus.NoConflict : ConflictStatus.ConflictResolved;

            InternalPrintTicket validatedTicket = DevModeToPrintTicket(deltaDevMode, scope, supportedFields);

            return(validatedTicket.XmlStream);
        }
Example #2
0
        /// <summary>
        /// Converts the given PrintTicket into Win32 DEVMODE.
        /// </summary>
        /// <param name="printTicket">MemoryStream containing the XML PrintTicket.</param>
        /// <param name="baseType">Type of default DEVMODE to use as base of conversion.</param>
        /// <param name="scope">scope that the input PrintTicket will be limited to</param>
        /// <returns>Byte buffer that contains the converted Win32 DEVMODE.</returns>
        /// <exception cref="ObjectDisposedException">
        /// The PTProvider instance has already been disposed.
        /// </exception>
        /// <exception cref="ArgumentException">
        /// The PrintTicket specified by <paramref name="printTicket"/> is not well-formed.
        /// </exception>
        /// <exception cref="PrintQueueException">
        /// The PTProvider instance failed to convert the PrintTicket to a DEVMODE.
        /// </exception>
        public override byte[] ConvertPrintTicketToDevMode(MemoryStream printTicket,
                                                           BaseDevModeType baseType,
                                                           PrintTicketScope scope)
        {
            VerifyAccess();

            InternalPrintTicket ticket = (printTicket != null) ? new InternalPrintTicket(printTicket) : null;

            DevMode result = GetDEVMODE(baseType);

            DevModeFields supportedFields;
            WinSpoolPrinterCapabilities capabilities = GetCapabilities(result);

            try
            {
                supportedFields = capabilities.Fields;
            }
            finally
            {
                capabilities.Release();
            }

            PrintTicketToDevMode(result, ticket, scope, supportedFields);

            return(result.ByteData);
        }
Example #3
0
        /// <summary>
        /// Copies DevMode fields
        /// </summary>
        /// <param name="src">Source DevMode to copy from</param>
        /// <param name="fields">Fields to copy</param>
        public void Copy(DevMode src, DevModeFields fields)
        {
            if (src == null)
            {
                return;
            }

            Copy(DevModeFields.DM_ORIENTATION, fields, src.Orientation, (DevModeOrientation value) => this.Orientation = value);
            Copy(DevModeFields.DM_PAPERSIZE, fields, src.PaperSize, (short value) => this.PaperSize       = value);
            Copy(DevModeFields.DM_PAPERLENGTH, fields, src.PaperLength, (short value) => this.PaperLength = value);
            Copy(DevModeFields.DM_PAPERWIDTH, fields, src.PaperWidth, (short value) => this.PaperWidth    = value);
            Copy(DevModeFields.DM_SCALE, fields, src.Scale, (short value) => this.Scale    = value);
            Copy(DevModeFields.DM_COPIES, fields, src.Copies, (short value) => this.Copies = value);
            Copy(DevModeFields.DM_DEFAULTSOURCE, fields, src.DefaultSource, (short value) => this.DefaultSource = value);
            Copy(DevModeFields.DM_PRINTQUALITY, fields, src.PrintQuality, (short value) => this.PrintQuality    = value);
            Copy(DevModeFields.DM_COLOR, fields, src.Color, (DevModeColor value) => this.Color                   = value);
            Copy(DevModeFields.DM_DUPLEX, fields, src.Duplex, (DevModeDuplex value) => this.Duplex               = value);
            Copy(DevModeFields.DM_YRESOLUTION, fields, src.YResolution, (short value) => this.YResolution        = value);
            Copy(DevModeFields.DM_TTOPTION, fields, src.TTOption, (DevModeTrueTypeOption value) => this.TTOption = value);
            Copy(DevModeFields.DM_COLLATE, fields, src.Collate, (DevModeCollate value) => this.Collate           = value);
            Copy(DevModeFields.DM_FORMNAME, fields, src.FormName, (string value) => this.FormName                = value);
            Copy(DevModeFields.DM_NUP, fields, src.Nup, (DevModeNUp value) => this.Nup = value);
            Copy(DevModeFields.DM_ICMMETHOD, fields, src.ICMMethod, (DevModeICMMethod value) => this.ICMMethod = value);
            Copy(DevModeFields.DM_ICMINTENT, fields, src.ICMIntent, (uint value) => this.ICMIntent             = value);
            Copy(DevModeFields.DM_MEDIATYPE, fields, src.MediaType, (uint value) => this.MediaType             = value);
            Copy(DevModeFields.DM_DITHERTYPE, fields, src.DitherType, (uint value) => this.DitherType          = value);
        }
Example #4
0
        private InternalPrintTicket DevModeToPrintTicket(DevMode devmode, PrintTicketScope scope, DevModeFields supportedFields)
        {
            InternalPrintTicket resultTicket = new InternalPrintTicket();

            PrintSchemaShim.TryEmbedDevMode(resultTicket, this.OemDriverNamespace, devmode);
            PrintSchemaShim.CopyDevModeToTicket(resultTicket, devmode, scope, supportedFields);
            return(resultTicket);
        }
Example #5
0
        public bool CompatibleCopy(DevMode ticketDevMode)
        {
            if (DevMode.AreCompatible(this, ticketDevMode))
            {
                Array.Copy(ticketDevMode.ByteData, this.dmFieldsByteOffset, this.ByteData, this.dmFieldsByteOffset, this.ByteData.Length - this.dmFieldsByteOffset);
                return(true);
            }

            return(false);
        }
Example #6
0
        private bool Validate(DevMode devMode)
        {
            bool settingsChanged = false;

            // Create a copy of the devmode before validating... if anything
            // changes, then we'll report it
            DevMode originalDevMode = devMode.Clone();

            // Validate the DEVMODE via a call to the driver.
            SetDocumentProperties(devMode.ByteData, true);

            // Compare the devmods to decide whether any features
            // changed.  Ignore changes in the DM_FORMNAME field
            // because the shim may clear it in selecting a paper size.

            // If other paper size fields are set in the DEVMODE, ignore the form field
            // because some driver change set / clear the form field during DocumentProperties
            // without actually changing the selected paper size.
            if (originalDevMode.IsAnyFieldSet(DevModeFields.DM_PAPERWIDTH | DevModeFields.DM_PAPERLENGTH | DevModeFields.DM_PAPERSIZE))
            {
                originalDevMode.Fields  &= ~DevModeFields.DM_FORMNAME;
                originalDevMode.Fields  |= devMode.Fields & DevModeFields.DM_FORMNAME;
                originalDevMode.FormName = devMode.FormName;
            }

            // Ignore device name in the original DEVMODE.  Copy the full buffer so that any extra
            // garbage in the device name after the string also matches.  The device name isn't actually
            // a setting per-se.  Version changes should be noted, because the same content may mean different
            // things in different versions of a driver.
            originalDevMode.DeviceName = devMode.DeviceName;

            // Do the actual comparison.  Note that if there are issues in the private DEVMODE similar
            // to the issues fixed up in the public DEVMODE, there may be false positive return values
            // from this API.  There's no way to fix this issue.
            for (int i = 0; i < originalDevMode.ByteData.Length; i++)
            {
                if (originalDevMode.ByteData[i] != devMode.ByteData[i])
                {
                    settingsChanged = true;
                }
            }

            WinSpoolPrinterCapabilities capabilities = GetCapabilities(null);

            try
            {
                PrintSchemaShim.PruneFeatures(devMode, capabilities);
            }
            finally
            {
                capabilities.Release();
            }

            return(settingsChanged);
        }
        /// <summary>
        /// Get the default paper width and height
        /// </summary>
        /// <param name="defaultDevMode">devMode that contains the code for the default paper size</param>
        /// <param name="mediaSizeCodes">List of supported paperSizeCodes</param>
        /// <param name="mediaSizes">List of supported paperSize widths and heights</param>
        /// <param name="defaultPaperSize">Out parameter that recieves the default paper width and height</param>
        /// <returns>True if the call succeded</returns>
        public bool GetDefaultPaperSize(DevMode defaultDevMode, IList <short> paperSizeCodes, IList <DC_PAPER_SIZE> paperSizes, out DC_PAPER_SIZE defaultPaperSize)
        {
            defaultPaperSize = new DC_PAPER_SIZE();

            if (defaultDevMode == null)
            {
                if (paperSizes.Count > 0)
                {
                    defaultPaperSize = paperSizes[0];
                    return(true);
                }

                return(false);
            }
            else
            {
                bool hasWidth = false;
                hasWidth = defaultDevMode.IsFieldSet(DevModeFields.DM_PAPERWIDTH);
                if (hasWidth)
                {
                    defaultPaperSize.Width = defaultDevMode.PaperWidth;
                }

                bool hasHeight = false;
                hasHeight = defaultDevMode.IsFieldSet(DevModeFields.DM_PAPERWIDTH);
                if (hasHeight)
                {
                    defaultPaperSize.Height = defaultDevMode.PaperLength;
                }

                if (!hasWidth || !hasHeight)
                {
                    if (defaultDevMode.IsFieldSet(DevModeFields.DM_PAPERSIZE))
                    {
                        int defaultPaperSizeIndex = paperSizeCodes.IndexOf(defaultDevMode.PaperSize);
                        if (0 <= defaultPaperSizeIndex && defaultPaperSizeIndex < paperSizes.Count)
                        {
                            if (!hasWidth)
                            {
                                defaultPaperSize.Width = paperSizes[defaultPaperSizeIndex].Width;
                            }

                            if (!hasHeight)
                            {
                                defaultPaperSize.Height = paperSizes[defaultPaperSizeIndex].Height;
                            }

                            hasWidth = hasHeight = true;
                        }
                    }
                }

                return(hasWidth && hasHeight);
            }
        }
Example #8
0
        /// <summary>
        /// Tests to see if two DEVMODEs were obtained from or apply to the same device
        /// </summary>
        /// <param name="a">DEVMODE to compare</param>
        /// <param name="b">DEVMODE to compare</param>
        /// <returns>True if both DEVMODE were obtained or apply to the same device</returns>
        public static bool AreCompatible(DevMode a, DevMode b)
        {
            if (a == null || b == null)
            {
                return(false);
            }

            return((a.DriverVersion == b.DriverVersion) &&
                   (a.SpecVersion == b.SpecVersion) &&
                   (a.Size == b.Size) &&
                   (a.DriverExtra == b.DriverExtra));
        }
Example #9
0
        public DevMode Clone()
        {
            DevMode result = new DevMode();

            if (this._byteData != null)
            {
                result._byteData = (byte[])this._byteData.Clone();
            }

            result._isDevModeW = this._isDevModeW;

            return(result);
        }
Example #10
0
        private void PrintTicketToDevMode(DevMode devMode, InternalPrintTicket ticket, PrintTicketScope scope, DevModeFields supportedFields)
        {
            if (ticket != null)
            {
                // Apply the DEVMODE snapshot from the print ticket to our starting DEVMODE, if supported.
                DevMode ticketDevMode = PrintSchemaShim.TryGetEmbeddedDevMode(ticket, this.OemDriverNamespace);
                if (ticketDevMode != null)
                {
                    devMode.CompatibleCopy(ticketDevMode);
                }

                PrintSchemaShim.CopyTicketToDevMode(devMode, ticket, scope, supportedFields);
            }
        }
Example #11
0
            /// <summary>
            /// A callback that copies PRINTER_INFO_8_AND_9 fields from an unmanaged buffer
            /// </summary>
            public void Callback(HGlobalBuffer pPrinterBuffer)
            {
                // PRINTER_INFO_8 layout from http://msdn.microsoft.com/en-us/library/dd162851(VS.85).aspx
                //
                // typedef struct _PRINTER_INFO_8 {
                //  LPDEVMODE pDevMode;
                // } PRINTER_INFO_8, *PPRINTER_INFO_8;
                //
                // PRINTER_INFO_9 layout from http://msdn.microsoft.com/en-us/library/dd162852(VS.85).aspx
                //
                // typedef struct _PRINTER_INFO_9 {
                //  LPDEVMODE pDevMode;
                // } PRINTER_INFO_9, *PPRINTER_INFO_9;

                //  LPDEVMODE pDevMode;

                PRINTER_INFO_8_AND_9 = new PRINTER_INFO_8_AND_9();

                bool shouldRelease = false;

                pPrinterBuffer.Handle.DangerousAddRef(ref shouldRelease);
                try
                {
                    IntPtr pDevMode = Marshal.ReadIntPtr(pPrinterBuffer.Handle.DangerousGetHandle());
                    if (pDevMode != IntPtr.Zero)
                    {
                        PRINTER_INFO_8_AND_9.pDevMode = DevMode.FromIntPtr(pDevMode);
                    }
                }
                finally
                {
                    if (shouldRelease)
                    {
                        pPrinterBuffer.Handle.DangerousRelease();
                    }
                }
            }
Example #12
0
            /// <summary>
            /// A callback that copies PRINTER_INFO_2 fields from an unmanaged buffer
            /// </summary>
            public void Callback(HGlobalBuffer pPrinterBuffer)
            {
                // PRINTER_INFO_2 layout from http://msdn.microsoft.com/en-us/library/dd162845(VS.85).aspx
                //
                //typedef struct _PRINTER_INFO_2 {
                //   LPTSTR               pServerName;
                //   LPTSTR               pPrinterName;
                //   LPTSTR               pShareName;
                //   LPTSTR               pPortName;
                //   LPTSTR               pDriverName;
                //   LPTSTR               pComment;
                //   LPTSTR               pLocation;
                //   LPDEVMODE            pDevMode;
                //   LPTSTR               pSepFile;
                //   LPTSTR               pPrintProcessor;
                //   LPTSTR               pDatatype;
                //   LPTSTR               pParameters;
                //   PSECURITY_DESCRIPTOR pSecurityDescriptor;
                //   DWORD                Attributes;
                //   DWORD                Priority;
                //   DWORD                DefaultPriority;
                //   DWORD                StartTime;
                //   DWORD                UntilTime;
                //   DWORD                Status;
                //   DWORD                cJobs;
                //   DWORD                AveragePPM;
                // } PRINTER_INFO_2, *PPRINTER_INFO_2;


                PRINTER_INFO_2 = new PRINTER_INFO_2();

                bool shouldRelease = false;

                pPrinterBuffer.Handle.DangerousAddRef(ref shouldRelease);
                try
                {
                    IntPtr ptr = pPrinterBuffer.Handle.DangerousGetHandle();

                    //   LPTSTR               pPrinterName;
                    IntPtr pPrinterName = Marshal.ReadIntPtr(ptr, 1 * Marshal.SizeOf(typeof(IntPtr)));
                    if (pPrinterName != IntPtr.Zero)
                    {
                        PRINTER_INFO_2.pPrinterName = Marshal.PtrToStringUni(pPrinterName);
                    }

                    //   LPTSTR               pPortName;
                    IntPtr pPortName = Marshal.ReadIntPtr(ptr, 3 * Marshal.SizeOf(typeof(IntPtr)));
                    if (pPortName != IntPtr.Zero)
                    {
                        PRINTER_INFO_2.pPortName = Marshal.PtrToStringUni(pPortName);
                    }

                    //   LPTSTR               pDriverName;
                    IntPtr pDriverName = Marshal.ReadIntPtr(ptr, 4 * Marshal.SizeOf(typeof(IntPtr)));
                    if (pDriverName != IntPtr.Zero)
                    {
                        PRINTER_INFO_2.pDriverName = Marshal.PtrToStringUni(pDriverName);
                    }

                    //   LPDEVMODE            pDevMode;
                    IntPtr pDevMode = Marshal.ReadIntPtr(ptr, 7 * Marshal.SizeOf(typeof(IntPtr)));
                    if (pDevMode != IntPtr.Zero)
                    {
                        PRINTER_INFO_2.pDevMode = DevMode.FromIntPtr(pDevMode);
                    }
                }
                finally
                {
                    if (shouldRelease)
                    {
                        pPrinterBuffer.Handle.DangerousRelease();
                    }
                }
            }
Example #13
0
 private WinSpoolPrinterCapabilities GetCapabilities(DevMode devMode)
 {
     return(new WinSpoolPrinterCapabilities(this._deviceName, this._driverName, this._portName, devMode));
 }
Example #14
0
        /// <summary>
        /// Gets the PrintCapabilities relative to the given PrintTicket.
        /// </summary>
        /// <param name="printTicket">The stream that contains XML PrintTicket based on which PrintCapabilities should be built.</param>
        /// <returns>Stream that contains XML PrintCapabilities.</returns>
        /// <exception cref="ObjectDisposedException">
        /// The PTProvider instance has already been disposed.
        /// </exception>
        /// <exception cref="ArgumentException">
        /// The input PrintTicket specified by <paramref name="printTicket"/> is not well-formed.
        /// </exception>
        /// <exception cref="PrintQueueException">
        /// The PTProvider instance failed to retrieve the PrintCapabilities.
        /// </exception>
        public override MemoryStream GetPrintCapabilities(MemoryStream printTicket)
        {
            VerifyAccess();

            InternalPrintTicket internalTicket = null;

            try
            {
                internalTicket = (printTicket != null) ? new InternalPrintTicket(printTicket) : null;
            }
            catch (XmlException xmlException)
            {
                throw new ArgumentException(
                          String.Format(
                              CultureInfo.CurrentCulture,
                              "{0} {1} {2}",
                              PrintSchemaTags.Framework.PrintTicketRoot,
                              PTUtility.GetTextFromResource("FormatException.XMLNotWellFormed"),
                              xmlException.Message),
                          "printTicket",
                          xmlException);
            }

            DevMode defaultDevMode = GetDEVMODE(BaseDevModeType.UserDefault);
            DevMode devMode        = defaultDevMode.Clone();

            PrintTicketToDevMode(devMode, internalTicket, PrintTicketScope.JobScope, DevModeFields.All);

            MemoryStream capabilitiesStream = new MemoryStream();

            WinSpoolPrinterCapabilities capabilities = GetCapabilities(devMode);

            try
            {
                PrintCapabilitiesWriter writer = new PrintCapabilitiesWriter(capabilitiesStream, "ns0000", this.OemDriverNamespace, false);
                try
                {
                    writer.WriteStartDocument();
                    {
                        writer.WritePageDevmodeSnapshot(devMode.ByteData);

                        if (capabilities.HasICMIntent)
                        {
                            writer.WritePageICMRenderingIntentFeature();
                        }

                        if (capabilities.HasICMMethod)
                        {
                            writer.WritePageColorManagementFeature();
                        }

                        if (capabilities.CanCollate)
                        {
                            writer.WriteDocumentCollateFeature();
                        }

                        int minCopies = capabilities.MinCopies;
                        int maxCopies = capabilities.MaxCopies;

                        int defaultCopies = minCopies;
                        defaultCopies = Math.Max(minCopies, Math.Min(defaultDevMode.Copies, maxCopies));

                        writer.WriteJobCopiesAllDocumentsParameterDef(minCopies, maxCopies, defaultCopies);

                        writer.WriteJobNUpAllDocumentsContiguously(capabilities.NUp);

                        writer.WriteJobDuplexAllDocumentsContiguouslyFeature(capabilities.CanDuplex);

                        if (capabilities.CanScale)
                        {
                            writer.WritePageScalingFeature(1, 1000, 100);
                        }

                        writer.WritePageMediaSizeFeature(
                            capabilities.Papers,
                            capabilities.PaperNames,
                            PrintSchemaShim.TenthOfMillimeterToMicrons(capabilities.PaperSizes)
                            );

                        writer.WritePageResolutionFeature(capabilities.Resolutions);

                        int logicalPixelsX, logicalPixelsY;
                        int physicalWidth, physicalHeight;
                        int physicalOffsetX, physicalOffsetY;
                        int horizontalResolution, verticalResolution;

                        bool gotDevCaps = capabilities.TryGetDeviceCapabilities(
                            out logicalPixelsX, out logicalPixelsY,
                            out physicalWidth, out physicalHeight,
                            out physicalOffsetX, out physicalOffsetY,
                            out horizontalResolution, out verticalResolution);

                        if (gotDevCaps && logicalPixelsX > 0 && logicalPixelsY > 0)
                        {
                            int imageableSizeWidth  = PrintSchemaShim.DpiToMicrons(physicalWidth, logicalPixelsX);
                            int imageableSizeHeight = PrintSchemaShim.DpiToMicrons(physicalHeight, logicalPixelsY);
                            int originWidth         = PrintSchemaShim.DpiToMicrons(physicalOffsetX, logicalPixelsY);
                            int originHeight        = PrintSchemaShim.DpiToMicrons(physicalOffsetY, logicalPixelsY);
                            int extentWidth         = PrintSchemaShim.DpiToMicrons(horizontalResolution, logicalPixelsY);
                            int extentHeight        = PrintSchemaShim.DpiToMicrons(verticalResolution, logicalPixelsY);

                            writer.WritePageImageableSizeProperty(
                                imageableSizeWidth, imageableSizeHeight,
                                originWidth, originHeight,
                                extentWidth, extentHeight);
                        }

                        writer.WritePageOrientationFeature(capabilities.LandscapeOrientation);

                        writer.WritePageOutputColorFeature(capabilities.HasColor);

                        writer.WriteJobInputBinFeature(capabilities.Bins, capabilities.BinNames);

                        writer.WritePageMediaTypeFeature(capabilities.MediaTypes, capabilities.MediaTypeNames);

                        if (capabilities.TrueType)
                        {
                            writer.WritePageTrueTypeFontModeFeature();

                            writer.WritePageDeviceFontSubstitutionFeature();
                        }
                    }
                    writer.WriteEndDocument();
                }
                finally
                {
                    writer.Release();
                    writer = null;
                }
            }
            finally
            {
                capabilities.Release();
                capabilities = null;
            }

            // calls Security Critical Dispose on a private resource
            capabilitiesStream.Position = 0;

            return(capabilitiesStream);
        }
 public WinSpoolPrinterCapabilities(string deviceName, string driverName, string portName, DevMode devMode)
 {
     this._deviceName = deviceName;
     this._driverName = driverName;
     this._portName   = portName;
     if (devMode != null)
     {
         SafeMemoryHandle buffer = SafeMemoryHandle.Create(devMode.ByteData.Length);
         buffer.CopyFromArray(devMode.ByteData, 0, devMode.ByteData.Length);
         this._devMode = buffer;
     }
     else
     {
         this._devMode = SafeMemoryHandle.Null;
     }
 }