/// <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); }
/// <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); }
/// <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); }
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); }
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); }
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); } }
/// <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)); }
public DevMode Clone() { DevMode result = new DevMode(); if (this._byteData != null) { result._byteData = (byte[])this._byteData.Clone(); } result._isDevModeW = this._isDevModeW; return(result); }
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); } }
/// <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(); } } }
/// <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(); } } }
private WinSpoolPrinterCapabilities GetCapabilities(DevMode devMode) { return(new WinSpoolPrinterCapabilities(this._deviceName, this._driverName, this._portName, devMode)); }
/// <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; } }