internal static T GetProviderParameterStruct <T>(SafeCspHandle provider, ProviderParameter parameter, ProviderParameterFlags flags) where T : struct { Contract.Requires(provider != null); Contract.Requires(parameter == ProviderParameter.EnumerateAlgorithms); // Figure out how big the parameter is int bufferSize = 0; IntPtr buffer = IntPtr.Zero; if (!UnsafeNativeMethods.CryptGetProvParam(provider, parameter, buffer, ref bufferSize, flags)) { int errorCode = Marshal.GetLastWin32Error(); // NoMoreItems means that we've finished the enumeration we're currently working on, this is // not a real error, so return an empty structure to mark the end. if (errorCode == (int)ErrorCode.NoMoreItems) { return(new T()); } else if (errorCode != (int)ErrorCode.MoreData) { throw new CryptographicException(errorCode); } } Debug.Assert(Marshal.SizeOf(typeof(T)) <= bufferSize, "Buffer size does not match structure size"); // // Pull the parameter back and marshal it into the return structure // RuntimeHelpers.PrepareConstrainedRegions(); try { // Allocate in a CER because we could fail between the alloc and the assignment RuntimeHelpers.PrepareConstrainedRegions(); try { } finally { buffer = Marshal.AllocCoTaskMem(bufferSize); } if (!UnsafeNativeMethods.CryptGetProvParam(provider, parameter, buffer, ref bufferSize, flags)) { throw new CryptographicException(Marshal.GetLastWin32Error()); } return((T)Marshal.PtrToStructure(buffer, typeof(T))); } finally { if (buffer != IntPtr.Zero) { Marshal.FreeCoTaskMem(buffer); } } }
public static extern bool CryptGetProvParam(SafeCspHandle hProv, ProviderParameter dwParam, IntPtr pbData, [In, Out] ref int pdwDataLen, ProviderParameterFlags dwFlags);
internal static T GetProviderParameterStruct <T>(SafeCspHandle provider, ProviderParameter parameter, ProviderParameterFlags flags) where T : struct { T local; int pdwDataLen = 0; IntPtr zero = IntPtr.Zero; if (!UnsafeNativeMethods.CryptGetProvParam(provider, parameter, zero, ref pdwDataLen, flags)) { int hr = Marshal.GetLastWin32Error(); if (hr == 0x103) { return(default(T)); } if (hr != 0xea) { throw new CryptographicException(hr); } } RuntimeHelpers.PrepareConstrainedRegions(); try { RuntimeHelpers.PrepareConstrainedRegions(); try { } finally { zero = Marshal.AllocCoTaskMem(pdwDataLen); } if (!UnsafeNativeMethods.CryptGetProvParam(provider, parameter, zero, ref pdwDataLen, flags)) { throw new CryptographicException(Marshal.GetLastWin32Error()); } local = (T)Marshal.PtrToStructure(zero, typeof(T)); } finally { if (zero != IntPtr.Zero) { Marshal.FreeCoTaskMem(zero); } } return(local); }