Code:
/ 4.0 / 4.0 / DEVDIV_TFS / Dev10 / Releases / RTMRel / ndp / clr / src / BCL / System / IO / UnmanagedMemoryStream.cs / 1305376 / UnmanagedMemoryStream.cs
// ==++== // // Copyright (c) Microsoft Corporation. All rights reserved. // // ==--== /*============================================================ ** ** Class: UnmanagedMemoryStream ** **[....] ** ** Purpose: Create a stream over unmanaged memory, mostly ** useful for memory-mapped files. ** ** Date: October 20, 2000 (made public August 4, 2003) ** ===========================================================*/ using System; using System.Runtime; using System.Runtime.CompilerServices; using System.Runtime.InteropServices; using System.Security.Permissions; using System.Threading; using System.Diagnostics.Contracts; namespace System.IO { /* * This class is used to access a contiguous block of memory, likely outside * the GC heap (or pinned in place in the GC heap, but a MemoryStream may * make more sense in those cases). It's great if you have a pointer and * a length for a section of memory mapped in by someone else and you don't * want to copy this into the GC heap. UnmanagedMemoryStream assumes these * two things: * * 1) All the memory in the specified block is readable or writable, * depending on the values you pass to the constructor. * 2) The lifetime of the block of memory is at least as long as the lifetime * of the UnmanagedMemoryStream. * 3) You clean up the memory when appropriate. The UnmanagedMemoryStream * currently will do NOTHING to free this memory. * 4) All calls to Write and WriteByte may not be threadsafe currently. * * It may become necessary to add in some sort of * DeallocationMode enum, specifying whether we unmap a section of memory, * call free, run a user-provided delegate to free the memory, etc etc. * We'll suggest user write a subclass of UnmanagedMemoryStream that uses * a SafeHandle subclass to hold onto the memory. * Check for problems when using this in the negative parts of a * process's address space. We may need to use unsigned longs internally * and change the overflow detection logic. * * -----SECURITY MODEL AND SILVERLIGHT----- * A few key notes about exposing UMS in silverlight: * 1. No ctors are exposed to transparent code. This version of UMS only * supports byte* (not SafeBuffer). Therefore, framework code can create * a UMS and hand it to transparent code. Transparent code can use most * operations on a UMS, but not operations that directly expose a * pointer. * * 2. Scope of "unsafe" and non-CLS compliant operations reduced: The * Whidbey version of this class has CLSCompliant(false) at the class * level and unsafe modifiers at the method level. These were reduced to * only where the unsafe operation is performed -- i.e. immediately * around the pointer manipulation. Note that this brings UMS in line * with recent changes in pu/clr to support SafeBuffer. * * 3. Currently, the only caller that creates a UMS is ResourceManager, * which creates read-only UMSs, and therefore operations that can * change the length will throw because write isn't supported. A * conservative option would be to formalize the concept that _only_ * read-only UMSs can be creates, and enforce this by making WriteX and * SetLength SecurityCritical. However, this is a violation of * security inheritance rules, so we must keep these safe. The * following notes make this acceptable for future use. * a. a race condition in WriteX that could have allowed a thread to * read from unzeroed memory was fixed * b. memory region cannot be expanded beyond _capacity; in other * words, a UMS creator is saying a writeable UMS is safe to * write to anywhere in the memory range up to _capacity, specified * in the ctor. Even if the caller doesn't specify a capacity, then * length is used as the capacity. */ public class UnmanagedMemoryStream : Stream { // private const long UnmanagedMemStreamMaxLength = Int64.MaxValue; [System.Security.SecurityCritical /*auto-generated*/] private SafeBuffer _buffer; private unsafe byte* _mem; private long _length; private long _capacity; private long _position; private long _offset; private FileAccess _access; internal bool _isOpen; // Needed for subclasses that need to map a file, etc. [System.Security.SecuritySafeCritical] // auto-generated protected UnmanagedMemoryStream() { unsafe { _mem = null; } _isOpen = false; } [System.Security.SecuritySafeCritical] // auto-generated public UnmanagedMemoryStream(SafeBuffer buffer, long offset, long length) { Initialize(buffer, offset, length, FileAccess.Read, false); } [System.Security.SecuritySafeCritical] // auto-generated public UnmanagedMemoryStream(SafeBuffer buffer, long offset, long length, FileAccess access) { Initialize(buffer, offset, length, access, false); } // We must create one of these without doing a security check. This // class is created while security is trying to start up. Plus, doing // a Demand from Assembly.GetManifestResourceStream isn't useful. [System.Security.SecurityCritical] // auto-generated internal UnmanagedMemoryStream(SafeBuffer buffer, long offset, long length, FileAccess access, bool skipSecurityCheck) { Initialize(buffer, offset, length, access, skipSecurityCheck); } [System.Security.SecuritySafeCritical] // auto-generated protected void Initialize(SafeBuffer buffer, long offset, long length, FileAccess access) { Initialize(buffer, offset, length, access, false); } [System.Security.SecurityCritical] // auto-generated internal void Initialize(SafeBuffer buffer, long offset, long length, FileAccess access, bool skipSecurityCheck) { if (buffer == null) { throw new ArgumentNullException("buffer"); } if (offset < 0) { throw new ArgumentOutOfRangeException("offset", Environment.GetResourceString("ArgumentOutOfRange_NeedNonNegNum")); } if (length < 0) { throw new ArgumentOutOfRangeException("length", Environment.GetResourceString("ArgumentOutOfRange_NeedNonNegNum")); } if (buffer.ByteLength < (ulong)(offset + length)) { throw new ArgumentException(Environment.GetResourceString("Argument_InvalidSafeBufferOffLen")); } if (access < FileAccess.Read || access > FileAccess.ReadWrite) { throw new ArgumentOutOfRangeException("access"); } Contract.EndContractBlock(); if (_isOpen) { throw new InvalidOperationException(Environment.GetResourceString("InvalidOperation_CalledTwice")); } if (!skipSecurityCheck) { new SecurityPermission(SecurityPermissionFlag.UnmanagedCode).Demand(); } // check for wraparound unsafe { byte* pointer = null; RuntimeHelpers.PrepareConstrainedRegions(); try { buffer.AcquirePointer(ref pointer); if ( (pointer + offset + length) < pointer) { throw new ArgumentException(Environment.GetResourceString("ArgumentOutOfRange_UnmanagedMemStreamWrapAround")); } } finally { if (pointer != null) { buffer.ReleasePointer(); } } } _offset = offset; _buffer = buffer; _length = length; _capacity = length; _access = access; _isOpen = true; } [System.Security.SecurityCritical] // auto-generated [CLSCompliant(false)] public unsafe UnmanagedMemoryStream(byte* pointer, long length) { Initialize(pointer, length, length, FileAccess.Read, false); } [System.Security.SecurityCritical] // auto-generated [CLSCompliant(false)] public unsafe UnmanagedMemoryStream(byte* pointer, long length, long capacity, FileAccess access) { Initialize(pointer, length, capacity, access, false); } // We must create one of these without doing a security check. This // class is created while security is trying to start up. Plus, doing // a Demand from Assembly.GetManifestResourceStream isn't useful. [System.Security.SecurityCritical] // auto-generated internal unsafe UnmanagedMemoryStream(byte* pointer, long length, long capacity, FileAccess access, bool skipSecurityCheck) { Initialize(pointer, length, capacity, access, skipSecurityCheck); } [System.Security.SecurityCritical] // auto-generated [CLSCompliant(false)] protected unsafe void Initialize(byte* pointer, long length, long capacity, FileAccess access) { Initialize(pointer, length, capacity, access, false); } [System.Security.SecurityCritical] // auto-generated internal unsafe void Initialize(byte* pointer, long length, long capacity, FileAccess access, bool skipSecurityCheck) { if (pointer == null) throw new ArgumentNullException("pointer"); if (length < 0 || capacity < 0) throw new ArgumentOutOfRangeException((length < 0) ? "length" : "capacity", Environment.GetResourceString("ArgumentOutOfRange_NeedNonNegNum")); if (length > capacity) throw new ArgumentOutOfRangeException("length", Environment.GetResourceString("ArgumentOutOfRange_LengthGreaterThanCapacity")); Contract.EndContractBlock(); // Check for wraparound. if (((byte*) ((long)pointer + capacity)) < pointer) throw new ArgumentOutOfRangeException("capacity", Environment.GetResourceString("ArgumentOutOfRange_UnmanagedMemStreamWrapAround")); if (access < FileAccess.Read || access > FileAccess.ReadWrite) throw new ArgumentOutOfRangeException("access", Environment.GetResourceString("ArgumentOutOfRange_Enum")); if (_isOpen) throw new InvalidOperationException(Environment.GetResourceString("InvalidOperation_CalledTwice")); if (!skipSecurityCheck) new SecurityPermission(SecurityPermissionFlag.UnmanagedCode).Demand(); _mem = pointer; _offset = 0; _length = length; _capacity = capacity; _access = access; _isOpen = true; } public override bool CanRead { [Pure] #if !FEATURE_CORECLR [TargetedPatchingOptOut("Performance critical to inline across NGen image boundaries")] #endif get { return _isOpen && (_access & FileAccess.Read) != 0; } } public override bool CanSeek { [Pure] #if !FEATURE_CORECLR [TargetedPatchingOptOut("Performance critical to inline across NGen image boundaries")] #endif get { return _isOpen; } } public override bool CanWrite { [Pure] #if !FEATURE_CORECLR [TargetedPatchingOptOut("Performance critical to inline across NGen image boundaries")] #endif get { return _isOpen && (_access & FileAccess.Write) != 0; } } [System.Security.SecuritySafeCritical] // auto-generated protected override void Dispose(bool disposing) { _isOpen = false; unsafe { _mem = null; } // Stream allocates WaitHandles for async calls. So for correctness // call base.Dispose(disposing) for better perf, avoiding waiting // for the finalizers to run on those types. base.Dispose(disposing); } public override void Flush() { if (!_isOpen) __Error.StreamIsClosed(); } public override long Length { #if !FEATURE_CORECLR [TargetedPatchingOptOut("Performance critical to inline across NGen image boundaries")] #endif get { if (!_isOpen) __Error.StreamIsClosed(); return Interlocked.Read(ref _length); } } public long Capacity { get { if (!_isOpen) __Error.StreamIsClosed(); return _capacity; } } public override long Position { #if !FEATURE_CORECLR [TargetedPatchingOptOut("Performance critical to inline across NGen image boundaries")] #endif get { if (!CanSeek) __Error.StreamIsClosed(); Contract.EndContractBlock(); return Interlocked.Read(ref _position); } [System.Security.SecuritySafeCritical] // auto-generated set { if (value < 0) throw new ArgumentOutOfRangeException("value", Environment.GetResourceString("ArgumentOutOfRange_NeedNonNegNum")); Contract.EndContractBlock(); if (!CanSeek) __Error.StreamIsClosed(); #if WIN32 unsafe { // On 32 bit machines, ensure we don't wrap around. if (value > (long) Int32.MaxValue || _mem + value < _mem) throw new ArgumentOutOfRangeException("value", Environment.GetResourceString("ArgumentOutOfRange_StreamLength")); } #endif Interlocked.Exchange(ref _position, value); } } [CLSCompliant(false)] public unsafe byte* PositionPointer { [System.Security.SecurityCritical] // auto-generated_required get { if (_buffer != null) { throw new NotSupportedException(Environment.GetResourceString("NotSupported_UmsSafeBuffer")); } // Use a temp to avoid a race long pos = Interlocked.Read(ref _position); if (pos > _capacity) throw new IndexOutOfRangeException(Environment.GetResourceString("IndexOutOfRange_UMSPosition")); byte * ptr = _mem + pos; if (!_isOpen) __Error.StreamIsClosed(); return ptr; } [System.Security.SecurityCritical] // auto-generated_required #if FEATURE_CORECLR //Need the getter to be public and the setter to be internal: TrimSrc doesn't parse into property declarations internal #endif //FEATURE_CORECLR set { if (_buffer != null) throw new NotSupportedException(Environment.GetResourceString("NotSupported_UmsSafeBuffer")); if (!_isOpen) __Error.StreamIsClosed(); // Note: subtracting pointers returns an Int64. Working around // to avoid hitting compiler warning CS0652 on this line. if (new IntPtr(value - _mem).ToInt64() > UnmanagedMemStreamMaxLength) throw new ArgumentOutOfRangeException("offset", Environment.GetResourceString("ArgumentOutOfRange_UnmanagedMemStreamLength")); if (value < _mem) throw new IOException(Environment.GetResourceString("IO.IO_SeekBeforeBegin")); Interlocked.Exchange(ref _position, value - _mem); } } internal unsafe byte* Pointer { [System.Security.SecurityCritical] // auto-generated get { if (_buffer != null) throw new NotSupportedException(Environment.GetResourceString("NotSupported_UmsSafeBuffer")); return _mem; } } [System.Security.SecuritySafeCritical] // auto-generated public override int Read([In, Out] byte[] buffer, int offset, int count) { if (buffer==null) throw new ArgumentNullException("buffer", Environment.GetResourceString("ArgumentNull_Buffer")); if (offset < 0) throw new ArgumentOutOfRangeException("offset", Environment.GetResourceString("ArgumentOutOfRange_NeedNonNegNum")); if (count < 0) throw new ArgumentOutOfRangeException("count", Environment.GetResourceString("ArgumentOutOfRange_NeedNonNegNum")); if (buffer.Length - offset < count) throw new ArgumentException(Environment.GetResourceString("Argument_InvalidOffLen")); Contract.EndContractBlock(); if (!_isOpen) __Error.StreamIsClosed(); if (!CanRead) __Error.ReadNotSupported(); // Use a local variable to avoid a race where another thread // changes our position after we decide we can read some bytes. long pos = Interlocked.Read(ref _position); long len = Interlocked.Read(ref _length); long n = len - pos; if (n > count) n = count; if (n <= 0) return 0; int nInt = (int) n; // Safe because n <= count, which is an Int32 if (nInt < 0) nInt = 0; // _position could be beyond EOF Contract.Assert(pos + nInt >= 0, "_position + n >= 0"); // len is less than 2^63 -1. if (_buffer != null) { unsafe { byte* pointer = null; RuntimeHelpers.PrepareConstrainedRegions(); try { _buffer.AcquirePointer(ref pointer); Buffer.memcpy(pointer + pos + _offset, 0, buffer, offset, nInt); } finally { if (pointer != null) { _buffer.ReleasePointer(); } } } } else { unsafe { Buffer.memcpy(_mem + pos, 0, buffer, offset, nInt); } } Interlocked.Exchange(ref _position, pos + n); return nInt; } [System.Security.SecuritySafeCritical] // auto-generated public override int ReadByte() { if (!_isOpen) __Error.StreamIsClosed(); if (!CanRead) __Error.ReadNotSupported(); long pos = Interlocked.Read(ref _position); // Use a local to avoid a race condition long len = Interlocked.Read(ref _length); if (pos >= len) return -1; Interlocked.Exchange(ref _position, pos + 1); int result; if (_buffer != null) { unsafe { byte* pointer = null; RuntimeHelpers.PrepareConstrainedRegions(); try { _buffer.AcquirePointer(ref pointer); result = *(pointer + pos + _offset); } finally { if (pointer != null) { _buffer.ReleasePointer(); } } } } else { unsafe { result = _mem[pos]; } } return result; } public override long Seek(long offset, SeekOrigin loc) { if (!_isOpen) __Error.StreamIsClosed(); if (offset > UnmanagedMemStreamMaxLength) throw new ArgumentOutOfRangeException("offset", Environment.GetResourceString("ArgumentOutOfRange_UnmanagedMemStreamLength")); switch(loc) { case SeekOrigin.Begin: if (offset < 0) throw new IOException(Environment.GetResourceString("IO.IO_SeekBeforeBegin")); Interlocked.Exchange(ref _position, offset); break; case SeekOrigin.Current: long pos = Interlocked.Read(ref _position); if (offset + pos < 0) throw new IOException(Environment.GetResourceString("IO.IO_SeekBeforeBegin")); Interlocked.Exchange(ref _position, offset + pos); break; case SeekOrigin.End: long len = Interlocked.Read(ref _length); if (len + offset < 0) throw new IOException(Environment.GetResourceString("IO.IO_SeekBeforeBegin")); Interlocked.Exchange(ref _position, len + offset); break; default: throw new ArgumentException(Environment.GetResourceString("Argument_InvalidSeekOrigin")); } long finalPos = Interlocked.Read(ref _position); Contract.Assert(finalPos >= 0, "_position >= 0"); return finalPos; } [System.Security.SecuritySafeCritical] // auto-generated public override void SetLength(long value) { if (value < 0) throw new ArgumentOutOfRangeException("length", Environment.GetResourceString("ArgumentOutOfRange_NeedNonNegNum")); Contract.EndContractBlock(); if (_buffer != null) throw new NotSupportedException(Environment.GetResourceString("NotSupported_UmsSafeBuffer")); if (!_isOpen) __Error.StreamIsClosed(); if (!CanWrite) __Error.WriteNotSupported(); if (value > _capacity) throw new IOException(Environment.GetResourceString("IO.IO_FixedCapacity")); long pos = Interlocked.Read(ref _position); long len = Interlocked.Read(ref _length); if (value > len) { unsafe { Buffer.ZeroMemory(_mem+len, value-len); } } Interlocked.Exchange(ref _length, value); if (pos > value) { Interlocked.Exchange(ref _position, value); } } [System.Security.SecuritySafeCritical] // auto-generated public override void Write(byte[] buffer, int offset, int count) { if (buffer==null) throw new ArgumentNullException("buffer", Environment.GetResourceString("ArgumentNull_Buffer")); if (offset < 0) throw new ArgumentOutOfRangeException("offset", Environment.GetResourceString("ArgumentOutOfRange_NeedNonNegNum")); if (count < 0) throw new ArgumentOutOfRangeException("count", Environment.GetResourceString("ArgumentOutOfRange_NeedNonNegNum")); if (buffer.Length - offset < count) throw new ArgumentException(Environment.GetResourceString("Argument_InvalidOffLen")); Contract.EndContractBlock(); if (!_isOpen) __Error.StreamIsClosed(); if (!CanWrite) __Error.WriteNotSupported(); long pos = Interlocked.Read(ref _position); // Use a local to avoid a race condition long len = Interlocked.Read(ref _length); long n = pos + count; // Check for overflow if (n < 0) throw new IOException(Environment.GetResourceString("IO.IO_StreamTooLong")); if (n > _capacity) { throw new NotSupportedException(Environment.GetResourceString("IO.IO_FixedCapacity")); } if (_buffer == null) { // Check to see whether we are now expanding the stream and must // zero any memory in the middle. if (pos > len) { unsafe { Buffer.ZeroMemory(_mem+len, pos-len); } } // set length after zeroing memory to avoid race condition of accessing unzeroed memory if (n > len) { Interlocked.Exchange(ref _length, n); } } if (_buffer != null) { long bytesLeft = _capacity - pos; if (bytesLeft < count) { throw new ArgumentException(Environment.GetResourceString("Arg_BufferTooSmall")); } unsafe { byte* pointer = null; RuntimeHelpers.PrepareConstrainedRegions(); try { _buffer.AcquirePointer(ref pointer); Buffer.memcpy(buffer, offset, pointer + pos + _offset, 0, count); } finally { if (pointer != null) { _buffer.ReleasePointer(); } } } } else { unsafe { Buffer.memcpy(buffer, offset, _mem + pos, 0, count); } } Interlocked.Exchange(ref _position, n); return; } [System.Security.SecuritySafeCritical] // auto-generated public override void WriteByte(byte value) { if (!_isOpen) __Error.StreamIsClosed(); if (!CanWrite) __Error.WriteNotSupported(); long pos = Interlocked.Read(ref _position); // Use a local to avoid a race condition long len = Interlocked.Read(ref _length); long n = pos + 1; if (pos >= len) { // Check for overflow if (n < 0) throw new IOException(Environment.GetResourceString("IO.IO_StreamTooLong")); if (n > _capacity) throw new NotSupportedException(Environment.GetResourceString("IO.IO_FixedCapacity")); // Check to see whether we are now expanding the stream and must // zero any memory in the middle. // don't do if created from SafeBuffer if (_buffer == null) { if (pos > len) { unsafe { Buffer.ZeroMemory(_mem+len, pos-len); } } // set length after zeroing memory to avoid race condition of accessing unzeroed memory Interlocked.Exchange(ref _length, n); } } if (_buffer != null) { unsafe { byte* pointer = null; RuntimeHelpers.PrepareConstrainedRegions(); try { _buffer.AcquirePointer(ref pointer); *(pointer + pos + _offset) = value; } finally { if (pointer != null) { _buffer.ReleasePointer(); } } } } else { unsafe { _mem[pos] = value; } } Interlocked.Exchange(ref _position, n); } } } // File provided for Reference Use Only by Microsoft Corporation (c) 2007. // ==++== // // Copyright (c) Microsoft Corporation. All rights reserved. // // ==--== /*============================================================ ** ** Class: UnmanagedMemoryStream ** **[....] ** ** Purpose: Create a stream over unmanaged memory, mostly ** useful for memory-mapped files. ** ** Date: October 20, 2000 (made public August 4, 2003) ** ===========================================================*/ using System; using System.Runtime; using System.Runtime.CompilerServices; using System.Runtime.InteropServices; using System.Security.Permissions; using System.Threading; using System.Diagnostics.Contracts; namespace System.IO { /* * This class is used to access a contiguous block of memory, likely outside * the GC heap (or pinned in place in the GC heap, but a MemoryStream may * make more sense in those cases). It's great if you have a pointer and * a length for a section of memory mapped in by someone else and you don't * want to copy this into the GC heap. UnmanagedMemoryStream assumes these * two things: * * 1) All the memory in the specified block is readable or writable, * depending on the values you pass to the constructor. * 2) The lifetime of the block of memory is at least as long as the lifetime * of the UnmanagedMemoryStream. * 3) You clean up the memory when appropriate. The UnmanagedMemoryStream * currently will do NOTHING to free this memory. * 4) All calls to Write and WriteByte may not be threadsafe currently. * * It may become necessary to add in some sort of * DeallocationMode enum, specifying whether we unmap a section of memory, * call free, run a user-provided delegate to free the memory, etc etc. * We'll suggest user write a subclass of UnmanagedMemoryStream that uses * a SafeHandle subclass to hold onto the memory. * Check for problems when using this in the negative parts of a * process's address space. We may need to use unsigned longs internally * and change the overflow detection logic. * * -----SECURITY MODEL AND SILVERLIGHT----- * A few key notes about exposing UMS in silverlight: * 1. No ctors are exposed to transparent code. This version of UMS only * supports byte* (not SafeBuffer). Therefore, framework code can create * a UMS and hand it to transparent code. Transparent code can use most * operations on a UMS, but not operations that directly expose a * pointer. * * 2. Scope of "unsafe" and non-CLS compliant operations reduced: The * Whidbey version of this class has CLSCompliant(false) at the class * level and unsafe modifiers at the method level. These were reduced to * only where the unsafe operation is performed -- i.e. immediately * around the pointer manipulation. Note that this brings UMS in line * with recent changes in pu/clr to support SafeBuffer. * * 3. Currently, the only caller that creates a UMS is ResourceManager, * which creates read-only UMSs, and therefore operations that can * change the length will throw because write isn't supported. A * conservative option would be to formalize the concept that _only_ * read-only UMSs can be creates, and enforce this by making WriteX and * SetLength SecurityCritical. However, this is a violation of * security inheritance rules, so we must keep these safe. The * following notes make this acceptable for future use. * a. a race condition in WriteX that could have allowed a thread to * read from unzeroed memory was fixed * b. memory region cannot be expanded beyond _capacity; in other * words, a UMS creator is saying a writeable UMS is safe to * write to anywhere in the memory range up to _capacity, specified * in the ctor. Even if the caller doesn't specify a capacity, then * length is used as the capacity. */ public class UnmanagedMemoryStream : Stream { // private const long UnmanagedMemStreamMaxLength = Int64.MaxValue; [System.Security.SecurityCritical /*auto-generated*/] private SafeBuffer _buffer; private unsafe byte* _mem; private long _length; private long _capacity; private long _position; private long _offset; private FileAccess _access; internal bool _isOpen; // Needed for subclasses that need to map a file, etc. [System.Security.SecuritySafeCritical] // auto-generated protected UnmanagedMemoryStream() { unsafe { _mem = null; } _isOpen = false; } [System.Security.SecuritySafeCritical] // auto-generated public UnmanagedMemoryStream(SafeBuffer buffer, long offset, long length) { Initialize(buffer, offset, length, FileAccess.Read, false); } [System.Security.SecuritySafeCritical] // auto-generated public UnmanagedMemoryStream(SafeBuffer buffer, long offset, long length, FileAccess access) { Initialize(buffer, offset, length, access, false); } // We must create one of these without doing a security check. This // class is created while security is trying to start up. Plus, doing // a Demand from Assembly.GetManifestResourceStream isn't useful. [System.Security.SecurityCritical] // auto-generated internal UnmanagedMemoryStream(SafeBuffer buffer, long offset, long length, FileAccess access, bool skipSecurityCheck) { Initialize(buffer, offset, length, access, skipSecurityCheck); } [System.Security.SecuritySafeCritical] // auto-generated protected void Initialize(SafeBuffer buffer, long offset, long length, FileAccess access) { Initialize(buffer, offset, length, access, false); } [System.Security.SecurityCritical] // auto-generated internal void Initialize(SafeBuffer buffer, long offset, long length, FileAccess access, bool skipSecurityCheck) { if (buffer == null) { throw new ArgumentNullException("buffer"); } if (offset < 0) { throw new ArgumentOutOfRangeException("offset", Environment.GetResourceString("ArgumentOutOfRange_NeedNonNegNum")); } if (length < 0) { throw new ArgumentOutOfRangeException("length", Environment.GetResourceString("ArgumentOutOfRange_NeedNonNegNum")); } if (buffer.ByteLength < (ulong)(offset + length)) { throw new ArgumentException(Environment.GetResourceString("Argument_InvalidSafeBufferOffLen")); } if (access < FileAccess.Read || access > FileAccess.ReadWrite) { throw new ArgumentOutOfRangeException("access"); } Contract.EndContractBlock(); if (_isOpen) { throw new InvalidOperationException(Environment.GetResourceString("InvalidOperation_CalledTwice")); } if (!skipSecurityCheck) { new SecurityPermission(SecurityPermissionFlag.UnmanagedCode).Demand(); } // check for wraparound unsafe { byte* pointer = null; RuntimeHelpers.PrepareConstrainedRegions(); try { buffer.AcquirePointer(ref pointer); if ( (pointer + offset + length) < pointer) { throw new ArgumentException(Environment.GetResourceString("ArgumentOutOfRange_UnmanagedMemStreamWrapAround")); } } finally { if (pointer != null) { buffer.ReleasePointer(); } } } _offset = offset; _buffer = buffer; _length = length; _capacity = length; _access = access; _isOpen = true; } [System.Security.SecurityCritical] // auto-generated [CLSCompliant(false)] public unsafe UnmanagedMemoryStream(byte* pointer, long length) { Initialize(pointer, length, length, FileAccess.Read, false); } [System.Security.SecurityCritical] // auto-generated [CLSCompliant(false)] public unsafe UnmanagedMemoryStream(byte* pointer, long length, long capacity, FileAccess access) { Initialize(pointer, length, capacity, access, false); } // We must create one of these without doing a security check. This // class is created while security is trying to start up. Plus, doing // a Demand from Assembly.GetManifestResourceStream isn't useful. [System.Security.SecurityCritical] // auto-generated internal unsafe UnmanagedMemoryStream(byte* pointer, long length, long capacity, FileAccess access, bool skipSecurityCheck) { Initialize(pointer, length, capacity, access, skipSecurityCheck); } [System.Security.SecurityCritical] // auto-generated [CLSCompliant(false)] protected unsafe void Initialize(byte* pointer, long length, long capacity, FileAccess access) { Initialize(pointer, length, capacity, access, false); } [System.Security.SecurityCritical] // auto-generated internal unsafe void Initialize(byte* pointer, long length, long capacity, FileAccess access, bool skipSecurityCheck) { if (pointer == null) throw new ArgumentNullException("pointer"); if (length < 0 || capacity < 0) throw new ArgumentOutOfRangeException((length < 0) ? "length" : "capacity", Environment.GetResourceString("ArgumentOutOfRange_NeedNonNegNum")); if (length > capacity) throw new ArgumentOutOfRangeException("length", Environment.GetResourceString("ArgumentOutOfRange_LengthGreaterThanCapacity")); Contract.EndContractBlock(); // Check for wraparound. if (((byte*) ((long)pointer + capacity)) < pointer) throw new ArgumentOutOfRangeException("capacity", Environment.GetResourceString("ArgumentOutOfRange_UnmanagedMemStreamWrapAround")); if (access < FileAccess.Read || access > FileAccess.ReadWrite) throw new ArgumentOutOfRangeException("access", Environment.GetResourceString("ArgumentOutOfRange_Enum")); if (_isOpen) throw new InvalidOperationException(Environment.GetResourceString("InvalidOperation_CalledTwice")); if (!skipSecurityCheck) new SecurityPermission(SecurityPermissionFlag.UnmanagedCode).Demand(); _mem = pointer; _offset = 0; _length = length; _capacity = capacity; _access = access; _isOpen = true; } public override bool CanRead { [Pure] #if !FEATURE_CORECLR [TargetedPatchingOptOut("Performance critical to inline across NGen image boundaries")] #endif get { return _isOpen && (_access & FileAccess.Read) != 0; } } public override bool CanSeek { [Pure] #if !FEATURE_CORECLR [TargetedPatchingOptOut("Performance critical to inline across NGen image boundaries")] #endif get { return _isOpen; } } public override bool CanWrite { [Pure] #if !FEATURE_CORECLR [TargetedPatchingOptOut("Performance critical to inline across NGen image boundaries")] #endif get { return _isOpen && (_access & FileAccess.Write) != 0; } } [System.Security.SecuritySafeCritical] // auto-generated protected override void Dispose(bool disposing) { _isOpen = false; unsafe { _mem = null; } // Stream allocates WaitHandles for async calls. So for correctness // call base.Dispose(disposing) for better perf, avoiding waiting // for the finalizers to run on those types. base.Dispose(disposing); } public override void Flush() { if (!_isOpen) __Error.StreamIsClosed(); } public override long Length { #if !FEATURE_CORECLR [TargetedPatchingOptOut("Performance critical to inline across NGen image boundaries")] #endif get { if (!_isOpen) __Error.StreamIsClosed(); return Interlocked.Read(ref _length); } } public long Capacity { get { if (!_isOpen) __Error.StreamIsClosed(); return _capacity; } } public override long Position { #if !FEATURE_CORECLR [TargetedPatchingOptOut("Performance critical to inline across NGen image boundaries")] #endif get { if (!CanSeek) __Error.StreamIsClosed(); Contract.EndContractBlock(); return Interlocked.Read(ref _position); } [System.Security.SecuritySafeCritical] // auto-generated set { if (value < 0) throw new ArgumentOutOfRangeException("value", Environment.GetResourceString("ArgumentOutOfRange_NeedNonNegNum")); Contract.EndContractBlock(); if (!CanSeek) __Error.StreamIsClosed(); #if WIN32 unsafe { // On 32 bit machines, ensure we don't wrap around. if (value > (long) Int32.MaxValue || _mem + value < _mem) throw new ArgumentOutOfRangeException("value", Environment.GetResourceString("ArgumentOutOfRange_StreamLength")); } #endif Interlocked.Exchange(ref _position, value); } } [CLSCompliant(false)] public unsafe byte* PositionPointer { [System.Security.SecurityCritical] // auto-generated_required get { if (_buffer != null) { throw new NotSupportedException(Environment.GetResourceString("NotSupported_UmsSafeBuffer")); } // Use a temp to avoid a race long pos = Interlocked.Read(ref _position); if (pos > _capacity) throw new IndexOutOfRangeException(Environment.GetResourceString("IndexOutOfRange_UMSPosition")); byte * ptr = _mem + pos; if (!_isOpen) __Error.StreamIsClosed(); return ptr; } [System.Security.SecurityCritical] // auto-generated_required #if FEATURE_CORECLR //Need the getter to be public and the setter to be internal: TrimSrc doesn't parse into property declarations internal #endif //FEATURE_CORECLR set { if (_buffer != null) throw new NotSupportedException(Environment.GetResourceString("NotSupported_UmsSafeBuffer")); if (!_isOpen) __Error.StreamIsClosed(); // Note: subtracting pointers returns an Int64. Working around // to avoid hitting compiler warning CS0652 on this line. if (new IntPtr(value - _mem).ToInt64() > UnmanagedMemStreamMaxLength) throw new ArgumentOutOfRangeException("offset", Environment.GetResourceString("ArgumentOutOfRange_UnmanagedMemStreamLength")); if (value < _mem) throw new IOException(Environment.GetResourceString("IO.IO_SeekBeforeBegin")); Interlocked.Exchange(ref _position, value - _mem); } } internal unsafe byte* Pointer { [System.Security.SecurityCritical] // auto-generated get { if (_buffer != null) throw new NotSupportedException(Environment.GetResourceString("NotSupported_UmsSafeBuffer")); return _mem; } } [System.Security.SecuritySafeCritical] // auto-generated public override int Read([In, Out] byte[] buffer, int offset, int count) { if (buffer==null) throw new ArgumentNullException("buffer", Environment.GetResourceString("ArgumentNull_Buffer")); if (offset < 0) throw new ArgumentOutOfRangeException("offset", Environment.GetResourceString("ArgumentOutOfRange_NeedNonNegNum")); if (count < 0) throw new ArgumentOutOfRangeException("count", Environment.GetResourceString("ArgumentOutOfRange_NeedNonNegNum")); if (buffer.Length - offset < count) throw new ArgumentException(Environment.GetResourceString("Argument_InvalidOffLen")); Contract.EndContractBlock(); if (!_isOpen) __Error.StreamIsClosed(); if (!CanRead) __Error.ReadNotSupported(); // Use a local variable to avoid a race where another thread // changes our position after we decide we can read some bytes. long pos = Interlocked.Read(ref _position); long len = Interlocked.Read(ref _length); long n = len - pos; if (n > count) n = count; if (n <= 0) return 0; int nInt = (int) n; // Safe because n <= count, which is an Int32 if (nInt < 0) nInt = 0; // _position could be beyond EOF Contract.Assert(pos + nInt >= 0, "_position + n >= 0"); // len is less than 2^63 -1. if (_buffer != null) { unsafe { byte* pointer = null; RuntimeHelpers.PrepareConstrainedRegions(); try { _buffer.AcquirePointer(ref pointer); Buffer.memcpy(pointer + pos + _offset, 0, buffer, offset, nInt); } finally { if (pointer != null) { _buffer.ReleasePointer(); } } } } else { unsafe { Buffer.memcpy(_mem + pos, 0, buffer, offset, nInt); } } Interlocked.Exchange(ref _position, pos + n); return nInt; } [System.Security.SecuritySafeCritical] // auto-generated public override int ReadByte() { if (!_isOpen) __Error.StreamIsClosed(); if (!CanRead) __Error.ReadNotSupported(); long pos = Interlocked.Read(ref _position); // Use a local to avoid a race condition long len = Interlocked.Read(ref _length); if (pos >= len) return -1; Interlocked.Exchange(ref _position, pos + 1); int result; if (_buffer != null) { unsafe { byte* pointer = null; RuntimeHelpers.PrepareConstrainedRegions(); try { _buffer.AcquirePointer(ref pointer); result = *(pointer + pos + _offset); } finally { if (pointer != null) { _buffer.ReleasePointer(); } } } } else { unsafe { result = _mem[pos]; } } return result; } public override long Seek(long offset, SeekOrigin loc) { if (!_isOpen) __Error.StreamIsClosed(); if (offset > UnmanagedMemStreamMaxLength) throw new ArgumentOutOfRangeException("offset", Environment.GetResourceString("ArgumentOutOfRange_UnmanagedMemStreamLength")); switch(loc) { case SeekOrigin.Begin: if (offset < 0) throw new IOException(Environment.GetResourceString("IO.IO_SeekBeforeBegin")); Interlocked.Exchange(ref _position, offset); break; case SeekOrigin.Current: long pos = Interlocked.Read(ref _position); if (offset + pos < 0) throw new IOException(Environment.GetResourceString("IO.IO_SeekBeforeBegin")); Interlocked.Exchange(ref _position, offset + pos); break; case SeekOrigin.End: long len = Interlocked.Read(ref _length); if (len + offset < 0) throw new IOException(Environment.GetResourceString("IO.IO_SeekBeforeBegin")); Interlocked.Exchange(ref _position, len + offset); break; default: throw new ArgumentException(Environment.GetResourceString("Argument_InvalidSeekOrigin")); } long finalPos = Interlocked.Read(ref _position); Contract.Assert(finalPos >= 0, "_position >= 0"); return finalPos; } [System.Security.SecuritySafeCritical] // auto-generated public override void SetLength(long value) { if (value < 0) throw new ArgumentOutOfRangeException("length", Environment.GetResourceString("ArgumentOutOfRange_NeedNonNegNum")); Contract.EndContractBlock(); if (_buffer != null) throw new NotSupportedException(Environment.GetResourceString("NotSupported_UmsSafeBuffer")); if (!_isOpen) __Error.StreamIsClosed(); if (!CanWrite) __Error.WriteNotSupported(); if (value > _capacity) throw new IOException(Environment.GetResourceString("IO.IO_FixedCapacity")); long pos = Interlocked.Read(ref _position); long len = Interlocked.Read(ref _length); if (value > len) { unsafe { Buffer.ZeroMemory(_mem+len, value-len); } } Interlocked.Exchange(ref _length, value); if (pos > value) { Interlocked.Exchange(ref _position, value); } } [System.Security.SecuritySafeCritical] // auto-generated public override void Write(byte[] buffer, int offset, int count) { if (buffer==null) throw new ArgumentNullException("buffer", Environment.GetResourceString("ArgumentNull_Buffer")); if (offset < 0) throw new ArgumentOutOfRangeException("offset", Environment.GetResourceString("ArgumentOutOfRange_NeedNonNegNum")); if (count < 0) throw new ArgumentOutOfRangeException("count", Environment.GetResourceString("ArgumentOutOfRange_NeedNonNegNum")); if (buffer.Length - offset < count) throw new ArgumentException(Environment.GetResourceString("Argument_InvalidOffLen")); Contract.EndContractBlock(); if (!_isOpen) __Error.StreamIsClosed(); if (!CanWrite) __Error.WriteNotSupported(); long pos = Interlocked.Read(ref _position); // Use a local to avoid a race condition long len = Interlocked.Read(ref _length); long n = pos + count; // Check for overflow if (n < 0) throw new IOException(Environment.GetResourceString("IO.IO_StreamTooLong")); if (n > _capacity) { throw new NotSupportedException(Environment.GetResourceString("IO.IO_FixedCapacity")); } if (_buffer == null) { // Check to see whether we are now expanding the stream and must // zero any memory in the middle. if (pos > len) { unsafe { Buffer.ZeroMemory(_mem+len, pos-len); } } // set length after zeroing memory to avoid race condition of accessing unzeroed memory if (n > len) { Interlocked.Exchange(ref _length, n); } } if (_buffer != null) { long bytesLeft = _capacity - pos; if (bytesLeft < count) { throw new ArgumentException(Environment.GetResourceString("Arg_BufferTooSmall")); } unsafe { byte* pointer = null; RuntimeHelpers.PrepareConstrainedRegions(); try { _buffer.AcquirePointer(ref pointer); Buffer.memcpy(buffer, offset, pointer + pos + _offset, 0, count); } finally { if (pointer != null) { _buffer.ReleasePointer(); } } } } else { unsafe { Buffer.memcpy(buffer, offset, _mem + pos, 0, count); } } Interlocked.Exchange(ref _position, n); return; } [System.Security.SecuritySafeCritical] // auto-generated public override void WriteByte(byte value) { if (!_isOpen) __Error.StreamIsClosed(); if (!CanWrite) __Error.WriteNotSupported(); long pos = Interlocked.Read(ref _position); // Use a local to avoid a race condition long len = Interlocked.Read(ref _length); long n = pos + 1; if (pos >= len) { // Check for overflow if (n < 0) throw new IOException(Environment.GetResourceString("IO.IO_StreamTooLong")); if (n > _capacity) throw new NotSupportedException(Environment.GetResourceString("IO.IO_FixedCapacity")); // Check to see whether we are now expanding the stream and must // zero any memory in the middle. // don't do if created from SafeBuffer if (_buffer == null) { if (pos > len) { unsafe { Buffer.ZeroMemory(_mem+len, pos-len); } } // set length after zeroing memory to avoid race condition of accessing unzeroed memory Interlocked.Exchange(ref _length, n); } } if (_buffer != null) { unsafe { byte* pointer = null; RuntimeHelpers.PrepareConstrainedRegions(); try { _buffer.AcquirePointer(ref pointer); *(pointer + pos + _offset) = value; } finally { if (pointer != null) { _buffer.ReleasePointer(); } } } } else { unsafe { _mem[pos] = value; } } Interlocked.Exchange(ref _position, n); } } } // File provided for Reference Use Only by Microsoft Corporation (c) 2007.
Link Menu
This book is available now!
Buy at Amazon US or
Buy at Amazon UK
- Misc.cs
- GrammarBuilderDictation.cs
- BinaryUtilClasses.cs
- MulticastDelegate.cs
- SiteMapDataSourceView.cs
- RtfControls.cs
- UnsafeCollabNativeMethods.cs
- FlowLayout.cs
- RestHandler.cs
- LassoSelectionBehavior.cs
- SourceSwitch.cs
- SqlAliaser.cs
- ListControl.cs
- Expr.cs
- AnimationException.cs
- AsyncOperation.cs
- ClientUIRequest.cs
- TextSchema.cs
- RangeBase.cs
- _OSSOCK.cs
- AbsoluteQuery.cs
- OleDbCommand.cs
- StringDictionaryWithComparer.cs
- SamlAuthorityBinding.cs
- CompilationUtil.cs
- HttpErrorTraceRecord.cs
- HtmlSelect.cs
- RelatedCurrencyManager.cs
- RoutedEventHandlerInfo.cs
- SrgsText.cs
- ClientRoleProvider.cs
- Int64.cs
- documentation.cs
- CopyAttributesAction.cs
- OleDbConnectionPoolGroupProviderInfo.cs
- EventDescriptor.cs
- ComboBoxRenderer.cs
- ControlValuePropertyAttribute.cs
- HttpRuntimeSection.cs
- Bits.cs
- DoubleCollection.cs
- PrincipalPermission.cs
- EntitySqlQueryState.cs
- PeerNameRecord.cs
- AutoSizeToolBoxItem.cs
- ISO2022Encoding.cs
- WebInvokeAttribute.cs
- SecurityException.cs
- GridItemProviderWrapper.cs
- RecognitionResult.cs
- CodeGeneratorOptions.cs
- InputMethodStateTypeInfo.cs
- HijriCalendar.cs
- ControlEvent.cs
- ToolStripItemClickedEventArgs.cs
- EditorZoneAutoFormat.cs
- TraceProvider.cs
- Math.cs
- SafeViewOfFileHandle.cs
- HelpProvider.cs
- ping.cs
- BinaryCommonClasses.cs
- ContainerUtilities.cs
- CompareInfo.cs
- FileDialogCustomPlacesCollection.cs
- UnderstoodHeaders.cs
- ItemsControl.cs
- HttpContext.cs
- thaishape.cs
- ContractAdapter.cs
- MemberDomainMap.cs
- NativeMethodsCLR.cs
- MetadataArtifactLoaderXmlReaderWrapper.cs
- QueryRewriter.cs
- SignatureToken.cs
- WeakEventManager.cs
- ManagementObject.cs
- BaseConfigurationRecord.cs
- SqlException.cs
- BamlResourceDeserializer.cs
- StateBag.cs
- CommandHelpers.cs
- PixelFormats.cs
- EntityDataSourceWrapperPropertyDescriptor.cs
- NavigationFailedEventArgs.cs
- RoutingEndpointTrait.cs
- EmulateRecognizeCompletedEventArgs.cs
- MaterialGroup.cs
- PointLight.cs
- SessionStateUtil.cs
- SizeAnimationBase.cs
- ErrorsHelper.cs
- HelloOperationCD1AsyncResult.cs
- SspiNegotiationTokenAuthenticator.cs
- DataGridTablesFactory.cs
- M3DUtil.cs
- RuleSetReference.cs
- CallbackHandler.cs
- PromptBuilder.cs
- ByteConverter.cs