private static unsafe SafeCertStoreHandle SelectFromStore(SafeCertStoreHandle safeSourceStoreHandle, string title, string message, X509SelectionFlag selectionFlags, IntPtr hwndParent) { int dwErrorCode = ERROR_SUCCESS; SafeCertStoreHandle safeCertStoreHandle = Interop.Crypt32.CertOpenStore( (IntPtr)Interop.Crypt32.CERT_STORE_PROV_MEMORY, Interop.Crypt32.X509_ASN_ENCODING | Interop.Crypt32.PKCS_7_ASN_ENCODING, IntPtr.Zero, 0, null); if (safeCertStoreHandle == null || safeCertStoreHandle.IsInvalid) { throw new CryptographicException(Marshal.GetLastWin32Error()); } Interop.CryptUI.CRYPTUI_SELECTCERTIFICATE_STRUCTW csc = new Interop.CryptUI.CRYPTUI_SELECTCERTIFICATE_STRUCTW(); // Older versions of CRYPTUI do not check the size correctly, // so always force it to the oldest version of the structure. csc.dwSize = (uint)Marshal.OffsetOf(typeof(Interop.CryptUI.CRYPTUI_SELECTCERTIFICATE_STRUCTW), "hSelectedCertStore"); csc.hwndParent = hwndParent; csc.dwFlags = (uint)selectionFlags; csc.szTitle = title; csc.dwDontUseColumn = 0; csc.szDisplayString = message; csc.pFilterCallback = IntPtr.Zero; csc.pDisplayCallback = IntPtr.Zero; csc.pvCallbackData = IntPtr.Zero; csc.cDisplayStores = 1; IntPtr hSourceCertStore = safeSourceStoreHandle.DangerousGetHandle(); csc.rghDisplayStores = new IntPtr(&hSourceCertStore); csc.cStores = 0; csc.rghStores = IntPtr.Zero; csc.cPropSheetPages = 0; csc.rgPropSheetPages = IntPtr.Zero; csc.hSelectedCertStore = safeCertStoreHandle.DangerousGetHandle(); SafeCertContextHandle safeCertContextHandle = Interop.CryptUI.CryptUIDlgSelectCertificateW(csc); if (safeCertContextHandle != null && !safeCertContextHandle.IsInvalid) { // Single select, so add it to our hCertStore SafeCertContextHandle ppStoreContext = SafeCertContextHandle.InvalidHandle; if (!Interop.Crypt32.CertAddCertificateLinkToStore(safeCertStoreHandle, safeCertContextHandle, Interop.Crypt32.CERT_STORE_ADD_ALWAYS, ppStoreContext)) { dwErrorCode = Marshal.GetLastWin32Error(); } } if (dwErrorCode != ERROR_SUCCESS) { throw new CryptographicException(dwErrorCode); } return(safeCertStoreHandle); }
private static unsafe SafeCertStoreHandle SelectFromStore(SafeCertStoreHandle safeSourceStoreHandle, string?title, string?message, X509SelectionFlag selectionFlags, IntPtr hwndParent) { int dwErrorCode = ERROR_SUCCESS; SafeCertStoreHandle safeCertStoreHandle = Interop.Crypt32.CertOpenStore( (IntPtr)Interop.Crypt32.CERT_STORE_PROV_MEMORY, Interop.Crypt32.X509_ASN_ENCODING | Interop.Crypt32.PKCS_7_ASN_ENCODING, IntPtr.Zero, 0, IntPtr.Zero); if (safeCertStoreHandle == null || safeCertStoreHandle.IsInvalid) { throw new CryptographicException(Marshal.GetLastWin32Error()); } Interop.CryptUI.CRYPTUI_SELECTCERTIFICATE_STRUCTW csc = default; // Older versions of CRYPTUI do not check the size correctly, // so always force it to the oldest version of the structure. #if NET7_0_OR_GREATER // Declare a local for Native to enable us to get the managed byte offset // without having a null check cause a failure. Interop.CryptUI.CRYPTUI_SELECTCERTIFICATE_STRUCTW.Marshaller.Native native; Unsafe.SkipInit(out native); csc.dwSize = (uint)Unsafe.ByteOffset(ref Unsafe.As <Interop.CryptUI.CRYPTUI_SELECTCERTIFICATE_STRUCTW.Marshaller.Native, byte>(ref native), ref Unsafe.As <IntPtr, byte>(ref native.hSelectedCertStore)); #else csc.dwSize = (uint)Marshal.OffsetOf(typeof(Interop.CryptUI.CRYPTUI_SELECTCERTIFICATE_STRUCTW), "hSelectedCertStore"); #endif csc.hwndParent = hwndParent; csc.dwFlags = (uint)selectionFlags; csc.szTitle = title; csc.dwDontUseColumn = 0; csc.szDisplayString = message; csc.pFilterCallback = IntPtr.Zero; csc.pDisplayCallback = IntPtr.Zero; csc.pvCallbackData = IntPtr.Zero; csc.cDisplayStores = 1; IntPtr hSourceCertStore = safeSourceStoreHandle.DangerousGetHandle(); csc.rghDisplayStores = new IntPtr(&hSourceCertStore); csc.cStores = 0; csc.rghStores = IntPtr.Zero; csc.cPropSheetPages = 0; csc.rgPropSheetPages = IntPtr.Zero; csc.hSelectedCertStore = safeCertStoreHandle.DangerousGetHandle(); SafeCertContextHandle safeCertContextHandle = Interop.CryptUI.CryptUIDlgSelectCertificateW(ref csc); if (safeCertContextHandle != null && !safeCertContextHandle.IsInvalid) { // Single select, so add it to our hCertStore SafeCertContextHandle ppStoreContext = SafeCertContextHandle.InvalidHandle; if (!Interop.Crypt32.CertAddCertificateLinkToStore(safeCertStoreHandle, safeCertContextHandle, Interop.Crypt32.CERT_STORE_ADD_ALWAYS, ppStoreContext)) { dwErrorCode = Marshal.GetLastWin32Error(); } } if (dwErrorCode != ERROR_SUCCESS) { throw new CryptographicException(dwErrorCode); } return(safeCertStoreHandle); }