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