Beispiel #1
0
        /// <summary>
        /// Add namespace declaration for the specified namespace URI.
        /// </summary>
        /// <exception cref="FormatException">
        /// Unable to add standard namespace declaration at root element.
        /// </exception>
        public static string AddStdNamespaceDeclaration(XmlElement root, string prefix_header, string nsURI)
        {
            int    limit = 1000; // hard-coded upper limit for namespace prefix string look up
            int    index;
            string prefix = null;

            // We need to find a prefix string that doesn't conflict with any prefixes already used.
            for (index = 0; index < limit; index++)
            {
                // the new prefix is in the format like: "psk0000" "xsi0001" "xsd0100"
                prefix = prefix_header + index.ToString(CultureInfo.InvariantCulture).PadLeft(4, '0');

                if (root.Attributes["xmlns:" + prefix] == null)
                {
                    root.SetAttribute("xmlns:" + prefix, nsURI);
                    break;
                }
            }

            if (index >= limit)
            {
                throw NewPTFormatException(String.Format(CultureInfo.CurrentCulture,
                                                         PTUtility.GetTextFromResource("FormatException.AddXmlnsFailAtRootElement")));
            }

            return(prefix);
        }
 /// <summary>
 /// Returns a new FormatException instance for not-well-formed PrintCapabilities XML.
 /// </summary>
 /// <param name="detailMsg">detailed message about the violation of well-formness</param>
 /// <param name="innerException">the exception that causes the violation of well-formness</param>
 /// <returns>the new FormatException instance</returns>
 internal static FormatException NewPrintCapFormatException(string detailMsg, Exception innerException)
 {
     return(new FormatException(String.Format(CultureInfo.CurrentCulture,
                                              "{0} {1} {2}",
                                              PrintSchemaTags.Framework.PrintCapRoot,
                                              PTUtility.GetTextFromResource("FormatException.XMLNotWellFormed"),
                                              detailMsg),
                                innerException));
 }
        /// <summary>
        /// Gets current Property/ScoredProperty's ParameterRef name from its "ParameterRef" child-element.
        /// The returned ParameterRef name is guaranteed to be in the standard keyword set namespace.
        /// </summary>
        /// <exception cref="FormatException">either can't find the child-element or its name is private</exception>
        /// <exception cref="XmlException">XML is not well-formed.</exception>
        public string GetCurrentPropertyParamRefNameWithException()
        {
            if (!MoveToNextSchemaElement(CurrentElementDepth + 1, PrintSchemaNodeTypes.ParameterRef))
            {
                throw NewPrintCapFormatException(String.Format(CultureInfo.CurrentCulture,
                                                               PTUtility.GetTextFromResource("FormatException.MissingRequiredChildElement"),
                                                               PrintSchemaTags.Framework.ParameterRef,
                                                               _xmlReader.LineNumber,
                                                               _xmlReader.LinePosition));
            }

            return(CurrentElementNameAttrValue);
        }
Beispiel #4
0
        /// <summary>
        /// Creates a COM stream over HGlobal allocated memory
        /// </summary>
        /// <param name="hGlobal">HGlobal to create stream over, IntPtr.Zero to auto allocate memory</param>
        /// <param name="fDeleteOnRelease">Delete the allocated memory when the stream is released</param>
        /// <param name="ppstm">Created Stream</param>
        /// <returns>HRESULT</returns>
        private static IStream CreateStreamOnHGlobal()
        {
            IStream result;

            uint hResult = UnsafeNativeMethods.CreateStreamOnHGlobal(SafeMemoryHandle.Wrap(IntPtr.Zero), true, out result);

            if (!PTUtility.IsSuccessCode(hResult))
            {
                Marshal.ThrowExceptionForHR((int)hResult);
            }

            return(result);
        }
        /// <summary>
        /// Gets current Property/ScoredProperty's full text value from its "Value" child-element.
        /// </summary>
        /// <exception cref="FormatException">can't find the value</exception>
        /// <exception cref="XmlException">XML is not well-formed.</exception>
        public string GetCurrentPropertyFullValueWithException()
        {
            // No need to loop here. We just need to look for the first <Value> child-element
            if (!MoveToNextSchemaElement(CurrentElementDepth + 1, PrintSchemaNodeTypes.Value))
            {
                throw NewPrintCapFormatException(String.Format(CultureInfo.CurrentCulture,
                                                               PTUtility.GetTextFromResource("FormatException.MissingRequiredChildElement"),
                                                               PrintSchemaTags.Framework.Value,
                                                               _xmlReader.LineNumber,
                                                               _xmlReader.LinePosition));
            }

            return(CurrentElementTextValue);
        }
Beispiel #6
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>
        /// <exception cref="PrintingNotSupportedException">
        /// Printing components are not installed on the client
        /// </exception>
        public override MemoryStream GetPrintCapabilities(MemoryStream printTicket)
        {
            VerifyAccess();

            IStream printCapabilitiesStream = CreateStreamOnHGlobal();

            try
            {
                IStream printTicketStream = IStreamFromMemoryStream(printTicket);
                try
                {
                    string errorMsg;
                    // What happens if the native code returns a iStreamLength that is too long?
                    // One option is we trust providers and don't do run-time check.
                    uint hResult = UnsafeNativeMethods.PTGetPrintCapabilities(_providerHandle, printTicketStream, printCapabilitiesStream, out errorMsg);
                    if (PTUtility.IsSuccessCode(hResult))
                    {
                        RewindIStream(printCapabilitiesStream);
                        return(MemoryStreamFromIStream(printCapabilitiesStream));
                    }

                    if (hResult == (uint)NativeErrorCode.E_PRINTTICKET_FORMAT)
                    {
                        throw new ArgumentException(String.Format(CultureInfo.CurrentCulture,
                                                                  "{0} {1} {2}",
                                                                  PrintSchemaTags.Framework.PrintTicketRoot,
                                                                  PTUtility.GetTextFromResource("FormatException.XMLNotWellFormed"),
                                                                  errorMsg),
                                                    "printTicket");
                    }
                    else
                    {
                        throw new PrintQueueException((int)hResult,
                                                      "PrintConfig.Provider.GetPrintCapFail",
                                                      _deviceName,
                                                      errorMsg);
                    }
                }
                finally
                {
                    DeleteIStream(ref printTicketStream);
                }
            }
            finally
            {
                DeleteIStream(ref printCapabilitiesStream);
            }
        }
 /// <summary>
 /// Post-process states populated by the builder and populate aggregates states
 /// </summary>
 /// <exception cref="FormatException">thrown if XML PrintCapabilities is not well-formed</exception>
 private void PostBuildProcessing()
 {
     for (int i = 0; i < _countLocalParamDefs; i++)
     {
         if (_baLocalParamRequired[i])
         {
             // If a parameter definition has be referenced, then the parameter definition must be present in the XML.
             if (_pcLocalParamDefs[i] == null)
             {
                 throw NewPrintCapFormatException(String.Format(CultureInfo.CurrentCulture,
                                                                PTUtility.GetTextFromResource("FormatException.ParameterDefMissOrInvalid"),
                                                                PrintSchemaTags.Framework.ParameterDef,
                                                                (PrintSchemaLocalParameterDefs)i));
             }
         }
     }
 }
Beispiel #8
0
        /// <summary>
        /// Sets page scaling setting to custom square scaling.
        /// </summary>
        /// <param name="squareScale">custom square scaling percentage</param>
        /// <exception cref="ArgumentOutOfRangeException">
        /// "squareScale" is not non-negative value.
        /// </exception>
        public void SetCustomSquareScaling(int squareScale)
        {
            // Scaling percentage value must be non-negative. We do allow negative scaling offset values.
            if (squareScale < 0)
            {
                throw new ArgumentOutOfRangeException("squareScale",
                                                      PTUtility.GetTextFromResource("ArgumentException.NonNegativeValue"));
            }

            // Remove all XML content related to PageScaling feature
            // any way to avoid redundant NotifyPropertyChanged calls?
            ClearSetting();

            this[PrintSchemaTags.Framework.OptionNameProperty] = (int)PageScaling.CustomSquare;

            this[PrintSchemaTags.Keywords.PageScalingKeys.CustomSquareScale] = squareScale;
        }
Beispiel #9
0
        /// <summary>
        /// Converts the given Win32 DEVMODE into PrintTicket.
        /// </summary>
        /// <param name="devMode">Byte buffer containing the Win32 DEVMODE.</param>
        /// <param name="scope">scope that the result PrintTicket will be limited to</param>
        /// <returns>MemoryStream that contains the converted XML PrintTicket.</returns>
        /// <exception cref="ObjectDisposedException">
        /// The PTProvider instance has already been disposed.
        /// </exception>
        /// <exception cref="ArgumentException">
        /// The DEVMODE specified by <paramref name="devMode"/> is not well-formed.
        /// </exception>
        /// <exception cref="PrintQueueException">
        /// The PTProvider instance failed to convert the DEVMODE to a PrintTicket.
        /// </exception>
        /// <exception cref="PrintingNotSupportedException">
        /// Printing components are not installed on the client
        /// </exception>
        public override MemoryStream ConvertDevModeToPrintTicket(byte[] devMode,
                                                                 PrintTicketScope scope)
        {
            VerifyAccess();

            IntPtr umDevMode = Marshal.AllocCoTaskMem(devMode.Length);

            try
            {
                // Allocate unmanaged buffer and copy devMode byte array into the unmanaged buffer
                Marshal.Copy(devMode, 0, umDevMode, devMode.Length);

                IStream printTicketStream = CreateStreamOnHGlobal();
                try
                {
                    uint hResult = UnsafeNativeMethods.PTConvertDevModeToPrintTicket(_providerHandle,
                                                                                     (uint)devMode.Length,
                                                                                     new HandleRef(this, umDevMode),
                                                                                     (uint)scope,
                                                                                     printTicketStream);

                    if (PTUtility.IsSuccessCode(hResult))
                    {
                        RewindIStream(printTicketStream);
                        return(MemoryStreamFromIStream(printTicketStream));
                    }

                    throw new PrintQueueException((int)hResult,
                                                  "PrintConfig.Provider.DevMode2PTFail",
                                                  _deviceName);
                }
                finally
                {
                    DeleteIStream(ref printTicketStream);
                }
            }
            finally
            {
                if (umDevMode != IntPtr.Zero)
                {
                    Marshal.FreeCoTaskMem(umDevMode);
                    umDevMode = IntPtr.Zero;
                }
            }
        }
        /// <summary>
        /// Gets current Property/ScoredProperty's QName LocalName value from its "Value" child-element.
        /// The returned property QName value is guaranteed to be in the standard keyword set namespace.
        /// </summary>
        /// <exception cref="FormatException">either can't find the value or value is private</exception>
        /// <exception cref="XmlException">XML is not well-formed.</exception>
        public string GetCurrentPropertyQNameValueWithException()
        {
            string QName = GetCurrentPropertyFullValueWithException();

            if (XmlReaderQName.GetURI(_xmlReader, QName) == PrintSchemaNamespaces.StandardKeywordSet)
            {
                return(XmlReaderQName.GetLocalName(QName));
            }
            else
            {
                // Needs to handle private XML text value
                throw NewPrintCapFormatException(String.Format(CultureInfo.CurrentCulture,
                                                               PTUtility.GetTextFromResource("FormatException.PrivateXMLTextValue"),
                                                               QName,
                                                               _xmlReader.LineNumber,
                                                               _xmlReader.LinePosition));
            }
        }
        /// <exception cref="ArgumentOutOfRangeException">
        /// "value" is not one of the standard <see cref="PageMediaSizeName"/>.
        /// </exception>
        /// <exception cref="ArgumentOutOfRangeException">
        /// Either "mediaSizeWidth" or "mediaSizeHeight" is not a positive dimension value.
        /// </exception>
        private void InternalSetFixedMediaSize(PageMediaSizeName value,
                                               bool bSetValue,
                                               double mediaSizeWidth,
                                               double mediaSizeHeight,
                                               bool bSetWH)
        {
            if (bSetValue)
            {
                if (value < PrintSchema.PageMediaSizeNameEnumMin ||
                    value > PrintSchema.PageMediaSizeNameEnumMax)
                {
                    throw new ArgumentOutOfRangeException("value");
                }
            }

            if (bSetWH)
            {
                if ((mediaSizeWidth <= 0) || (mediaSizeHeight <= 0))
                {
                    throw new ArgumentOutOfRangeException((mediaSizeWidth <= 0) ? "mediaSizeWidth" : "mediaSizeHeight",
                                                          PTUtility.GetTextFromResource("ArgumentException.PositiveValue"));
                }
            }

            // Remove all XML content related to PageMediaSize feature
            ClearSetting();

            if (bSetValue)
            {
                this[PrintSchemaTags.Framework.OptionNameProperty] = (int)value;
            }

            if (bSetWH)
            {
                this[PrintSchemaTags.Keywords.PageMediaSizeKeys.MediaSizeWidth] =
                    UnitConverter.LengthValueFromDIPToMicron(mediaSizeWidth);
                this[PrintSchemaTags.Keywords.PageMediaSizeKeys.MediaSizeHeight] =
                    UnitConverter.LengthValueFromDIPToMicron(mediaSizeHeight);
            }
        }
Beispiel #12
0
        /// <summary>
        /// Constructs a new PrintTicket provider instance for the given device.
        /// </summary>
        /// <param name="deviceName">name of printer device the provider should be bound to</param>
        /// <param name="maxVersion">max schema version supported by client</param>
        /// <param name="clientVersion">schema version requested by client</param>
        /// <exception cref="PrintQueueException">
        /// The PTProvider instance failed to bind to the specified printer.
        /// </exception>
        /// <exception cref="PrintingNotSupportedException">
        /// Printing components are not installed on the client
        /// </exception>
        public PTProvider(string deviceName, int maxVersion, int clientVersion)
        {
            Toolbox.EmitEvent(EventTrace.Event.WClientDRXPTProviderStart);

            // We are not doing late binding to the device here because we should
            // indicate right away if there was an error in binding the provider
            // to the device.  Doing late binding would mean that any instance
            // method could throw a no such printer exception.
            uint hResult = UnsafeNativeMethods.PTOpenProviderEx(deviceName,
                                                                maxVersion,
                                                                clientVersion,
                                                                out _providerHandle,
                                                                out _schemaVersion);

            if (!PTUtility.IsSuccessCode(hResult))
            {
                throw new PrintQueueException((int)hResult, "PrintConfig.Provider.BindFail", deviceName);
            }

#if _DEBUG
            if (_schemaVersion != clientVersion)
            {
                // PTOpenProviderEx() shouldn't succeed if it can't support the requested version.
                throw new InvalidOperationException("_DEBUG: Client requested Print Schema version " +
                                                    clientVersion.ToString(CultureInfo.CurrentCulture) +
                                                    " doesn't match to provider Print Schema version " +
                                                    _schemaVersion.ToString(CultureInfo.CurrentCulture));
            }
#endif

            // If succeeded, PTOpenProviderEx() function should ensure that a valid _providerHandle
            // is returned and the returned schemaVersion is within valid range (i.e. no greater than maxVersion)
            this._deviceName = deviceName;

            this._thread = Thread.CurrentThread;

            Toolbox.EmitEvent(EventTrace.Event.WClientDRXPTProviderEnd);
        }
        /// <summary>
        /// Gets current Property/ScoredProperty's integer value from its "Value" child-element
        /// </summary>
        /// <exception cref="FormatException">either can't find the value or find invalid value number</exception>
        /// <exception cref="XmlException">XML is not well-formed.</exception>
        public int GetCurrentPropertyIntValueWithException()
        {
            // Do the assignment outside of try-catch so the FormatException of value-not-found could be thrown properly.
            string textValue = GetCurrentPropertyFullValueWithException();

            int intValue = 0;

            try
            {
                intValue = XmlConvertHelper.ConvertStringToInt32(textValue);
            }
            catch (FormatException e)
            {
                throw NewPrintCapFormatException(String.Format(CultureInfo.CurrentCulture,
                                                               PTUtility.GetTextFromResource("FormatException.InvalidXMLIntValue"),
                                                               CurrentElementTextValue,
                                                               _xmlReader.LineNumber,
                                                               _xmlReader.LinePosition),
                                                 e);
            }

            return(intValue);
        }
Beispiel #14
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>
        /// <exception cref="PrintingNotSupportedException">
        /// Printing components are not installed on the client
        /// </exception>
        public override byte[] ConvertPrintTicketToDevMode(MemoryStream printTicket,
                                                           BaseDevModeType baseType,
                                                           PrintTicketScope scope)
        {
            VerifyAccess();

            uint   hResult  = 0;
            string errorMsg = null;

            IntPtr umDevMode = IntPtr.Zero;

            try
            {
                IStream printTicketStream = IStreamFromMemoryStream(printTicket);
                try
                {
                    uint umDevModeLen = 0;
                    hResult = UnsafeNativeMethods.PTConvertPrintTicketToDevMode(_providerHandle,
                                                                                printTicketStream,
                                                                                (uint)baseType,
                                                                                (uint)scope,
                                                                                out umDevModeLen,
                                                                                out umDevMode,
                                                                                out errorMsg);

                    if (PTUtility.IsSuccessCode(hResult))
                    {
                        byte[] devMode = new byte[umDevModeLen];
                        Marshal.Copy(umDevMode, devMode, 0, (int)umDevModeLen);
                        return(devMode);
                    }
                }
                finally
                {
                    DeleteIStream(ref printTicketStream);
                }
            }
            finally
            {
                if (umDevMode != IntPtr.Zero)
                {
                    UnsafeNativeMethods.PTReleaseMemory(new HandleRef(this, umDevMode));
                    umDevMode = IntPtr.Zero;
                }
            }

            if ((hResult == (uint)NativeErrorCode.E_XML_INVALID) ||
                (hResult == (uint)NativeErrorCode.E_PRINTTICKET_FORMAT))
            {
                throw new ArgumentException(String.Format(CultureInfo.CurrentCulture,
                                                          "{0} {1} {2}",
                                                          PrintSchemaTags.Framework.PrintTicketRoot,
                                                          PTUtility.GetTextFromResource("FormatException.XMLNotWellFormed"),
                                                          errorMsg),
                                            "printTicket");
            }

            throw new PrintQueueException((int)hResult,
                                          "PrintConfig.Provider.PT2DevModeFail",
                                          _deviceName,
                                          errorMsg);
        }
Beispiel #15
0
        /// <summary>
        /// Verifies if the PrintTicket is well-formed
        /// </summary>
        /// <exception cref="FormatException">
        /// The PrintTicket is not well-formed.
        /// </exception>
        public static void CheckIsWellFormedPrintTicket(InternalPrintTicket pt)
        {
            XmlElement root = pt.XmlDoc.DocumentElement;

            // Root element should be in our standard namespace and should be <PrintTicket>.
            if ((root.NamespaceURI != PrintSchemaNamespaces.Framework) ||
                (root.LocalName != PrintSchemaTags.Framework.PrintTicketRoot))
            {
                throw NewPTFormatException(String.Format(CultureInfo.CurrentCulture,
                                                         PTUtility.GetTextFromResource("FormatException.InvalidRootElement"),
                                                         root.NamespaceURI,
                                                         root.LocalName));
            }

            string version = root.GetAttribute(PrintSchemaTags.Framework.RootVersionAttr,
                                               PrintSchemaNamespaces.FrameworkAttrForXmlDOM);

            // Root element should have the "version" attribute
            // (XmlElement.GetAttribute returns empty string when the attribute is not found, but
            // (XmlTextReader.GetAttribute returns null when the attribute is not found)
            if ((version == null) || (version.Length == 0))
            {
                throw NewPTFormatException(String.Format(CultureInfo.CurrentCulture,
                                                         PTUtility.GetTextFromResource("FormatException.RootMissingAttribute"),
                                                         PrintSchemaTags.Framework.RootVersionAttr));
            }

            decimal versionNum;

            try
            {
                versionNum = XmlConvertHelper.ConvertStringToDecimal(version);
            }
            catch (FormatException e)
            {
                throw NewPTFormatException(String.Format(CultureInfo.CurrentCulture,
                                                         PTUtility.GetTextFromResource("FormatException.RootInvalidAttribute"),
                                                         PrintSchemaTags.Framework.RootVersionAttr,
                                                         version),
                                           e);
            }

            // and the "version" attribute value should be what we support
            if (versionNum != PrintSchemaTags.Framework.SchemaVersion)
            {
                throw NewPTFormatException(String.Format(CultureInfo.CurrentCulture,
                                                         PTUtility.GetTextFromResource("FormatException.VersionNotSupported"),
                                                         versionNum));
            }

            // Now go through each root child element and verify they are valid children
            XmlNode rootChild = root.FirstChild;

            // It's recommended that traversing the node in forward-only movement by using NextSibling
            // is best for XmlDocument performance. This is because the list is not double-linked.
            while (rootChild != null)
            {
                // If the root child doesn't live in our standard namespace, we should ignore it
                // rather than rejecting it since it's acceptable to have private elements under
                // the root.
                if (rootChild.NamespaceURI == PrintSchemaNamespaces.Framework)
                {
                    // For <PrintTicket> root, our Framework schema only allow these children elements:
                    // <Feature> <AttributeSet> <Property> <ParameterInit>
                    if ((rootChild.NodeType != XmlNodeType.Element) ||
                        ((rootChild.LocalName != PrintSchemaTags.Framework.Feature) &&
                         (rootChild.LocalName != PrintSchemaTags.Framework.ParameterInit) &&
                         (rootChild.LocalName != PrintSchemaTags.Framework.Property)))
                    {
                        throw NewPTFormatException(String.Format(CultureInfo.CurrentCulture,
                                                                 PTUtility.GetTextFromResource("FormatException.RootInvalidChildElement"),
                                                                 rootChild.Name));
                    }

                    string childName = ((XmlElement)rootChild).GetAttribute(PrintSchemaTags.Framework.NameAttr,
                                                                            PrintSchemaNamespaces.FrameworkAttrForXmlDOM);

                    // All the recognized root child element should have an XML attribut "name"
                    if ((childName == null) || (childName.Length == 0))
                    {
                        throw NewPTFormatException(String.Format(CultureInfo.CurrentCulture,
                                                                 PTUtility.GetTextFromResource("FormatException.RootChildMissingAttribute"),
                                                                 rootChild.Name,
                                                                 PrintSchemaTags.Framework.NameAttr));
                    }
                }

                rootChild = rootChild.NextSibling;
            }

            // We will end the verification at the root child level here. Instead of traversing the whole tree
            // to find violations in this construtor, we will delay detecting violations under root child level
            // until information of an individual feature/property subtree is requested.
        }
Beispiel #16
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>
        /// <exception cref="PrintingNotSupportedException">
        /// Printing components are not installed on the client
        /// </exception>
        public override MemoryStream MergeAndValidatePrintTicket(MemoryStream basePrintTicket,
                                                                 MemoryStream deltaPrintTicket,
                                                                 PrintTicketScope scope,
                                                                 out ConflictStatus conflictStatus)
        {
            VerifyAccess();

            conflictStatus = ConflictStatus.NoConflict;

            IStream validatedPrintTicketStream = CreateStreamOnHGlobal();

            try
            {
                IStream baseTicketStream = IStreamFromMemoryStream(basePrintTicket);
                try
                {
                    IStream deltaTicketStream = IStreamFromMemoryStream(deltaPrintTicket);
                    try
                    {
                        string errorMsg;
                        uint   hResult = UnsafeNativeMethods.PTMergeAndValidatePrintTicket(_providerHandle,
                                                                                           baseTicketStream,
                                                                                           deltaTicketStream,
                                                                                           (uint)scope,
                                                                                           validatedPrintTicketStream,
                                                                                           out errorMsg);

                        if (PTUtility.IsSuccessCode(hResult))
                        {
                            // convert the success hResult to an enum value
                            switch (hResult)
                            {
                            case (uint)NativeErrorCode.S_PT_CONFLICT_RESOLVED:
                            {
                                conflictStatus = ConflictStatus.ConflictResolved;
                                break;
                            }

                            case (uint)NativeErrorCode.S_PT_NO_CONFLICT:
                            {
                                conflictStatus = ConflictStatus.NoConflict;
                                break;
                            }

                            default:
                            {
                                throw new PrintQueueException((int)hResult,
                                                              "PrintConfig.Provider.MergeValidateFail",
                                                              _deviceName);
                            }
                            }

                            RewindIStream(validatedPrintTicketStream);

                            return(MemoryStreamFromIStream(validatedPrintTicketStream));
                        }

                        if ((hResult == (uint)NativeErrorCode.E_PRINTTICKET_FORMAT) ||
                            (hResult == (uint)NativeErrorCode.E_DELTA_PRINTTICKET_FORMAT))
                        {
                            throw new ArgumentException(String.Format(CultureInfo.CurrentCulture,
                                                                      "{0} {1} {2}",
                                                                      PrintSchemaTags.Framework.PrintTicketRoot,
                                                                      PTUtility.GetTextFromResource("FormatException.XMLNotWellFormed"),
                                                                      errorMsg),
                                                        (hResult == (uint)NativeErrorCode.E_PRINTTICKET_FORMAT) ? "basePrintTicket" : "deltaPrintTicket");
                        }
                        else
                        {
                            throw new PrintQueueException((int)hResult,
                                                          "PrintConfig.Provider.MergeValidateFail",
                                                          _deviceName,
                                                          errorMsg);
                        }
                    }
                    finally
                    {
                        DeleteIStream(ref deltaTicketStream);
                    }
                }
                finally
                {
                    DeleteIStream(ref baseTicketStream);
                }
            }
            finally
            {
                DeleteIStream(ref validatedPrintTicketStream);
            }
        }
Beispiel #17
0
 // Implementation of SafeHandle's this abstract method specifies how to free the handle.
 // The boolean returned should be true for success and false if the runtime
 // should fire a SafeHandleCriticalFailure MDA (CustomerDebugProbe) if that
 // MDA is enabled.
 protected override bool ReleaseHandle()
 {
     return(PTUtility.IsSuccessCode(UnsafeNativeMethods.PTCloseProviderImpl(this.handle)));
 }
        /// <summary>
        /// Instantiates a reader object for the given XML PrintCapabilities
        /// </summary>
        /// <remarks>Constructor verifies the root element is valid</remarks>
        /// <exception cref="FormatException">thrown if XML PrintCapabilities is not well-formed</exception>
        public XmlPrintCapReader(Stream xmlStream)
        {
            // Internally the XML PrintCapabilities reader uses XmlTextReader
            _xmlReader = new XmlTextReader(xmlStream);

            // We need namespace support from the reader.
            _xmlReader.Namespaces = true;

            // Don't resolve external resources.
            _xmlReader.XmlResolver = null;

            // Verify root element is <PrintCapabilities> in our standard namespace
            if ((_xmlReader.MoveToContent() != XmlNodeType.Element) ||
                (_xmlReader.LocalName != PrintSchemaTags.Framework.PrintCapRoot) ||
                (_xmlReader.NamespaceURI != PrintSchemaNamespaces.Framework))
            {
                throw NewPrintCapFormatException(String.Format(CultureInfo.CurrentCulture,
                                                               PTUtility.GetTextFromResource("FormatException.InvalidRootElement"),
                                                               _xmlReader.NamespaceURI,
                                                               _xmlReader.LocalName));
            }

            // Verify the XML PrintCapabilities version is supported

            // For XML attribute without a prefix (e.g. <... name="prn:PageMediaSize">),
            // even though the XML document has default namespace defined as our standard
            // Print Schema framework namespace, the XML atribute still has NULL namespaceURI.
            // It will only have the correct namespaceURI when a prefix is used. This doesn't
            // apply to XML element, whose namespaceURI works fine with default namespace.

            // GetAttribute doesn't move the reader cursor away from the current element
            string version = _xmlReader.GetAttribute(PrintSchemaTags.Framework.RootVersionAttr,
                                                     PrintSchemaNamespaces.FrameworkAttrForXmlReader);

            if (version == null)
            {
                throw NewPrintCapFormatException(String.Format(CultureInfo.CurrentCulture,
                                                               PTUtility.GetTextFromResource("FormatException.RootMissingAttribute"),
                                                               PrintSchemaTags.Framework.RootVersionAttr));
            }

            // Convert string to number to verify
            decimal versionNum;

            try
            {
                versionNum = XmlConvertHelper.ConvertStringToDecimal(version);
            }
            catch (FormatException e)
            {
                throw NewPrintCapFormatException(String.Format(CultureInfo.CurrentCulture,
                                                               PTUtility.GetTextFromResource("FormatException.RootInvalidAttribute"),
                                                               PrintSchemaTags.Framework.RootVersionAttr,
                                                               version),
                                                 e);
            }

            if (versionNum != PrintSchemaTags.Framework.SchemaVersion)
            {
                throw NewPrintCapFormatException(String.Format(CultureInfo.CurrentCulture,
                                                               PTUtility.GetTextFromResource("FormatException.VersionNotSupported"),
                                                               versionNum));
            }

            // Reset internal states to be ready for client's reading of the PrintCapabilities XML
            ResetCurrentElementState();
        }
Beispiel #19
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);
        }