///<summary>
        /// Opens the USB device handle.
        ///</summary>
        ///<returns>
        ///True if the device is already opened or was opened successfully.
        ///False if the device does not exists or is no longer valid.  
        ///</returns>
        public override bool Open()
        {
            if (IsOpen) return true;
            LibUsbDeviceHandle handle = new LibUsbDeviceHandle(mMonoUSBProfile.ProfileHandle);
            if (handle.IsInvalid)
            {
                UsbError.Error(ErrorCode.MonoApiError, (int) LibUsbDeviceHandle.LastErrorCode, "MonoUsbDevice.Open Failed", this);
                mUsbHandle = null;
                return false;
            }
            mUsbHandle = handle;
            if (IsOpen) return true;

            mUsbHandle.Close();
            return false;
        }
 /// <summary>
 /// Retrieve a descriptor from the default control pipe. 
 /// </summary>
 /// <remarks>
 /// <para>This is a convenience function which formulates the appropriate control message to retrieve the descriptor.</para>
 /// <note type="tip" title="Libusb-1.0 API:"><seelibusb10 group="desc"/></note>
 /// </remarks>
 /// <param name="deviceHandle">Retrieve a descriptor from the default control pipe.</param>
 /// <param name="descType">The descriptor type, <see cref="DescriptorType"/></param>
 /// <param name="descIndex">The index of the descriptor to retrieve.</param>
 /// <param name="pData">Output buffer for descriptor.</param>
 /// <param name="length">Size of data buffer.</param>
 /// <returns>Number of bytes returned in data, or a <see cref="LibUsbError"/> code on failure.</returns>
 public static int GetDescriptor(LibUsbDeviceHandle deviceHandle, byte descType, byte descIndex, IntPtr pData, int length)
 {
     return ControlTransfer(deviceHandle,
                                    (byte) UsbEndpointDirection.EndpointIn,
                                    (byte) UsbStandardRequest.GetDescriptor,
                                    (short) ((descType << 8) | descIndex),
                                    0,
                                    pData,
                                    (short) length,
                                    1000);
 }
 /// <summary>
 /// Retrieve a descriptor from the default control pipe. 
 /// </summary>
 /// <remarks>
 /// <para>This is a convenience function which formulates the appropriate control message to retrieve the descriptor.</para>
 /// <note type="tip" title="Libusb-1.0 API:"><seelibusb10 group="desc"/></note>
 /// </remarks>
 /// <param name="deviceHandle">Retrieve a descriptor from the default control pipe.</param>
 /// <param name="descType">The descriptor type, <see cref="DescriptorType"/></param>
 /// <param name="descIndex">The index of the descriptor to retrieve.</param>
 /// <param name="data">Output buffer for descriptor. This object is pinned using <see cref="PinnedHandle"/>.</param>
 /// <param name="length">Size of data buffer.</param>
 /// <returns>Number of bytes returned in data, or <see cref="LibUsbError"/> code on failure.</returns>
 public static int GetDescriptor(LibUsbDeviceHandle deviceHandle, byte descType, byte descIndex, object data, int length)
 {
     PinnedHandle p = new PinnedHandle(data);
     return GetDescriptor(deviceHandle, descType, descIndex, p.Handle, length);
 }
 /// <summary>
 /// Get a <see cref="LibUsbProfileHandle"/> for a <see cref="LibUsbDeviceHandle"/>. 
 /// </summary>
 /// <remarks>
 /// <para>
 /// This function differs from the Libusb-1.0 C API in that when the new <see cref="LibUsbProfileHandle"/> is returned, the device profile reference count 
 /// is incremented ensuring the profile will remain valid as long as it is in-use.
 /// </para>
 /// <note type="tip" title="Libusb-1.0 API:"><seelibusb10 group="dev"/></note>
 /// </remarks>
 /// <param name="devicehandle">A device handle.</param>
 /// <returns>The underlying profile handle.</returns>
 public static LibUsbProfileHandle GetDevice(LibUsbDeviceHandle devicehandle) { return new LibUsbProfileHandle(GetDeviceInternal(devicehandle)); }