securestring.cs source code in C# .NET

Source code for the .NET framework in C#

                        

Code:

/ 4.0 / 4.0 / DEVDIV_TFS / Dev10 / Releases / RTMRel / ndp / clr / src / BCL / System / Security / securestring.cs / 1305376 / securestring.cs

                            // [....] 
namespace System.Security {
    using System.Security.Cryptography;
    using System.Runtime.InteropServices;
#if FEATURE_CORRUPTING_EXCEPTIONS 
    using System.Runtime.ExceptionServices;
#endif // FEATURE_CORRUPTING_EXCEPTIONS 
    using System.Text; 
    using Microsoft.Win32;
    using System.Runtime.CompilerServices; 
    using System.Security.Permissions;
    using System.Runtime.ConstrainedExecution;
    using System.Runtime.Versioning;
    using Microsoft.Win32.SafeHandles; 
    using System.Diagnostics.Contracts;
 
 
#if FEATURE_CRYPTO || FEATURE_X509_SECURESTRINGS
    public sealed class SecureString: IDisposable { 
        [System.Security.SecurityCritical /*auto-generated*/]
        private SafeBSTRHandle m_buffer;
        [ContractPublicPropertyName("Length")]
        private int       m_length; 
        private bool     m_readOnly;
        private bool     m_encrypted; 
 
        static bool supportedOnCurrentPlatform = EncryptionSupported();
 
        const int BlockSize = (int)Win32Native.CRYPTPROTECTMEMORY_BLOCK_SIZE /2;  // a char is two bytes
        const int MaxLength = 65536;
        const uint ProtectionScope = Win32Native.CRYPTPROTECTMEMORY_SAME_PROCESS;
 
        [System.Security.SecuritySafeCritical]  // auto-generated
        static SecureString() 
        { 
        }
 
        [System.Security.SecurityCritical]  // auto-generated
        unsafe static bool EncryptionSupported() {
            // check if the enrypt/decrypt function is supported on current OS
            bool supported = true; 
            try {
                Win32Native.SystemFunction041( 
                    SafeBSTRHandle.Allocate(null , (int)Win32Native.CRYPTPROTECTMEMORY_BLOCK_SIZE), 
                    Win32Native.CRYPTPROTECTMEMORY_BLOCK_SIZE,
                    Win32Native.CRYPTPROTECTMEMORY_SAME_PROCESS); 
            }
            catch (EntryPointNotFoundException) {
                supported = false;
            } 
            return supported;
        } 
 
        [System.Security.SecurityCritical]  // auto-generated
        internal SecureString(SecureString str) { 
            AllocateBuffer(str.BufferLength);
            SafeBSTRHandle.Copy(str.m_buffer, this.m_buffer);
            m_length = str.m_length;
            m_encrypted = str.m_encrypted; 
        }
 
 
        [System.Security.SecuritySafeCritical]  // auto-generated
        public SecureString() { 
            CheckSupportedOnCurrentPlatform();

            // allocate the minimum block size for calling protectMemory
            AllocateBuffer(BlockSize); 
            m_length = 0;
        } 
 

        [System.Security.SecurityCritical]  // auto-generated 
#if FEATURE_CORRUPTING_EXCEPTIONS
        [HandleProcessCorruptedStateExceptions] //
#endif // FEATURE_CORRUPTING_EXCEPTIONS
        private unsafe void InitializeSecureString(char* value, int length) 
        {
            CheckSupportedOnCurrentPlatform(); 
 
            AllocateBuffer(length);
            m_length = length; 

            byte* bufferPtr = null;
            RuntimeHelpers.PrepareConstrainedRegions();
            try 
            {
                m_buffer.AcquirePointer(ref bufferPtr); 
                Buffer.memcpyimpl((byte*)value, bufferPtr, length * 2); 
            }
            catch (Exception) { 
                ProtectMemory();
                throw;
            }
            finally 
            {
                if (bufferPtr != null) 
                    m_buffer.ReleasePointer(); 
            }
 
            ProtectMemory();
        }

        [System.Security.SecurityCritical]  // auto-generated 
        [CLSCompliant(false)]
        public unsafe SecureString(char* value, int length) { 
            if( value == null) { 
                throw new ArgumentNullException("value");
            } 

            if( length < 0) {
                throw new ArgumentOutOfRangeException("length", Environment.GetResourceString("ArgumentOutOfRange_NeedNonNegNum"));
            } 

            if( length > MaxLength) { 
                throw new ArgumentOutOfRangeException("length", Environment.GetResourceString("ArgumentOutOfRange_Length")); 
            }
            Contract.EndContractBlock(); 

            // Refactored since HandleProcessCorruptedStateExceptionsAttribute applies to methods only (yet).
            InitializeSecureString(value, length);
        } 

        public int Length { 
            [System.Security.SecuritySafeCritical]  // auto-generated 
            [MethodImplAttribute(MethodImplOptions.Synchronized)]
            get  { 
                EnsureNotDisposed();
                return m_length;
            }
        } 

        [System.Security.SecuritySafeCritical]  // auto-generated 
        [MethodImplAttribute(MethodImplOptions.Synchronized)] 
#if FEATURE_CORRUPTING_EXCEPTIONS
        [HandleProcessCorruptedStateExceptions] // 
#endif // FEATURE_CORRUPTING_EXCEPTIONS
        public void AppendChar(char c) {
            EnsureNotDisposed();
            EnsureNotReadOnly(); 

            EnsureCapacity(m_length + 1); 
 
            RuntimeHelpers.PrepareConstrainedRegions();
            try { 
                UnProtectMemory();
                m_buffer.Write((uint)m_length * sizeof(char), c);
                m_length++;
            } 
            catch (Exception) {
                ProtectMemory(); 
                throw; 
            }
            finally { 
                ProtectMemory();
            }
        }
 
        // clears the current contents. Only available if writable
        [System.Security.SecuritySafeCritical]  // auto-generated 
        [MethodImplAttribute(MethodImplOptions.Synchronized)] 
        public void Clear() {
            EnsureNotDisposed(); 
            EnsureNotReadOnly();

            m_length = 0;
            m_buffer.ClearBuffer(); 
            m_encrypted = false;
        } 
 
        // Do a deep-copy of the SecureString
        [System.Security.SecuritySafeCritical]  // auto-generated 
        [MethodImplAttribute(MethodImplOptions.Synchronized)]
        public SecureString Copy() {
            EnsureNotDisposed();
            return new SecureString(this); 
        }
 
        [System.Security.SecuritySafeCritical]  // auto-generated 
        [MethodImplAttribute(MethodImplOptions.Synchronized)]
        public void Dispose() { 
            if(m_buffer != null && !m_buffer.IsInvalid) {
                m_buffer.Close();
                m_buffer = null;
            } 
        }
 
        [System.Security.SecuritySafeCritical]  // auto-generated 
        [MethodImplAttribute(MethodImplOptions.Synchronized)]
#if FEATURE_CORRUPTING_EXCEPTIONS 
        [HandleProcessCorruptedStateExceptions] //
#endif // FEATURE_CORRUPTING_EXCEPTIONS
        public void InsertAt( int index, char c ) {
            if( index < 0 || index > m_length) { 
                throw new ArgumentOutOfRangeException("index", Environment.GetResourceString("ArgumentOutOfRange_IndexString"));
            } 
            Contract.EndContractBlock(); 

            EnsureNotDisposed(); 
            EnsureNotReadOnly();

            EnsureCapacity(m_length + 1);
 
            unsafe {
                byte* bufferPtr = null; 
                RuntimeHelpers.PrepareConstrainedRegions(); 
                try {
                    UnProtectMemory(); 
                    m_buffer.AcquirePointer(ref bufferPtr);
                    char* pBuffer = (char*)bufferPtr;

                    for (int i = m_length; i > index; i--) { 
                        pBuffer[i] = pBuffer[i - 1];
                    } 
                    pBuffer[index] = c; 
                    ++m_length;
                } 
                catch (Exception) {
                    ProtectMemory();
                    throw;
                } 
                finally {
                    ProtectMemory(); 
                    if (bufferPtr != null) 
                        m_buffer.ReleasePointer();
                } 
            }
        }

        [System.Security.SecuritySafeCritical]  // auto-generated 
        [MethodImplAttribute(MethodImplOptions.Synchronized)]
        public bool IsReadOnly() { 
            EnsureNotDisposed(); 
            return m_readOnly;
        } 

        [System.Security.SecuritySafeCritical]  // auto-generated
        [MethodImplAttribute(MethodImplOptions.Synchronized)]
        public void MakeReadOnly() { 
            EnsureNotDisposed();
            m_readOnly = true; 
        } 

        [System.Security.SecuritySafeCritical]  // auto-generated 
        [MethodImplAttribute(MethodImplOptions.Synchronized)]
#if FEATURE_CORRUPTING_EXCEPTIONS
        [HandleProcessCorruptedStateExceptions] //
#endif // FEATURE_CORRUPTING_EXCEPTIONS 
        public void RemoveAt( int index ) {
            EnsureNotDisposed(); 
            EnsureNotReadOnly(); 

            if( index < 0 || index >= m_length) { 
                throw new ArgumentOutOfRangeException("index", Environment.GetResourceString("ArgumentOutOfRange_IndexString"));
            }

            unsafe 
            {
                byte* bufferPtr = null; 
                RuntimeHelpers.PrepareConstrainedRegions(); 
                try
                { 
                    UnProtectMemory();
                    m_buffer.AcquirePointer(ref bufferPtr);
                    char* pBuffer = (char*)bufferPtr;
 
                    for (int i = index; i < m_length - 1; i++)
                    { 
                        pBuffer[i] = pBuffer[i + 1]; 
                    }
                    pBuffer[--m_length] = (char)0; 
                }
                catch (Exception) {
                    ProtectMemory();
                    throw; 
                }
                finally 
                { 
                    ProtectMemory();
                    if (bufferPtr != null) 
                        m_buffer.ReleasePointer();
                }
            }
        } 

        [System.Security.SecuritySafeCritical]  // auto-generated 
        [MethodImplAttribute(MethodImplOptions.Synchronized)] 
#if FEATURE_CORRUPTING_EXCEPTIONS
        [HandleProcessCorruptedStateExceptions] // 
#endif // FEATURE_CORRUPTING_EXCEPTIONS
        public void SetAt( int index, char c ) {
            if( index < 0 || index >= m_length) {
                throw new ArgumentOutOfRangeException("index", Environment.GetResourceString("ArgumentOutOfRange_IndexString")); 
            }
            Contract.EndContractBlock(); 
            Contract.Assert(index <= Int32.MaxValue / sizeof(char)); 

            EnsureNotDisposed(); 
            EnsureNotReadOnly();

            RuntimeHelpers.PrepareConstrainedRegions();
            try { 
                UnProtectMemory();
                m_buffer.Write((uint)index * sizeof(char), c); 
            } 
            catch (Exception) {
                ProtectMemory(); 
                throw;
            }
            finally {
                ProtectMemory(); 
            }
        } 
 
        private int BufferLength {
            [System.Security.SecurityCritical]  // auto-generated 
            get {
                Contract.Assert(m_buffer != null, "Buffer is not initialized!");
                return m_buffer.Length;
            } 
        }
 
        [System.Security.SecurityCritical]  // auto-generated 
        [ReliabilityContract(Consistency.WillNotCorruptState, Cer.MayFail)]
        private void AllocateBuffer(int size) { 
            uint alignedSize = GetAlignedSize(size);

            m_buffer = SafeBSTRHandle.Allocate(null, alignedSize);
            if (m_buffer.IsInvalid) { 
                throw new OutOfMemoryException();
            } 
        } 

        private void CheckSupportedOnCurrentPlatform() { 
            if( !supportedOnCurrentPlatform) {
                throw new NotSupportedException(Environment.GetResourceString("Arg_PlatformSecureString"));
            }
            Contract.EndContractBlock(); 
        }
 
        [System.Security.SecurityCritical]  // auto-generated 
        private void EnsureCapacity(int capacity) {
            if( capacity > MaxLength) { 
                throw new ArgumentOutOfRangeException("capacity", Environment.GetResourceString("ArgumentOutOfRange_Capacity"));
            }
            Contract.EndContractBlock();
 
            if( capacity <= m_buffer.Length) {
                return; 
            } 

            SafeBSTRHandle newBuffer = SafeBSTRHandle.Allocate(null, GetAlignedSize(capacity)); 

            if (newBuffer.IsInvalid) {
                throw new OutOfMemoryException();
            } 

            SafeBSTRHandle.Copy(m_buffer, newBuffer); 
            m_buffer.Close(); 
            m_buffer = newBuffer;
        } 

        [System.Security.SecurityCritical]  // auto-generated
        private void EnsureNotDisposed() {
            if( m_buffer == null) { 
                throw new ObjectDisposedException(null);
            } 
            Contract.EndContractBlock(); 
        }
 
        private void EnsureNotReadOnly() {
            if( m_readOnly) {
                throw new InvalidOperationException(Environment.GetResourceString("InvalidOperation_ReadOnly"));
            } 
            Contract.EndContractBlock();
        } 
 
        [ReliabilityContract(Consistency.WillNotCorruptState, Cer.Success)]
        private static uint GetAlignedSize( int size) { 
            Contract.Assert(size >= 0, "size must be non-negative");

            uint alignedSize = ((uint)size / BlockSize) * BlockSize;
            if( (size % BlockSize != 0) || size == 0) {  // if size is 0, set allocated size to blocksize 
                alignedSize += BlockSize;
            } 
            return alignedSize; 
        }
 
        [System.Security.SecurityCritical]  // auto-generated
        private unsafe int GetAnsiByteCount() {
            const uint CP_ACP               = 0;
            const uint WC_NO_BEST_FIT_CHARS = 0x00000400; 

            uint flgs = WC_NO_BEST_FIT_CHARS; 
            uint DefaultCharUsed = (uint)'?'; 

            byte* bufferPtr = null; 
            RuntimeHelpers.PrepareConstrainedRegions();
            try {
                m_buffer.AcquirePointer(ref bufferPtr);
 
                return Win32Native.WideCharToMultiByte(
                    CP_ACP, 
                    flgs, 
                    (char*) bufferPtr,
                    m_length, 
                    null,
                    0,
                    IntPtr.Zero,
                    new IntPtr((void*)&DefaultCharUsed)); 
            }
            finally { 
                if (bufferPtr != null) 
                    m_buffer.ReleasePointer();
            } 
        }

        [System.Security.SecurityCritical]  // auto-generated
        private unsafe void GetAnsiBytes( byte * ansiStrPtr, int byteCount) { 
            const uint CP_ACP               = 0;
            const uint WC_NO_BEST_FIT_CHARS = 0x00000400; 
 
            uint flgs = WC_NO_BEST_FIT_CHARS;
            uint DefaultCharUsed = (uint)'?'; 

            byte* bufferPtr = null;
            RuntimeHelpers.PrepareConstrainedRegions();
            try { 
                m_buffer.AcquirePointer(ref bufferPtr);
 
                Win32Native.WideCharToMultiByte( 
                    CP_ACP,
                    flgs, 
                    (char*) bufferPtr,
                    m_length,
                    ansiStrPtr,
                    byteCount - 1, 
                    IntPtr.Zero,
                    new IntPtr((void*)&DefaultCharUsed)); 
 
                *(ansiStrPtr + byteCount - 1) = (byte)0;
            } 
            finally {
                if (bufferPtr != null)
                    m_buffer.ReleasePointer();
            } 
        }
 
        [System.Security.SecurityCritical]  // auto-generated 
        [ReliabilityContract(Consistency.MayCorruptInstance, Cer.MayFail)]
        private void ProtectMemory() { 
            Contract.Assert(!m_buffer.IsInvalid && m_buffer.Length != 0, "Invalid buffer!");
            Contract.Assert(m_buffer.Length % BlockSize == 0, "buffer length must be multiple of blocksize!");

            if( m_length == 0 || m_encrypted) { 
                return;
            } 
 
            RuntimeHelpers.PrepareConstrainedRegions();
            try { 
            }
            finally {
                // RtlEncryptMemory return an NTSTATUS
                int status = Win32Native.SystemFunction040(m_buffer, (uint)m_buffer.Length * 2, ProtectionScope); 
                if (status < 0)  { // non-negative numbers indicate success
                    throw new CryptographicException(Win32Native.LsaNtStatusToWinError(status)); 
                } 
                m_encrypted = true;
            } 
        }

        [System.Security.SecurityCritical]  // auto-generated
        [ReliabilityContract(Consistency.WillNotCorruptState, Cer.MayFail)] 
        [MethodImplAttribute(MethodImplOptions.Synchronized)]
#if FEATURE_CORRUPTING_EXCEPTIONS 
        [HandleProcessCorruptedStateExceptions] // 
#endif // FEATURE_CORRUPTING_EXCEPTIONS
        internal unsafe IntPtr ToBSTR() { 
            EnsureNotDisposed();
            int length = m_length;
            IntPtr ptr = IntPtr.Zero;
            IntPtr result = IntPtr.Zero; 
            byte* bufferPtr = null;
 
            RuntimeHelpers.PrepareConstrainedRegions(); 
            try {
                RuntimeHelpers.PrepareConstrainedRegions(); 
                try {
                }
                finally {
                    ptr = Win32Native.SysAllocStringLen(null, length); 
                }
 
                if (ptr == IntPtr.Zero) { 
                    throw new OutOfMemoryException();
                } 

                UnProtectMemory();
                m_buffer.AcquirePointer(ref bufferPtr);
                Buffer.memcpyimpl(bufferPtr, (byte*) ptr.ToPointer(), length *2); 
                result = ptr;
            } 
            catch (Exception) { 
                ProtectMemory();
                throw; 
            }
            finally {
                ProtectMemory();
                if( result == IntPtr.Zero) { 
                    // If we failed for any reason, free the new buffer
                    if (ptr != IntPtr.Zero) { 
                        Win32Native.ZeroMemory(ptr, (uint)(length * 2)); 
                        Win32Native.SysFreeString(ptr);
                    } 
                }
                if (bufferPtr != null)
                    m_buffer.ReleasePointer();
            } 
            return result;
        } 
 
        [System.Security.SecurityCritical]  // auto-generated
        [MethodImplAttribute(MethodImplOptions.Synchronized)] 
#if FEATURE_CORRUPTING_EXCEPTIONS
        [HandleProcessCorruptedStateExceptions] //
#endif // FEATURE_CORRUPTING_EXCEPTIONS
        internal unsafe IntPtr ToUniStr(bool allocateFromHeap) { 
            EnsureNotDisposed();
            int length = m_length; 
            IntPtr ptr = IntPtr.Zero; 
            IntPtr result = IntPtr.Zero;
            byte* bufferPtr = null; 

            RuntimeHelpers.PrepareConstrainedRegions();
            try {
                RuntimeHelpers.PrepareConstrainedRegions(); 
                try {
                } 
                finally { 
                    if( allocateFromHeap) {
                        ptr = Marshal.AllocHGlobal((length + 1) * 2); 
                    }
                    else {
#if FEATURE_COMINTEROP
                        ptr = Marshal.AllocCoTaskMem((length + 1) * 2); 
#else // FEATURE_COMINTEROP
                        Contract.Assert(false, "allocateFromHeap must never be set to false when FEATURE_COMINTEROP isn't enabled!"); 
                        throw new NotSupportedException(); 
#endif // FEATURE_COMINTEROP
                    } 
                }

                if (ptr == IntPtr.Zero) {
                    throw new OutOfMemoryException(); 
                }
 
                UnProtectMemory(); 
                m_buffer.AcquirePointer(ref bufferPtr);
                Buffer.memcpyimpl(bufferPtr, (byte*) ptr.ToPointer(), length *2); 
                char * endptr = (char *) ptr.ToPointer();
                *(endptr + length) = '\0';
                result = ptr;
            } 
            catch (Exception) {
                ProtectMemory(); 
                throw; 
            }
            finally { 
                ProtectMemory();

                if( result == IntPtr.Zero) {
                    // If we failed for any reason, free the new buffer 
                    if (ptr != IntPtr.Zero) {
                        Win32Native.ZeroMemory(ptr, (uint)(length * 2)); 
                        if( allocateFromHeap) { 
                            Marshal.FreeHGlobal(ptr);
                        } 
                        else {
#if FEATURE_COMINTEROP
                            Marshal.FreeCoTaskMem(ptr);
#else // FEATURE_COMINTEROP 
                            Contract.Assert(false, "allocateFromHeap must never be set to false when FEATURE_COMINTEROP isn't enabled!");
                            throw new NotSupportedException(); 
#endif // FEATURE_COMINTEROP 
                        }
                    } 
                }

                if (bufferPtr != null)
                    m_buffer.ReleasePointer(); 
            }
            return result; 
        } 

        [System.Security.SecurityCritical]  // auto-generated 
        [MethodImplAttribute(MethodImplOptions.Synchronized)]
#if FEATURE_CORRUPTING_EXCEPTIONS
        [HandleProcessCorruptedStateExceptions] //
#endif // FEATURE_CORRUPTING_EXCEPTIONS 
        internal unsafe IntPtr ToAnsiStr(bool allocateFromHeap) {
            EnsureNotDisposed(); 
 
            IntPtr ptr = IntPtr.Zero;
            IntPtr result = IntPtr.Zero; 
            int byteCount = 0;
            RuntimeHelpers.PrepareConstrainedRegions();
            try {
                // GetAnsiByteCount uses the string data, so the calculation must happen after we are decrypted. 
                UnProtectMemory();
 
                // allocating an extra char for terminating zero 
                byteCount = GetAnsiByteCount() + 1;
 
                RuntimeHelpers.PrepareConstrainedRegions();
                try {
                }
                finally { 
                    if( allocateFromHeap) {
                        ptr = Marshal.AllocHGlobal(byteCount); 
                    } 
                    else {
#if FEATURE_COMINTEROP 
                        ptr = Marshal.AllocCoTaskMem(byteCount);
#else // FEATURE_COMINTEROP
                        Contract.Assert(false, "allocateFromHeap must never be set to false when FEATURE_COMINTEROP isn't enabled!");
                        throw new NotSupportedException(); 
#endif // FEATURE_COMINTEROP
                    } 
                } 

                if (ptr == IntPtr.Zero) { 
                    throw new OutOfMemoryException();
                }

                GetAnsiBytes((byte *)ptr.ToPointer(), byteCount); 
                result = ptr;
            } 
            catch (Exception) { 
                ProtectMemory();
                throw; 
            }
            finally {
                ProtectMemory();
                if( result == IntPtr.Zero) { 
                    // If we failed for any reason, free the new buffer
                    if (ptr != IntPtr.Zero) { 
                        Win32Native.ZeroMemory(ptr, (uint)byteCount); 
                        if( allocateFromHeap) {
                            Marshal.FreeHGlobal(ptr); 
                        }
                        else {
#if FEATURE_COMINTEROP
                            Marshal.FreeCoTaskMem(ptr); 
#else // FEATURE_COMINTEROP
                            Contract.Assert(false, "allocateFromHeap must never be set to false when FEATURE_COMINTEROP isn't enabled!"); 
                            throw new NotSupportedException(); 
#endif // FEATURE_COMINTEROP
                        } 
                    }
                }

            } 
            return result;
        } 
 
        [System.Security.SecurityCritical]  // auto-generated
        [ReliabilityContract(Consistency.WillNotCorruptState, Cer.Success)] 
        private void UnProtectMemory() {
            Contract.Assert(!m_buffer.IsInvalid && m_buffer.Length != 0, "Invalid buffer!");
            Contract.Assert(m_buffer.Length % BlockSize == 0, "buffer length must be multiple of blocksize!");
 
            if( m_length == 0) {
                return; 
            } 

            RuntimeHelpers.PrepareConstrainedRegions(); 
            try {
            }
            finally {
                if (m_encrypted) { 
                    // RtlEncryptMemory return an NTSTATUS
                    int status = Win32Native.SystemFunction041(m_buffer, (uint)m_buffer.Length * 2, ProtectionScope); 
                    if (status < 0) 
                    { // non-negative numbers indicate success
                        throw new CryptographicException(Win32Native.LsaNtStatusToWinError(status)); 
                    }
                    m_encrypted = false;
                }
            } 
        }
    } 
#endif // FEATURE_CRYPTO || FEATURE_X509_SECURESTRINGS 

    [System.Security.SecurityCritical]  // auto-generated 
    [SuppressUnmanagedCodeSecurityAttribute()]
    internal sealed class SafeBSTRHandle : SafeBuffer {
        internal SafeBSTRHandle () : base(true) {}
 
        internal static SafeBSTRHandle Allocate(String src, uint len)
        { 
            SafeBSTRHandle bstr = SysAllocStringLen(src, len); 
            bstr.Initialize(len * sizeof(char));
            return bstr; 
        }

        [ResourceExposure(ResourceScope.None)]
        [DllImport(Win32Native.OLEAUT32, CharSet = CharSet.Unicode)] 
        [ReliabilityContract(Consistency.WillNotCorruptState, Cer.MayFail)]
        private static extern SafeBSTRHandle SysAllocStringLen(String src, uint len);  // BSTR 
 
        [System.Security.SecurityCritical]
        override protected bool ReleaseHandle() 
        {
            Win32Native.ZeroMemory(handle, (uint)Win32Native.SysStringLen(handle) * 2);
            Win32Native.SysFreeString(handle);
            return true; 
        }
 
        [ReliabilityContract(Consistency.WillNotCorruptState, Cer.Success)] 
        internal unsafe void ClearBuffer() {
            byte* bufferPtr = null; 
            RuntimeHelpers.PrepareConstrainedRegions();
            try
            {
                AcquirePointer(ref bufferPtr); 
                Win32Native.ZeroMemory((IntPtr)bufferPtr, (uint)Win32Native.SysStringLen((IntPtr)bufferPtr) * 2);
            } 
            finally 
            {
                if (bufferPtr != null) 
                    ReleasePointer();
            }
        }
 

        internal unsafe int Length { 
            get { 
                return Win32Native.SysStringLen(this);
            } 
        }

        internal unsafe static void Copy(SafeBSTRHandle source, SafeBSTRHandle target) {
            byte* sourcePtr = null, targetPtr = null; 
            RuntimeHelpers.PrepareConstrainedRegions();
            try 
            { 
                source.AcquirePointer(ref sourcePtr);
                target.AcquirePointer(ref targetPtr); 

                Contract.Assert(Win32Native.SysStringLen((IntPtr)targetPtr) >= Win32Native.SysStringLen((IntPtr)sourcePtr), "Target buffer is not large enough!");

                Buffer.memcpyimpl(sourcePtr, targetPtr, Win32Native.SysStringLen((IntPtr)sourcePtr) * 2); 
            }
            finally 
            { 
                if (sourcePtr != null)
                    source.ReleasePointer(); 
                if (targetPtr != null)
                    target.ReleasePointer();
            }
        } 
    }
} 
 

// File provided for Reference Use Only by Microsoft Corporation (c) 2007.
// Copyright (c) Microsoft Corporation. All rights reserved.
// [....] 
namespace System.Security {
    using System.Security.Cryptography;
    using System.Runtime.InteropServices;
#if FEATURE_CORRUPTING_EXCEPTIONS 
    using System.Runtime.ExceptionServices;
#endif // FEATURE_CORRUPTING_EXCEPTIONS 
    using System.Text; 
    using Microsoft.Win32;
    using System.Runtime.CompilerServices; 
    using System.Security.Permissions;
    using System.Runtime.ConstrainedExecution;
    using System.Runtime.Versioning;
    using Microsoft.Win32.SafeHandles; 
    using System.Diagnostics.Contracts;
 
 
#if FEATURE_CRYPTO || FEATURE_X509_SECURESTRINGS
    public sealed class SecureString: IDisposable { 
        [System.Security.SecurityCritical /*auto-generated*/]
        private SafeBSTRHandle m_buffer;
        [ContractPublicPropertyName("Length")]
        private int       m_length; 
        private bool     m_readOnly;
        private bool     m_encrypted; 
 
        static bool supportedOnCurrentPlatform = EncryptionSupported();
 
        const int BlockSize = (int)Win32Native.CRYPTPROTECTMEMORY_BLOCK_SIZE /2;  // a char is two bytes
        const int MaxLength = 65536;
        const uint ProtectionScope = Win32Native.CRYPTPROTECTMEMORY_SAME_PROCESS;
 
        [System.Security.SecuritySafeCritical]  // auto-generated
        static SecureString() 
        { 
        }
 
        [System.Security.SecurityCritical]  // auto-generated
        unsafe static bool EncryptionSupported() {
            // check if the enrypt/decrypt function is supported on current OS
            bool supported = true; 
            try {
                Win32Native.SystemFunction041( 
                    SafeBSTRHandle.Allocate(null , (int)Win32Native.CRYPTPROTECTMEMORY_BLOCK_SIZE), 
                    Win32Native.CRYPTPROTECTMEMORY_BLOCK_SIZE,
                    Win32Native.CRYPTPROTECTMEMORY_SAME_PROCESS); 
            }
            catch (EntryPointNotFoundException) {
                supported = false;
            } 
            return supported;
        } 
 
        [System.Security.SecurityCritical]  // auto-generated
        internal SecureString(SecureString str) { 
            AllocateBuffer(str.BufferLength);
            SafeBSTRHandle.Copy(str.m_buffer, this.m_buffer);
            m_length = str.m_length;
            m_encrypted = str.m_encrypted; 
        }
 
 
        [System.Security.SecuritySafeCritical]  // auto-generated
        public SecureString() { 
            CheckSupportedOnCurrentPlatform();

            // allocate the minimum block size for calling protectMemory
            AllocateBuffer(BlockSize); 
            m_length = 0;
        } 
 

        [System.Security.SecurityCritical]  // auto-generated 
#if FEATURE_CORRUPTING_EXCEPTIONS
        [HandleProcessCorruptedStateExceptions] //
#endif // FEATURE_CORRUPTING_EXCEPTIONS
        private unsafe void InitializeSecureString(char* value, int length) 
        {
            CheckSupportedOnCurrentPlatform(); 
 
            AllocateBuffer(length);
            m_length = length; 

            byte* bufferPtr = null;
            RuntimeHelpers.PrepareConstrainedRegions();
            try 
            {
                m_buffer.AcquirePointer(ref bufferPtr); 
                Buffer.memcpyimpl((byte*)value, bufferPtr, length * 2); 
            }
            catch (Exception) { 
                ProtectMemory();
                throw;
            }
            finally 
            {
                if (bufferPtr != null) 
                    m_buffer.ReleasePointer(); 
            }
 
            ProtectMemory();
        }

        [System.Security.SecurityCritical]  // auto-generated 
        [CLSCompliant(false)]
        public unsafe SecureString(char* value, int length) { 
            if( value == null) { 
                throw new ArgumentNullException("value");
            } 

            if( length < 0) {
                throw new ArgumentOutOfRangeException("length", Environment.GetResourceString("ArgumentOutOfRange_NeedNonNegNum"));
            } 

            if( length > MaxLength) { 
                throw new ArgumentOutOfRangeException("length", Environment.GetResourceString("ArgumentOutOfRange_Length")); 
            }
            Contract.EndContractBlock(); 

            // Refactored since HandleProcessCorruptedStateExceptionsAttribute applies to methods only (yet).
            InitializeSecureString(value, length);
        } 

        public int Length { 
            [System.Security.SecuritySafeCritical]  // auto-generated 
            [MethodImplAttribute(MethodImplOptions.Synchronized)]
            get  { 
                EnsureNotDisposed();
                return m_length;
            }
        } 

        [System.Security.SecuritySafeCritical]  // auto-generated 
        [MethodImplAttribute(MethodImplOptions.Synchronized)] 
#if FEATURE_CORRUPTING_EXCEPTIONS
        [HandleProcessCorruptedStateExceptions] // 
#endif // FEATURE_CORRUPTING_EXCEPTIONS
        public void AppendChar(char c) {
            EnsureNotDisposed();
            EnsureNotReadOnly(); 

            EnsureCapacity(m_length + 1); 
 
            RuntimeHelpers.PrepareConstrainedRegions();
            try { 
                UnProtectMemory();
                m_buffer.Write((uint)m_length * sizeof(char), c);
                m_length++;
            } 
            catch (Exception) {
                ProtectMemory(); 
                throw; 
            }
            finally { 
                ProtectMemory();
            }
        }
 
        // clears the current contents. Only available if writable
        [System.Security.SecuritySafeCritical]  // auto-generated 
        [MethodImplAttribute(MethodImplOptions.Synchronized)] 
        public void Clear() {
            EnsureNotDisposed(); 
            EnsureNotReadOnly();

            m_length = 0;
            m_buffer.ClearBuffer(); 
            m_encrypted = false;
        } 
 
        // Do a deep-copy of the SecureString
        [System.Security.SecuritySafeCritical]  // auto-generated 
        [MethodImplAttribute(MethodImplOptions.Synchronized)]
        public SecureString Copy() {
            EnsureNotDisposed();
            return new SecureString(this); 
        }
 
        [System.Security.SecuritySafeCritical]  // auto-generated 
        [MethodImplAttribute(MethodImplOptions.Synchronized)]
        public void Dispose() { 
            if(m_buffer != null && !m_buffer.IsInvalid) {
                m_buffer.Close();
                m_buffer = null;
            } 
        }
 
        [System.Security.SecuritySafeCritical]  // auto-generated 
        [MethodImplAttribute(MethodImplOptions.Synchronized)]
#if FEATURE_CORRUPTING_EXCEPTIONS 
        [HandleProcessCorruptedStateExceptions] //
#endif // FEATURE_CORRUPTING_EXCEPTIONS
        public void InsertAt( int index, char c ) {
            if( index < 0 || index > m_length) { 
                throw new ArgumentOutOfRangeException("index", Environment.GetResourceString("ArgumentOutOfRange_IndexString"));
            } 
            Contract.EndContractBlock(); 

            EnsureNotDisposed(); 
            EnsureNotReadOnly();

            EnsureCapacity(m_length + 1);
 
            unsafe {
                byte* bufferPtr = null; 
                RuntimeHelpers.PrepareConstrainedRegions(); 
                try {
                    UnProtectMemory(); 
                    m_buffer.AcquirePointer(ref bufferPtr);
                    char* pBuffer = (char*)bufferPtr;

                    for (int i = m_length; i > index; i--) { 
                        pBuffer[i] = pBuffer[i - 1];
                    } 
                    pBuffer[index] = c; 
                    ++m_length;
                } 
                catch (Exception) {
                    ProtectMemory();
                    throw;
                } 
                finally {
                    ProtectMemory(); 
                    if (bufferPtr != null) 
                        m_buffer.ReleasePointer();
                } 
            }
        }

        [System.Security.SecuritySafeCritical]  // auto-generated 
        [MethodImplAttribute(MethodImplOptions.Synchronized)]
        public bool IsReadOnly() { 
            EnsureNotDisposed(); 
            return m_readOnly;
        } 

        [System.Security.SecuritySafeCritical]  // auto-generated
        [MethodImplAttribute(MethodImplOptions.Synchronized)]
        public void MakeReadOnly() { 
            EnsureNotDisposed();
            m_readOnly = true; 
        } 

        [System.Security.SecuritySafeCritical]  // auto-generated 
        [MethodImplAttribute(MethodImplOptions.Synchronized)]
#if FEATURE_CORRUPTING_EXCEPTIONS
        [HandleProcessCorruptedStateExceptions] //
#endif // FEATURE_CORRUPTING_EXCEPTIONS 
        public void RemoveAt( int index ) {
            EnsureNotDisposed(); 
            EnsureNotReadOnly(); 

            if( index < 0 || index >= m_length) { 
                throw new ArgumentOutOfRangeException("index", Environment.GetResourceString("ArgumentOutOfRange_IndexString"));
            }

            unsafe 
            {
                byte* bufferPtr = null; 
                RuntimeHelpers.PrepareConstrainedRegions(); 
                try
                { 
                    UnProtectMemory();
                    m_buffer.AcquirePointer(ref bufferPtr);
                    char* pBuffer = (char*)bufferPtr;
 
                    for (int i = index; i < m_length - 1; i++)
                    { 
                        pBuffer[i] = pBuffer[i + 1]; 
                    }
                    pBuffer[--m_length] = (char)0; 
                }
                catch (Exception) {
                    ProtectMemory();
                    throw; 
                }
                finally 
                { 
                    ProtectMemory();
                    if (bufferPtr != null) 
                        m_buffer.ReleasePointer();
                }
            }
        } 

        [System.Security.SecuritySafeCritical]  // auto-generated 
        [MethodImplAttribute(MethodImplOptions.Synchronized)] 
#if FEATURE_CORRUPTING_EXCEPTIONS
        [HandleProcessCorruptedStateExceptions] // 
#endif // FEATURE_CORRUPTING_EXCEPTIONS
        public void SetAt( int index, char c ) {
            if( index < 0 || index >= m_length) {
                throw new ArgumentOutOfRangeException("index", Environment.GetResourceString("ArgumentOutOfRange_IndexString")); 
            }
            Contract.EndContractBlock(); 
            Contract.Assert(index <= Int32.MaxValue / sizeof(char)); 

            EnsureNotDisposed(); 
            EnsureNotReadOnly();

            RuntimeHelpers.PrepareConstrainedRegions();
            try { 
                UnProtectMemory();
                m_buffer.Write((uint)index * sizeof(char), c); 
            } 
            catch (Exception) {
                ProtectMemory(); 
                throw;
            }
            finally {
                ProtectMemory(); 
            }
        } 
 
        private int BufferLength {
            [System.Security.SecurityCritical]  // auto-generated 
            get {
                Contract.Assert(m_buffer != null, "Buffer is not initialized!");
                return m_buffer.Length;
            } 
        }
 
        [System.Security.SecurityCritical]  // auto-generated 
        [ReliabilityContract(Consistency.WillNotCorruptState, Cer.MayFail)]
        private void AllocateBuffer(int size) { 
            uint alignedSize = GetAlignedSize(size);

            m_buffer = SafeBSTRHandle.Allocate(null, alignedSize);
            if (m_buffer.IsInvalid) { 
                throw new OutOfMemoryException();
            } 
        } 

        private void CheckSupportedOnCurrentPlatform() { 
            if( !supportedOnCurrentPlatform) {
                throw new NotSupportedException(Environment.GetResourceString("Arg_PlatformSecureString"));
            }
            Contract.EndContractBlock(); 
        }
 
        [System.Security.SecurityCritical]  // auto-generated 
        private void EnsureCapacity(int capacity) {
            if( capacity > MaxLength) { 
                throw new ArgumentOutOfRangeException("capacity", Environment.GetResourceString("ArgumentOutOfRange_Capacity"));
            }
            Contract.EndContractBlock();
 
            if( capacity <= m_buffer.Length) {
                return; 
            } 

            SafeBSTRHandle newBuffer = SafeBSTRHandle.Allocate(null, GetAlignedSize(capacity)); 

            if (newBuffer.IsInvalid) {
                throw new OutOfMemoryException();
            } 

            SafeBSTRHandle.Copy(m_buffer, newBuffer); 
            m_buffer.Close(); 
            m_buffer = newBuffer;
        } 

        [System.Security.SecurityCritical]  // auto-generated
        private void EnsureNotDisposed() {
            if( m_buffer == null) { 
                throw new ObjectDisposedException(null);
            } 
            Contract.EndContractBlock(); 
        }
 
        private void EnsureNotReadOnly() {
            if( m_readOnly) {
                throw new InvalidOperationException(Environment.GetResourceString("InvalidOperation_ReadOnly"));
            } 
            Contract.EndContractBlock();
        } 
 
        [ReliabilityContract(Consistency.WillNotCorruptState, Cer.Success)]
        private static uint GetAlignedSize( int size) { 
            Contract.Assert(size >= 0, "size must be non-negative");

            uint alignedSize = ((uint)size / BlockSize) * BlockSize;
            if( (size % BlockSize != 0) || size == 0) {  // if size is 0, set allocated size to blocksize 
                alignedSize += BlockSize;
            } 
            return alignedSize; 
        }
 
        [System.Security.SecurityCritical]  // auto-generated
        private unsafe int GetAnsiByteCount() {
            const uint CP_ACP               = 0;
            const uint WC_NO_BEST_FIT_CHARS = 0x00000400; 

            uint flgs = WC_NO_BEST_FIT_CHARS; 
            uint DefaultCharUsed = (uint)'?'; 

            byte* bufferPtr = null; 
            RuntimeHelpers.PrepareConstrainedRegions();
            try {
                m_buffer.AcquirePointer(ref bufferPtr);
 
                return Win32Native.WideCharToMultiByte(
                    CP_ACP, 
                    flgs, 
                    (char*) bufferPtr,
                    m_length, 
                    null,
                    0,
                    IntPtr.Zero,
                    new IntPtr((void*)&DefaultCharUsed)); 
            }
            finally { 
                if (bufferPtr != null) 
                    m_buffer.ReleasePointer();
            } 
        }

        [System.Security.SecurityCritical]  // auto-generated
        private unsafe void GetAnsiBytes( byte * ansiStrPtr, int byteCount) { 
            const uint CP_ACP               = 0;
            const uint WC_NO_BEST_FIT_CHARS = 0x00000400; 
 
            uint flgs = WC_NO_BEST_FIT_CHARS;
            uint DefaultCharUsed = (uint)'?'; 

            byte* bufferPtr = null;
            RuntimeHelpers.PrepareConstrainedRegions();
            try { 
                m_buffer.AcquirePointer(ref bufferPtr);
 
                Win32Native.WideCharToMultiByte( 
                    CP_ACP,
                    flgs, 
                    (char*) bufferPtr,
                    m_length,
                    ansiStrPtr,
                    byteCount - 1, 
                    IntPtr.Zero,
                    new IntPtr((void*)&DefaultCharUsed)); 
 
                *(ansiStrPtr + byteCount - 1) = (byte)0;
            } 
            finally {
                if (bufferPtr != null)
                    m_buffer.ReleasePointer();
            } 
        }
 
        [System.Security.SecurityCritical]  // auto-generated 
        [ReliabilityContract(Consistency.MayCorruptInstance, Cer.MayFail)]
        private void ProtectMemory() { 
            Contract.Assert(!m_buffer.IsInvalid && m_buffer.Length != 0, "Invalid buffer!");
            Contract.Assert(m_buffer.Length % BlockSize == 0, "buffer length must be multiple of blocksize!");

            if( m_length == 0 || m_encrypted) { 
                return;
            } 
 
            RuntimeHelpers.PrepareConstrainedRegions();
            try { 
            }
            finally {
                // RtlEncryptMemory return an NTSTATUS
                int status = Win32Native.SystemFunction040(m_buffer, (uint)m_buffer.Length * 2, ProtectionScope); 
                if (status < 0)  { // non-negative numbers indicate success
                    throw new CryptographicException(Win32Native.LsaNtStatusToWinError(status)); 
                } 
                m_encrypted = true;
            } 
        }

        [System.Security.SecurityCritical]  // auto-generated
        [ReliabilityContract(Consistency.WillNotCorruptState, Cer.MayFail)] 
        [MethodImplAttribute(MethodImplOptions.Synchronized)]
#if FEATURE_CORRUPTING_EXCEPTIONS 
        [HandleProcessCorruptedStateExceptions] // 
#endif // FEATURE_CORRUPTING_EXCEPTIONS
        internal unsafe IntPtr ToBSTR() { 
            EnsureNotDisposed();
            int length = m_length;
            IntPtr ptr = IntPtr.Zero;
            IntPtr result = IntPtr.Zero; 
            byte* bufferPtr = null;
 
            RuntimeHelpers.PrepareConstrainedRegions(); 
            try {
                RuntimeHelpers.PrepareConstrainedRegions(); 
                try {
                }
                finally {
                    ptr = Win32Native.SysAllocStringLen(null, length); 
                }
 
                if (ptr == IntPtr.Zero) { 
                    throw new OutOfMemoryException();
                } 

                UnProtectMemory();
                m_buffer.AcquirePointer(ref bufferPtr);
                Buffer.memcpyimpl(bufferPtr, (byte*) ptr.ToPointer(), length *2); 
                result = ptr;
            } 
            catch (Exception) { 
                ProtectMemory();
                throw; 
            }
            finally {
                ProtectMemory();
                if( result == IntPtr.Zero) { 
                    // If we failed for any reason, free the new buffer
                    if (ptr != IntPtr.Zero) { 
                        Win32Native.ZeroMemory(ptr, (uint)(length * 2)); 
                        Win32Native.SysFreeString(ptr);
                    } 
                }
                if (bufferPtr != null)
                    m_buffer.ReleasePointer();
            } 
            return result;
        } 
 
        [System.Security.SecurityCritical]  // auto-generated
        [MethodImplAttribute(MethodImplOptions.Synchronized)] 
#if FEATURE_CORRUPTING_EXCEPTIONS
        [HandleProcessCorruptedStateExceptions] //
#endif // FEATURE_CORRUPTING_EXCEPTIONS
        internal unsafe IntPtr ToUniStr(bool allocateFromHeap) { 
            EnsureNotDisposed();
            int length = m_length; 
            IntPtr ptr = IntPtr.Zero; 
            IntPtr result = IntPtr.Zero;
            byte* bufferPtr = null; 

            RuntimeHelpers.PrepareConstrainedRegions();
            try {
                RuntimeHelpers.PrepareConstrainedRegions(); 
                try {
                } 
                finally { 
                    if( allocateFromHeap) {
                        ptr = Marshal.AllocHGlobal((length + 1) * 2); 
                    }
                    else {
#if FEATURE_COMINTEROP
                        ptr = Marshal.AllocCoTaskMem((length + 1) * 2); 
#else // FEATURE_COMINTEROP
                        Contract.Assert(false, "allocateFromHeap must never be set to false when FEATURE_COMINTEROP isn't enabled!"); 
                        throw new NotSupportedException(); 
#endif // FEATURE_COMINTEROP
                    } 
                }

                if (ptr == IntPtr.Zero) {
                    throw new OutOfMemoryException(); 
                }
 
                UnProtectMemory(); 
                m_buffer.AcquirePointer(ref bufferPtr);
                Buffer.memcpyimpl(bufferPtr, (byte*) ptr.ToPointer(), length *2); 
                char * endptr = (char *) ptr.ToPointer();
                *(endptr + length) = '\0';
                result = ptr;
            } 
            catch (Exception) {
                ProtectMemory(); 
                throw; 
            }
            finally { 
                ProtectMemory();

                if( result == IntPtr.Zero) {
                    // If we failed for any reason, free the new buffer 
                    if (ptr != IntPtr.Zero) {
                        Win32Native.ZeroMemory(ptr, (uint)(length * 2)); 
                        if( allocateFromHeap) { 
                            Marshal.FreeHGlobal(ptr);
                        } 
                        else {
#if FEATURE_COMINTEROP
                            Marshal.FreeCoTaskMem(ptr);
#else // FEATURE_COMINTEROP 
                            Contract.Assert(false, "allocateFromHeap must never be set to false when FEATURE_COMINTEROP isn't enabled!");
                            throw new NotSupportedException(); 
#endif // FEATURE_COMINTEROP 
                        }
                    } 
                }

                if (bufferPtr != null)
                    m_buffer.ReleasePointer(); 
            }
            return result; 
        } 

        [System.Security.SecurityCritical]  // auto-generated 
        [MethodImplAttribute(MethodImplOptions.Synchronized)]
#if FEATURE_CORRUPTING_EXCEPTIONS
        [HandleProcessCorruptedStateExceptions] //
#endif // FEATURE_CORRUPTING_EXCEPTIONS 
        internal unsafe IntPtr ToAnsiStr(bool allocateFromHeap) {
            EnsureNotDisposed(); 
 
            IntPtr ptr = IntPtr.Zero;
            IntPtr result = IntPtr.Zero; 
            int byteCount = 0;
            RuntimeHelpers.PrepareConstrainedRegions();
            try {
                // GetAnsiByteCount uses the string data, so the calculation must happen after we are decrypted. 
                UnProtectMemory();
 
                // allocating an extra char for terminating zero 
                byteCount = GetAnsiByteCount() + 1;
 
                RuntimeHelpers.PrepareConstrainedRegions();
                try {
                }
                finally { 
                    if( allocateFromHeap) {
                        ptr = Marshal.AllocHGlobal(byteCount); 
                    } 
                    else {
#if FEATURE_COMINTEROP 
                        ptr = Marshal.AllocCoTaskMem(byteCount);
#else // FEATURE_COMINTEROP
                        Contract.Assert(false, "allocateFromHeap must never be set to false when FEATURE_COMINTEROP isn't enabled!");
                        throw new NotSupportedException(); 
#endif // FEATURE_COMINTEROP
                    } 
                } 

                if (ptr == IntPtr.Zero) { 
                    throw new OutOfMemoryException();
                }

                GetAnsiBytes((byte *)ptr.ToPointer(), byteCount); 
                result = ptr;
            } 
            catch (Exception) { 
                ProtectMemory();
                throw; 
            }
            finally {
                ProtectMemory();
                if( result == IntPtr.Zero) { 
                    // If we failed for any reason, free the new buffer
                    if (ptr != IntPtr.Zero) { 
                        Win32Native.ZeroMemory(ptr, (uint)byteCount); 
                        if( allocateFromHeap) {
                            Marshal.FreeHGlobal(ptr); 
                        }
                        else {
#if FEATURE_COMINTEROP
                            Marshal.FreeCoTaskMem(ptr); 
#else // FEATURE_COMINTEROP
                            Contract.Assert(false, "allocateFromHeap must never be set to false when FEATURE_COMINTEROP isn't enabled!"); 
                            throw new NotSupportedException(); 
#endif // FEATURE_COMINTEROP
                        } 
                    }
                }

            } 
            return result;
        } 
 
        [System.Security.SecurityCritical]  // auto-generated
        [ReliabilityContract(Consistency.WillNotCorruptState, Cer.Success)] 
        private void UnProtectMemory() {
            Contract.Assert(!m_buffer.IsInvalid && m_buffer.Length != 0, "Invalid buffer!");
            Contract.Assert(m_buffer.Length % BlockSize == 0, "buffer length must be multiple of blocksize!");
 
            if( m_length == 0) {
                return; 
            } 

            RuntimeHelpers.PrepareConstrainedRegions(); 
            try {
            }
            finally {
                if (m_encrypted) { 
                    // RtlEncryptMemory return an NTSTATUS
                    int status = Win32Native.SystemFunction041(m_buffer, (uint)m_buffer.Length * 2, ProtectionScope); 
                    if (status < 0) 
                    { // non-negative numbers indicate success
                        throw new CryptographicException(Win32Native.LsaNtStatusToWinError(status)); 
                    }
                    m_encrypted = false;
                }
            } 
        }
    } 
#endif // FEATURE_CRYPTO || FEATURE_X509_SECURESTRINGS 

    [System.Security.SecurityCritical]  // auto-generated 
    [SuppressUnmanagedCodeSecurityAttribute()]
    internal sealed class SafeBSTRHandle : SafeBuffer {
        internal SafeBSTRHandle () : base(true) {}
 
        internal static SafeBSTRHandle Allocate(String src, uint len)
        { 
            SafeBSTRHandle bstr = SysAllocStringLen(src, len); 
            bstr.Initialize(len * sizeof(char));
            return bstr; 
        }

        [ResourceExposure(ResourceScope.None)]
        [DllImport(Win32Native.OLEAUT32, CharSet = CharSet.Unicode)] 
        [ReliabilityContract(Consistency.WillNotCorruptState, Cer.MayFail)]
        private static extern SafeBSTRHandle SysAllocStringLen(String src, uint len);  // BSTR 
 
        [System.Security.SecurityCritical]
        override protected bool ReleaseHandle() 
        {
            Win32Native.ZeroMemory(handle, (uint)Win32Native.SysStringLen(handle) * 2);
            Win32Native.SysFreeString(handle);
            return true; 
        }
 
        [ReliabilityContract(Consistency.WillNotCorruptState, Cer.Success)] 
        internal unsafe void ClearBuffer() {
            byte* bufferPtr = null; 
            RuntimeHelpers.PrepareConstrainedRegions();
            try
            {
                AcquirePointer(ref bufferPtr); 
                Win32Native.ZeroMemory((IntPtr)bufferPtr, (uint)Win32Native.SysStringLen((IntPtr)bufferPtr) * 2);
            } 
            finally 
            {
                if (bufferPtr != null) 
                    ReleasePointer();
            }
        }
 

        internal unsafe int Length { 
            get { 
                return Win32Native.SysStringLen(this);
            } 
        }

        internal unsafe static void Copy(SafeBSTRHandle source, SafeBSTRHandle target) {
            byte* sourcePtr = null, targetPtr = null; 
            RuntimeHelpers.PrepareConstrainedRegions();
            try 
            { 
                source.AcquirePointer(ref sourcePtr);
                target.AcquirePointer(ref targetPtr); 

                Contract.Assert(Win32Native.SysStringLen((IntPtr)targetPtr) >= Win32Native.SysStringLen((IntPtr)sourcePtr), "Target buffer is not large enough!");

                Buffer.memcpyimpl(sourcePtr, targetPtr, Win32Native.SysStringLen((IntPtr)sourcePtr) * 2); 
            }
            finally 
            { 
                if (sourcePtr != null)
                    source.ReleasePointer(); 
                if (targetPtr != null)
                    target.ReleasePointer();
            }
        } 
    }
} 
 

// File provided for Reference Use Only by Microsoft Corporation (c) 2007.
// Copyright (c) Microsoft Corporation. All rights reserved.

                        

Link Menu

Network programming in C#, Network Programming in VB.NET, Network Programming in .NET
This book is available now!
Buy at Amazon US or
Buy at Amazon UK