Ejemplo n.º 1
0
        /// <summary>Initiates an asynchronous read operation on the pipe. </summary>
        /// <param name="buffer">Buffer that will receive the data read from the pipe.</param>
        /// <param name="offset">Byte offset within the buffer at which to begin writing the data received.</param>
        /// <param name="length">Length of the data to transfer.</param>
        /// <param name="userCallback">An optional asynchronous callback, to be called when the operation is complete. Can be null if no callback is required.</param>
        /// <param name="stateObject">A user-provided object that distinguishes this particular asynchronous operation. Can be null if not required.</param>
        /// <returns>An <see cref="IAsyncResult"/> object repesenting the asynchronous operation, which could still be pending.</returns>
        /// <remarks>This method always completes immediately even if the operation is still pending. The <see cref="IAsyncResult"/> object returned represents the operation
        /// and must be passed to <see cref="EndRead"/> to retrieve the result of the operation. For every call to this method a matching call to
        /// <see cref="EndRead"/> must be made. When <paramref name="userCallback"/> specifies a callback function, this function will be called when the operation is completed. The optional
        /// <paramref name="stateObject"/> parameter can be used to pass user-defined information to this callback or the <see cref="IAsyncResult"/>. The <see cref="IAsyncResult"/>
        /// also provides an event handle (<see cref="IAsyncResult.AsyncWaitHandle" />) that will be triggered when the operation is complete as well.
        /// </remarks>
        public IAsyncResult BeginRead(byte[] buffer, int offset, int length, AsyncCallback userCallback, object stateObject)
        {
            CheckReadParams(buffer, offset, length);

            USBAsyncResult result = new USBAsyncResult(userCallback, stateObject);

            try
            {
                _device.InternalDevice.ReadPipeOverlapped(Interface.InterfaceIndex, _pipeInfo.PipeId, buffer, offset, length, result);
            }
            catch (API.APIException e)
            {
                if (result != null)
                {
                    result.Dispose();
                }
                // throw new USBException("Failed to read from pipe.", e);
                LogAndThrowException(new USBException("Failed to read from pipe.", e));
            }
            catch (Exception e)
            {
                if (result != null)
                {
                    result.Dispose();
                }
                // throw;
                LogException(e);
                throw;
            }
            return(result);
        }
Ejemplo n.º 2
0
        /// <summary>Initiates an asynchronous write operation on the pipe. </summary>
        /// <param name="buffer">Buffer that contains the data to write to the pipe.</param>
        /// <param name="offset">Byte offset within the buffer from which to begin writing.</param>
        /// <param name="length">Length of the data to transfer.</param>
        /// <param name="userCallback">An optional asynchronous callback, to be called when the operation is complete. Can be null if no callback is required.</param>
        /// <param name="stateObject">A user-provided object that distinguishes this particular asynchronous operation. Can be null if not required.</param>
        /// <returns>An <see cref="IAsyncResult"/> object repesenting the asynchronous operation, which could still be pending.</returns>
        /// <remarks>This method always completes immediately even if the operation is still pending. The <see cref="IAsyncResult"/> object returned represents the operation
        /// and must be passed to <see cref="EndWrite"/> to retrieve the result of the operation. For every call to this method a matching call to
        /// <see cref="EndWrite"/> must be made. When <paramref name="userCallback"/> specifies a callback function, this function will be called when the operation is completed. The optional
        /// <paramref name="stateObject"/> parameter can be used to pass user-defined information to this callback or the <see cref="IAsyncResult"/>. The <see cref="IAsyncResult"/>
        /// also provides an event handle (<see cref="IAsyncResult.AsyncWaitHandle" />) that will be triggered when the operation is complete as well.
        /// </remarks>
        public IAsyncResult BeginWrite(byte[] buffer, int offset, int length, AsyncCallback userCallback, object stateObject)
        {
            CheckWriteParams(buffer, offset, length);

            USBAsyncResult result = new USBAsyncResult(userCallback, stateObject);

            try
            {
                _device.InternalDevice.WriteOverlapped(Interface.InterfaceIndex, _pipeInfo.PipeId, buffer, offset, length, result);
            }
            catch (API.APIException e)
            {
                if (result != null)
                {
                    result.Dispose();
                }
                throw new USBException("Failed to write to pipe.", e);
            }
            catch (Exception)
            {
                if (result != null)
                {
                    result.Dispose();
                }
                throw;
            }
            return(result);
        }
Ejemplo n.º 3
0
        /// <summary>
        /// Waits for a pending asynchronous write operation to complete.
        /// </summary>
        /// <param name="asyncResult">The <see cref="IAsyncResult"/> object representing the asynchonous operation,
        /// as returned by <see cref="BeginWrite"/>.</param>
        /// <returns>The number of bytes transfered during the operation.</returns>
        /// <remarks>Every call to <see cref="BeginWrite"/> must have a matching call to <see cref="EndWrite"/> to dispose
        /// of any resources used and to retrieve the result of the operation. When the operation was successful the method returns the number
        /// of bytes that were transfered. If an error occurred during the operation this method will throw the exceptions that would
        /// otherwise have ocurred during the operation. If the operation is not yet finished EndWrite will wait for the
        /// operation to finish before returning.</remarks>
        public void EndWrite(IAsyncResult asyncResult)
        {
            if (asyncResult == null)
            {
                // throw new NullReferenceException("asyncResult cannot be null");
                LogAndThrowException(new NullReferenceException("asyncResult cannot be null"));
            }
            if (!(asyncResult is USBAsyncResult))
            {
                // throw new ArgumentException("AsyncResult object was not created by calling BeginWrite on this class.");
                LogAndThrowException(new ArgumentException("AsyncResult object was not created by calling BeginWrite on this class."));
            }

            USBAsyncResult result = (USBAsyncResult)asyncResult;

            try
            {
                // todo: check duplicate end writes?

                if (!result.IsCompleted)
                {
                    result.AsyncWaitHandle.WaitOne();
                }

                if (result.Error != null)
                {
                    // throw new USBException("Asynchronous write to pipe has failed.", result.Error);
                    LogAndThrowException(new USBException("Asynchronous write to pipe has failed.", result.Error));
                }
            }
            finally
            {
                result.Dispose();
            }
        }
Ejemplo n.º 4
0
        /// <summary>
        /// Waits for a pending asynchronous read operation to complete.
        /// </summary>
        /// <param name="asyncResult">The <see cref="IAsyncResult"/> object representing the asynchonous operation,
        /// as returned by <see cref="BeginRead"/>.</param>
        /// <returns>The number of bytes transfered during the operation.</returns>
        /// <remarks>Every call to <see cref="BeginRead"/> must have a matching call to <see cref="EndRead"/> to dispose
        /// of any resources used and to retrieve the result of the operation. When the operation was successful the method returns the number
        /// of bytes that were transfered. If an error occurred during the operation this method will throw the exceptions that would
        /// otherwise have ocurred during the operation. If the operation is not yet finished EndWrite will wait for the
        /// operation to finish before returning.</remarks>
        public int EndRead(IAsyncResult asyncResult)
        {
            if (asyncResult == null)
            {
                throw new NullReferenceException("asyncResult cannot be null");
            }
            if (!(asyncResult is USBAsyncResult))
            {
                throw new ArgumentException("AsyncResult object was not created by calling BeginRead on this class.");
            }

            // todo: check duplicate end reads?
            USBAsyncResult result = (USBAsyncResult)asyncResult;

            try
            {
                if (!result.IsCompleted)
                {
                    result.AsyncWaitHandle.WaitOne();
                }

                if (result.Error != null)
                {
                    throw new USBException("Asynchronous read from pipe has failed.", result.Error);
                }

                return(result.BytesTransfered);
            }
            finally
            {
                result.Dispose();
            }
        }
Ejemplo n.º 5
0
        /// <summary>Initiates an asynchronous write operation on the pipe. </summary>
        /// <param name="buffer">Buffer that contains the data to write to the pipe.</param>
        /// <param name="offset">Byte offset within the buffer from which to begin writing.</param>
        /// <param name="length">Length of the data to transfer.</param>
        /// <param name="userCallback">An optional asynchronous callback, to be called when the operation is complete. Can be null if no callback is required.</param>
        /// <param name="stateObject">A user-provided object that distinguishes this particular asynchronous operation. Can be null if not required.</param>
        /// <returns>An <see cref="IAsyncResult"/> object repesenting the asynchronous operation, which could still be pending.</returns>
        /// <remarks>This method always completes immediately even if the operation is still pending. The <see cref="IAsyncResult"/> object returned represents the operation
        /// and must be passed to <see cref="EndWrite"/> to retrieve the result of the operation. For every call to this method a matching call to
        /// <see cref="EndWrite"/> must be made. When <paramref name="userCallback"/> specifies a callback function, this function will be called when the operation is completed. The optional
        /// <paramref name="stateObject"/> parameter can be used to pass user-defined information to this callback or the <see cref="IAsyncResult"/>. The <see cref="IAsyncResult"/>
        /// also provides an event handle (<see cref="IAsyncResult.AsyncWaitHandle" />) that will be triggered when the operation is complete as well.
        /// </remarks>
        public IAsyncResult BeginWrite(byte[] buffer, int offset, int length, AsyncCallback userCallback, object stateObject)
        {
            CheckWriteParams(buffer, offset, length);

            LogLastWrite(buffer, offset, length);

            USBAsyncResult result = new USBAsyncResult(userCallback, stateObject);

            try
            {
                _device.InternalDevice.WriteOverlapped(Interface.InterfaceIndex, _pipeInfo.PipeId, buffer, offset, length, result);
            }
            catch (API.APIException e)
            {
                if (result != null)
                {
                    result.Dispose();
                }

                byte[] SubBuffer = new byte[(length < 16 ? length : 16)];
                Array.Copy(buffer, offset, SubBuffer, 0, (length < 16 ? length : 16));
                // throw new USBException("Failed to write to pipe: " + WPinternals.Converter.ConvertHexToString(SubBuffer, ""), e);
                LogAndThrowException(new USBException("Failed to write to pipe: " + WPinternals.Converter.ConvertHexToString(SubBuffer, ""), e));
            }
            catch (Exception e)
            {
                if (result != null)
                {
                    result.Dispose();
                }
                // throw;
                LogException(e);
                throw;
            }
            return(result);
        }
Ejemplo n.º 6
0
        /// <summary>Initiates an asynchronous write operation on the pipe. </summary>
        /// <param name="buffer">Buffer that contains the data to write to the pipe.</param>
        /// <param name="offset">Byte offset within the buffer from which to begin writing.</param>
        /// <param name="length">Length of the data to transfer.</param>
        /// <param name="userCallback">An optional asynchronous callback, to be called when the operation is complete. Can be null if no callback is required.</param>
        /// <param name="stateObject">A user-provided object that distinguishes this particular asynchronous operation. Can be null if not required.</param>
        /// <returns>An <see cref="IAsyncResult"/> object repesenting the asynchronous operation, which could still be pending.</returns>
        /// <remarks>This method always completes immediately even if the operation is still pending. The <see cref="IAsyncResult"/> object returned represents the operation
        /// and must be passed to <see cref="EndWrite"/> to retrieve the result of the operation. For every call to this method a matching call to
        /// <see cref="EndWrite"/> must be made. When <paramref name="userCallback"/> specifies a callback function, this function will be called when the operation is completed. The optional
        /// <paramref name="stateObject"/> parameter can be used to pass user-defined information to this callback or the <see cref="IAsyncResult"/>. The <see cref="IAsyncResult"/> 
        /// also provides an event handle (<see cref="IAsyncResult.AsyncWaitHandle" />) that will be triggered when the operation is complete as well.
        /// </remarks>
        public IAsyncResult BeginWrite(byte[] buffer, int offset, int length, AsyncCallback userCallback, object stateObject)
        {
            CheckWriteParams(buffer, offset, length);

            USBAsyncResult result = new USBAsyncResult(userCallback, stateObject);
            try
            {
                _device.InternalDevice.WriteOverlapped(Interface.InterfaceIndex, _pipeInfo.PipeId, buffer, offset, length, result);
            }
            catch (API.APIException e)
            {
                if (result != null)
                    result.Dispose();
                throw new USBException("Failed to write to pipe.", e);
            }
            catch (Exception)
            {
                if (result != null)
                    result.Dispose();
                throw;
            }
            return result;
        }
Ejemplo n.º 7
0
        /// <summary>
        /// Initiates an asynchronous control transfer over the default control endpoint. This method allows both IN and OUT direction transfers, depending
        /// on the highest bit of the <paramref name="requestType"/> parameter. Alternatively, <see cref="BeginControlIn(byte,byte,int,int,byte[],int,AsyncCallback,object)"/> and
        /// <see cref="BeginControlIn(byte,byte,int,int,byte[],int,AsyncCallback,object)"/> can be used for asynchronous control transfers in a specific direction, which is 
        /// the recommended way because it prevents using the wrong direction accidentally. Use the BeginControlTransfer method when the direction is not 
        /// known at compile time. </summary>
        /// <param name="requestType">The setup packet request type.</param>
        /// <param name="request">The setup packet device request.</param>
        /// <param name="value">The value member in the setup packet. Its meaning depends on the request. Value should be between zero and 65535 (0xFFFF).</param>
        /// <param name="index">The index member in the setup packet. Its meaning depends on the request. Index should be between zero and 65535 (0xFFFF).</param>
        /// <param name="buffer">The data to transfer in the data stage of the control. When the transfer is in the IN direction the data received will be 
        /// written to this buffer. For an OUT direction transfer the contents of the buffer are written sent through the pipe. Note: This buffer is not allowed
        /// to change for the duration of the asynchronous operation.</param>
        /// <param name="length">Length of the data to transfer. Must be equal to or less than the length of <paramref name="buffer"/>. The setup packet's length member will be set to this length.</param>
        /// <param name="userCallback">An optional asynchronous callback, to be called when the control transfer is complete. Can be null if no callback is required.</param>
        /// <param name="stateObject">A user-provided object that distinguishes this particular asynchronous operation. Can be null if not required.</param>
        /// <returns>An <see cref="IAsyncResult"/> object repesenting the asynchronous control transfer, which could still be pending.</returns>
        /// <remarks>This method always completes immediately even if the operation is still pending. The <see cref="IAsyncResult"/> object returned represents the operation
        /// and must be passed to <see cref="EndControlTransfer"/> to retrieve the result of the operation. For every call to this method a matching call to
        /// <see cref="EndControlTransfer"/> must be made. When <paramref name="userCallback"/> specifies a callback function, this function will be called when the operation is completed. The optional
        /// <paramref name="stateObject"/> parameter can be used to pass user-defined information to this callback or the <see cref="IAsyncResult"/>. The <see cref="IAsyncResult"/> 
        /// also provides an event handle (<see cref="IAsyncResult.AsyncWaitHandle" />) that will be triggered when the operation is complete as well.
        /// </remarks>
        public IAsyncResult BeginControlTransfer(byte requestType, byte request, int value, int index, byte[] buffer, int length, AsyncCallback userCallback, object stateObject)
        {
            // Parameters are int and not ushort because ushort is not CLS compliant.
            CheckNotDisposed();
            CheckControlParams(value, index, buffer, length);

            USBAsyncResult result = new USBAsyncResult(userCallback, stateObject);

            try
            {
                _wuDevice.ControlTransferOverlapped(requestType, request, (ushort)value, (ushort)index, (ushort)length, buffer, result);
            }
            catch (API.APIException e)
            {
                if (result != null)
                    result.Dispose();
                 throw new USBException("Asynchronous control transfer failed", e);
            }
            catch (Exception)
            {
                if (result != null)
                    result.Dispose();
                throw;
            }
            return result;
        }