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);
Exemple #3
0
        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);
        }