{"record":{"id":"dde614d57952380c","repo":"dotnet/wpf","slug":"printconfig-provider-devmode2ptfail","errorCode":"PrintConfig.Provider.DevMode2PTFail","errorMessage":"PrintConfig.Provider.DevMode2PTFail","messagePattern":"PrintConfig\\.Provider\\.DevMode2PTFail","errorType":"error_code","errorClass":"PrintQueueException","httpStatus":null,"severity":"error","filePath":"src/Microsoft.DotNet.Wpf/src/ReachFramework/PrintConfig/PTProvider.cs","lineNumber":411,"sourceCode":"                // Allocate unmanaged buffer and copy devMode byte array into the unmanaged buffer\n                Marshal.Copy(devMode, 0, umDevMode, devMode.Length);\n\n                IStream printTicketStream = CreateStreamOnHGlobal();\n                try\n                {\n                    uint hResult = UnsafeNativeMethods.PTConvertDevModeToPrintTicket(_providerHandle,\n                                                                             (uint)devMode.Length,\n                                                                             new HandleRef(this, umDevMode),\n                                                                             (uint)scope,\n                                                                             printTicketStream);\n\n                    if (PTUtility.IsSuccessCode(hResult))\n                    {\n                        RewindIStream(printTicketStream);\n                        return MemoryStreamFromIStream(printTicketStream);\n                    }\n\n                    throw new PrintQueueException((int)hResult,\n                                                  \"PrintConfig.Provider.DevMode2PTFail\",\n                                                  _deviceName);\n                }\n                finally\n                {\n                    DeleteIStream(ref printTicketStream);\n                }\n            }\n            finally\n            {\n                if (umDevMode != IntPtr.Zero)\n                {\n                    Marshal.FreeCoTaskMem(umDevMode);\n                    umDevMode = IntPtr.Zero;\n                }\n            }\n        }\n","sourceCodeStart":393,"sourceCodeEnd":429,"githubUrl":"https://github.com/dotnet/wpf/blob/81131a70a4c573cd62748a5c36908fc4d662daa9/src/Microsoft.DotNet.Wpf/src/ReachFramework/PrintConfig/PTProvider.cs#L393-L429","documentation":"PTProvider.ConvertDevModeToPrintTicket checks the HRESULT of the native PTConvertDevModeToPrintTicket call; on failure it throws PrintQueueException with reason PrintConfig.Provider.DevMode2PTFail. This means the driver provider could not convert the supplied binary DEVMODE structure into a PrintTicket document.","triggerScenarios":"Calling PTProvider.ConvertDevModeToPrintTicket(devMode byte[]) where the native conversion fails: DEVMODE buffer size mismatch, DEVMODE from a different driver, or corrupt/partial DEVMODE bytes.","commonSituations":"Caching a DEVMODE from one printer and applying it to another; DEVMODE struct marshaled with wrong dmSize/dmDriverExtra; DEVMODE obtained from an old driver version; passing a truncated byte buffer.","solutions":["Verify the DEVMODE came from the same printer/driver that the PTProvider was bound to.","Check dmSize and dmDriverExtra are consistent with the buffer length passed in.","Re-obtain a fresh DEVMODE via the queue's GetPrintCapabilities/DocumentProperties flow instead of caching.","Inspect the HRESULT in the PrintQueueException for the native error code.","If the DEVMODE is from a different driver, convert via PrintQueue interpolation rather than direct conversion."],"exampleFix":"// before\nbyte[] devMode = cachedDevModeFromOtherDriver; // DEVMODE from a different driver\nvar pt = provider.ConvertDevModeToPrintTicket(devMode);\n// after\nbyte[] devMode = currentQueue.GetPrintCapabilities(); // or fresh MARSHAL from current queue\nvar pt = provider.ConvertDevModeToPrintTicket(freshDevModeFromSameDriver);","handlingStrategy":"validation","validationCode":"// devMode bytes must be freshly obtained for the SAME queue the provider is bound to\nvar devMode = queue.CurrentJobSettings == null ? null : GetFreshDevMode(queue); // via Marshal/DocumentProperties\nif (devMode == null || devMode.Length == 0)\n    throw new InvalidOperationException(\"No valid DEVMODE for this queue.\");","typeGuard":"static bool IsPlausibleDevMode(byte[] buf)\n{\n    if (buf == null || buf.Length < 40) return false;\n    short dmSize = BitConverter.ToInt16(buf, 0);\n    return dmSize >= 40 && dmSize <= buf.Length;\n}","tryCatchPattern":"try { pt = provider.ConvertDevModeToPrintTicket(devMode); }\ncatch (PrintQueueException ex) when (ex.Message.Contains(\"PrintConfig.Provider.DevMode2PTFail\"))\n{\n    pt = queue.DefaultPrintTicket; // fall back to defaults\n}","preventionTips":["Never reuse DEVMODE buffers across different printers or driver versions.","Check dmSize/dmDriverExtra consistency with the byte buffer length.","Re-fetch DEVMODE from the current queue instead of caching long-lived copies."],"tags":["wpf","printing","devmode","native-interop"],"backgroundTag":"invalid-argument-format","analyzedSha":"81131a70a4c573cd62748a5c36908fc4d662daa9","analyzedAt":"2026-09-14T10:12:48.479Z","contentChangedAt":"2026-09-14T10:12:48.479Z","schemaVersion":2},"datasetVersion":"2026-09-21T21:30:21.729Z"}