{"record":{"id":"3213c3cbc63d462e","repo":"dotnet/wpf","slug":"sr-cryptoproviderdisposed","errorCode":null,"errorMessage":"SR.CryptoProviderDisposed","messagePattern":"SR\\.CryptoProviderDisposed","errorType":"exception","errorClass":"ObjectDisposedException","httpStatus":null,"severity":"error","filePath":"src/Microsoft.DotNet.Wpf/src/WindowsBase/System/Security/RightsManagement/CryptoProvider.cs","lineNumber":373,"sourceCode":"            else\n            {\n                return new UnsignedPublishLicense(BoundLicenseOwnerViewRightsHandle, serializedPublishLicense);\n            }\n        }\n\n        //------------------------------------------------------\n        //\n        //  Private Methods  \n        //\n        //------------------------------------------------------\n\n        /// <summary>\n        /// Call this before accepting any API call \n        /// </summary>\n        private void CheckDisposed()\n        {\n            if (_disposed)\n                throw new ObjectDisposedException(null, SR.CryptoProviderDisposed);\n        }\n\n\n        private int QueryBlockSize()\n        {\n            uint attributeSize = 0;\n            byte[] dataBuffer = null;\n            \n            uint encodingType;\n\n            int hr = SafeNativeMethods.DRMGetInfo(DecryptorHandle,\n                                                    NativeConstants.QUERY_BLOCKSIZE,\n                                                    out encodingType,\n                                                    ref attributeSize,\n                                                    null);\n            Errors.ThrowOnErrorCode(hr);\n\n            // it must return 4 bytes for block size ","sourceCodeStart":355,"sourceCodeEnd":391,"githubUrl":"https://github.com/dotnet/wpf/blob/81131a70a4c573cd62748a5c36908fc4d662daa9/src/Microsoft.DotNet.Wpf/src/WindowsBase/System/Security/RightsManagement/CryptoProvider.cs#L355-L391","documentation":"CryptoProvider.CheckDisposed throws ObjectDisposedException with message SR.CryptoProviderDisposed when any member (Encrypt, Decrypt, BlockSize, CanMergeBlocks, BoundGrants, CanEncrypt, CanDecrypt, etc.) is used after Dispose was called. The provider wraps an unmanaged DRM handle that is released on Dispose, so further calls are invalid.","triggerScenarios":"Calling Encrypt/Decrypt/BlockSize/CanMergeBlocks/BoundGrants/CanEncrypt on a CryptoProvider after its Dispose() ran — commonly due to a using block, deterministic finalization, or caching the provider beyond the scope in which it was disposed.","commonSituations":"Storing the CryptoProvider in a long-lived field while wrapping creation in using; reusing a provider across requests after a request-scoped dispose; double-dispose then late access.","solutions":["Keep the CryptoProvider alive for the whole usage window; extend the using scope or dispose only after last use","Re-create the provider from the UseLicense and SecureEnvironment when the old one was disposed","Check _disposed via a public wrapper or track disposal in your own flag before calling members","Centralize ownership so exactly one component disposes the provider"],"exampleFix":"// before\nCryptoProvider provider;\nusing (var tmp = useLicense.Bind(env)) { provider = tmp; } // disposed here\nprovider.Encrypt(data); // ObjectDisposedException\n// after\nusing (var provider = useLicense.Bind(env))\n{\n    var cipher = provider.Encrypt(data); // used inside lifetime\n}","handlingStrategy":"try-catch","validationCode":"bool usable = provider != null && !isDisposedFlag; // track disposal in a wrapper class","typeGuard":"bool IsUsable(CryptoProvider p) => p != null && !isDisposedTracker.Contains(p);","tryCatchPattern":"try { blockSize = provider.BlockSize; }\ncatch (ObjectDisposedException)\n{ provider = useLicense.Bind(env); blockSize = provider.BlockSize; }","preventionTips":["Scope using blocks to cover the entire provider usage window","Never cache a provider beyond its owning using/dispose scope","Assign ownership of Dispose to a single component"],"tags":["drm","rights-management","disposed","object-lifetime"],"backgroundTag":"invalid-state-transition","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"}