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;
 }
Exemplo n.º 3
0
        /// <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;
        }
Exemplo n.º 4
0
		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)));
		}
Exemplo n.º 5
0
		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)));
		}
 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));
 }
        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));
 }
 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));
 }
Exemplo n.º 10
0
		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);
         }
     }
 }
Exemplo n.º 12
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 );            
        }
 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;
     }
 }
 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;
     }
 }
Exemplo n.º 15
0
 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;
 }
Exemplo n.º 16
0
        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;
 }
Exemplo n.º 18
0
 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);
 }
Exemplo n.º 19
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;
        }
Exemplo n.º 20
0
        // 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;
        }
Exemplo n.º 21
0
        // 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;
            }
        }
Exemplo n.º 22
0
        // 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();
                }
            }
        }
Exemplo n.º 23
0
 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();
     }
 }
Exemplo n.º 24
0
        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;
                    }
                }
            }
Exemplo n.º 27
0
 public static extern bool ConnectNamedPipe(PipeHandle hNamedPipe,        // handle to named pipe
                                             Overlapped lpOverlapped  // overlapped structure
                                             );
Exemplo n.º 28
0
 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;
 }
Exemplo n.º 29
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;
                    }
                }
            }
Exemplo n.º 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 == 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);
            }
        }
Exemplo n.º 32
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;
        }
Exemplo n.º 33
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);
              }
        }
 internal OverlappedData(Overlapped overlapped) => _overlapped = overlapped;