internal unsafe IntPtr MarshalToBSTRCore()
        {
            int    length    = _decryptedLength;
            IntPtr ptr       = IntPtr.Zero;
            IntPtr result    = IntPtr.Zero;
            byte * bufferPtr = null;

            try
            {
                _buffer.AcquirePointer(ref bufferPtr);
                int resultByteLength = (length + 1) * sizeof(char);

                ptr = Marshal.AllocBSTR(length);

                Buffer.MemoryCopy(bufferPtr, (byte *)ptr, resultByteLength, length * sizeof(char));

                result = ptr;
            }
            finally
            {
                // If we failed for any reason, free the new buffer
                if (result == IntPtr.Zero && ptr != IntPtr.Zero)
                {
                    RuntimeImports.RhZeroMemory(ptr, (UIntPtr)(length * sizeof(char)));
                    Marshal.FreeBSTR(ptr);
                }

                if (bufferPtr != null)
                {
                    _buffer.ReleasePointer();
                }
            }
            return(result);
        }
Beispiel #2
0
        internal unsafe IntPtr MarshalToBSTR()
        {
            lock (_methodLock)
            {
                EnsureNotDisposed();

                UnprotectMemory();

                SafeBuffer?bufferToRelease = null;
                IntPtr     ptr             = IntPtr.Zero;
                int        length          = 0;
                try
                {
                    Span <char> span = AcquireSpan(ref bufferToRelease);

                    length = _decryptedLength;
                    ptr    = Marshal.AllocBSTR(length);
                    span.Slice(0, length).CopyTo(new Span <char>((void *)ptr, length));

                    IntPtr result = ptr;
                    ptr = IntPtr.Zero;
                    return(result);
                }
                finally
                {
                    // If we failed for any reason, free the new buffer
                    if (ptr != IntPtr.Zero)
                    {
                        new Span <char>((void *)ptr, length).Clear();
                        Marshal.FreeBSTR(ptr);
                    }

                    ProtectMemory();
                    bufferToRelease?.DangerousRelease();
                }
            }
        }