Beispiel #1
0
        private unsafe PipeStreamAsyncResult BeginWriteCore(byte[] buffer, int offset, int count, AsyncCallback callback, object state)
        {
            PipeStreamAsyncResult ar = new PipeStreamAsyncResult {
                _userCallback    = callback,
                _userStateObject = state,
                _isWrite         = true,
                _handle          = this.m_handle
            };

            if (buffer.Length == 0)
            {
                ar.CallUserCallback();
                return(ar);
            }
            ManualResetEvent event2 = new ManualResetEvent(false);

            ar._waitHandle = event2;
            NativeOverlapped *overlapped = new Overlapped(0, 0, IntPtr.Zero, ar).Pack(IOCallback, buffer);

            ar._overlapped = overlapped;
            int hr = 0;

            if ((this.WriteFileNative(this.m_handle, buffer, offset, count, overlapped, out hr) == -1) && (hr != 0x3e5))
            {
                if (overlapped != null)
                {
                    Overlapped.Free(overlapped);
                }
                this.WinIOError(hr);
            }
            return(ar);
        }
Beispiel #2
0
        private IAsyncResult BeginRead(AsyncCallback callback, Object state)
        {
            ReadWriteAsyncParams readWriteParams = state as ReadWriteAsyncParams;

            Debug.Assert(readWriteParams != null);
            byte[] buffer = readWriteParams.Buffer;
            int    offset = readWriteParams.Offset;
            int    count  = readWriteParams.Count;

            if (buffer == null)
            {
                throw new ArgumentNullException("buffer", SR.ArgumentNull_Buffer);
            }
            if (offset < 0)
            {
                throw new ArgumentOutOfRangeException("offset", SR.ArgumentOutOfRange_NeedNonNegNum);
            }
            if (count < 0)
            {
                throw new ArgumentOutOfRangeException("count", SR.ArgumentOutOfRange_NeedNonNegNum);
            }
            if (buffer.Length - offset < count)
            {
                throw new ArgumentException(SR.Argument_InvalidOffLen);
            }
            if (!CanRead)
            {
                throw __Error.GetReadNotSupported();
            }
            CheckReadOperations();

            if (!_isAsync)
            {
                // special case when this is called for sync broken pipes because otherwise Stream's
                // Begin/EndRead hang. Reads return 0 bytes in this case so we can call the user's
                // callback immediately
                if (_state == PipeState.Broken)
                {
                    PipeStreamAsyncResult asyncResult = new PipeStreamAsyncResult();
                    asyncResult._handle          = _handle;
                    asyncResult._userCallback    = callback;
                    asyncResult._userStateObject = state;
                    asyncResult._isWrite         = false;
                    asyncResult.CallUserCallback();
                    return(asyncResult);
                }
                else
                {
                    return(_streamAsyncHelper.BeginRead(buffer, offset, count, callback, state));
                }
            }
            else
            {
                return(BeginReadCore(buffer, offset, count, callback, state));
            }
        }
Beispiel #3
0
        private unsafe PipeStreamAsyncResult BeginReadCore(byte[] buffer, int offset, int count, AsyncCallback callback, object state)
        {
            PipeStreamAsyncResult ar = new PipeStreamAsyncResult {
                _handle          = this.m_handle,
                _userCallback    = callback,
                _userStateObject = state,
                _isWrite         = false
            };

            if (buffer.Length == 0)
            {
                ar.CallUserCallback();
                return(ar);
            }
            ManualResetEvent event2 = new ManualResetEvent(false);

            ar._waitHandle = event2;
            NativeOverlapped *overlapped = new Overlapped(0, 0, IntPtr.Zero, ar).Pack(IOCallback, buffer);

            ar._overlapped = overlapped;
            int hr = 0;

            if (this.ReadFileNative(this.m_handle, buffer, offset, count, overlapped, out hr) == -1)
            {
                if ((hr == 0x6d) || (hr == 0xe9))
                {
                    this.State = PipeState.Broken;
                    overlapped->InternalLow = IntPtr.Zero;
                    ar.CallUserCallback();
                    return(ar);
                }
                if (hr != 0x3e5)
                {
                    System.IO.__Error.WinIOError(hr, string.Empty);
                }
            }
            return(ar);
        }
Beispiel #4
0
 public override IAsyncResult BeginRead(byte[] buffer, int offset, int count, AsyncCallback callback, object state)
 {
     if (buffer == null)
     {
         throw new ArgumentNullException("buffer", System.SR.GetString("ArgumentNull_Buffer"));
     }
     if (offset < 0)
     {
         throw new ArgumentOutOfRangeException("offset", System.SR.GetString("ArgumentOutOfRange_NeedNonNegNum"));
     }
     if (count < 0)
     {
         throw new ArgumentOutOfRangeException("count", System.SR.GetString("ArgumentOutOfRange_NeedNonNegNum"));
     }
     if ((buffer.Length - offset) < count)
     {
         throw new ArgumentException(System.SR.GetString("Argument_InvalidOffLen"));
     }
     if (!this.CanRead)
     {
         System.IO.__Error.ReadNotSupported();
     }
     this.CheckReadOperations();
     if (this.m_isAsync)
     {
         return(this.BeginReadCore(buffer, offset, count, callback, state));
     }
     if (this.m_state == PipeState.Broken)
     {
         PipeStreamAsyncResult result = new PipeStreamAsyncResult {
             _handle          = this.m_handle,
             _userCallback    = callback,
             _userStateObject = state,
             _isWrite         = false
         };
         result.CallUserCallback();
         return(result);
     }
     return(base.BeginRead(buffer, offset, count, callback, state));
 }
Beispiel #5
0
        unsafe private PipeStreamAsyncResult BeginReadCore(byte[] buffer, int offset, int count,
                                                           AsyncCallback callback, Object state)
        {
            Debug.Assert(_handle != null, "_handle is null");
            Debug.Assert(!_handle.IsClosed, "_handle is closed");
            Debug.Assert(CanRead, "can't read");
            Debug.Assert(buffer != null, "buffer == null");
            Debug.Assert(_isAsync, "BeginReadCore doesn't work on synchronous file streams!");
            Debug.Assert(offset >= 0, "offset is negative");
            Debug.Assert(count >= 0, "count is negative");

            // Create and store async stream class library specific data in the async result
            PipeStreamAsyncResult asyncResult = new PipeStreamAsyncResult();

            asyncResult._handle          = _handle;
            asyncResult._userCallback    = callback;
            asyncResult._userStateObject = state;
            asyncResult._isWrite         = false;

            // handle zero-length buffers separately; fixed keyword ReadFileNative doesn't like
            // 0-length buffers. Call user callback and we're done
            if (buffer.Length == 0)
            {
                asyncResult.CallUserCallback();
            }
            else
            {
                // For Synchronous IO, I could go with either a userCallback and using
                // the managed Monitor class, or I could create a handle and wait on it.
                ManualResetEvent waitHandle = new ManualResetEvent(false);
                asyncResult._waitHandle = waitHandle;

                NativeOverlapped *intOverlapped = _threadPoolBinding.AllocateNativeOverlapped(s_IOCallback, asyncResult, buffer);
                asyncResult._overlapped = intOverlapped;

                // Queue an async ReadFile operation and pass in a packed overlapped
                int errorCode = 0;
                int r         = ReadFileNative(_handle, buffer, offset, count, intOverlapped, out errorCode);

                // ReadFile, the OS version, will return 0 on failure, but this ReadFileNative wrapper
                // returns -1. This will return the following:
                // - On error, r==-1.
                // - On async requests that are still pending, r==-1 w/ hr==ERROR_IO_PENDING
                // - On async requests that completed sequentially, r==0
                //
                // You will NEVER RELIABLY be able to get the number of buffer read back from this call
                // when using overlapped structures!  You must not pass in a non-null lpNumBytesRead to
                // ReadFile when using overlapped structures!  This is by design NT behavior.
                if (r == -1)
                {
                    // One side has closed its handle or server disconnected. Set the state to Broken
                    // and do some cleanup work
                    if (errorCode == Interop.mincore.Errors.ERROR_BROKEN_PIPE ||
                        errorCode == Interop.mincore.Errors.ERROR_PIPE_NOT_CONNECTED)
                    {
                        State = PipeState.Broken;

                        // Clear the overlapped status bit for this special case. Failure to do so looks
                        // like we are freeing a pending overlapped.
                        intOverlapped->InternalLow = IntPtr.Zero;

                        // EndRead will free the Overlapped struct
                        asyncResult.CallUserCallback();
                    }
                    else if (errorCode != Interop.mincore.Errors.ERROR_IO_PENDING)
                    {
                        throw Win32Marshal.GetExceptionForWin32Error(errorCode);
                    }
                }
                ReadWriteAsyncParams readWriteParams = state as ReadWriteAsyncParams;
                if (readWriteParams != null)
                {
                    if (readWriteParams.CancellationHelper != null)
                    {
                        readWriteParams.CancellationHelper.AllowCancellation(_handle, intOverlapped);
                    }
                }
            }
            return(asyncResult);
        }
Beispiel #6
0
        unsafe private PipeStreamAsyncResult BeginWriteCore(byte[] buffer, int offset, int count,
                                                            AsyncCallback callback, Object state)
        {
            Debug.Assert(_handle != null, "_handle is null");
            Debug.Assert(!_handle.IsClosed, "_handle is closed");
            Debug.Assert(CanWrite, "can't write");
            Debug.Assert(buffer != null, "buffer == null");
            Debug.Assert(_isAsync, "BeginWriteCore doesn't work on synchronous file streams!");
            Debug.Assert(offset >= 0, "offset is negative");
            Debug.Assert(count >= 0, "count is negative");

            // Create and store async stream class library specific data in the async result
            PipeStreamAsyncResult asyncResult = new PipeStreamAsyncResult();

            asyncResult._userCallback    = callback;
            asyncResult._userStateObject = state;
            asyncResult._isWrite         = true;
            asyncResult._handle          = _handle;

            // fixed doesn't work well with zero length arrays. Set the zero-byte flag in case
            // caller needs to do any cleanup
            if (buffer.Length == 0)
            {
                //intOverlapped->InternalLow = IntPtr.Zero;

                // EndRead will free the Overlapped struct
                asyncResult.CallUserCallback();
            }
            else
            {
                // For Synchronous IO, I could go with either a userCallback and using the managed
                // Monitor class, or I could create a handle and wait on it.
                ManualResetEvent waitHandle = new ManualResetEvent(false);
                asyncResult._waitHandle = waitHandle;

                NativeOverlapped *intOverlapped = _threadPoolBinding.AllocateNativeOverlapped(s_IOCallback, asyncResult, buffer);
                asyncResult._overlapped = intOverlapped;

                int errorCode = 0;

                // Queue an async WriteFile operation and pass in a packed overlapped
                int r = WriteFileNative(_handle, buffer, offset, count, intOverlapped, out errorCode);

                // WriteFile, the OS version, will return 0 on failure, but this WriteFileNative
                // wrapper returns -1. This will return the following:
                // - On error, r==-1.
                // - On async requests that are still pending, r==-1 w/ hr==ERROR_IO_PENDING
                // - On async requests that completed sequentially, r==0
                //
                // You will NEVER RELIABLY be able to get the number of buffer written back from this
                // call when using overlapped structures!  You must not pass in a non-null
                // lpNumBytesWritten to WriteFile when using overlapped structures!  This is by design
                // NT behavior.
                if (r == -1 && errorCode != Interop.mincore.Errors.ERROR_IO_PENDING)
                {
                    // Clean up
                    if (intOverlapped != null)
                    {
                        _threadPoolBinding.FreeNativeOverlapped(intOverlapped);
                    }
                    WinIOError(errorCode);
                }

                ReadWriteAsyncParams readWriteParams = state as ReadWriteAsyncParams;
                if (readWriteParams != null)
                {
                    if (readWriteParams.CancellationHelper != null)
                    {
                        readWriteParams.CancellationHelper.AllowCancellation(_handle, intOverlapped);
                    }
                }
            }

            return(asyncResult);
        }
        private IAsyncResult BeginRead(AsyncCallback callback, Object state)
        {
            ReadWriteAsyncParams readWriteParams = state as ReadWriteAsyncParams;
            Debug.Assert(readWriteParams != null);
            byte[] buffer = readWriteParams.Buffer;
            int offset = readWriteParams.Offset;
            int count = readWriteParams.Count;

            if (buffer == null)
            {
                throw new ArgumentNullException("buffer", SR.ArgumentNull_Buffer);
            }
            if (offset < 0)
            {
                throw new ArgumentOutOfRangeException("offset", SR.ArgumentOutOfRange_NeedNonNegNum);
            }
            if (count < 0)
            {
                throw new ArgumentOutOfRangeException("count", SR.ArgumentOutOfRange_NeedNonNegNum);
            }
            if (buffer.Length - offset < count)
            {
                throw new ArgumentException(SR.Argument_InvalidOffLen);
            }
            if (!CanRead)
            {
                throw __Error.GetReadNotSupported();
            }
            CheckReadOperations();

            if (!_isAsync)
            {
                // special case when this is called for sync broken pipes because otherwise Stream's
                // Begin/EndRead hang. Reads return 0 bytes in this case so we can call the user's
                // callback immediately
                if (_state == PipeState.Broken)
                {
                    PipeStreamAsyncResult asyncResult = new PipeStreamAsyncResult();
                    asyncResult._handle = _handle;
                    asyncResult._userCallback = callback;
                    asyncResult._userStateObject = state;
                    asyncResult._isWrite = false;
                    asyncResult.CallUserCallback();
                    return asyncResult;
                }
                else
                {
                    return _streamAsyncHelper.BeginRead(buffer, offset, count, callback, state);
                }
            }
            else
            {
                return BeginReadCore(buffer, offset, count, callback, state);
            }
        }
        unsafe private PipeStreamAsyncResult BeginWriteCore(byte[] buffer, int offset, int count,
                AsyncCallback callback, Object state)
        {
            Debug.Assert(_handle != null, "_handle is null");
            Debug.Assert(!_handle.IsClosed, "_handle is closed");
            Debug.Assert(CanWrite, "can't write");
            Debug.Assert(buffer != null, "buffer == null");
            Debug.Assert(_isAsync, "BeginWriteCore doesn't work on synchronous file streams!");
            Debug.Assert(offset >= 0, "offset is negative");
            Debug.Assert(count >= 0, "count is negative");

            // Create and store async stream class library specific data in the async result
            PipeStreamAsyncResult asyncResult = new PipeStreamAsyncResult();
            asyncResult._userCallback = callback;
            asyncResult._userStateObject = state;
            asyncResult._isWrite = true;
            asyncResult._handle = _handle;

            // fixed doesn't work well with zero length arrays. Set the zero-byte flag in case
            // caller needs to do any cleanup
            if (buffer.Length == 0)
            {
                //intOverlapped->InternalLow = IntPtr.Zero;

                // EndRead will free the Overlapped struct
                asyncResult.CallUserCallback();
            }
            else
            {
                // For Synchronous IO, I could go with either a userCallback and using the managed 
                // Monitor class, or I could create a handle and wait on it.
                ManualResetEvent waitHandle = new ManualResetEvent(false);
                asyncResult._waitHandle = waitHandle;

                // Create a managed overlapped class; set the file offsets later
                Overlapped overlapped = new Overlapped();
                overlapped.OffsetLow = 0;
                overlapped.OffsetHigh = 0;
                overlapped.AsyncResult = asyncResult;

                // Pack the Overlapped class, and store it in the async result
                NativeOverlapped* intOverlapped = overlapped.Pack(s_IOCallback, buffer);
                asyncResult._overlapped = intOverlapped;

                int errorCode = 0;

                // Queue an async WriteFile operation and pass in a packed overlapped
                int r = WriteFileNative(_handle, buffer, offset, count, intOverlapped, out errorCode);

                // WriteFile, the OS version, will return 0 on failure, but this WriteFileNative 
                // wrapper returns -1. This will return the following:
                // - On error, r==-1.
                // - On async requests that are still pending, r==-1 w/ hr==ERROR_IO_PENDING
                // - On async requests that completed sequentially, r==0
                // 
                // You will NEVER RELIABLY be able to get the number of buffer written back from this 
                // call when using overlapped structures!  You must not pass in a non-null 
                // lpNumBytesWritten to WriteFile when using overlapped structures!  This is by design 
                // NT behavior.
                if (r == -1 && errorCode != Interop.ERROR_IO_PENDING)
                {
                    // Clean up
                    if (intOverlapped != null) Overlapped.Free(intOverlapped);
                    WinIOError(errorCode);
                }

                ReadWriteAsyncParams readWriteParams = state as ReadWriteAsyncParams;
                if (readWriteParams != null)
                {
                    if (readWriteParams.CancellationHelper != null)
                    {
                        readWriteParams.CancellationHelper.AllowCancellation(_handle, intOverlapped);
                    }
                }
            }

            return asyncResult;
        }
        unsafe private PipeStreamAsyncResult BeginReadCore(byte[] buffer, int offset, int count,
                AsyncCallback callback, Object state)
        {
            Debug.Assert(_handle != null, "_handle is null");
            Debug.Assert(!_handle.IsClosed, "_handle is closed");
            Debug.Assert(CanRead, "can't read");
            Debug.Assert(buffer != null, "buffer == null");
            Debug.Assert(_isAsync, "BeginReadCore doesn't work on synchronous file streams!");
            Debug.Assert(offset >= 0, "offset is negative");
            Debug.Assert(count >= 0, "count is negative");

            // Create and store async stream class library specific data in the async result
            PipeStreamAsyncResult asyncResult = new PipeStreamAsyncResult();
            asyncResult._handle = _handle;
            asyncResult._userCallback = callback;
            asyncResult._userStateObject = state;
            asyncResult._isWrite = false;

            // handle zero-length buffers separately; fixed keyword ReadFileNative doesn't like
            // 0-length buffers. Call user callback and we're done
            if (buffer.Length == 0)
            {
                asyncResult.CallUserCallback();
            }
            else
            {
                // For Synchronous IO, I could go with either a userCallback and using
                // the managed Monitor class, or I could create a handle and wait on it.
                ManualResetEvent waitHandle = new ManualResetEvent(false);
                asyncResult._waitHandle = waitHandle;

                // Create a managed overlapped class; set the file offsets later
                Overlapped overlapped = new Overlapped();
                overlapped.OffsetLow = 0;
                overlapped.OffsetHigh = 0;
                overlapped.AsyncResult = asyncResult;

                // Pack the Overlapped class, and store it in the async result
                NativeOverlapped* intOverlapped;
                intOverlapped = overlapped.Pack(s_IOCallback, buffer);


                asyncResult._overlapped = intOverlapped;

                // Queue an async ReadFile operation and pass in a packed overlapped
                int errorCode = 0;
                int r = ReadFileNative(_handle, buffer, offset, count, intOverlapped, out errorCode);

                // ReadFile, the OS version, will return 0 on failure, but this ReadFileNative wrapper
                // returns -1. This will return the following:
                // - On error, r==-1.
                // - On async requests that are still pending, r==-1 w/ hr==ERROR_IO_PENDING
                // - On async requests that completed sequentially, r==0
                // 
                // You will NEVER RELIABLY be able to get the number of buffer read back from this call 
                // when using overlapped structures!  You must not pass in a non-null lpNumBytesRead to
                // ReadFile when using overlapped structures!  This is by design NT behavior.
                if (r == -1)
                {
                    // One side has closed its handle or server disconnected. Set the state to Broken 
                    // and do some cleanup work
                    if (errorCode == Interop.ERROR_BROKEN_PIPE ||
                        errorCode == Interop.ERROR_PIPE_NOT_CONNECTED)
                    {
                        State = PipeState.Broken;

                        // Clear the overlapped status bit for this special case. Failure to do so looks 
                        // like we are freeing a pending overlapped.
                        intOverlapped->InternalLow = IntPtr.Zero;

                        // EndRead will free the Overlapped struct
                        asyncResult.CallUserCallback();
                    }
                    else if (errorCode != Interop.ERROR_IO_PENDING)
                    {
                        throw Win32Marshal.GetExceptionForWin32Error(errorCode);
                    }
                }
                ReadWriteAsyncParams readWriteParams = state as ReadWriteAsyncParams;
                if (readWriteParams != null)
                {
                    if (readWriteParams.CancellationHelper != null)
                    {
                        readWriteParams.CancellationHelper.AllowCancellation(_handle, intOverlapped);
                    }
                }
            }
            return asyncResult;
        }
Beispiel #10
0
        public override IAsyncResult BeginRead(byte[] buffer, int offset, int count, AsyncCallback callback, Object state) {
            if (buffer == null) {
                throw new ArgumentNullException("buffer", SR.GetString(SR.ArgumentNull_Buffer));
            }
            if (offset < 0) {
                throw new ArgumentOutOfRangeException("offset", SR.GetString(SR.ArgumentOutOfRange_NeedNonNegNum));
            }
            if (count < 0) {
                throw new ArgumentOutOfRangeException("count", SR.GetString(SR.ArgumentOutOfRange_NeedNonNegNum));
            }
            if (buffer.Length - offset < count) {
                throw new ArgumentException(SR.GetString(SR.Argument_InvalidOffLen));
            }
            if (!CanRead) {
                __Error.ReadNotSupported();
            }
            CheckReadOperations();

            if (!m_isAsync) {
                // special case when this is called for sync broken pipes because otherwise Stream's
                // Begin/EndRead hang. Reads return 0 bytes in this case so we can call the user's
                // callback immediately
                if (m_state == PipeState.Broken) {
                    PipeStreamAsyncResult asyncResult = new PipeStreamAsyncResult();
                    asyncResult._handle = m_handle;
                    asyncResult._userCallback = callback;
                    asyncResult._userStateObject = state;
                    asyncResult._isWrite = false;
                    asyncResult.CallUserCallback();
                    return asyncResult;
                }
                else {
                    return base.BeginRead(buffer, offset, count, callback, state);
                }
            }
            else {
                return BeginReadCore(buffer, offset, count, callback, state);
            }
        }
 public override IAsyncResult BeginRead(byte[] buffer, int offset, int count, AsyncCallback callback, object state)
 {
     if (buffer == null)
     {
         throw new ArgumentNullException("buffer", System.SR.GetString("ArgumentNull_Buffer"));
     }
     if (offset < 0)
     {
         throw new ArgumentOutOfRangeException("offset", System.SR.GetString("ArgumentOutOfRange_NeedNonNegNum"));
     }
     if (count < 0)
     {
         throw new ArgumentOutOfRangeException("count", System.SR.GetString("ArgumentOutOfRange_NeedNonNegNum"));
     }
     if ((buffer.Length - offset) < count)
     {
         throw new ArgumentException(System.SR.GetString("Argument_InvalidOffLen"));
     }
     if (!this.CanRead)
     {
         System.IO.__Error.ReadNotSupported();
     }
     this.CheckReadOperations();
     if (this.m_isAsync)
     {
         return this.BeginReadCore(buffer, offset, count, callback, state);
     }
     if (this.m_state == PipeState.Broken)
     {
         PipeStreamAsyncResult result = new PipeStreamAsyncResult {
             _handle = this.m_handle,
             _userCallback = callback,
             _userStateObject = state,
             _isWrite = false
         };
         result.CallUserCallback();
         return result;
     }
     return base.BeginRead(buffer, offset, count, callback, state);
 }
 private unsafe PipeStreamAsyncResult BeginWriteCore(byte[] buffer, int offset, int count, AsyncCallback callback, object state)
 {
     PipeStreamAsyncResult ar = new PipeStreamAsyncResult {
         _userCallback = callback,
         _userStateObject = state,
         _isWrite = true,
         _handle = this.m_handle
     };
     if (buffer.Length == 0)
     {
         ar.CallUserCallback();
         return ar;
     }
     ManualResetEvent event2 = new ManualResetEvent(false);
     ar._waitHandle = event2;
     NativeOverlapped* overlapped = new Overlapped(0, 0, IntPtr.Zero, ar).Pack(IOCallback, buffer);
     ar._overlapped = overlapped;
     int hr = 0;
     if ((this.WriteFileNative(this.m_handle, buffer, offset, count, overlapped, out hr) == -1) && (hr != 0x3e5))
     {
         if (overlapped != null)
         {
             Overlapped.Free(overlapped);
         }
         this.WinIOError(hr);
     }
     return ar;
 }
 private unsafe PipeStreamAsyncResult BeginReadCore(byte[] buffer, int offset, int count, AsyncCallback callback, object state)
 {
     PipeStreamAsyncResult ar = new PipeStreamAsyncResult {
         _handle = this.m_handle,
         _userCallback = callback,
         _userStateObject = state,
         _isWrite = false
     };
     if (buffer.Length == 0)
     {
         ar.CallUserCallback();
         return ar;
     }
     ManualResetEvent event2 = new ManualResetEvent(false);
     ar._waitHandle = event2;
     NativeOverlapped* overlapped = new Overlapped(0, 0, IntPtr.Zero, ar).Pack(IOCallback, buffer);
     ar._overlapped = overlapped;
     int hr = 0;
     if (this.ReadFileNative(this.m_handle, buffer, offset, count, overlapped, out hr) == -1)
     {
         if ((hr == 0x6d) || (hr == 0xe9))
         {
             this.State = PipeState.Broken;
             overlapped->InternalLow = IntPtr.Zero;
             ar.CallUserCallback();
             return ar;
         }
         if (hr != 0x3e5)
         {
             System.IO.__Error.WinIOError(hr, string.Empty);
         }
     }
     return ar;
 }