WinUSB: Merge upstream changes

This commit is contained in:
Gus
2021-02-08 17:08:46 +01:00
parent f438d0dd71
commit 8630a89553
8 changed files with 203 additions and 139 deletions
+84 -66
View File
@@ -1,6 +1,6 @@
/* WinUSBNet library
/* WinUSBNet library
* (C) 2010 Thomas Bleeker (www.madwizard.org)
*
*
* Licensed under the MIT license, see license.txt or:
* http://www.opensource.org/licenses/mit-license.php
*/
@@ -96,7 +96,7 @@ namespace MadWizard.WinUSBNet
/// <summary>
/// Disposes the object
/// </summary>
/// <param name="disposing">Indicates wether Dispose was called manually (true) or by
/// <param name="disposing">Indicates whether Dispose was called manually (true) or by
/// the garbage collector (false) via the destructor.</param>
protected virtual void Dispose(bool disposing)
{
@@ -166,7 +166,7 @@ namespace MadWizard.WinUSBNet
API.WINUSB_PIPE_INFORMATION[] pipesInfo;
_wuDevice.GetInterfaceInfo(i, out descriptor, out pipesInfo);
USBPipe[] interfacePipes = new USBPipe[pipesInfo.Length];
for (int k = 0; k < pipesInfo.Length; k++)
for(int k=0;k<pipesInfo.Length;k++)
{
USBPipe pipe = new USBPipe(this, pipesInfo[k]);
interfacePipes[k] = pipe;
@@ -187,13 +187,13 @@ namespace MadWizard.WinUSBNet
private void CheckControlParams(int value, int index, byte[] buffer, int length)
{
if (value < ushort.MinValue || value > ushort.MaxValue)
throw new ArgumentOutOfRangeException("Value parameter out of range.");
throw new ArgumentOutOfRangeException(nameof(value), "Value parameter out of range.");
if (index < ushort.MinValue || index > ushort.MaxValue)
throw new ArgumentOutOfRangeException("Index parameter out of range.");
throw new ArgumentOutOfRangeException(nameof(index), "Index parameter out of range.");
if (length > buffer.Length)
throw new ArgumentOutOfRangeException("Length parameter is larger than the size of the buffer.");
throw new ArgumentOutOfRangeException(nameof(length), "Length parameter is larger than the size of the buffer.");
if (length > ushort.MaxValue)
throw new ArgumentOutOfRangeException("Length too large");
throw new ArgumentOutOfRangeException(nameof(length), "Length too large");
}
/// <summary>
@@ -213,7 +213,7 @@ namespace MadWizard.WinUSBNet
set
{
if (value < 0)
throw new ArgumentOutOfRangeException("Control pipe timeout cannot be negative.");
throw new ArgumentOutOfRangeException(nameof(value), "Control pipe timeout cannot be negative.");
//_wuDevice.SetPipePolicy(0, 0x00, API.POLICY_TYPE.PIPE_TRANSFER_TIMEOUT, (uint)value);
if (InputPipe != null)
_wuDevice.SetPipePolicy(0, InputPipe.Address, API.POLICY_TYPE.PIPE_TRANSFER_TIMEOUT, (uint)value);
@@ -233,11 +233,12 @@ namespace MadWizard.WinUSBNet
/// <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
/// <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.</param>
/// <param name="length">Length of the data to transfer. Must be equal to or less than the length of <paramref name="buffer"/>.
/// <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>
public void ControlTransfer(byte requestType, byte request, int value, int index, byte[] buffer, int length)
/// <returns>The number of bytes received from the device.</returns>
public int ControlTransfer(byte requestType, byte request, int value, int index, byte[] buffer, int length)
{
// Parameters are int and not ushort because ushort is not CLS compliant.
CheckNotDisposed();
@@ -245,7 +246,7 @@ namespace MadWizard.WinUSBNet
try
{
_wuDevice.ControlTransfer(requestType, request, (ushort)value, (ushort)index, (ushort)length, buffer);
return _wuDevice.ControlTransfer(requestType, request, (ushort)value, (ushort)index, (ushort)length, buffer);
}
catch (API.APIException e)
{
@@ -256,24 +257,24 @@ namespace MadWizard.WinUSBNet
/// <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
/// <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
/// <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>
/// <returns>An <see cref="IAsyncResult"/> object representing 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"/>
/// <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)
@@ -306,23 +307,23 @@ namespace MadWizard.WinUSBNet
/// <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
/// <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. The setup packet's length member will
/// <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. The setup packet's length member will
/// be set to the length of this buffer. Note: This buffer is not allowed to change for the duration of the asynchronous operation. </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>
/// <returns>An <see cref="IAsyncResult"/> object representing 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"/>
/// <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, AsyncCallback userCallback, object stateObject)
@@ -334,13 +335,13 @@ namespace MadWizard.WinUSBNet
/// <summary>
/// Waits for a pending asynchronous control transfer to complete.
/// </summary>
/// <param name="asyncResult">The <see cref="IAsyncResult"/> object representing the asynchonous operation,
/// <param name="asyncResult">The <see cref="IAsyncResult"/> object representing the asynchronous operation,
/// as returned by one of the ControlIn, ControlOut or ControlTransfer methods.</param>
/// <returns>The number of bytes transfered during the operation.</returns>
/// <remarks>Every asynchronous control transfer must have a matching call to <see cref="EndControlTransfer"/> 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 EndControlTransfer will wait for the
/// 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 occurred during the operation. If the operation is not yet finished EndControlTransfer will wait for the
/// operation to finish before returning.</remarks>
public int EndControlTransfer(IAsyncResult asyncResult)
{
@@ -379,12 +380,13 @@ namespace MadWizard.WinUSBNet
/// <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
/// <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. The length of this
/// buffer is used as the number of bytes in the control transfer. The setup packet's length member will be set to this length as well.</param>
public void ControlTransfer(byte requestType, byte request, int value, int index, byte[] buffer)
/// <returns>The number of bytes received from the device.</returns>
public int ControlTransfer(byte requestType, byte request, int value, int index, byte[] buffer)
{
ControlTransfer(requestType, request, value, index, buffer, buffer.Length);
return ControlTransfer(requestType, request, value, index, buffer, buffer.Length);
}
/// <summary>
@@ -423,14 +425,23 @@ namespace MadWizard.WinUSBNet
/// <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="length">Length of the data to transfer. A buffer will be created with this length and the length member of the setup packet
/// <param name="length">Length of the data to transfer. A buffer will be created with this length and the length member of the setup packet
/// will be set to this length.</param>
/// <returns>A buffer containing the data transfered.</returns>
/// <remarks>This routine initially allocates a buffer to hold the <paramref name="length"/> bytes of data expected from the device.
/// If the device responds with less data than expected, this routine will allocate a smaller buffer to copy and return only the bytes actually received.
/// </remarks>
public byte[] ControlIn(byte requestType, byte request, int value, int index, int length)
{
CheckIn(requestType);
byte[] buffer = new byte[length];
ControlTransfer(requestType, request, value, index, buffer, buffer.Length);
int actuallyReceived = ControlTransfer(requestType, request, value, index, buffer, buffer.Length);
if (actuallyReceived < length)
{
byte[] outBuffer = new byte[actuallyReceived];
Array.Copy(buffer, 0, outBuffer, 0, actuallyReceived);
return outBuffer;
}
return buffer;
}
@@ -444,12 +455,13 @@ namespace MadWizard.WinUSBNet
/// <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 buffer that will receive the data transfered.</param>
/// <param name="length">Length of the data to transfer. The length member of the setup packet will be set to this length. The buffer specified
/// <param name="length">Length of the data to transfer. The length member of the setup packet will be set to this length. The buffer specified
/// by the <paramref name="buffer"/> parameter should have at least this length.</param>
public void ControlIn(byte requestType, byte request, int value, int index, byte[] buffer, int length)
/// <returns>The number of bytes received from the device.</returns>
public int ControlIn(byte requestType, byte request, int value, int index, byte[] buffer, int length)
{
CheckIn(requestType);
ControlTransfer(requestType, request, value, index, buffer, length);
return ControlTransfer(requestType, request, value, index, buffer, length);
}
/// <summary>
@@ -462,10 +474,11 @@ namespace MadWizard.WinUSBNet
/// <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 buffer that will receive the data transfered. The length of this buffer will be the number of bytes transfered.</param>
public void ControlIn(byte requestType, byte request, int value, int index, byte[] buffer)
/// <returns>The number of bytes received from the device.</returns>
public int ControlIn(byte requestType, byte request, int value, int index, byte[] buffer)
{
CheckIn(requestType);
ControlTransfer(requestType, request, value, index, buffer);
return ControlTransfer(requestType, request, value, index, buffer);
}
/// <summary>
@@ -536,8 +549,8 @@ namespace MadWizard.WinUSBNet
/// <summary>
/// Initiates an asynchronous control transfer without a data stage 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
/// <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>
@@ -545,11 +558,11 @@ namespace MadWizard.WinUSBNet
/// <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="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>
/// <returns>An <see cref="IAsyncResult"/> object representing 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"/>
/// <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, AsyncCallback userCallback, object stateObject)
@@ -571,11 +584,11 @@ namespace MadWizard.WinUSBNet
/// <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>
/// <returns>An <see cref="IAsyncResult"/> object representing 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"/>
/// <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 BeginControlIn(byte requestType, byte request, int value, int index, byte[] buffer, int length, AsyncCallback userCallback, object stateObject)
@@ -594,11 +607,11 @@ namespace MadWizard.WinUSBNet
/// <param name="buffer">The buffer that will receive the data transfered. The setup packet's length member will be set to the length of this buffer.</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>
/// <returns>An <see cref="IAsyncResult"/> object representing 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"/>
/// <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 BeginControlIn(byte requestType, byte request, int value, int index, byte[] buffer, AsyncCallback userCallback, object stateObject)
@@ -608,7 +621,7 @@ namespace MadWizard.WinUSBNet
}
/// <summary>
/// Initiates an asynchronous control transfer without a data stage over the default control endpoint.
/// Initiates an asynchronous control transfer without a data stage over the default control endpoint.
/// The request should have an IN direction (specified by the highest bit of the <paramref name="requestType"/> parameter).
/// The setup packets' length member will be set to zero.</summary>
/// <param name="requestType">The setup packet request type. The request type must specify the IN direction (highest bit set).</param>
@@ -617,11 +630,11 @@ namespace MadWizard.WinUSBNet
/// <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="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>
/// <returns>An <see cref="IAsyncResult"/> object representing 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"/>
/// <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 BeginControlIn(byte requestType, byte request, int value, int index, AsyncCallback userCallback, object stateObject)
@@ -641,11 +654,11 @@ namespace MadWizard.WinUSBNet
/// <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>
/// <returns>An <see cref="IAsyncResult"/> object representing 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"/>
/// <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 BeginControlOut(byte requestType, byte request, int value, int index, byte[] buffer, int length, AsyncCallback userCallback, object stateObject)
@@ -664,11 +677,11 @@ namespace MadWizard.WinUSBNet
/// <param name="buffer">The buffer that contains the data to be transfered. The setup packet's length member will be set to the length of this buffer.</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>
/// <returns>An <see cref="IAsyncResult"/> object representing 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"/>
/// <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 BeginControlOut(byte requestType, byte request, int value, int index, byte[] buffer, AsyncCallback userCallback, object stateObject)
@@ -678,7 +691,7 @@ namespace MadWizard.WinUSBNet
}
/// <summary>
/// Initiates an asynchronous control transfer without a data stage over the default control endpoint.
/// Initiates an asynchronous control transfer without a data stage over the default control endpoint.
/// The request should have an OUT direction (specified by the highest bit of the <paramref name="requestType"/> parameter).
/// The setup packets' length member will be set to zero.</summary>
/// <param name="requestType">The setup packet request type. The request type must specify the OUT direction (highest bit cleared).</param>
@@ -687,11 +700,11 @@ namespace MadWizard.WinUSBNet
/// <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="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>
/// <returns>An <see cref="IAsyncResult"/> object representing 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"/>
/// <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 BeginControlOut(byte requestType, byte request, int value, int index, AsyncCallback userCallback, object stateObject)
@@ -712,10 +725,10 @@ namespace MadWizard.WinUSBNet
/// Finds WinUSB devices with a GUID matching the parameter guidString
/// </summary>
/// <param name="guidString">The GUID string that the device should match.
/// The format of this string may be any format accepted by the constructor
/// The format of this string may be any format accepted by the constructor
/// of the System.Guid class</param>
/// <returns>An array of USBDeviceInfo objects representing the
/// devices found. When no devices are found an empty array is
/// <returns>An array of USBDeviceInfo objects representing the
/// devices found. When no devices are found an empty array is
/// returned.</returns>
public static USBDeviceInfo[] GetDevices(string guidString)
{
@@ -726,8 +739,8 @@ namespace MadWizard.WinUSBNet
/// Finds WinUSB devices with a GUID matching the parameter guid
/// </summary>
/// <param name="guid">The GUID that the device should match.</param>
/// <returns>An array of USBDeviceInfo objects representing the
/// devices found. When no devices are found an empty array is
/// <returns>An array of USBDeviceInfo objects representing the
/// devices found. When no devices are found an empty array is
/// returned.</returns>
public static USBDeviceInfo[] GetDevices(Guid guid)
{
@@ -781,8 +794,13 @@ namespace MadWizard.WinUSBNet
{
wuDevice.OpenDevice(devicePath);
API.USB_DEVICE_DESCRIPTOR deviceDesc = wuDevice.GetDeviceDescriptor();
// string q = wuDevice.GetStringDescriptor(0);
// TODO: use language id properly
// Get first supported language ID
ushort[] langIDs = wuDevice.GetSupportedLanguageIDs();
ushort langID = 0;
if (langIDs.Length > 0)
langID = langIDs[0];
string manufacturer = null, product = null, serialNumber = null;
byte idx = 0;
@@ -790,7 +808,7 @@ namespace MadWizard.WinUSBNet
{
idx = deviceDesc.iManufacturer;
if (idx > 0)
manufacturer = wuDevice.GetStringDescriptor(idx);
manufacturer = wuDevice.GetStringDescriptor(idx, langID);
}
catch { }
@@ -798,7 +816,7 @@ namespace MadWizard.WinUSBNet
{
idx = deviceDesc.iProduct;
if (idx > 0)
product = wuDevice.GetStringDescriptor(idx);
product = wuDevice.GetStringDescriptor(idx, langID);
}
catch { }
@@ -806,7 +824,7 @@ namespace MadWizard.WinUSBNet
{
idx = deviceDesc.iSerialNumber;
if (idx > 0)
serialNumber = wuDevice.GetStringDescriptor(idx);
serialNumber = wuDevice.GetStringDescriptor(idx, langID);
}
catch { }