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); } } }
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 ); }
internal void Reset(uint size) { if (size == m_Size) { return; } if (m_Size != 0) { Overlapped.Free(m_pOverlapped); } m_Size = size; if (size == 0) { m_pOverlapped = null; m_MemoryBlob = null; m_BackingBuffer = null; return; } m_BackingBuffer = new byte[checked((int) size)]; Overlapped overlapped = new Overlapped(); overlapped.AsyncResult = this; m_pOverlapped = overlapped.Pack(s_IOCallback, m_BackingBuffer); m_MemoryBlob = (UnsafeNclNativeMethods.HttpApi.HTTP_SSL_CLIENT_CERT_INFO*) Marshal.UnsafeAddrOfPinnedArrayElement(m_BackingBuffer, 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); } }
//-------------------------------------------------------------------------- // Data transmission //-------------------------------------------------------------------------- public override bool Send(NxtMessage msg) { bool fResult = false; if (this.IsOpen) { try { lock (this.msgReplyTargets) { this.msgReplyTargets.Add(msg); } byte[] rgbToSend = msg.DataForBluetoothTransmission; int cbSent = 0; unsafe { EventWaitHandle asyncWriteCompleteEvent = new EventWaitHandle(false, System.Threading.EventResetMode.ManualReset); Overlapped overlappedWrite = new Overlapped(-1, -1, asyncWriteCompleteEvent.SafeWaitHandle.DangerousGetHandle(), null); NativeOverlapped* pNativeOverlappedWrite = overlappedWrite.Pack(null, rgbToSend); try { bool fSuccess = WriteFile(this.hSerialPort, rgbToSend, rgbToSend.Length, out cbSent, new IntPtr(pNativeOverlappedWrite)); if (!fSuccess) { int err = Marshal.GetLastWin32Error(); if (ERROR_IO_PENDING == err) { asyncWriteCompleteEvent.WaitOne(); } else ThrowWin32Error(err); } } finally { System.Threading.Overlapped.Free(pNativeOverlappedWrite); } } msg.NoteSent(); fResult = true; } catch (Exception) { } } return fResult; }
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; }
private unsafe FileStreamAsyncResult BeginWriteCore(byte[] bytes, int offset, int numBytes, AsyncCallback userCallback, object stateObject) { NativeOverlapped* overlappedPtr; FileStreamAsyncResult ar = new FileStreamAsyncResult { _handle = this._handle, _userCallback = userCallback, _userStateObject = stateObject, _isWrite = true }; ManualResetEvent event2 = new ManualResetEvent(false); ar._waitHandle = event2; Overlapped overlapped = new Overlapped(0, 0, IntPtr.Zero, ar); if (userCallback != null) { overlappedPtr = overlapped.Pack(IOCallback, bytes); } else { overlappedPtr = overlapped.UnsafePack(null, bytes); } ar._overlapped = overlappedPtr; if (this.CanSeek) { long length = this.Length; if (this._exposedHandle) { this.VerifyOSHandlePosition(); } if ((this._pos + numBytes) > length) { this.SetLengthCore(this._pos + numBytes); } overlappedPtr->OffsetLow = (int) this._pos; overlappedPtr->OffsetHigh = (int) (this._pos >> 0x20); this.SeekCore((long) numBytes, SeekOrigin.Current); } int hr = 0; if ((this.WriteFileNative(this._handle, bytes, offset, numBytes, overlappedPtr, out hr) == -1) && (numBytes != -1)) { if (hr == 0xe8) { ar.CallUserCallback(); return ar; } if (hr == 0x3e5) { return ar; } if (!this._handle.IsClosed && this.CanSeek) { this.SeekCore(0L, SeekOrigin.Current); } if (hr == 0x26) { __Error.EndOfFile(); return ar; } __Error.WinIOError(hr, string.Empty); } return ar; }
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 HttpResponseStreamAsyncResult(object asyncObject, object userState, AsyncCallback callback, byte[] buffer, int offset, int size, bool chunked, bool sentHeaders): base(asyncObject, userState, callback){ m_SentHeaders = sentHeaders; Overlapped overlapped = new Overlapped(); overlapped.AsyncResult = this; if (size == 0) { m_DataChunks = null; m_pOverlapped = overlapped.Pack(s_IOCallback, null); } else { m_DataChunks = new UnsafeNclNativeMethods.HttpApi.HTTP_DATA_CHUNK[chunked ? 3 : 1]; GlobalLog.Print("HttpResponseStreamAsyncResult#" + ValidationHelper.HashString(this) + "::.ctor() m_pOverlapped:0x" + ((IntPtr)m_pOverlapped).ToString("x8")); object[] objectsToPin = new object[1 + m_DataChunks.Length]; objectsToPin[m_DataChunks.Length] = m_DataChunks; int chunkHeaderOffset = 0; byte[] chunkHeaderBuffer = null; if (chunked) { chunkHeaderBuffer = ConnectStream.GetChunkHeader(size, out chunkHeaderOffset); m_DataChunks[0] = new UnsafeNclNativeMethods.HttpApi.HTTP_DATA_CHUNK(); m_DataChunks[0].DataChunkType = UnsafeNclNativeMethods.HttpApi.HTTP_DATA_CHUNK_TYPE.HttpDataChunkFromMemory; m_DataChunks[0].BufferLength = (uint)(chunkHeaderBuffer.Length - chunkHeaderOffset); objectsToPin[0] = chunkHeaderBuffer; m_DataChunks[1] = new UnsafeNclNativeMethods.HttpApi.HTTP_DATA_CHUNK(); m_DataChunks[1].DataChunkType = UnsafeNclNativeMethods.HttpApi.HTTP_DATA_CHUNK_TYPE.HttpDataChunkFromMemory; m_DataChunks[1].BufferLength = (uint)size; objectsToPin[1] = buffer; m_DataChunks[2] = new UnsafeNclNativeMethods.HttpApi.HTTP_DATA_CHUNK(); m_DataChunks[2].DataChunkType = UnsafeNclNativeMethods.HttpApi.HTTP_DATA_CHUNK_TYPE.HttpDataChunkFromMemory; m_DataChunks[2].BufferLength = (uint)NclConstants.CRLF.Length; objectsToPin[2] = NclConstants.CRLF; } else { m_DataChunks[0] = new UnsafeNclNativeMethods.HttpApi.HTTP_DATA_CHUNK(); m_DataChunks[0].DataChunkType = UnsafeNclNativeMethods.HttpApi.HTTP_DATA_CHUNK_TYPE.HttpDataChunkFromMemory; m_DataChunks[0].BufferLength = (uint)size; objectsToPin[0] = buffer; } // This call will pin needed memory m_pOverlapped = overlapped.Pack(s_IOCallback, objectsToPin); if (chunked) { m_DataChunks[0].pBuffer = (byte*)(Marshal.UnsafeAddrOfPinnedArrayElement(chunkHeaderBuffer, chunkHeaderOffset)); m_DataChunks[1].pBuffer = (byte*)(Marshal.UnsafeAddrOfPinnedArrayElement(buffer, offset)); m_DataChunks[2].pBuffer = (byte*)(Marshal.UnsafeAddrOfPinnedArrayElement(NclConstants.CRLF, 0)); } else { m_DataChunks[0].pBuffer = (byte*)(Marshal.UnsafeAddrOfPinnedArrayElement(buffer, offset)); } } }
public override int WriteDirect(Page start, long pagePosition, int pagesToWrite) { if (_fileInfo.Extension == ".voron" && pagePosition > 1) { } var position = pagePosition * PageSize; var toWrite = pagesToWrite * PageSize; var overlapped = new Overlapped() { OffsetLow = (int)(position & 0xffffffff), OffsetHigh = (int)(position >> 32), }; var nativeOverlapped = overlapped.Pack(null, null); try { var startWrite = start.Base; while (toWrite != 0) { int written; if (NativeFileMethods.WriteFile(_safeFileHandle, startWrite, toWrite, out written, nativeOverlapped) == false) { throw new Win32Exception(); } toWrite -= written; startWrite += written; } return toWrite; } finally { Overlapped.Unpack(nativeOverlapped); Overlapped.Free(nativeOverlapped); } }
internal FileStreamAsyncResult( int numBufferedBytes, byte[] bytes, #if USE_OVERLAPPED SafeFileHandle handle, #endif AsyncCallback userCallback, Object userStateObject, bool isWrite) { _userCallback = userCallback; _userStateObject = userStateObject; _isWrite = isWrite; _numBufferedBytes = numBufferedBytes; #if USE_OVERLAPPED _handle = handle; #endif // 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); _waitHandle = waitHandle; #if USE_OVERLAPPED // Create a managed overlapped class // We will set the file offsets later Overlapped overlapped = new Overlapped(); overlapped.AsyncResult = this; // Pack the Overlapped class, and store it in the async result var ioCallback = s_IOCallback; // cached static delegate; delay initialized due to it being SecurityCritical if (ioCallback == null) s_IOCallback = ioCallback = new IOCompletionCallback(AsyncFSCallback); _overlapped = overlapped.Pack(ioCallback, bytes); Debug.Assert(_overlapped != null, "Did Overlapped.Pack or Overlapped.UnsafePack just return a null?"); #endif }
private UnsafeNclNativeMethods.HttpApi.HTTP_REQUEST* Allocate(uint size) { uint newSize = size != 0 ? size : RequestBuffer == null ? 4096 : Size; if (m_NativeOverlapped != null && newSize != RequestBuffer.Length) { NativeOverlapped* nativeOverlapped = m_NativeOverlapped; m_NativeOverlapped = null; Overlapped.Free(nativeOverlapped); } if (m_NativeOverlapped == null) { SetBuffer(checked((int) newSize)); Overlapped overlapped = new Overlapped(); overlapped.AsyncResult = m_Result; m_NativeOverlapped = overlapped.Pack(ListenerAsyncResult.IOCallback, RequestBuffer); return (UnsafeNclNativeMethods.HttpApi.HTTP_REQUEST*) Marshal.UnsafeAddrOfPinnedArrayElement(RequestBuffer, 0); } return RequestBlob; }
private unsafe int WaitForCommEvent() { int eventsOccurred = 0; Win32API_Serial.SetCommMask(_safeHandle.Handle, Win32API_Serial.ALL_EVENTS); AsyncSerialStream_AsyncResult asyncResult = new AsyncSerialStream_AsyncResult(); asyncResult._userCallback = null; asyncResult._userStateObject = null; asyncResult._isWrite = false; asyncResult._oldTimeout = -1; asyncResult._numBufferedBytes = 0; ManualResetEvent waitHandle = new ManualResetEvent(false); asyncResult._waitHandle = waitHandle; Overlapped overlapped = new Overlapped(0, 0, 0, asyncResult); NativeOverlapped* intOverlapped = overlapped.Pack(IOCallback); if (Win32API_Serial.WaitCommEvent(_safeHandle.Handle, ref eventsOccurred, intOverlapped) == false) { int hr = Marshal.GetLastWin32Error(); if (hr == Win32API_Serial.ERROR_IO_PENDING) { int temp = Win32API_Serial.WaitForSingleObject(waitHandle.Handle, -1); if(temp == 0) // no error return eventsOccurred; else Resources.WinIOError(); } else Resources.WinIOError(); } return eventsOccurred; }
unsafe private AsyncSerialStream_AsyncResult BeginWriteCore(byte[] array, int offset, int numBytes, AsyncCallback userCallback, Object stateObject, int timeout) { AsyncSerialStream_AsyncResult asyncResult = new AsyncSerialStream_AsyncResult(); asyncResult._userCallback = userCallback; asyncResult._userStateObject = stateObject; asyncResult._isWrite = true; asyncResult._oldTimeout = WriteTimeout; WriteTimeout = timeout; ManualResetEvent waitHandle = new ManualResetEvent(false); asyncResult._waitHandle = waitHandle; Overlapped overlapped = new Overlapped(0, 0, 0, asyncResult); NativeOverlapped* intOverlapped = overlapped.Pack(IOCallback); int hr = 0; int r = WriteFileNative(_safeHandle, array, offset, numBytes, intOverlapped, out hr); if (r==-1) { if (hr != Win32API_Serial.ERROR_IO_PENDING) { if (hr == Win32API_Serial.ERROR_HANDLE_EOF) Resources.EndOfFile(); else Resources.WinIOError(hr, String.Empty); } } return asyncResult; }
unsafe private SerialStreamAsyncResult BeginWriteCore(byte[] array, int offset, int numBytes, AsyncCallback userCallback, Object stateObject) { // Create and store async stream class library specific data in the // async result SerialStreamAsyncResult asyncResult = new SerialStreamAsyncResult(); 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 = overlapped.Pack(IOCallback, array); asyncResult._overlapped = intOverlapped; int hr = 0; // queue an async WriteFile operation and pass in a packed overlapped int r = WriteFileNative(array, 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 // Note that 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! if (r==-1) { if (hr != NativeMethods.ERROR_IO_PENDING) { if (hr == NativeMethods.ERROR_HANDLE_EOF) InternalResources.EndOfFile(); else InternalResources.WinIOError(hr, String.Empty); } } return asyncResult; }
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)); }
internal unsafe void WaitForCommEvent() { int unused = 0; bool doCleanup = false; NativeOverlapped* intOverlapped = null; while (!ShutdownLoop) { SerialStreamAsyncResult asyncResult = null; if (isAsync) { asyncResult = new SerialStreamAsyncResult(); asyncResult._userCallback = null; asyncResult._userStateObject = null; asyncResult._isWrite = false; // we're going to use _numBytes for something different in this loop. In this case, both // freeNativeOverlappedCallback and this thread will decrement that value. Whichever one decrements it // to zero will be the one to free the native overlapped. This guarantees the overlapped gets freed // after both the callback and GetOverlappedResult have had a chance to use it. asyncResult._numBytes = 2; asyncResult._waitHandle = waitCommEventWaitHandle; waitCommEventWaitHandle.Reset(); Overlapped overlapped = new Overlapped(0, 0, waitCommEventWaitHandle.SafeWaitHandle.DangerousGetHandle(), asyncResult); // Pack the Overlapped class, and store it in the async result intOverlapped = overlapped.Pack(freeNativeOverlappedCallback, null); } fixed (int* eventsOccurredPtr = &eventsOccurred) { if (UnsafeNativeMethods.WaitCommEvent(handle, eventsOccurredPtr, intOverlapped) == false) { int hr = Marshal.GetLastWin32Error(); // When a device is disconnected unexpectedly from a serial port, there appear to be // at least two error codes Windows or drivers may return. if (hr == NativeMethods.ERROR_ACCESS_DENIED || hr == NativeMethods.ERROR_BAD_COMMAND) { doCleanup = true; break; } if (hr == NativeMethods.ERROR_IO_PENDING) { Debug.Assert(isAsync, "The port is not open for async, so we should not get ERROR_IO_PENDING from WaitCommEvent"); int error; // if we get IO pending, MSDN says we should wait on the WaitHandle, then call GetOverlappedResult // to get the results of WaitCommEvent. bool success = waitCommEventWaitHandle.WaitOne(); Debug.Assert(success, "waitCommEventWaitHandle.WaitOne() returned error " + Marshal.GetLastWin32Error()); do { // NOTE: GetOverlappedResult will modify the original pointer passed into WaitCommEvent. success = UnsafeNativeMethods.GetOverlappedResult(handle, intOverlapped, ref unused, false); error = Marshal.GetLastWin32Error(); } while (error == NativeMethods.ERROR_IO_INCOMPLETE && !ShutdownLoop && !success); if (!success) { // Ignore ERROR_IO_INCOMPLETE and ERROR_INVALID_PARAMETER, because there's a chance we'll get // one of those while shutting down if (! ( (error == NativeMethods.ERROR_IO_INCOMPLETE || error == NativeMethods.ERROR_INVALID_PARAMETER) && ShutdownLoop)) Debug.Assert(false, "GetOverlappedResult returned error, we might leak intOverlapped memory" + error.ToString(CultureInfo.InvariantCulture)); } } else if (hr != NativeMethods.ERROR_INVALID_PARAMETER) { // ignore ERROR_INVALID_PARAMETER errors. WaitCommError seems to return this // when SetCommMask is changed while it's blocking (like we do in Dispose()) Debug.Assert(false, "WaitCommEvent returned error " + hr); } } } if (!ShutdownLoop) CallEvents(eventsOccurred); if (isAsync) { if (Interlocked.Decrement(ref asyncResult._numBytes) == 0) Overlapped.Free(intOverlapped); } } // while (!ShutdownLoop) if (doCleanup) { // the rest will be handled in Dispose() endEventLoop = true; Overlapped.Free(intOverlapped); } eventLoopEndedSignal.Set(); }
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; }
static void Main(string[] args) { var nancyApp = StartupNancyApp(); //var workingTitleApp = StartupWorkingTitleApp(); for (;;) { var input = Console.ReadLine(); if (input == "exit") { nancyApp.Dispose(); //workingTitleApp.Dispose(); return; } if (input == "1") { var request = (HttpWebRequest)WebRequest.Create("http://127.0.0.1:8080"); try { request.GetResponse(); } catch (WebException ex) { Console.WriteLine(ex.Message); } } else if (input == "2") { var socket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.IP); socket.Connect("localhost", 8080); var blocking = socket.Blocking; socket.Blocking = false; //var sr = socket.BeginReceive(new byte[0], 0, 0, SocketFlags.None, ar => // { // socket.EndReceive(ar); // }, null); //var optionOutValue = new byte[4]; //var ioControl = socket.IOControl(IOControlCode.NonBlockingIO, new byte[] {1, 0, 0, 0}, optionOutValue); unsafe { var wsabuf = new WSABUF(); uint numberOfBytesRecvd; var flags = SocketFlags.None; var result = WSARecv( socket.Handle, ref wsabuf, 1, out numberOfBytesRecvd, ref flags, null, CallbackThunk1); var lastError = result == -1 ? Marshal.GetLastWin32Error() : 0; var overlapped = new Overlapped(); overlapped.AsyncResult = new ARes(); var nativeOverlapped = overlapped.Pack(Iocb, null); Trace.WriteLine(string.Format("{0}", new IntPtr(nativeOverlapped))); wsabuf = new WSABUF {buf = Marshal.AllocCoTaskMem(512), len = 512}; var result2 = WSARecv2( socket.Handle, ref wsabuf, 1, out numberOfBytesRecvd, ref flags, nativeOverlapped, IntPtr.Zero); var lastError2 = result2 == -1 ? Marshal.GetLastWin32Error() : 0; var data = @"GET / HTTP/1.1 Host: localhost Connection: close ".ToArraySegment(); SocketError err; socket.BeginSend( data.Array, data.Offset, data.Count, SocketFlags.None, out err, ar => { socket.EndSend(ar); socket.Shutdown(SocketShutdown.Send); }, null); } } else { Console.WriteLine("Known input. Enter exit to exit."); } } }
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; }
public unsafe IAsyncResult BeginWaitForConnection(AsyncCallback callback, Object state) { CheckConnectOperationsServer(); if (!IsAsync) { throw new InvalidOperationException(SR.GetString(SR.InvalidOperation_PipeNotAsync)); } // Create and store async stream class library specific data in the // async result PipeAsyncResult asyncResult = new PipeAsyncResult(); asyncResult._handle = InternalHandle; asyncResult._userCallback = callback; asyncResult._userStateObject = state; IOCancellationHelper cancellationHelper = state as IOCancellationHelper; // Create wait handle and store in async result 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 = overlapped.Pack(WaitForConnectionCallback, null); asyncResult._overlapped = intOverlapped; if (!UnsafeNativeMethods.ConnectNamedPipe(InternalHandle, intOverlapped)) { int errorCode = Marshal.GetLastWin32Error(); if (errorCode == UnsafeNativeMethods.ERROR_IO_PENDING) { if (cancellationHelper != null) { cancellationHelper.AllowCancellation(InternalHandle, intOverlapped); } return asyncResult; } // WaitForConnectionCallback will not be called becasue we completed synchronously. // Either the pipe is already connected, or there was an error. Unpin and free the overlapped again. Overlapped.Free(intOverlapped); asyncResult._overlapped = null; // Did the client already connect to us? if (errorCode == UnsafeNativeMethods.ERROR_PIPE_CONNECTED) { if (State == PipeState.Connected) { throw new InvalidOperationException(SR.GetString(SR.InvalidOperation_PipeAlreadyConnected)); } asyncResult.CallUserCallback(); return asyncResult; } __Error.WinIOError(errorCode, String.Empty); } // will set state to Connected when EndWait is called if (cancellationHelper != null) { cancellationHelper.AllowCancellation(InternalHandle, intOverlapped); } return asyncResult; }
public unsafe void ReadOverlapped(byte[] readBuffer) { var completedEvent = new ManualResetEvent(false); uint bytesRead = 0; var inOverlapped = new Overlapped(); inOverlapped.EventHandleIntPtr = completedEvent.SafeWaitHandle.DangerousGetHandle(); NativeOverlapped* inNativeOverlapped = inOverlapped.Pack(null, null); try { // send the data to the device fixed (byte* outBuffer = readBuffer) { var success = false; try { success = InteropKernel32.ReadFile(_readHandle, outBuffer, (uint)readBuffer.Length, ref bytesRead, inNativeOverlapped); } catch (ObjectDisposedException) { throw new Exception("File handle already closed"); } if (!success) { HandleIOError(true); CancelOverlapped(_readHandle, completedEvent); } } } finally { // clean up Overlapped.Free(inNativeOverlapped); } }
//-------------------------------------------------------------------------- // Data Reception //-------------------------------------------------------------------------- // http://www.beefycode.com/post/Using-Overlapped-IO-from-Managed-Code.aspx #pragma warning disable 0618 // warning CS0618: 'System.Threading.WaitHandle.Handle' is obsolete: 'Use the SafeWaitHandle property instead.' unsafe void ReadThread(ThreadContext ctx) { System.Threading.Thread.CurrentThread.Name = "USBConnection.ReadThread"; EventWaitHandle asyncReadCompleteEvent = new EventWaitHandle(false, System.Threading.EventResetMode.ManualReset); NativeOverlapped* pNativeOverlapped = null; byte[] rgbBuffer = new byte[64]; try { WaitHandle[] waitHandles = new WaitHandle[2]; waitHandles[0] = asyncReadCompleteEvent; waitHandles[1] = ctx.StopEvent; // // If we get unexpected errors, we stop reading; likely these are caused by a device // in the process of disconnecting. // bool fStop = false; // while (!fStop && !ctx.StopRequest) { // Issue an async read // asyncReadCompleteEvent.Reset(); Overlapped overlapped = new Overlapped(0, 0, asyncReadCompleteEvent.Handle, null); pNativeOverlapped = overlapped.Pack(null, rgbBuffer); int cbRead = 0; // Program.Trace("issuing async read: 0x{0:08X} 0x{1:08X}", new IntPtr(pNativeOverlappedWrite), this.hWinUSB); bool fSuccess = WinUsb_ReadPipe( this.hWinUSB, bulkInPipe, rgbBuffer, rgbBuffer.Length, out cbRead, new IntPtr(pNativeOverlapped)); this.readThreadRunning.Set(); if (!fSuccess) { int err = Marshal.GetLastWin32Error(); if (err != ERROR_IO_PENDING) { Program.Trace("USB Read: WinUsb_ReadPipe=={0}", err); fStop = true; continue; } } // Wait until either the async read completes or we're asked to stop int iWait = WaitHandle.WaitAny(waitHandles); // Process according to which event fired switch (iWait) { case 0: // Async read completed { // Program.Trace("async read complete: 0x{0:08X} 0x{1:08X}", new IntPtr(pNativeOverlappedWrite), this.hWinUSB); if (WinUsb_GetOverlappedResult(this.hWinUSB, new IntPtr(pNativeOverlapped), ref cbRead, System.Convert.ToByte(true))) { ProcessIncomingPacket(rgbBuffer, cbRead); } else { int err = Marshal.GetLastWin32Error(); Program.Trace("USB Read: WinUsb_GetOverlappedResult=={0}", err); fStop = true; } // System.Threading.Overlapped.Free(pNativeOverlapped); pNativeOverlapped = null; } break; case 1: // StopEvent // Program.Trace("async read stop requested"); break; // end switch } } } finally { // Program.Trace("async cleanup: 0x{0:08X} 0x{1:08X}", new IntPtr(pNativeOverlappedWrite), this.hWinUSB); WinUsb_AbortPipe(this.hWinUSB, bulkInPipe); asyncReadCompleteEvent.Close(); if (pNativeOverlapped != null) { System.Threading.Overlapped.Free(pNativeOverlapped); pNativeOverlapped = null; } } }
public unsafe void WriteControlOverlapped(uint controlCode, byte[] writeBuffer) { var completedEvent = new ManualResetEvent(false); uint bytesReturned = 0; var outOverlapped = new Overlapped(); outOverlapped.EventHandleIntPtr = completedEvent.SafeWaitHandle.DangerousGetHandle(); NativeOverlapped* outNativeOverlapped = outOverlapped.Pack(null, null); try { fixed (byte* inBuffer = writeBuffer) { var success = false; try { success = InteropKernel32.DeviceIoControl(_writeHandle, controlCode, inBuffer, writeBuffer == null ? 0 : (uint)writeBuffer.Length, null, 0, ref bytesReturned, outNativeOverlapped); } catch (ObjectDisposedException) { throw new Exception("File handle already closed"); } if (!success) { HandleIOError(true); CancelOverlapped(_writeHandle, completedEvent); } } } finally { Overlapped.Free(outNativeOverlapped); } }
//-------------------------------------------------------------------------- // Data reception //-------------------------------------------------------------------------- unsafe void ReadThread(ThreadContext ctx) { System.Threading.Thread.CurrentThread.Name = "BluetoothConnection.ReadThread"; EventWaitHandle asyncReadCompleteEvent = new EventWaitHandle(false, System.Threading.EventResetMode.ManualReset); NativeOverlapped* pNativeOverlapped = null; byte[] rgbBuffer = new byte[64]; try { WaitHandle[] waitHandles = new WaitHandle[2]; waitHandles[0] = asyncReadCompleteEvent; waitHandles[1] = ctx.StopEvent; // while (!ctx.StopRequest) { // Issue an async read // asyncReadCompleteEvent.Reset(); Overlapped overlapped = new Overlapped(0, 0, asyncReadCompleteEvent.SafeWaitHandle.DangerousGetHandle(), null); pNativeOverlapped = overlapped.Pack(null, rgbBuffer); int cbRead = 0; bool fSuccess = ReadFile(this.hSerialPort, rgbBuffer, rgbBuffer.Length, out cbRead, new IntPtr(pNativeOverlapped)); readThreadRunning.Set(); if (!fSuccess) { int err = Marshal.GetLastWin32Error(); if (err != ERROR_IO_PENDING) ThrowWin32Error(err); } // Wait until either the async read completes or we're asked to stop int iWait = WaitHandle.WaitAny(waitHandles); // Process according to which event fired switch (iWait) { case 0: // Async read completed { ThrowIfFail(GetOverlappedResult(this.hSerialPort, new IntPtr(pNativeOverlapped), ref cbRead, System.Convert.ToByte(true))); // Program.Trace("async read complete: 0x{0:08X} 0x{1:08X} cb={2}", new IntPtr(pNativeOverlapped), this.hSerialPort, cbRead); // Record the new data and process any packets that are now complete this.RecordIncomingData(rgbBuffer, cbRead); ProcessPacketIfPossible(); System.Threading.Overlapped.Free(pNativeOverlapped); pNativeOverlapped = null; } break; case 1: // StopEvent break; // end switch } } } finally { CancelIo(this.hSerialPort); asyncReadCompleteEvent.Close(); if (pNativeOverlapped != null) { System.Threading.Overlapped.Free(pNativeOverlapped); pNativeOverlapped = null; } } }
public unsafe void WriteOverlapped(byte[] writeBuffer) { var completedEvent = new ManualResetEvent(false); uint bytesWritten = 0; var outOverlapped = new Overlapped(); outOverlapped.EventHandleIntPtr = completedEvent.SafeWaitHandle.DangerousGetHandle(); NativeOverlapped* outNativeOverlapped = outOverlapped.Pack(null, null); try { // send the data to the device fixed (byte* inBuffer = writeBuffer) { var success = false; try { success = InteropKernel32.WriteFile(_writeHandle, inBuffer, (uint)writeBuffer.Length, ref bytesWritten, outNativeOverlapped); } catch (ObjectDisposedException) { throw new Exception("File handle already closed"); } if (!success) { HandleIOError(true); CancelOverlapped(_writeHandle, completedEvent); } } } finally { Overlapped.Free(outNativeOverlapped); } }
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 == 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); } }
private unsafe void Monitor(byte[] buffer) { if (!enabled || IsHandleInvalid) { return; } Overlapped overlapped = new Overlapped(); if (buffer == null) { try { buffer = new byte[internalBufferSize]; } catch (OutOfMemoryException) { throw new OutOfMemoryException(SR.GetString(SR.BufferSizeTooLarge, internalBufferSize.ToString(CultureInfo.CurrentCulture))); } } // Pass "session" counter to callback: FSWAsyncResult asyncResult = new FSWAsyncResult(); asyncResult.session = currentSession; asyncResult.buffer = buffer; // Pack overlapped. The buffer will be pinned by Overlapped: overlapped.AsyncResult = asyncResult; NativeOverlapped* overlappedPointer = overlapped.Pack(new IOCompletionCallback(this.CompletionStatusChanged), buffer); // Can now call OS: int size; bool ok = false; try { // There could be a ---- in user code between calling StopRaisingEvents (where we close the handle) // and when we get here from CompletionStatusChanged. // We might need to take a lock to prevent ---- absolutely, instead just catch // ObjectDisposedException from SafeHandle in case it is disposed if (!IsHandleInvalid) { // An interrupt is possible here fixed (byte * buffPtr = buffer) { ok = UnsafeNativeMethods.ReadDirectoryChangesW(directoryHandle, new HandleRef(this, (IntPtr) buffPtr), internalBufferSize, includeSubdirectories ? 1 : 0, (int) notifyFilters, out size, overlappedPointer, NativeMethods.NullHandleRef); } } } catch (ObjectDisposedException ) { //Ignore Debug.Assert(IsHandleInvalid, "ObjectDisposedException from something other than SafeHandle?"); } catch (ArgumentNullException ) { //Ignore Debug.Assert(IsHandleInvalid, "ArgumentNullException from something other than SafeHandle?"); } finally { if (! ok) { Overlapped.Free(overlappedPointer); // 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 (!IsHandleInvalid) { OnError(new ErrorEventArgs(new Win32Exception())); } } } }
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); } }
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); } }