Ejemplo n.º 1
0
        unsafe private int WriteFileNative(byte[] bytes, int offset, int count, NativeOverlapped *overlapped, out int hr)
        {
            if (_handle.IsClosed)
            {
                __Error.FileNotOpen();
            }

            if (_disableLogging)
            {
                hr = 0;
                return(0);
            }

            Debug.Assert(offset >= 0, "offset >= 0");
            Debug.Assert(count >= 0, "count >= 0");
            Debug.Assert(bytes != null, "bytes != null");

            // Don't corrupt memory when multiple threads are erroneously writing
            // to this stream simultaneously.  (the OS is reading from
            // the array we pass to WriteFile, but if we read beyond the end and
            // that memory isn't allocated, we could get an AV.)
            if (bytes.Length - offset < count)
            {
                throw new IndexOutOfRangeException(SR.GetString(SR.IndexOutOfRange_IORaceCondition));
            }

            // You can't use the fixed statement on an array of length 0.
            if (bytes.Length == 0)
            {
                hr = 0;
                return(0);
            }

            int numBytesWritten = 0;
            int r = 0;

            fixed(byte *p = bytes)
            {
                r = UnsafeNativeMethods.WriteFile(_handle, p + offset, count, out numBytesWritten, overlapped);
            }

            if (r == 0)
            {
                // We should never silently ---- an error here without some
                // extra work.  We must make sure that BeginWriteCore won't return an
                // IAsyncResult that will cause EndWrite to block, since the OS won't
                // call AsyncFSCallback for us.
                hr = Marshal.GetLastWin32Error();

                // For invalid handles, detect the error and mark our handle
                // as closed to give slightly better error messages.  Also
                // help ensure we avoid handle recycling bugs.
                if (hr == UnsafeNativeMethods.ERROR_INVALID_HANDLE)
                {
                    _handle.SetHandleAsInvalid();
                }

                return(-1);
            }
            else
            {
                hr = 0;
            }
            return(numBytesWritten);
        }