/// <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); }
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> /// 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); }