Exemplo n.º 1
0
        public SafeCspHandle Duplicate()
        {
            Contract.Requires(!IsInvalid && !IsClosed);

            // In the window between the call to CryptContextAddRef and when the raw handle value is assigned
            // into this safe handle, there's a second reference to the original safe handle that the CLR does
            // not know about, so we need to bump the reference count around this entire operation to ensure
            // that we don't have the original handle closed underneath us.
            bool acquired = false;

            RuntimeHelpers.PrepareConstrainedRegions();
            try
            {
                DangerousAddRef(ref acquired);
                IntPtr originalHandle = DangerousGetHandle();

                int error = (int)CapiNative.ErrorCode.Success;

                SafeCspHandle duplicate = new SafeCspHandle();

                // A successful call to CryptContextAddRef and an assignment of the handle value to the duplicate
                // SafeHandle need to happen atomically, so we contain them within a CER.
                RuntimeHelpers.PrepareConstrainedRegions();
                try { }
                finally
                {
                    if (!CryptContextAddRef(this, IntPtr.Zero, 0))
                    {
                        error = Marshal.GetLastWin32Error();
                    }
                    else
                    {
                        duplicate.SetHandle(originalHandle);
                    }
                }

                // If we could not call CryptContextAddRef succesfully, then throw the error here otherwise
                // we should be in a valid state at this point.
                if (error != (int)CapiNative.ErrorCode.Success)
                {
                    duplicate.Dispose();
                    throw new CryptographicException(error);
                }
                else
                {
                    Debug.Assert(!duplicate.IsInvalid, "Failed to duplicate handle successfully");
                }

                return(duplicate);
            }
            finally
            {
                if (acquired)
                {
                    DangerousRelease();
                }
            }
        }
 public SafeCspHandle Duplicate()
 {
     SafeCspHandle handle2;
     bool success = false;
     RuntimeHelpers.PrepareConstrainedRegions();
     try
     {
         base.DangerousAddRef(ref success);
         IntPtr ptr = base.DangerousGetHandle();
         int hr = 0;
         SafeCspHandle handle = new SafeCspHandle();
         RuntimeHelpers.PrepareConstrainedRegions();
         try
         {
         }
         finally
         {
             if (!CryptContextAddRef(this, IntPtr.Zero, 0))
             {
                 hr = Marshal.GetLastWin32Error();
             }
             else
             {
                 handle.SetHandle(ptr);
             }
         }
         if (hr != 0)
         {
             handle.Dispose();
             throw new CryptographicException(hr);
         }
         handle2 = handle;
     }
     finally
     {
         if (success)
         {
             base.DangerousRelease();
         }
     }
     return handle2;
 }