internal unsafe HttpResponseStreamAsyncResult(object asyncObject, object userState, AsyncCallback callback, byte[] buffer, int offset, int size, bool chunked, bool sentHeaders) : base(asyncObject, userState, callback)
        {
            this.m_SentHeaders = sentHeaders;
            Overlapped overlapped = new Overlapped {
                AsyncResult = this
            };

            if (size == 0)
            {
                this.m_DataChunks  = null;
                this.m_pOverlapped = overlapped.Pack(s_IOCallback, null);
            }
            else
            {
                this.m_DataChunks = new UnsafeNclNativeMethods.HttpApi.HTTP_DATA_CHUNK[chunked ? 3 : 1];
                object[] userData = new object[1 + this.m_DataChunks.Length];
                userData[this.m_DataChunks.Length] = this.m_DataChunks;
                int    num = 0;
                byte[] arr = null;
                if (chunked)
                {
                    arr = ConnectStream.GetChunkHeader(size, out num);
                    this.m_DataChunks[0] = new UnsafeNclNativeMethods.HttpApi.HTTP_DATA_CHUNK();
                    this.m_DataChunks[0].DataChunkType = UnsafeNclNativeMethods.HttpApi.HTTP_DATA_CHUNK_TYPE.HttpDataChunkFromMemory;
                    this.m_DataChunks[0].BufferLength  = (uint)(arr.Length - num);
                    userData[0]          = arr;
                    this.m_DataChunks[1] = new UnsafeNclNativeMethods.HttpApi.HTTP_DATA_CHUNK();
                    this.m_DataChunks[1].DataChunkType = UnsafeNclNativeMethods.HttpApi.HTTP_DATA_CHUNK_TYPE.HttpDataChunkFromMemory;
                    this.m_DataChunks[1].BufferLength  = (uint)size;
                    userData[1]          = buffer;
                    this.m_DataChunks[2] = new UnsafeNclNativeMethods.HttpApi.HTTP_DATA_CHUNK();
                    this.m_DataChunks[2].DataChunkType = UnsafeNclNativeMethods.HttpApi.HTTP_DATA_CHUNK_TYPE.HttpDataChunkFromMemory;
                    this.m_DataChunks[2].BufferLength  = (uint)NclConstants.CRLF.Length;
                    userData[2] = NclConstants.CRLF;
                }
                else
                {
                    this.m_DataChunks[0] = new UnsafeNclNativeMethods.HttpApi.HTTP_DATA_CHUNK();
                    this.m_DataChunks[0].DataChunkType = UnsafeNclNativeMethods.HttpApi.HTTP_DATA_CHUNK_TYPE.HttpDataChunkFromMemory;
                    this.m_DataChunks[0].BufferLength  = (uint)size;
                    userData[0] = buffer;
                }
                this.m_pOverlapped = overlapped.Pack(s_IOCallback, userData);
                if (chunked)
                {
                    this.m_DataChunks[0].pBuffer = (byte *)Marshal.UnsafeAddrOfPinnedArrayElement(arr, num);
                    this.m_DataChunks[1].pBuffer = (byte *)Marshal.UnsafeAddrOfPinnedArrayElement(buffer, offset);
                    this.m_DataChunks[2].pBuffer = (byte *)Marshal.UnsafeAddrOfPinnedArrayElement(NclConstants.CRLF, 0);
                }
                else
                {
                    this.m_DataChunks[0].pBuffer = (byte *)Marshal.UnsafeAddrOfPinnedArrayElement(buffer, offset);
                }
            }
        }
Example #2
0
        private unsafe void SubmitReadRequest()
        {
            _rxBuffer = new byte[64];
            Overlapped        overlapped       = new Overlapped();
            NativeOverlapped *nativeOverlapped = overlapped.Pack(ReadComplete, _rxBuffer);
            bool   success;
            UInt32 numBytes;
            int    errorCode;

            fixed(byte *buf = _rxBuffer)
            {
                success   = WinUsb_ReadPipe(_interfaceHandle, RxEndpointAddress, buf, (UInt32)_rxBuffer.Length, out numBytes, nativeOverlapped);
                errorCode = Marshal.GetLastWin32Error();
            }

            if (success)
            {
                // call was executed synchronously
                ReadComplete(0, numBytes, nativeOverlapped);
            }
            else
            {
                if (errorCode != ERROR_IO_PENDING)
                {
                    Overlapped.Unpack(nativeOverlapped);
                    Overlapped.Free(nativeOverlapped);
                    WirekiteException.ThrowWin32Exception("Failed to submit read request for Wirekite device");
                }
            }
        }
Example #3
0
        public void ControlTransferOverlapped(byte requestType, byte request, ushort value,
                                              ushort index, ushort length, byte[] data, WinUSBAsyncResult result)
        {
            uint bytesReturned = 0;

            NativeInterface.WINUSB_SETUP_PACKET setupPacket;

            setupPacket.RequestType = requestType;
            setupPacket.Request     = request;
            setupPacket.Value       = value;
            setupPacket.Index       = index;
            setupPacket.Length      = length;

            Overlapped overlapped = new Overlapped();

            overlapped.AsyncResult = result;

            unsafe
            {
                NativeOverlapped *pOverlapped = null;
                pOverlapped = overlapped.Pack(_PipeIOCallback, data);
                bool success = NativeInterface.WinUsb_ControlTransfer(_winUsbHandle, setupPacket,
                                                                      data, length, ref bytesReturned, pOverlapped);
                _HandleOverlappedAPI(success, "Asynchronous control transfer on WinUSB device failed.",
                                     pOverlapped, result, (int)bytesReturned);
            }
        }
Example #4
0
        public void WritePipeOverlapped(int ifaceIndex, byte pipeID, byte[] buffer,
                                        int offset, int bytesToWrite, WinUSBAsyncResult result)
        {
            Overlapped overlapped = new Overlapped();

            overlapped.AsyncResult = result;

            unsafe
            {
                NativeOverlapped *pOverlapped = null;

                uint bytesWritten;
                pOverlapped = overlapped.Pack(_PipeIOCallback, buffer);

                bool success;
                // Buffer is pinned already by overlapped.Pack
                fixed(byte *pBuffer = buffer)
                {
                    success = NativeInterface.WinUsb_WritePipe(_InterfaceHandle(ifaceIndex), pipeID,
                                                               pBuffer + offset, (uint)bytesToWrite, out bytesWritten, pOverlapped);
                }

                _HandleOverlappedAPI(success, "Failed to asynchronously write pipe on WinUSB device.",
                                     pOverlapped, result, (int)bytesWritten);
            }
        }
        public override IAsyncResult BeginWrite(byte[] buffer, int offset, int count, AsyncCallback callback, object state)
        {
            SerialAsyncResult ar = new SerialAsyncResult(this);

            ar.Init(state, callback, false);
            Overlapped ov = new Overlapped(0, 0, ar.AsyncWaitHandle.Handle.ToInt32(), ar);

            unsafe
            {
                fixed(byte *data = &buffer[0])
                {
                    int write             = 0;
                    NativeOverlapped *nov = ov.Pack(m_IOCompletionCallback);

                    WriteFile(m_hFile, data, count, &write, nov);
                }
            }
            if (GetLastError() == ERROR_IO_PENDING)
            {
                return(ar);
            }
            else
            {
                throw new Exception("Unable to initialize write. Errorcode: " + GetLastError().ToString());
            }
        }
        internal void Pack(object pinnedObjects)
        {
            if (this.nativeOverlapped != null)
            {
                // If we reach this condition, we have a bug in a derived AsyncResult class.
                // It attempted to initiate a new async I/O operation before the previous
                // one completed. This is a fatal condition, so we cannot continue execution.
                DiagnosticUtility.FailFast("Must allow previous I/O to complete before packing");
            }

            GC.ReRegisterForFinalize(this);

            Overlapped overlapped = new Overlapped(0, 0, IntPtr.Zero, this);

            if (this.callback == null)
            {
                this.nativeOverlapped = overlapped.UnsafePack(
                    IOCompletionCallback,
                    pinnedObjects);
            }
            else
            {
                this.nativeOverlapped = overlapped.Pack(
                    IOCompletionCallback,
                    pinnedObjects);
            }
        }
Example #7
0
            private void Dispose(bool disposing)
            {
                if (_handle == null || _handle.IsClosed)
                {
                    return;
                }

                var overlapped = new Overlapped
                {
                    OffsetHigh = (int)(_position >> 32),
                    OffsetLow  = (int)_position
                };

                var native = overlapped.Pack(null, null);

                try
                {
                    if (!UnlockFileEx(_handle, 0, (uint)_length, (uint)(_length >> 32), native))
                    {
                        WinIoError();
                    }
                }
                finally
                {
                    Overlapped.Free(native);
                    _handle = null;
                }
            }
Example #8
0
        public override IAsyncResult BeginWrite(byte[] buffer, int offset, int count, AsyncCallback callback, object state)
        {
            GCHandle          gchBuffer = GCHandle.Alloc(buffer, GCHandleType.Pinned);
            SerialAsyncResult sar       = new SerialAsyncResult(this, state, callback, false, gchBuffer);
            Overlapped        ov        = new Overlapped(0, 0, sar.AsyncWaitHandle.Handle.ToInt32(), sar);

            unsafe
            {
                NativeOverlapped *nov  = ov.Pack(m_IOCompletionCallback);
                byte *            data = (byte *)((int)gchBuffer.AddrOfPinnedObject() + offset);

                uint written = 0;
                if (WriteFile(m_hFile, data, (uint)count, out written, nov))
                {
                    sar.m_bCompletedSynchronously = true;
                    return(sar);
                }
                else if (GetLastError() == ERROR_IO_PENDING)
                {
                    return(sar);
                }
                else
                {
                    throw new Exception("Não foi possível inicializar escrita. Código de erro: " + GetLastError().ToString());
                }
            }
        }
Example #9
0
        public static unsafe Task <int> ReadAsync(SafeFileHandle hFile, long fileOffset, byte[] buffer, int bytesToRead)
        {
            if (fileOffset < 0)
            {
                throw new ArgumentOutOfRangeException(nameof(fileOffset));
            }

            if (bytesToRead < 0 || bytesToRead > buffer.Length)
            {
                throw new ArgumentOutOfRangeException(nameof(bytesToRead));
            }

            var asyncResult = new AsyncResult();
            var o           = new Overlapped((int)(fileOffset & 0xFFFFFFFF), (int)(fileOffset >> 32), IntPtr.Zero, asyncResult);

            fixed(byte *bufferBase = buffer)
            {
                // https://docs.microsoft.com/en-us/dotnet/api/system.threading.overlapped.pack?view=netframework-4.7#System_Threading_Overlapped_Pack_System_Threading_IOCompletionCallback_System_Object_
                // The buffer or buffers specified in userData must be the same as those passed to the unmanaged operating system function that performs the asynchronous I/O.
                // The runtime pins the buffer or buffers specified in userData for the duration of the I/O operation.
                NativeOverlapped *pOverlapped = o.Pack(CompletionCallback, buffer);
                bool needToFree = true;

                try
                {
                    if (ReadFile(hFile, bufferBase, bytesToRead, IntPtr.Zero, pOverlapped) != 0)
                    {
                        // Completed synchronously.

                        // The number of bytes transferred for the I/ O request.The system sets this member if the request is completed without errors.
                        // https://msdn.microsoft.com/en-us/library/windows/desktop/ms684342(v=vs.85).aspx
                        int bytesRead = (int)pOverlapped->InternalHigh.ToInt64();
                        return(Task.FromResult(bytesRead));
                    }
                    else
                    {
                        int systemErrorCode = Marshal.GetLastWin32Error();
                        if (systemErrorCode == ERROR_IO_PENDING)
                        {
                            needToFree = false;
                        }
                        else
                        {
                            throw new Win32Exception(systemErrorCode, $"ReadFile failed with system error code:{systemErrorCode}");
                        }

                        return(asyncResult.CompletionSource.Value.Task);
                    }
                }
                finally
                {
                    if (needToFree)
                    {
                        Overlapped.Unpack(pOverlapped);
                        Overlapped.Free(pOverlapped);
                    }
                }
            }
        }
Example #10
0
        //solucion de https://stackoverflow.com/questions/33389896/c-sharp-wcf-hosted-in-windows-service-goes-idle-after-5-minutes/33396091#33396091
        private static unsafe void QueueDummyIOCPWork()
        {
            Overlapped        ovl  = new Overlapped();
            NativeOverlapped *pOvl = null;

            pOvl = ovl.Pack((a, b, c) => { Overlapped.Unpack(pOvl); Overlapped.Free(pOvl); }, null);
            ThreadPool.UnsafeQueueNativeOverlapped(pOvl);
        }
Example #11
0
            internal HttpRequestStreamAsyncResult(object asyncObject, object userState, AsyncCallback callback, byte[] buffer, int offset, uint size, uint dataAlreadyRead) : base(asyncObject, userState, callback)
            {
                m_dataAlreadyRead = dataAlreadyRead;
                Overlapped overlapped = new Overlapped();

                overlapped.AsyncResult = this;
                m_pOverlapped          = overlapped.Pack(s_IOCallback, buffer);
                m_pPinnedBuffer        = (void *)(Marshal.UnsafeAddrOfPinnedArrayElement(buffer, offset));
            }
Example #12
0
    public static unsafe void PackNegTest()
    {
        var helper = new AsyncHelper();
        IOCompletionCallback callback = MyCallback(helper);

        Overlapped        ov = new Overlapped();
        NativeOverlapped *nativeOverlapped = ov.Pack(new IOCompletionCallback(callback), null);

        try
        {
            Assert.True(nativeOverlapped != null);
            Assert.Throws <InvalidOperationException>(() => ov.Pack(new IOCompletionCallback(callback), null));
        }
        finally
        {
            Overlapped.Free(nativeOverlapped);
        }
    }
Example #13
0
        private unsafe void PostAcceptRequestToIOCP()
        {
            _shutdownEvent.AddCount();

            Overlapped        ov  = new Overlapped();
            NativeOverlapped *nov = ov.Pack(AcceptRequestIOCompletionCallback, null);

            ThreadPool.UnsafeQueueNativeOverlapped(nov);
        }
Example #14
0
    // clear out the USB input buffer
    public void FlushReadUSB()
    {
        // note the starting time so we don't wait forever
        DateTime t0 = DateTime.Now;

        // wait until a read would block
        int rptLen = inputReportLength;

        while ((DateTime.Now - t0).TotalMilliseconds < 100)
        {
            // set up a non-blocking read
            IntPtr buf = Marshal.AllocHGlobal(rptLen);
            try
            {
                unsafe
                {
                    // set up the overlapped I/O descriptor
                    Overlapped        o  = new Overlapped(0, 0, evov.SafeWaitHandle.DangerousGetHandle(), null);
                    NativeOverlapped *no = o.Pack(null, null);

                    // start the non-blocking read
                    Marshal.WriteByte(buf, 0);
                    HIDImports.ReadFile(fp, buf, rptLen, IntPtr.Zero, no);

                    // check to see if it's ready immediately
                    bool ready = evov.WaitOne(0);
                    if (ready)
                    {
                        // it's ready - complete the read
                        UInt32 readLen;
                        int    result = HIDImports.GetOverlappedResult(fp, no, out readLen, 0);
                    }
                    else
                    {
                        // Not ready - we'd have to wait to do a read, so the
                        // buffer is empty.  Cancel the read.
                        HIDImports.CancelIo(fp);
                    }

                    // done with the overlapped I/O descriptor
                    Overlapped.Unpack(no);
                    Overlapped.Free(no);

                    // if there was nothing ready to read, we've cleared out buffered
                    // inputs, so we're done
                    if (!ready)
                    {
                        return;
                    }
                }
            }
            finally
            {
                Marshal.FreeHGlobal(buf);
            }
        }
    }
        //
        // This method enables completion ports on the AsyncResult
        //
        internal unsafe void EnableCompletionPort()
        {
            //
            // Bind the Win32 Socket Handle to the ThreadPool
            //
            ((Socket)AsyncObject).BindToCompletionPort();
            m_NativeOverlapped = m_Overlapped.Pack(s_IOCallback);

            GlobalLog.Print("OverlappedAsyncResult#" + ValidationHelper.HashString(this) + "::EnableCompletionPort() m_Overlapped:" + ValidationHelper.HashString(m_Overlapped) + " m_NativeOverlapped = " + ((int)m_NativeOverlapped).ToString());
        }
Example #16
0
        public unsafe void Write(byte[] buffer, int offset)
        {
            Overlapped        ovl         = new Overlapped(offset, 0, IntPtr.Zero, null);
            NativeOverlapped *pOverlapped = ovl.Pack(WriteComplete, buffer);

            fixed(byte *bytes = buffer)
            {
                NativeMethods.WriteFile(_fileHandle, bytes, buffer.Length, IntPtr.Zero, pOverlapped);
            }
        }
Example #17
0
    public static unsafe void PackNegTest()
    {
        var helper = new AsyncHelper();
        IOCompletionCallback callback = MyCallback(helper);

        NativeOverlapped* nativeOverlapped;
        Overlapped ov = new Overlapped();
        nativeOverlapped = ov.Pack(new IOCompletionCallback(callback), null);

        try
        {
            Assert.True(nativeOverlapped != null);
            Assert.Throws<InvalidOperationException>(() => ov.Pack(new IOCompletionCallback(callback), null));
        }
        finally
        {
            Overlapped.Free(nativeOverlapped);
        }
    }
Example #18
0
    internal static unsafe IOCompletionCallback MyCallback(AsyncHelper helper)
    {
        IOCompletionCallback del = delegate(uint param1, uint param2, NativeOverlapped *overlapped)
        {
            Overlapped        ov = new Overlapped();
            NativeOverlapped *nativeOverlapped2 = ov.Pack(helper.Callback, null);
            ThreadPool.UnsafeQueueNativeOverlapped(nativeOverlapped2);
        };

        return(del);
    }
Example #19
0
        public NativeOverlapped *PackOverlapped(Object userData)
        {
            if (pOverlapped != null)
            {
                throw new InvalidOperationException();
            }
            //Passing a real WaitHandle to the Overlapped constructor results in a race condition between CompletionCallback / Complete because the event may be signalled before the callback completes
            Overlapped overlapped = new Overlapped(0, 0, IntPtr.Zero, this);

            return(pOverlapped = overlapped.Pack(CompletionCallback, userData));
        }
Example #20
0
        public unsafe void WriteSync(byte[] buffer, Func <int, bool> checkOffset, bool withLock = true)
        {
            int temp = 0, offset;

            do
            {
                temp   = _offset;
                offset = temp + buffer.Length;
            } while (Interlocked.CompareExchange(ref _offset, offset, temp) != temp);

            if (checkOffset((int)_offset))
            {
                Overlapped        ovl         = new Overlapped(temp, 0, IntPtr.Zero, null);
                NativeOverlapped *pOverlapped = ovl.Pack(WriteComplete, buffer);

                try
                {
                    if (withLock)
                    {
                        while (!(withLock = NativeMethods.LockFile(_fileHandle, offset, 0, buffer.Length, 0)))
                        {
                            Thread.Sleep(0);
                        }
                    }

                    fixed(byte *bytes = buffer)
                    {
                        if (0 == NativeMethods.WriteFile(_fileHandle, bytes, buffer.Length, IntPtr.Zero, pOverlapped))
                        {
                            var dwResult = NativeMethods.GetLastError();
                            if (ERROR_IO_PENDING == dwResult)
                            {
                                IntPtr transferred = Marshal.AllocHGlobal(sizeof(ulong));
                                try
                                {
                                    NativeMethods.GetOverlappedResult(_fileHandle, pOverlapped, transferred, true);
                                }
                                finally
                                {
                                    Marshal.FreeHGlobal(transferred);
                                }
                            }
                        }
                    }
                }
                finally
                {
                    if (withLock)
                    {
                        NativeMethods.UnlockFile(_fileHandle, offset, 0, buffer.Length, 0);
                    }
                }
            }
        }
        /// <summary>
        /// Creates and returns a NativeOverlapped structure to be passed to
        /// native code (i.e. the driver).
        /// </summary>
        /// <returns></returns>
        public unsafe NativeOverlapped *GetNativeOverlapped()
        {
            // Create a managed Overlapped structure that refers to this
            // IAsyncResult
            Overlapped overlapped = new Overlapped(0, 0, IntPtr.Zero, this);

            // Pack the managed Overlapped structure into a NativeOverlapped
            // structure, which pins the memory until the operation completes
            return(overlapped.Pack(new IOCompletionCallback(CompletionCallback),
                                   mOutDeviceBuffer.Target
                                   ));
        }
Example #22
0
        // Creates and returns a NativeOverlapped structure to be passed to native code
        public unsafe NativeOverlapped *GetNativeOverlapped()
        {
            // Create a managed Overlapped structure that refers to our IAsyncResult (this)
            Overlapped o = new Overlapped(0, 0, IntPtr.Zero, this);

            // Pack the managed Overlapped structure into a NativeOverlapped structure
            // Pack causes the CLR to ensure that:
            //    1. the input/output objects are pinned
            //    2. the IAsyncResult object (this) isn't GC'd while the I/O is pending
            //    3. the thread pool thread calls CompletionCallback in the invoking thread's AppDomain
            return(o.Pack(CompletionCallback, new Object[] { m_inBuffer.Target, m_outBuffer.Target }));
        }
Example #23
0
        internal AsyncFileStream_AsyncResult(AsyncCallback userCallback, Object stateObject, bool isWrite)
        {
            m_userCallback    = userCallback;
            m_userStateObject = stateObject;
            m_waitHandle      = new ManualResetEvent(false);

            m_isWrite = isWrite;

            Overlapped overlapped = new Overlapped(0, 0, IntPtr.Zero, this);

            m_overlapped = overlapped.Pack(s_callback, null);
        }
Example #24
0
    public static unsafe void PackNegTest1()
    {
#pragma warning disable 618
        var helper = new AsyncHelper();
        IOCompletionCallback callback = MyCallback(helper);

        NativeOverlapped *nativeOverlapped;
        Overlapped        ov = new Overlapped();
        nativeOverlapped = ov.Pack(new IOCompletionCallback(callback));

        try
        {
            Assert.True(nativeOverlapped != null);
            Assert.Throws <InvalidOperationException>(() => ov.Pack(new IOCompletionCallback(callback)));
        }
        finally
        {
            Overlapped.Free(nativeOverlapped);
        }
#pragma warning restore 618
    }
        /// <include file='doc\FileSystemWatcher.uex' path='docs/doc[@for="FileSystemWatcher.Monitor"]/*' />
        /// <devdoc>
        ///     Calls native API and sets up handle with the directory change API.
        /// </devdoc>
        /// <internalonly/>
        private unsafe void Monitor(IntPtr bufferPtr)
        {
            if (!enabled || (directoryHandle == (IntPtr)(-1)))
            {
                return;
            }

            Overlapped overlapped = new Overlapped();

            if (bufferPtr == (IntPtr)0)
            {
                try {
                    bufferPtr = Marshal.AllocHGlobal((INTPTR_INTPTRCAST)internalBufferSize);
                } catch (OutOfMemoryException) {
                    throw new OutOfMemoryException(SR.GetString(SR.BufferSizeTooLarge, internalBufferSize.ToString()));
                }
            }

            ulong bufferPtrTemp = (ulong)bufferPtr;

            overlapped.OffsetHigh = (int)(0xffffffff00000000 & bufferPtrTemp);
            overlapped.OffsetLow  = (int)(0x00000000ffffffff & bufferPtrTemp);
            NativeOverlapped *overlappedPointer = overlapped.Pack(new IOCompletionCallback(this.CompletionStatusChanged));

            IntPtr h = directoryHandle;
            int    size;
            bool   ok = UnsafeNativeMethods.ReadDirectoryChangesW(new HandleRef(this, h),
                                                                  new HandleRef(this, bufferPtr),
                                                                  internalBufferSize,
                                                                  includeSubdirectories ? 1 : 0,
                                                                  (int)notifyFilters,
                                                                  out size,
                                                                  overlappedPointer,
                                                                  NativeMethods.NullHandleRef);

            if (!ok)
            {
                Overlapped.Free(overlappedPointer);
                Marshal.FreeHGlobal(bufferPtr);

                // If the handle was for some reason changed or closed during this call, then don't throw an
                // exception.  Else, it's a valid error.
                if ((h == directoryHandle) && (directoryHandle != (IntPtr)(-1)))
                {
                    OnError(new ErrorEventArgs(new Win32Exception()));
                }
            }
        }
Example #26
0
        public unsafe static bool ConnectNamedPipe(IntPtr hNamedPipe,        // handle to named pipe
                                                   Overlapped lpOverlapped   // overlapped structure
                                                   )
        {
            NativeOverlapped *overlappedPack = lpOverlapped.Pack(null, null);
            bool fRet = false;

            if (overlappedPack != null)
            {
                fRet = ConnectNamedPipe(hNamedPipe, overlappedPack);

                Overlapped.Free(overlappedPack);
            }

            return(fRet);
        }
Example #27
0
        public unsafe void ReadControlOverlapped(uint controlCode, byte[] writeBuffer, byte[] readBuffer)
        {
            var  completedEvent = new ManualResetEvent(false);
            uint bytesReturned  = 0;
            var  inOverlapped   = new Overlapped();

            inOverlapped.EventHandleIntPtr = completedEvent.SafeWaitHandle.DangerousGetHandle();
            NativeOverlapped *inNativeOverlapped = inOverlapped.Pack(null, null);

            try
            {
                fixed(byte *inBuffer = writeBuffer)
                {
                    fixed(byte *outBuffer = readBuffer)
                    {
                        var success = false;

                        try
                        {
                            success = InteropKernel32.DeviceIoControl(_readHandle,
                                                                      controlCode,
                                                                      inBuffer,
                                                                      writeBuffer == null ? 0 : (uint)writeBuffer.Length,
                                                                      outBuffer,
                                                                      readBuffer == null ? 0 : (uint)readBuffer.Length,
                                                                      ref bytesReturned,
                                                                      inNativeOverlapped);
                        }
                        catch (ObjectDisposedException)
                        {
                            throw new Exception("File handle already closed");
                        }

                        if (!success)
                        {
                            HandleIOError(true);

                            CancelOverlapped(_readHandle, completedEvent);
                        }
                    }
                }
            }
            finally
            {
                Overlapped.Free(inNativeOverlapped);
            }
        }
        unsafe public void Write(string value)
        {
            if (value.Length > bufferSize)
            {
                throw new ArgumentException($"Value '{value}' longer than specified buffer size of {bufferSize}", nameof(value));
            }
            int errorCode;
            var overlapped = new Overlapped();

            NativeOverlapped *nativeOverlapped = overlapped.Pack(WriteCompletionCallback, null);

            try
            {
                var  valueAsByteArray = Encoding.ASCII.GetBytes(value);
                uint bytesWritten     = 0;
                var  writeFileResult  = UnsafeNativeMethods.WriteFile(fileHandle, valueAsByteArray, (uint)value.Length, ref bytesWritten, nativeOverlapped);
                errorCode = Marshal.GetLastWin32Error();
                if (writeFileResult != 0)
                {
                    if (bytesWritten != value.Length)
                    {
                        throw new InvalidOperationException($"Expected to write {value.Length} bytes, wrote {bytesWritten}");
                    }
                    return; //write was successful
                }
                if (errorCode == SafeNativeMethods.ERROR_IO_PENDING)
                {
                    uint bytesTransferred = 0;
                    if (UnsafeNativeMethods.GetOverlappedResult(fileHandle, nativeOverlapped, ref bytesTransferred, 1) == 0)
                    {
                        errorCode = Marshal.GetLastWin32Error();
                        throw new InvalidOperationException($"GetOverlappedResult returned FALSE. Last Win32 error code is {errorCode}.");
                    }
                    if (bytesTransferred != value.Length)
                    {
                        throw new InvalidOperationException($"Expected to transfer {value.Length}, transferred {bytesTransferred}");
                    }
                    return;
                }
                throw new InvalidOperationException($"WriteFile returned FALSE. Last Win32 error code is {errorCode}");
            }
            finally
            {
                Overlapped.Free(nativeOverlapped);
            }
        }
        public void WriteData(byte[] data)
        {
            if (Device != null)
            {
                uint       bytesWritten = 0;
                Overlapped overlapped   = new Overlapped();
                WriteOverlapped = overlapped.Pack(WriteDeviceIOCompletionCallback, null);

                WriteFile(
                    Device,
                    data,
                    (uint)data.Length,
                    ref bytesWritten,
                    WriteOverlapped
                    );
            }
        }
        unsafe public string Read(int numberOfBytes)
        {
            if (numberOfBytes > bufferSize)
            {
                throw new ArgumentException($"Cannot read {numberOfBytes} bytes because buffer size specified in constructor is only {bufferSize}.", nameof(numberOfBytes));
            }
            var overlapped = new Overlapped();
            NativeOverlapped *nativeOverlapped = overlapped.Pack(ReadCompletionCallback, null);

            try
            {
                int  errorCode;
                var  buffer         = new byte[numberOfBytes];
                uint bytesRead      = 0;
                var  readFileResult = UnsafeNativeMethods.ReadFile(fileHandle, buffer, numberOfBytes, ref bytesRead, nativeOverlapped);
                errorCode = Marshal.GetLastWin32Error();
                if (readFileResult != 0)
                {
                    if (bytesRead != numberOfBytes)
                    {
                        throw new InvalidOperationException($"Expected to read {numberOfBytes}, read {bytesRead}");
                    }
                    return(Encoding.ASCII.GetString(buffer));
                }
                if (errorCode == SafeNativeMethods.ERROR_IO_PENDING)
                {
                    uint bytesTransferred = 0;
                    if (UnsafeNativeMethods.GetOverlappedResult(fileHandle, nativeOverlapped, ref bytesTransferred, 1) == 0)
                    {
                        errorCode = Marshal.GetLastWin32Error();
                        throw new InvalidOperationException($"GetOverlappedResult returned FALSE. Last Win32 error code is {errorCode}.");
                    }
                    if (bytesTransferred != numberOfBytes)
                    {
                        throw new InvalidOperationException($"Expected to transfer {numberOfBytes} bytes, transferred {bytesTransferred}");
                    }
                    return(Encoding.ASCII.GetString(buffer));
                }
                throw new InvalidOperationException($"ReadFile returned FALSE. Last Win32 error code is {errorCode}");
            }
            finally
            {
                Overlapped.Free(nativeOverlapped);
            }
        }
Example #31
0
        public bool Read(long pageNumber, byte *buffer, int count)
        {
            if (_readHandle == null)
            {
                _readHandle = Win32NativeFileMethods.CreateFile(_filename,
                                                                Win32NativeFileAccess.GenericRead,
                                                                Win32NativeFileShare.Write | Win32NativeFileShare.Read | Win32NativeFileShare.Delete,
                                                                IntPtr.Zero,
                                                                Win32NativeFileCreationDisposition.OpenExisting,
                                                                Win32NativeFileAttributes.Normal,
                                                                IntPtr.Zero);
            }

            long position   = pageNumber * AbstractPager.PageSize;
            var  overlapped = new Overlapped((int)(position & 0xffffffff), (int)(position >> 32), IntPtr.Zero, null);
            NativeOverlapped *nativeOverlapped = overlapped.Pack(null, null);

            try
            {
                while (count > 0)
                {
                    int read;
                    if (Win32NativeFileMethods.ReadFile(_readHandle, buffer, count, out read, nativeOverlapped) == false)
                    {
                        int lastWin32Error = Marshal.GetLastWin32Error();
                        if (lastWin32Error == Win32NativeFileMethods.ErrorHandleEof)
                        {
                            return(false);
                        }
                        throw new Win32Exception(lastWin32Error);
                    }
                    count    -= read;
                    buffer   += read;
                    position += read;
                    nativeOverlapped->OffsetLow  = (int)(position & 0xffffffff);
                    nativeOverlapped->OffsetHigh = (int)(position >> 32);
                }
                return(true);
            }
            finally
            {
                Overlapped.Free(nativeOverlapped);
            }
        }
Example #32
0
    public static unsafe void PackPosTest()
    {
        #pragma warning disable 618
        Overlapped ov = new Overlapped();
        var helper = new AsyncHelper();
        IOCompletionCallback callback = MyCallback(helper);

        NativeOverlapped* nativeOverlapped = ov.Pack(callback);
        try
        {
            Assert.True(nativeOverlapped != null);

            Assert.True(ThreadPool.UnsafeQueueNativeOverlapped(nativeOverlapped));

            Assert.True(helper.Wait());
        }
        finally
        {
            Overlapped.Free(nativeOverlapped);
        }
        #pragma warning restore 618
    }
Example #33
0
    internal static unsafe IOCompletionCallback MyCallback(AsyncHelper helper)
    {
        IOCompletionCallback del = delegate (uint param1, uint param2, NativeOverlapped* overlapped)
        {

            Overlapped ov = new Overlapped();
            NativeOverlapped* nativeOverlapped2 = ov.Pack(helper.Callback, null);
            ThreadPool.UnsafeQueueNativeOverlapped(nativeOverlapped2);
        };

        return del;
    }
Example #34
0
        unsafe private FileStreamAsyncResult BeginWriteCore(byte[] bytes, int offset, int numBytes, AsyncCallback userCallback, Object stateObject)
        { 
            Contract.Assert(!_handle.IsClosed, "!_handle.IsClosed"); 
            Contract.Assert(CanWrite, "CanWrite");
            Contract.Assert(bytes != null, "bytes != null"); 
            Contract.Assert(_readPos == _readLen, "_readPos == _readLen");
            Contract.Assert(_isAsync, "BeginWriteCore doesn't work on synchronous file streams!");
            Contract.Assert(offset >= 0, "offset is negative");
            Contract.Assert(numBytes >= 0, "numBytes is negative"); 

            // Create and store async stream class library specific data in the 
            // async result 
            FileStreamAsyncResult asyncResult = new FileStreamAsyncResult();
            asyncResult._handle = _handle; 
            asyncResult._userCallback = userCallback;
            asyncResult._userStateObject = stateObject;
            asyncResult._isWrite = true;
 
            // For Synchronous IO, I could go with either a callback 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
            // We will set the file offsets later
            Overlapped overlapped = new Overlapped(0, 0, IntPtr.Zero, asyncResult);
 
            // Pack the Overlapped class, and store it in the async result
            NativeOverlapped* intOverlapped; 
            if (userCallback != null) 
                intOverlapped = overlapped.Pack(IOCallback, bytes);
            else 
                intOverlapped = overlapped.UnsafePack(null, bytes);
            asyncResult._overlapped = intOverlapped;

            if (CanSeek) { 
                // Make sure we set the length of the file appropriately.
                long len = Length; 
                //Console.WriteLine("BeginWrite - Calculating end pos.  pos: "+pos+"  len: "+len+"  numBytes: "+numBytes); 

                // Make sure we are writing to the position that we think we are 
                if (_exposedHandle)
                    VerifyOSHandlePosition();

                if (_pos + numBytes > len) { 
                    //Console.WriteLine("BeginWrite - Setting length to: "+(pos + numBytes));
                    SetLengthCore(_pos + numBytes); 
                } 

                // Now set the position to read from in the NativeOverlapped struct 
                // For pipes, we should leave the offset fields set to 0.
                intOverlapped->OffsetLow = (int)_pos;
                intOverlapped->OffsetHigh = (int)(_pos>>32);
 
                // When using overlapped IO, the OS is not supposed to
                // touch the file pointer location at all.  We will adjust it 
                // ourselves.  This isn't threadsafe. 

                // 



 

 
 
                SeekCore(numBytes, SeekOrigin.Current);
            } 

            //Console.WriteLine("BeginWrite finishing.  pos: "+pos+"  numBytes: "+numBytes+"  _pos: "+_pos+"  Position: "+Position);

            int hr = 0; 
            // queue an async WriteFile operation and pass in a packed overlapped
            int r = WriteFileNative(_handle, bytes, offset, numBytes, intOverlapped, out hr); 
 
            // WriteFile, the OS version, will return 0 on failure.  But
            // my WriteFileNative wrapper returns -1.  My wrapper 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 bytes
            // written back from this call when using overlapped IO!  You must 
            // not pass in a non-null lpNumBytesWritten to WriteFile when using 
            // overlapped structures!  This is ByDesign NT behavior.
            if (r==-1 && numBytes!=-1) { 
                //Console.WriteLine("WriteFile returned 0;  Write will complete asynchronously (if hr==3e5)  hr: 0x{0:x}", hr);

                // For pipes, when they are closed on the other side, they will come here.
                if (hr == ERROR_NO_DATA) { 
                    // Not an error, but EOF.  AsyncFSCallback will NOT be
                    // called.  Call the user callback here. 
                    asyncResult.CallUserCallback(); 
                    // EndWrite will free the Overlapped struct correctly.
                } 
                else if (hr != ERROR_IO_PENDING) {
                    if (!_handle.IsClosed && CanSeek)  // Update Position - It could be anywhere.
                        SeekCore(0, SeekOrigin.Current);
 
                    if (hr == ERROR_HANDLE_EOF)
                        __Error.EndOfFile(); 
                    else 
                        __Error.WinIOError(hr, String.Empty);
                } 
            }
            else {
                // Due to a workaround for a race condition in NT's ReadFile &
                // WriteFile routines, we will always be returning 0 from WriteFileNative 
                // when we do async IO instead of the number of bytes written,
                // irregardless of whether the operation completed 
                // synchronously or asynchronously.  We absolutely must not 
                // set asyncResult._numBytes here, since will never have correct
                // results. 
                //Console.WriteLine("WriteFile returned: "+r+" (0x"+Int32.Format(r, "x")+")  The IO completed synchronously, but the user callback was called on another thread.");
            }

            return asyncResult; 
        }
Example #35
0
	//
	// Starts an asynchronous read operation.
	// 

    public override unsafe IAsyncResult BeginRead(byte[] buffer, int offset, int count,
												  AsyncCallback userCallback, object userState) {
		if (!_isAsync) {
			return base.BeginRead(buffer, offset, count, userCallback, userState);
		}
		
        NativeOverlapped* overlappedPtr;
        SimpleFileStreamAsyncResult fsar = new SimpleFileStreamAsyncResult(userCallback, userState);
        Overlapped overlapped = new Overlapped(0, 0, IntPtr.Zero, fsar);
        overlappedPtr = overlapped.Pack(IOCallback, buffer);
        long length = Length;
		if (_position + count > length) {
			if (_position <= length) {
				count = (int)(length - _position);
			} else {
				count = 0;
			}
		}
        overlappedPtr->OffsetLow = (int)_position;
        overlappedPtr->OffsetHigh = (int) (_position >> 32);
        Seek((long)count, SeekOrigin.Current);
        int errorCode;
        if (ReadFileNative(buffer, offset, count, overlappedPtr, out errorCode) == -1) {
            if (errorCode == Win32Native.ERROR_IO_PENDING)
                return fsar;
            throw GetIOException(errorCode);
        }
        return fsar;
    }
Example #36
0
        unsafe private FileStreamAsyncResult BeginReadCore(byte[] bytes, int offset, int numBytes, AsyncCallback userCallback, Object stateObject, int numBufferedBytesRead)
        { 
            Contract.Assert(!_handle.IsClosed, "!_handle.IsClosed");
            Contract.Assert(CanRead, "CanRead"); 
            Contract.Assert(bytes != null, "bytes != null"); 
            Contract.Assert(_writePos == 0, "_writePos == 0");
            Contract.Assert(_isAsync, "BeginReadCore doesn't work on synchronous file streams!"); 
            Contract.Assert(offset >= 0, "offset is negative");
            Contract.Assert(numBytes >= 0, "numBytes is negative");

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

            // Must set this here to ensure all the state on the IAsyncResult
            // object is set before we call ReadFile, which gives the OS an 
            // opportunity to run our callback (including the user callback &
            // the call to EndRead) before ReadFile has returned. 
            asyncResult._numBufferedBytes = numBufferedBytesRead; 

            // For Synchronous IO, I could go with either a callback 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
            // We will set the file offsets later 
            Overlapped overlapped = new Overlapped(0, 0, IntPtr.Zero, asyncResult); 

            // Pack the Overlapped class, and store it in the async result 
            NativeOverlapped* intOverlapped;
            if (userCallback != null)
                intOverlapped = overlapped.Pack(IOCallback, bytes);
            else 
                intOverlapped = overlapped.UnsafePack(null, bytes);
 
            asyncResult._overlapped = intOverlapped; 

            // Calculate position in the file we should be at after the read is done 
            if (CanSeek) {
                long len = Length;

                // Make sure we are reading from the position that we think we are 
                if (_exposedHandle)
                    VerifyOSHandlePosition(); 
 
                if (_pos + numBytes > len) {
                    if (_pos <= len) 
                        numBytes = (int) (len - _pos);
                    else
                        numBytes = 0;
                } 

                // Now set the position to read from in the NativeOverlapped struct 
                // For pipes, we should leave the offset fields set to 0. 
                intOverlapped->OffsetLow = unchecked((int)_pos);
                intOverlapped->OffsetHigh = (int)(_pos>>32); 

                // When using overlapped IO, the OS is not supposed to
                // touch the file pointer location at all.  We will adjust it
                // ourselves. This isn't threadsafe. 

                // WriteFile should not update the file pointer when writing 
                // in overlapped mode, according to MSDN.  But it does update 
                // the file pointer when writing to a UNC path!
                // So changed the code below to seek to an absolute 
                // location, not a relative one.  ReadFile seems consistent though.
                SeekCore(numBytes, SeekOrigin.Current);
            }
 
            // queue an async ReadFile operation and pass in a packed overlapped
            int hr = 0; 
            int r = ReadFileNative(_handle, bytes, offset, numBytes, intOverlapped, out hr); 
            // ReadFile, the OS version, will return 0 on failure.  But
            // my ReadFileNative wrapper returns -1.  My wrapper 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 bytes
            // 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 && numBytes!=-1) { 

                // For pipes, when they hit EOF, they will come here.
                if (hr == ERROR_BROKEN_PIPE) {
                    // Not an error, but EOF.  AsyncFSCallback will NOT be 
                    // called.  Call the user callback here.
 
                    // We clear the overlapped status bit for this special case. 
                    // Failure to do so looks like we are freeing a pending overlapped later.
                    intOverlapped->InternalLow = IntPtr.Zero; 
                    asyncResult.CallUserCallback();
                    // EndRead will free the Overlapped struct correctly.
                }
                else if (hr != ERROR_IO_PENDING) { 
                    if (!_handle.IsClosed && CanSeek)  // Update Position - It could be anywhere.
                        SeekCore(0, SeekOrigin.Current); 
 
                    if (hr == ERROR_HANDLE_EOF)
                        __Error.EndOfFile(); 
                    else
                        __Error.WinIOError(hr, String.Empty);
                }
            } 
            else {
                // Due to a workaround for a race condition in NT's ReadFile & 
                // WriteFile routines, we will always be returning 0 from ReadFileNative 
                // when we do async IO instead of the number of bytes read,
                // irregardless of whether the operation completed 
                // synchronously or asynchronously.  We absolutely must not
                // set asyncResult._numBytes here, since will never have correct
                // results.
                //Console.WriteLine("ReadFile returned: "+r+" (0x"+Int32.Format(r, "x")+")  The IO completed synchronously, but the user callback was called on a separate thread"); 
            }
 
            return asyncResult; 
        }
Example #37
0
    public static unsafe void UnPackTest()
    {
        Assert.Throws<ArgumentNullException>(() => Overlapped.Unpack(null));

        Overlapped ov = new Overlapped();
        var helper = new AsyncHelper();
        IOCompletionCallback callback = MyCallback(helper);
        NativeOverlapped* nativeOverlapped = ov.Pack(new IOCompletionCallback(callback), null);
        try
        {
            Assert.True(null != nativeOverlapped);

            Overlapped ov1 = Overlapped.Unpack(nativeOverlapped);
            Assert.Same(ov1, ov);
        }
        finally
        {
            Overlapped.Free(nativeOverlapped);
        }
    }