internal OverlappedCache(System.Threading.Overlapped overlapped, object pinnedObjects, IOCompletionCallback callback, bool alreadyTriedCast) { this.m_Overlapped = overlapped; this.m_PinnedObjects = pinnedObjects; this.m_PinnedObjectsArray = alreadyTriedCast ? null : NclConstants.EmptyObjectArray; this.m_NativeOverlapped = new SafeNativeOverlapped(overlapped.UnsafePack(callback, pinnedObjects)); }
internal unsafe IAsyncResult BeginRead(byte[] data, int offset, int size, AsyncCallback callback, object state) { bool flag; PipeAsyncResult ar = new PipeAsyncResult(callback); NativeOverlapped* lpOverlapped = new Overlapped(0, 0, IntPtr.Zero, ar).UnsafePack(IOCallback, data); ar._overlapped = lpOverlapped; fixed (byte* numRef = data) { flag = NativePipe.ReadFile(this._handle, numRef + offset, size, IntPtr.Zero, lpOverlapped); } if (!flag) { int errorCode = Marshal.GetLastWin32Error(); if (errorCode == 0x6dL) { ar.CallUserCallback(); return ar; } if (errorCode != 0x3e5L) { throw new RemotingException(string.Format(CultureInfo.CurrentCulture, CoreChannel.GetResourceString("Remoting_Ipc_ReadFailure"), new object[] { GetMessage(errorCode) })); } } return ar; }
/// <summary> /// Creates a <see cref="CancellationTokenSource"/> for the given <paramref name="connectionId"/> and registers it for disconnect. /// </summary> /// <param name="connectionId">The connection id.</param> /// <returns>A <see cref="CancellationTokenSource"/> that is registered for disconnect for the connection associated with the <paramref name="connectionId"/>.</returns> public CancellationToken CreateToken(ulong connectionId) { Debug.WriteLine("Server: Registering connection for disconnect for connection ID: " + connectionId); // Create a nativeOverlapped callback so we can register for disconnect callback var overlapped = new Overlapped(); var cts = new CancellationTokenSource(); var nativeOverlapped = overlapped.UnsafePack((errorCode, numBytes, pOVERLAP) => { Debug.WriteLine("Server: http.sys disconnect callback fired for connection ID: " + connectionId); // Free the overlapped Overlapped.Free(pOVERLAP); // Pull the token out of the list and Cancel it. Lazy<CancellationToken> token; _connectionCancellationTokens.TryRemove(connectionId, out token); cts.Cancel(); }, null); uint hr = NativeMethods.HttpWaitForDisconnect(_requestQueueHandle, connectionId, nativeOverlapped); if (hr != NativeMethods.HttpErrors.ERROR_IO_PENDING && hr != NativeMethods.HttpErrors.NO_ERROR) { // We got an unknown result so throw Debug.WriteLine("Unable to register disconnect callback"); return CancellationToken.None; } return cts.Token; }
internal unsafe OverlappedCache(Overlapped overlapped, object[] pinnedObjectsArray, IOCompletionCallback callback) { this.m_Overlapped = overlapped; this.m_PinnedObjects = pinnedObjectsArray; this.m_PinnedObjectsArray = pinnedObjectsArray; this.m_NativeOverlapped = new SafeNativeOverlapped((IntPtr)((void*)overlapped.UnsafePack(callback, pinnedObjectsArray))); }
internal unsafe OverlappedCache(Overlapped overlapped, object pinnedObjects, IOCompletionCallback callback, bool alreadyTriedCast) { this.m_Overlapped = overlapped; this.m_PinnedObjects = pinnedObjects; this.m_PinnedObjectsArray = (alreadyTriedCast ? null : new object[0]); this.m_NativeOverlapped = new SafeNativeOverlapped((IntPtr)((void*)overlapped.UnsafePack(callback, pinnedObjects))); }
public OverlappedContext() { if (OverlappedContext.completeCallback == null) { OverlappedContext.completeCallback = Fx.ThunkCallback(new IOCompletionCallback(CompleteCallback)); } if (OverlappedContext.eventCallback == null) { OverlappedContext.eventCallback = Fx.ThunkCallback(new WaitOrTimerCallback(EventCallback)); } if (OverlappedContext.cleanupCallback == null) { OverlappedContext.cleanupCallback = Fx.ThunkCallback(new WaitOrTimerCallback(CleanupCallback)); } this.bufferHolder = new object[] { OverlappedContext.dummyBuffer }; this.overlapped = new Overlapped(); this.nativeOverlapped = this.overlapped.UnsafePack(OverlappedContext.completeCallback, this.bufferHolder); // When replacing the buffer, we need to provoke the CLR to fix up the handle of the pin. this.pinnedHandle = GCHandle.FromIntPtr(*((IntPtr*)nativeOverlapped + (IntPtr.Size == 4 ? HandleOffsetFromOverlapped32 : HandleOffsetFromOverlapped64))); this.pinnedTarget = this.pinnedHandle.Target; // Create the permanently rooted holder and put it in the Overlapped. this.rootedHolder = new RootedHolder(); this.overlapped.AsyncResult = rootedHolder; }
internal OverlappedCache(System.Threading.Overlapped overlapped, object[] pinnedObjectsArray, IOCompletionCallback callback) { this.m_Overlapped = overlapped; this.m_PinnedObjects = pinnedObjectsArray; this.m_PinnedObjectsArray = pinnedObjectsArray; this.m_NativeOverlapped = new SafeNativeOverlapped(overlapped.UnsafePack(callback, pinnedObjectsArray)); }
unsafe public static Overlapped Unpack (NativeOverlapped *nativeOverlappedPtr) { if ((IntPtr) nativeOverlappedPtr == IntPtr.Zero) throw new ArgumentNullException ("nativeOverlappedPtr"); Overlapped result = new Overlapped (); result.offsetL = nativeOverlappedPtr->OffsetLow; result.offsetH = nativeOverlappedPtr->OffsetHigh; result.evt = (int)nativeOverlappedPtr->EventHandle; return result; }
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 ); }
private void InternalFree() { this.m_Overlapped = null; this.m_PinnedObjects = null; if (this.m_NativeOverlapped != null) { if (!this.m_NativeOverlapped.IsInvalid) { this.m_NativeOverlapped.Dispose(); } this.m_NativeOverlapped = null; } }
internal void ReInitialize() { this.m_asyncResult = null; this.m_iocb = null; this.m_iocbHelper = null; this.m_overlapped = null; this.m_userObject = null; this.m_pinSelf = IntPtr.Zero; this.m_userObjectInternal = IntPtr.Zero; this.m_AppDomainId = 0; this.m_nativeOverlapped.EventHandle = IntPtr.Zero; this.m_isArray = 0; this.m_nativeOverlapped.InternalHigh = IntPtr.Zero; }
private unsafe CancellationToken CreateToken(ulong connectionId) { // Create a nativeOverlapped callback so we can register for disconnect callback var overlapped = new Overlapped(); var cts = new CancellationTokenSource(); CancellationToken returnToken = cts.Token; NativeOverlapped* nativeOverlapped = overlapped.UnsafePack( (errorCode, numBytes, overlappedPtr) => { // Free the overlapped Overlapped.Free(overlappedPtr); if (errorCode != NativeMethods.HttpErrors.NO_ERROR) { LogHelper.LogException(_logger, "IOCompletionCallback", new Win32Exception((int)errorCode)); } // Pull the token out of the list and Cancel it. ConnectionCancellation cancellation; _connectionCancellationTokens.TryRemove(connectionId, out cancellation); bool success = ThreadPool.UnsafeQueueUserWorkItem(CancelToken, cts); Debug.Assert(success, "Unable to queue disconnect notification."); }, null); uint hr = NativeMethods.HttpWaitForDisconnect(_requestQueueHandle, connectionId, nativeOverlapped); if (hr != NativeMethods.HttpErrors.ERROR_IO_PENDING && hr != NativeMethods.HttpErrors.NO_ERROR) { // We got an unknown result, assume the connection has been closed. Overlapped.Free(nativeOverlapped); ConnectionCancellation cancellation; _connectionCancellationTokens.TryRemove(connectionId, out cancellation); LogHelper.LogException(_logger, "HttpWaitForDisconnect", new Win32Exception((int)hr)); cts.Cancel(); cts.Dispose(); } return returnToken; }
public unsafe OverlappedContext() { if (completeCallback == null) { completeCallback = Fx.ThunkCallback(new IOCompletionCallback(OverlappedContext.CompleteCallback)); } if (eventCallback == null) { eventCallback = Fx.ThunkCallback(new WaitOrTimerCallback(OverlappedContext.EventCallback)); } if (cleanupCallback == null) { cleanupCallback = Fx.ThunkCallback(new WaitOrTimerCallback(OverlappedContext.CleanupCallback)); } this.bufferHolder = new object[] { dummyBuffer }; this.overlapped = new Overlapped(); this.nativeOverlapped = this.overlapped.UnsafePack(completeCallback, this.bufferHolder); this.pinnedHandle = GCHandle.FromIntPtr(*((IntPtr*) (this.nativeOverlapped + (((IntPtr.Size == 4) ? -4 : -3) * sizeof(IntPtr))))); this.pinnedTarget = this.pinnedHandle.Target; this.rootedHolder = new RootedHolder(); this.overlapped.AsyncResult = this.rootedHolder; }
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); }
// Method to setup an Overlapped object for SendPacketsAsync. unsafe private void SetupOverlappedSendPackets() { int index; // Alloc new Overlapped. m_Overlapped = new Overlapped(); // Alloc native descriptor. m_SendPacketsDescriptor = new UnsafeNclNativeMethods.OSSOCK.TransmitPacketsElement[m_SendPacketsElementsFileCount + m_SendPacketsElementsBufferCount]; // Number of things to pin is number of buffers + 1 (native descriptor). // Ensure we have properly sized object array. if(m_ObjectsToPin == null || (m_ObjectsToPin.Length != m_SendPacketsElementsBufferCount + 1)) { m_ObjectsToPin = new object[m_SendPacketsElementsBufferCount + 1]; } // Fill in objects to pin array. Native descriptor buffer first and then user specified buffers. m_ObjectsToPin[0] = m_SendPacketsDescriptor; index = 1; foreach(SendPacketsElement spe in m_SendPacketsElementsInternal) { if(spe != null && spe.m_Buffer != null && spe.m_Count > 0) { m_ObjectsToPin[index] = spe.m_Buffer; index++; } } // Pin buffers #if SOCKETTHREADPOOL m_Overlapped.AsyncResult = new DummyAsyncResult(CompletionPortCallback); m_PtrNativeOverlapped = new SafeNativeOverlapped(m_Overlapped.UnsafePack(null, m_ObjectsToPin)); #else m_PtrNativeOverlapped = new SafeNativeOverlapped(m_Overlapped.UnsafePack(CompletionPortCallback, m_ObjectsToPin)); #endif // Get pointer to native descriptor. m_PtrSendPacketsDescriptor = Marshal.UnsafeAddrOfPinnedArrayElement(m_SendPacketsDescriptor, 0); // Fill in native descriptor. int descriptorIndex = 0; int fileIndex = 0; foreach(SendPacketsElement spe in m_SendPacketsElementsInternal) { if (spe != null) { if(spe.m_Buffer != null && spe.m_Count > 0) { // a buffer m_SendPacketsDescriptor[descriptorIndex].buffer = Marshal.UnsafeAddrOfPinnedArrayElement(spe.m_Buffer, spe.m_Offset); m_SendPacketsDescriptor[descriptorIndex].length = (uint)spe.m_Count; m_SendPacketsDescriptor[descriptorIndex].flags = spe.m_Flags; descriptorIndex++; } else if (spe.m_FilePath != null) { // a file m_SendPacketsDescriptor[descriptorIndex].fileHandle = m_SendPacketsFileHandles[fileIndex].DangerousGetHandle(); m_SendPacketsDescriptor[descriptorIndex].fileOffset = spe.m_Offset; m_SendPacketsDescriptor[descriptorIndex].length = (uint)spe.m_Count; m_SendPacketsDescriptor[descriptorIndex].flags = spe.m_Flags; fileIndex++; descriptorIndex++; } } } m_PinState = PinState.SendPackets; }
// Method to setup an Overlapped object with with multiple buffers pinned. unsafe private void SetupOverlappedMultiple() { ArraySegment<byte>[] tempList = new ArraySegment<byte>[m_BufferList.Count]; m_BufferList.CopyTo(tempList, 0); // Alloc new Overlapped. m_Overlapped = new Overlapped(); // Number of things to pin is number of buffers. // Ensure we have properly sized object array. if(m_ObjectsToPin == null || (m_ObjectsToPin.Length != tempList.Length)) { m_ObjectsToPin = new object[tempList.Length]; } // Fill in object array. for(int i = 0; i < (tempList.Length); i++) { m_ObjectsToPin[i] = tempList[i].Array; } if(m_WSABufferArray == null || m_WSABufferArray.Length != tempList.Length) { m_WSABufferArray = new WSABuffer[tempList.Length]; } // Pin buffers and fill in WSABuffer descriptor pointers and lengths #if SOCKETTHREADPOOL m_Overlapped.AsyncResult = new DummyAsyncResult(CompletionPortCallback); m_PtrNativeOverlapped = new SafeNativeOverlapped(m_Overlapped.UnsafePack(null, m_ObjectsToPin)); #else m_PtrNativeOverlapped = new SafeNativeOverlapped(m_Overlapped.UnsafePack(CompletionPortCallback, m_ObjectsToPin)); #endif for(int i = 0; i < tempList.Length; i++) { ArraySegment<byte> localCopy = tempList[i]; ValidationHelper.ValidateSegment(localCopy); m_WSABufferArray[i].Pointer = Marshal.UnsafeAddrOfPinnedArrayElement(localCopy.Array, localCopy.Offset); m_WSABufferArray[i].Length = localCopy.Count; } m_PinState = PinState.MultipleBuffer; }
// Method to setup an Overlapped object with either m_Buffer or m_AcceptBuffer pinned. unsafe private void SetupOverlappedSingle(bool pinSingleBuffer) { // Alloc new Overlapped. m_Overlapped = new Overlapped(); // Pin buffer, get native pointers, and fill in WSABuffer descriptor. if(pinSingleBuffer) { if(m_Buffer != null) { #if SOCKETTHREADPOOL m_Overlapped.AsyncResult = new DummyAsyncResult(CompletionPortCallback); m_PtrNativeOverlapped = new SafeNativeOverlapped(m_Overlapped.UnsafePack(null, m_Buffer)); #else m_PtrNativeOverlapped = new SafeNativeOverlapped(m_Overlapped.UnsafePack(CompletionPortCallback, m_Buffer)); #endif m_PinnedSingleBuffer = m_Buffer; m_PinnedSingleBufferOffset = m_Offset; m_PinnedSingleBufferCount = m_Count; m_PtrSingleBuffer = Marshal.UnsafeAddrOfPinnedArrayElement(m_Buffer, m_Offset); m_PtrAcceptBuffer = IntPtr.Zero; m_WSABuffer.Pointer = m_PtrSingleBuffer; m_WSABuffer.Length = m_Count; m_PinState = PinState.SingleBuffer; } else { #if SOCKETTHREADPOOL m_Overlapped.AsyncResult = new DummyAsyncResult(CompletionPortCallback); m_PtrNativeOverlapped = new SafeNativeOverlapped(m_Overlapped.UnsafePack(null, null)); #else m_PtrNativeOverlapped = new SafeNativeOverlapped(m_Overlapped.UnsafePack(CompletionPortCallback, null)); #endif m_PinnedSingleBuffer = null; m_PinnedSingleBufferOffset = 0; m_PinnedSingleBufferCount = 0; m_PtrSingleBuffer = IntPtr.Zero; m_PtrAcceptBuffer = IntPtr.Zero; m_WSABuffer.Pointer = m_PtrSingleBuffer; m_WSABuffer.Length = m_Count; m_PinState = PinState.NoBuffer; } } else { #if SOCKETTHREADPOOL m_Overlapped.AsyncResult = new DummyAsyncResult(CompletionPortCallback); m_PtrNativeOverlapped = new SafeNativeOverlapped(m_Overlapped.UnsafePack(null, m_AcceptBuffer)); #else m_PtrNativeOverlapped = new SafeNativeOverlapped(m_Overlapped.UnsafePack(CompletionPortCallback, m_AcceptBuffer)); #endif m_PinnedAcceptBuffer = m_AcceptBuffer; m_PtrAcceptBuffer = Marshal.UnsafeAddrOfPinnedArrayElement(m_AcceptBuffer, 0); m_PtrSingleBuffer = IntPtr.Zero; m_PinState = PinState.SingleAcceptBuffer; } }
// Method to clean up any existing Overlapped object and related state variables. private void FreeOverlapped(bool checkForShutdown) { if (!checkForShutdown || !NclUtilities.HasShutdownStarted) { // Free the overlapped object if(m_PtrNativeOverlapped != null && !m_PtrNativeOverlapped.IsInvalid) { m_PtrNativeOverlapped.Dispose(); m_PtrNativeOverlapped = null; m_Overlapped = null; m_PinState = PinState.None; m_PinnedAcceptBuffer = null; m_PinnedSingleBuffer = null; m_PinnedSingleBufferOffset = 0; m_PinnedSingleBufferCount = 0; } // Free any alloc'd GCHandles if(m_SocketAddressGCHandle.IsAllocated) { m_SocketAddressGCHandle.Free(); } if(m_WSAMessageBufferGCHandle.IsAllocated) { m_WSAMessageBufferGCHandle.Free(); } if(m_WSARecvMsgWSABufferArrayGCHandle.IsAllocated) { m_WSARecvMsgWSABufferArrayGCHandle.Free(); } if(m_ControlBufferGCHandle.IsAllocated) { m_ControlBufferGCHandle.Free(); } } }
internal static OverlappedData GetOverlappedData(Overlapped overlapped) { OverlappedData data = null; Interlocked.Exchange(ref m_overlappedDataCacheAccessed, 1); while (true) { OverlappedDataCacheLine overlappedDataCache = s_firstFreeCacheLine; if (overlappedDataCache == null) { overlappedDataCache = m_overlappedDataCache; } while (overlappedDataCache != null) { for (short i = 0; i < 0x10; i = (short) (i + 1)) { if (overlappedDataCache.m_items[i] != null) { data = Interlocked.Exchange<OverlappedData>(ref overlappedDataCache.m_items[i], null); if (data != null) { s_firstFreeCacheLine = overlappedDataCache; data.m_overlapped = overlapped; return data; } } } overlappedDataCache = overlappedDataCache.m_next; } GrowOverlappedDataCache(); } }
private void RegisterForDisconnect(HttpListenerContext context, Action disconnectCallback) { // Get the connection id value FieldInfo connectionIdField = typeof(HttpListenerRequest).GetField("m_ConnectionId", BindingFlags.Instance | BindingFlags.NonPublic); if (_requestQueueHandle != null && connectionIdField != null) { Debug.WriteLine("Server: Registering for disconnect"); ulong connectionId = (ulong)connectionIdField.GetValue(context.Request); // Create a nativeOverlapped callback so we can register for disconnect callback var overlapped = new Overlapped(); var nativeOverlapped = overlapped.UnsafePack((errorCode, numBytes, pOVERLAP) => { Debug.WriteLine("Server: http.sys disconnect callback fired."); // Free the overlapped Overlapped.Free(pOVERLAP); // Mark the client as disconnected disconnectCallback(); }, null); uint hr = NativeMethods.HttpWaitForDisconnect(_requestQueueHandle, connectionId, nativeOverlapped); if (hr != NativeMethods.HttpErrors.ERROR_IO_PENDING && hr != NativeMethods.HttpErrors.NO_ERROR) { // We got an unknown result so throw throw new InvalidOperationException("Unable to register disconnect callback"); } } else { Debug.WriteLine("Server: Unable to resolve requestQueue handle. Disconnect notifications will be ignored"); } }
//-------------------------------------------------------------------------- // 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; }
//-------------------------------------------------------------------------- // 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 static extern bool ConnectNamedPipe(PipeHandle hNamedPipe, // handle to named pipe Overlapped lpOverlapped // overlapped structure );
internal void ReInitialize() { m_asyncResult = null; m_iocb = null; m_iocbHelper = null; m_overlapped = null; m_userObject = null; Debug.Assert(m_pinSelf.IsNull(), "OverlappedData has not been freed: m_pinSelf"); m_pinSelf = (IntPtr)0; m_userObjectInternal = (IntPtr)0; Debug.Assert(m_AppDomainId == 0 || m_AppDomainId == AppDomain.CurrentDomain.Id, "OverlappedData is not in the current domain"); m_AppDomainId = 0; m_nativeOverlapped.EventHandle = (IntPtr)0; m_isArray = 0; m_nativeOverlapped.InternalLow = (IntPtr)0; m_nativeOverlapped.InternalHigh = (IntPtr)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 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 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); } }
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; }
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 OverlappedData(Overlapped overlapped) => _overlapped = overlapped;