diff --git a/WinUSBNet/API/WinUSBDevice.cs b/WinUSBNet/API/WinUSBDevice.cs
index 899dc8c..7f0df6c 100644
--- a/WinUSBNet/API/WinUSBDevice.cs
+++ b/WinUSBNet/API/WinUSBDevice.cs
@@ -1,6 +1,6 @@
/* 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
*/
@@ -97,23 +97,48 @@ namespace MadWizard.WinUSBNet.API
return deviceDesc;
}
- public string GetStringDescriptor(byte index)
+ private int ReadStringDescriptor(byte index, ushort languageID, byte[] buffer)
{
- byte[] buffer = new byte[256];
uint transfered;
bool success = WinUsb_GetDescriptor(_winUsbHandle, USB_STRING_DESCRIPTOR_TYPE,
- index, 0, buffer, (uint)buffer.Length, out transfered);
+ index, languageID, buffer, (uint)buffer.Length, out transfered);
if (!success)
- throw APIException.Win32("Failed to get USB string descriptor (" + index + "): 0x" + Marshal.GetLastWin32Error().ToString("X8"));
+ throw APIException.Win32("Failed to get USB string descriptor (" + index + ").");
- int length = buffer[0] - 2;
- if (length <= 0)
+ if (transfered == 0)
+ throw new APIException("No data returned when reading USB descriptor.");
+
+ int length = buffer[0];
+ if (length != transfered)
+ throw new APIException("Unexpected length when reading USB descriptor.");
+ return length;
+ }
+
+ public ushort[] GetSupportedLanguageIDs()
+ {
+ byte[] buffer = new byte[256];
+ int length = ReadStringDescriptor(0, 0, buffer);
+ length -= 2; // Skip length byte and descriptor type
+ if (length < 0 || (length % 2) != 0)
+ throw new APIException("Unexpected length when reading supported languages.");
+
+ ushort[] langIDs = new ushort[length / 2];
+ Buffer.BlockCopy(buffer, 2, langIDs, 0, length);
+ return langIDs;
+ }
+
+ public string GetStringDescriptor(byte index, ushort languageID)
+ {
+ byte[] buffer = new byte[256];
+ int length = ReadStringDescriptor(index, languageID, buffer);
+ length -= 2; // Skip length byte and descriptor type
+ if (length < 0)
return null;
char[] chars = System.Text.Encoding.Unicode.GetChars(buffer, 2, length);
return new string(chars);
}
- public void ControlTransfer(byte requestType, byte request, ushort value, ushort index, ushort length, byte[] data)
+ public int ControlTransfer(byte requestType, byte request, ushort value, ushort index, ushort length, byte[] data)
{
uint bytesReturned = 0;
WINUSB_SETUP_PACKET setupPacket;
@@ -127,6 +152,7 @@ namespace MadWizard.WinUSBNet.API
bool success = WinUsb_ControlTransfer(_winUsbHandle, setupPacket, data, length, ref bytesReturned, IntPtr.Zero);
if (!success) // todo check bytes returned?
throw APIException.Win32("Control transfer on WinUSB device failed.");
+ return (int)bytesReturned;
}
@@ -227,7 +253,7 @@ namespace MadWizard.WinUSBNet.API
finally
{
// Save interface handles (will be cleaned by Dispose)
- // also in case of exception (which is why it is in finally block),
+ // also in case of exception (which is why it is in finally block),
// because some handles might have already been opened and need
// to be disposed.
_addInterfaces = interfaces.ToArray();
diff --git a/WinUSBNet/DeviceNotifyHook.cs b/WinUSBNet/DeviceNotifyHook.cs
index a73dc81..551c5f0 100644
--- a/WinUSBNet/DeviceNotifyHook.cs
+++ b/WinUSBNet/DeviceNotifyHook.cs
@@ -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
*/
@@ -47,20 +47,13 @@ namespace MadWizard.WinUSBNet
/*
// Listen for the control's window creation and then hook into it.
- internal void OnHandleCreated(object sender, EventArgs e)
+ private void OnHandleCreated(object sender, EventArgs e)
{
try
{
// Window is now created, assign handle to NativeWindow.
IntPtr handle = ((Control)sender).Handle;
- AssignHandle(handle);
-
- if (_notifyHandle != IntPtr.Zero)
- {
- API.DeviceManagement.StopDeviceDeviceNotifications(_notifyHandle);
- _notifyHandle = IntPtr.Zero;
- }
- API.DeviceManagement.RegisterForDeviceNotifications(handle, _guid, ref _notifyHandle);
+ RegisterNotify(handle);
}
catch (API.APIException ex)
{
@@ -68,17 +61,12 @@ namespace MadWizard.WinUSBNet
}
}
- internal void OnHandleDestroyed(object sender, EventArgs e)
+ private void OnHandleDestroyed(object sender, EventArgs e)
{
try
{
// Window was destroyed, release hook.
- ReleaseHandle();
- if (_notifyHandle != null)
- {
- API.DeviceManagement.StopDeviceDeviceNotifications(_notifyHandle);
- _notifyHandle = IntPtr.Zero;
- }
+ StopNotify();
}
catch (API.APIException ex)
{
@@ -86,6 +74,28 @@ namespace MadWizard.WinUSBNet
}
}
+ private void RegisterNotify(IntPtr handle)
+ {
+ AssignHandle(handle);
+
+ if (_notifyHandle != IntPtr.Zero)
+ {
+ API.DeviceManagement.StopDeviceDeviceNotifications(_notifyHandle);
+ _notifyHandle = IntPtr.Zero;
+ }
+ API.DeviceManagement.RegisterForDeviceNotifications(handle, _guid, ref _notifyHandle);
+ }
+
+ private void StopNotify()
+ {
+ //ReleaseHandle();
+ if (_notifyHandle != IntPtr.Zero)
+ {
+ API.DeviceManagement.StopDeviceDeviceNotifications(_notifyHandle);
+ _notifyHandle = IntPtr.Zero;
+ }
+ }
+
protected override void WndProc(ref Message m)
{
// Listen for operating system messages
@@ -95,6 +105,17 @@ namespace MadWizard.WinUSBNet
case API.DeviceManagement.WM_DEVICECHANGE:
_notifier.HandleDeviceChange(m);
break;
+ case WM_NCDESTROY:
+ // Note: when a control is used, OnHandleDestroyed will be called and the
+ // handle is already released from NativeWindow. In that case, this
+ // WM_NCDESTROY message will not be caught here. This is no problem since
+ // StopNotify is already called. Even if it does, calling it twice does not cause
+ // problems.
+ // When a window handle is used instead of a Control the OnHandle events will not
+ // fire and this handler is necessary to release the handle and stop notifications
+ // when the window is destroyed.
+ StopNotify();
+ break;
}
base.WndProc(ref m);
}
diff --git a/WinUSBNet/USB.cs b/WinUSBNet/USB.cs
index 20e9669..9bd1785 100644
--- a/WinUSBNet/USB.cs
+++ b/WinUSBNet/USB.cs
@@ -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
*/
@@ -55,10 +55,10 @@ namespace MadWizard.WinUSBNet
/// Video base class (0x0E)
Video = 0x0E,
- /// Personal healthcare base class (0x0F)
+ /// Personal health care base class (0x0F)
PersonalHealthcare = 0x0F,
- /// Diagnosticdevice base class (0xDC)
+ /// Diagnostic device base class (0xDC)
DiagnosticDevice = 0xDC,
/// Wireless controller base class (0xE0)
diff --git a/WinUSBNet/USBDevice.cs b/WinUSBNet/USBDevice.cs
index d4bca20..b075a64 100644
--- a/WinUSBNet/USBDevice.cs
+++ b/WinUSBNet/USBDevice.cs
@@ -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
///
/// Disposes the object
///
- /// Indicates wether Dispose was called manually (true) or by
+ /// Indicates whether Dispose was called manually (true) or by
/// the garbage collector (false) via the destructor.
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 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");
}
///
@@ -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
/// The setup packet device request.
/// The value member in the setup packet. Its meaning depends on the request. Value should be between zero and 65535 (0xFFFF).
/// The index member in the setup packet. Its meaning depends on the request. Index should be between zero and 65535 (0xFFFF).
- /// The data to transfer in the data stage of the control. When the transfer is in the IN direction the data received will be
+ /// 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.
- /// Length of the data to transfer. Must be equal to or less than the length of .
+ /// Length of the data to transfer. Must be equal to or less than the length of .
/// The setup packet's length member will be set to this length.
- public void ControlTransfer(byte requestType, byte request, int value, int index, byte[] buffer, int length)
+ /// The number of bytes received from the device.
+ 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
///
/// 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 parameter. Alternatively, and
- /// 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
+ /// 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.
/// The setup packet request type.
/// The setup packet device request.
/// The value member in the setup packet. Its meaning depends on the request. Value should be between zero and 65535 (0xFFFF).
/// The index member in the setup packet. Its meaning depends on the request. Index should be between zero and 65535 (0xFFFF).
- /// The data to transfer in the data stage of the control. When the transfer is in the IN direction the data received will be
+ /// 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.
/// Length of the data to transfer. Must be equal to or less than the length of . The setup packet's length member will be set to this length.
/// An optional asynchronous callback, to be called when the control transfer is complete. Can be null if no callback is required.
/// A user-provided object that distinguishes this particular asynchronous operation. Can be null if not required.
- /// An object repesenting the asynchronous control transfer, which could still be pending.
+ /// An object representing the asynchronous control transfer, which could still be pending.
/// This method always completes immediately even if the operation is still pending. The object returned represents the operation
/// and must be passed to to retrieve the result of the operation. For every call to this method a matching call to
/// must be made. When specifies a callback function, this function will be called when the operation is completed. The optional
- /// parameter can be used to pass user-defined information to this callback or the . The
+ /// parameter can be used to pass user-defined information to this callback or the . The
/// also provides an event handle () that will be triggered when the operation is complete as well.
///
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
///
/// 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 parameter. Alternatively, and
- /// 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
+ /// 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.
/// The setup packet request type.
/// The setup packet device request.
/// The value member in the setup packet. Its meaning depends on the request. Value should be between zero and 65535 (0xFFFF).
/// The index member in the setup packet. Its meaning depends on the request. Index should be between zero and 65535 (0xFFFF).
- /// 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
+ /// 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.
/// An optional asynchronous callback, to be called when the control transfer is complete. Can be null if no callback is required.
/// A user-provided object that distinguishes this particular asynchronous operation. Can be null if not required.
- /// An object repesenting the asynchronous control transfer, which could still be pending.
+ /// An object representing the asynchronous control transfer, which could still be pending.
/// This method always completes immediately even if the operation is still pending. The object returned represents the operation
/// and must be passed to to retrieve the result of the operation. For every call to this method a matching call to
/// must be made. When specifies a callback function, this function will be called when the operation is completed. The optional
- /// parameter can be used to pass user-defined information to this callback or the . The
+ /// parameter can be used to pass user-defined information to this callback or the . The
/// also provides an event handle () that will be triggered when the operation is complete as well.
///
public IAsyncResult BeginControlTransfer(byte requestType, byte request, int value, int index, byte[] buffer, AsyncCallback userCallback, object stateObject)
@@ -334,13 +335,13 @@ namespace MadWizard.WinUSBNet
///
/// Waits for a pending asynchronous control transfer to complete.
///
- /// The object representing the asynchonous operation,
+ /// The object representing the asynchronous operation,
/// as returned by one of the ControlIn, ControlOut or ControlTransfer methods.
/// The number of bytes transfered during the operation.
/// Every asynchronous control transfer must have a matching call to 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.
public int EndControlTransfer(IAsyncResult asyncResult)
{
@@ -379,12 +380,13 @@ namespace MadWizard.WinUSBNet
/// The setup packet device request.
/// The value member in the setup packet. Its meaning depends on the request. Value should be between zero and 65535 (0xFFFF).
/// The index member in the setup packet. Its meaning depends on the request. Index should be between zero and 65535 (0xFFFF).
- /// The data to transfer in the data stage of the control. When the transfer is in the IN direction the data received will be
+ /// 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.
- public void ControlTransfer(byte requestType, byte request, int value, int index, byte[] buffer)
+ /// The number of bytes received from the device.
+ 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);
}
///
@@ -423,14 +425,23 @@ namespace MadWizard.WinUSBNet
/// The setup packet device request.
/// The value member in the setup packet. Its meaning depends on the request. Value should be between zero and 65535 (0xFFFF).
/// The index member in the setup packet. Its meaning depends on the request. Index should be between zero and 65535 (0xFFFF).
- /// Length of the data to transfer. A buffer will be created with this length and the length member of the setup packet
+ /// 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.
/// A buffer containing the data transfered.
+ /// This routine initially allocates a buffer to hold the 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.
+ ///
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
/// The value member in the setup packet. Its meaning depends on the request. Value should be between zero and 65535 (0xFFFF).
/// The index member in the setup packet. Its meaning depends on the request. Index should be between zero and 65535 (0xFFFF).
/// The buffer that will receive the data transfered.
- /// Length of the data to transfer. The length member of the setup packet will be set to this length. The buffer specified
+ /// Length of the data to transfer. The length member of the setup packet will be set to this length. The buffer specified
/// by the parameter should have at least this length.
- public void ControlIn(byte requestType, byte request, int value, int index, byte[] buffer, int length)
+ /// The number of bytes received from the device.
+ 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);
}
///
@@ -462,10 +474,11 @@ namespace MadWizard.WinUSBNet
/// The value member in the setup packet. Its meaning depends on the request. Value should be between zero and 65535 (0xFFFF).
/// The index member in the setup packet. Its meaning depends on the request. Index should be between zero and 65535 (0xFFFF).
/// The buffer that will receive the data transfered. The length of this buffer will be the number of bytes transfered.
- public void ControlIn(byte requestType, byte request, int value, int index, byte[] buffer)
+ /// The number of bytes received from the device.
+ 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);
}
///
@@ -536,8 +549,8 @@ namespace MadWizard.WinUSBNet
///
/// 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 parameter. Alternatively, and
- /// 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
+ /// 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.
/// The setup packet request type.
/// The setup packet device request.
@@ -545,11 +558,11 @@ namespace MadWizard.WinUSBNet
/// The index member in the setup packet. Its meaning depends on the request. Index should be between zero and 65535 (0xFFFF).
/// An optional asynchronous callback, to be called when the control transfer is complete. Can be null if no callback is required.
/// A user-provided object that distinguishes this particular asynchronous operation. Can be null if not required.
- /// An object repesenting the asynchronous control transfer, which could still be pending.
+ /// An object representing the asynchronous control transfer, which could still be pending.
/// This method always completes immediately even if the operation is still pending. The object returned represents the operation
/// and must be passed to to retrieve the result of the operation. For every call to this method a matching call to
/// must be made. When specifies a callback function, this function will be called when the operation is completed. The optional
- /// parameter can be used to pass user-defined information to this callback or the . The
+ /// parameter can be used to pass user-defined information to this callback or the . The
/// also provides an event handle () that will be triggered when the operation is complete as well.
///
public IAsyncResult BeginControlTransfer(byte requestType, byte request, int value, int index, AsyncCallback userCallback, object stateObject)
@@ -571,11 +584,11 @@ namespace MadWizard.WinUSBNet
/// Length of the data to transfer. Must be equal to or less than the length of . The setup packet's length member will be set to this length.
/// An optional asynchronous callback, to be called when the control transfer is complete. Can be null if no callback is required.
/// A user-provided object that distinguishes this particular asynchronous operation. Can be null if not required.
- /// An object repesenting the asynchronous control transfer, which could still be pending.
+ /// An object representing the asynchronous control transfer, which could still be pending.
/// This method always completes immediately even if the operation is still pending. The object returned represents the operation
/// and must be passed to to retrieve the result of the operation. For every call to this method a matching call to
/// must be made. When specifies a callback function, this function will be called when the operation is completed. The optional
- /// parameter can be used to pass user-defined information to this callback or the . The
+ /// parameter can be used to pass user-defined information to this callback or the . The
/// also provides an event handle () that will be triggered when the operation is complete as well.
///
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
/// The buffer that will receive the data transfered. The setup packet's length member will be set to the length of this buffer.
/// An optional asynchronous callback, to be called when the control transfer is complete. Can be null if no callback is required.
/// A user-provided object that distinguishes this particular asynchronous operation. Can be null if not required.
- /// An object repesenting the asynchronous control transfer, which could still be pending.
+ /// An object representing the asynchronous control transfer, which could still be pending.
/// This method always completes immediately even if the operation is still pending. The object returned represents the operation
/// and must be passed to to retrieve the result of the operation. For every call to this method a matching call to
/// must be made. When specifies a callback function, this function will be called when the operation is completed. The optional
- /// parameter can be used to pass user-defined information to this callback or the . The
+ /// parameter can be used to pass user-defined information to this callback or the . The
/// also provides an event handle () that will be triggered when the operation is complete as well.
///
public IAsyncResult BeginControlIn(byte requestType, byte request, int value, int index, byte[] buffer, AsyncCallback userCallback, object stateObject)
@@ -608,7 +621,7 @@ namespace MadWizard.WinUSBNet
}
///
- /// 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 parameter).
/// The setup packets' length member will be set to zero.
/// The setup packet request type. The request type must specify the IN direction (highest bit set).
@@ -617,11 +630,11 @@ namespace MadWizard.WinUSBNet
/// The index member in the setup packet. Its meaning depends on the request. Index should be between zero and 65535 (0xFFFF).
/// An optional asynchronous callback, to be called when the control transfer is complete. Can be null if no callback is required.
/// A user-provided object that distinguishes this particular asynchronous operation. Can be null if not required.
- /// An object repesenting the asynchronous control transfer, which could still be pending.
+ /// An object representing the asynchronous control transfer, which could still be pending.
/// This method always completes immediately even if the operation is still pending. The object returned represents the operation
/// and must be passed to to retrieve the result of the operation. For every call to this method a matching call to
/// must be made. When specifies a callback function, this function will be called when the operation is completed. The optional
- /// parameter can be used to pass user-defined information to this callback or the . The
+ /// parameter can be used to pass user-defined information to this callback or the . The
/// also provides an event handle () that will be triggered when the operation is complete as well.
///
public IAsyncResult BeginControlIn(byte requestType, byte request, int value, int index, AsyncCallback userCallback, object stateObject)
@@ -641,11 +654,11 @@ namespace MadWizard.WinUSBNet
/// Length of the data to transfer. Must be equal to or less than the length of . The setup packet's length member will be set to this length.
/// An optional asynchronous callback, to be called when the control transfer is complete. Can be null if no callback is required.
/// A user-provided object that distinguishes this particular asynchronous operation. Can be null if not required.
- /// An object repesenting the asynchronous control transfer, which could still be pending.
+ /// An object representing the asynchronous control transfer, which could still be pending.
/// This method always completes immediately even if the operation is still pending. The object returned represents the operation
/// and must be passed to to retrieve the result of the operation. For every call to this method a matching call to
/// must be made. When specifies a callback function, this function will be called when the operation is completed. The optional
- /// parameter can be used to pass user-defined information to this callback or the . The
+ /// parameter can be used to pass user-defined information to this callback or the . The
/// also provides an event handle () that will be triggered when the operation is complete as well.
///
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
/// The buffer that contains the data to be transfered. The setup packet's length member will be set to the length of this buffer.
/// An optional asynchronous callback, to be called when the control transfer is complete. Can be null if no callback is required.
/// A user-provided object that distinguishes this particular asynchronous operation. Can be null if not required.
- /// An object repesenting the asynchronous control transfer, which could still be pending.
+ /// An object representing the asynchronous control transfer, which could still be pending.
/// This method always completes immediately even if the operation is still pending. The object returned represents the operation
/// and must be passed to to retrieve the result of the operation. For every call to this method a matching call to
/// must be made. When specifies a callback function, this function will be called when the operation is completed. The optional
- /// parameter can be used to pass user-defined information to this callback or the . The
+ /// parameter can be used to pass user-defined information to this callback or the . The
/// also provides an event handle () that will be triggered when the operation is complete as well.
///
public IAsyncResult BeginControlOut(byte requestType, byte request, int value, int index, byte[] buffer, AsyncCallback userCallback, object stateObject)
@@ -678,7 +691,7 @@ namespace MadWizard.WinUSBNet
}
///
- /// 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 parameter).
/// The setup packets' length member will be set to zero.
/// The setup packet request type. The request type must specify the OUT direction (highest bit cleared).
@@ -687,11 +700,11 @@ namespace MadWizard.WinUSBNet
/// The index member in the setup packet. Its meaning depends on the request. Index should be between zero and 65535 (0xFFFF).
/// An optional asynchronous callback, to be called when the control transfer is complete. Can be null if no callback is required.
/// A user-provided object that distinguishes this particular asynchronous operation. Can be null if not required.
- /// An object repesenting the asynchronous control transfer, which could still be pending.
+ /// An object representing the asynchronous control transfer, which could still be pending.
/// This method always completes immediately even if the operation is still pending. The object returned represents the operation
/// and must be passed to to retrieve the result of the operation. For every call to this method a matching call to
/// must be made. When specifies a callback function, this function will be called when the operation is completed. The optional
- /// parameter can be used to pass user-defined information to this callback or the . The
+ /// parameter can be used to pass user-defined information to this callback or the . The
/// also provides an event handle () that will be triggered when the operation is complete as well.
///
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
///
/// 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
- /// An array of USBDeviceInfo objects representing the
- /// devices found. When no devices are found an empty array is
+ /// An array of USBDeviceInfo objects representing the
+ /// devices found. When no devices are found an empty array is
/// returned.
public static USBDeviceInfo[] GetDevices(string guidString)
{
@@ -726,8 +739,8 @@ namespace MadWizard.WinUSBNet
/// Finds WinUSB devices with a GUID matching the parameter guid
///
/// The GUID that the device should match.
- /// An array of USBDeviceInfo objects representing the
- /// devices found. When no devices are found an empty array is
+ /// An array of USBDeviceInfo objects representing the
+ /// devices found. When no devices are found an empty array is
/// returned.
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 { }
diff --git a/WinUSBNet/USBDeviceDescriptor.cs b/WinUSBNet/USBDeviceDescriptor.cs
index 31a2f8d..94c87ab 100644
--- a/WinUSBNet/USBDeviceDescriptor.cs
+++ b/WinUSBNet/USBDeviceDescriptor.cs
@@ -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
*/
@@ -46,7 +46,7 @@ namespace MadWizard.WinUSBNet
///
- /// Friendly device name, or path name when no
+ /// Friendly device name, or path name when no
/// further device information is available
///
public string FullName
@@ -67,7 +67,7 @@ namespace MadWizard.WinUSBNet
///
/// Device class code as defined in the interface descriptor
/// This property can be used if the class type is not defined
- /// int the USBBaseClass enumeraiton
+ /// int the USBBaseClass enumeration
///
public byte ClassValue
{
diff --git a/WinUSBNet/USBInterface.cs b/WinUSBNet/USBInterface.cs
index 066038d..8a208ea 100644
--- a/WinUSBNet/USBInterface.cs
+++ b/WinUSBNet/USBInterface.cs
@@ -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
*/
@@ -73,7 +73,7 @@ namespace MadWizard.WinUSBNet
///
/// Interface class code as defined in the interface descriptor
/// This property can be used if the class type is not defined
- /// int the USBBaseClass enumeraiton
+ /// int the USBBaseClass enumeration
///
public byte ClassValue
{
diff --git a/WinUSBNet/USBNotifier.cs b/WinUSBNet/USBNotifier.cs
index ae33727..d6d7e78 100644
--- a/WinUSBNet/USBNotifier.cs
+++ b/WinUSBNet/USBNotifier.cs
@@ -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
*/
@@ -61,7 +61,7 @@ namespace MadWizard.WinUSBNet
}
///
- /// Helper class to receive notifications on USB device changes such as
+ /// Helper class to receive notifications on USB device changes such as
/// connecting or removing a device.
///
public class USBNotifier : IDisposable
@@ -108,11 +108,11 @@ namespace MadWizard.WinUSBNet
}
///
- /// Constructs a new USBNotifier that will watch for events on
- /// devices matching the given interface GUID. A Windows Forms control
+ /// Constructs a new USBNotifier that will watch for events on
+ /// devices matching the given interface GUID. A Windows Forms control
/// is needed since the notifier relies on window messages.
///
- /// A control that will be used internally for device notification messages.
+ /// A control that will be used internally for device notification messages.
/// You can use a Form object for example.
/// The interface GUID string of the devices to watch.
public USBNotifier(string guidString) :
@@ -123,11 +123,11 @@ namespace MadWizard.WinUSBNet
///
- /// Constructs a new USBNotifier that will watch for events on
- /// devices matching the given interface GUID. A Windows Forms control
+ /// Constructs a new USBNotifier that will watch for events on
+ /// devices matching the given interface GUID. A Windows Forms control
/// is needed since the notifier relies on window messages.
///
- /// A control that will be used internally for device notification messages.
+ /// A control that will be used internally for device notification messages.
/// You can use a Form object for example.
/// The interface GUID of the devices to watch.
public USBNotifier(Guid guid)
@@ -146,7 +146,7 @@ namespace MadWizard.WinUSBNet
_Arrival(this, new USBEvent(USBEventType.DeviceArrival, _guid, devicePath));
}
///
- /// Trigggers the removal event
+ /// Triggers the removal event
///
/// Device pathname of the device that has been connected
protected void OnRemoval(string devicePath)
@@ -212,7 +212,7 @@ namespace MadWizard.WinUSBNet
}
///
- /// Disposes the USBNotifier object and frees all resources.
+ /// Disposes the USBNotifier object and frees all resources.
/// Call this method when the object is no longer needed.
///
public void Dispose()
diff --git a/WinUSBNet/USBPipe.cs b/WinUSBNet/USBPipe.cs
index b142e15..f59e09d 100644
--- a/WinUSBNet/USBPipe.cs
+++ b/WinUSBNet/USBPipe.cs
@@ -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
*/
@@ -139,29 +139,29 @@ namespace MadWizard.WinUSBNet
private void CheckReadParams(byte[] buffer, int offset, int length)
{
if (!IsIn)
- // throw new NotSupportedException("Cannot read from a pipe with OUT direction.");
- LogAndThrowException(new NotSupportedException("Cannot read from a pipe with OUT direction."));
+ // throw new ArgumentOutOfRangeException("Offset of data to read is outside the buffer boundaries.");
+ LogAndThrowException(new ArgumentOutOfRangeException("Offset of data to read is outside the buffer boundaries."));
int bufferLength = buffer.Length;
if (offset < 0 || offset >= bufferLength)
- // throw new ArgumentOutOfRangeException("Offset of data to read is outside the buffer boundaries.");
+ // throw new ArgumentOutOfRangeException(nameof(offset), "Offset of data to read is outside the buffer boundaries.");
LogAndThrowException(new ArgumentOutOfRangeException("Offset of data to read is outside the buffer boundaries."));
if (length < 0 || (offset + length) > bufferLength)
- // throw new ArgumentOutOfRangeException("Length of data to read is outside the buffer boundaries.");
+ // throw new ArgumentOutOfRangeException(nameof(length), "Length of data to read is outside the buffer boundaries.");
LogAndThrowException(new ArgumentOutOfRangeException("Length of data to read is outside the buffer boundaries."));
}
private void CheckWriteParams(byte[] buffer, int offset, int length)
{
if (!IsOut)
- // throw new NotSupportedException("Cannot write to a pipe with IN direction.");
+ //throw new NotSupportedException("Cannot write to a pipe with IN direction.");
LogAndThrowException(new NotSupportedException("Cannot write to a pipe with IN direction."));
int bufferLength = buffer.Length;
if (offset < 0 || offset >= bufferLength)
- // throw new ArgumentOutOfRangeException("Offset of data to write is outside the buffer boundaries.");
+ // throw new ArgumentOutOfRangeException(nameof(offset), "Offset of data to write is outside the buffer boundaries.");
LogAndThrowException(new ArgumentOutOfRangeException("Offset of data to write is outside the buffer boundaries."));
if (length < 0 || (offset + length) > bufferLength)
- // throw new ArgumentOutOfRangeException("Length of data to write is outside the buffer boundaries.");
+ // throw new ArgumentOutOfRangeException(nameof(length), "Length of data to write is outside the buffer boundaries.");
LogAndThrowException(new ArgumentOutOfRangeException("Length of data to write is outside the buffer boundaries."));
}
@@ -171,11 +171,11 @@ namespace MadWizard.WinUSBNet
/// Length of the data to transfer.
/// An optional asynchronous callback, to be called when the operation is complete. Can be null if no callback is required.
/// A user-provided object that distinguishes this particular asynchronous operation. Can be null if not required.
- /// An object repesenting the asynchronous operation, which could still be pending.
+ /// An object representing the asynchronous operation, which could still be pending.
/// This method always completes immediately even if the operation is still pending. The object returned represents the operation
/// and must be passed to to retrieve the result of the operation. For every call to this method a matching call to
/// must be made. When specifies a callback function, this function will be called when the operation is completed. The optional
- /// parameter can be used to pass user-defined information to this callback or the . The
+ /// parameter can be used to pass user-defined information to this callback or the . The
/// also provides an event handle () that will be triggered when the operation is complete as well.
///
public IAsyncResult BeginRead(byte[] buffer, int offset, int length, AsyncCallback userCallback, object stateObject)
@@ -189,9 +189,8 @@ namespace MadWizard.WinUSBNet
}
catch (API.APIException e)
{
- if (result != null)
- result.Dispose();
- // throw new USBException("Failed to read from pipe.", e);
+ result.Dispose();
+ //throw new USBException("Failed to read from pipe.", e);
LogAndThrowException(new USBException("Failed to read from pipe.", e));
}
catch (Exception e)
@@ -208,13 +207,13 @@ namespace MadWizard.WinUSBNet
///
/// Waits for a pending asynchronous read operation to complete.
///
- /// The object representing the asynchonous operation,
+ /// The object representing the asynchronous operation,
/// as returned by .
/// The number of bytes transfered during the operation.
/// Every call to must have a matching call to 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
+ /// 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 EndWrite will wait for the
/// operation to finish before returning.
public int EndRead(IAsyncResult asyncResult)
{
@@ -285,11 +284,11 @@ namespace MadWizard.WinUSBNet
/// Length of the data to transfer.
/// An optional asynchronous callback, to be called when the operation is complete. Can be null if no callback is required.
/// A user-provided object that distinguishes this particular asynchronous operation. Can be null if not required.
- /// An object repesenting the asynchronous operation, which could still be pending.
+ /// An object representing the asynchronous operation, which could still be pending.
/// This method always completes immediately even if the operation is still pending. The object returned represents the operation
/// and must be passed to to retrieve the result of the operation. For every call to this method a matching call to
/// must be made. When specifies a callback function, this function will be called when the operation is completed. The optional
- /// parameter can be used to pass user-defined information to this callback or the . The
+ /// parameter can be used to pass user-defined information to this callback or the . The
/// also provides an event handle () that will be triggered when the operation is complete as well.
///
public IAsyncResult BeginWrite(byte[] buffer, int offset, int length, AsyncCallback userCallback, object stateObject)
@@ -327,13 +326,13 @@ namespace MadWizard.WinUSBNet
///
/// Waits for a pending asynchronous write operation to complete.
///
- /// The object representing the asynchonous operation,
+ /// The object representing the asynchronous operation,
/// as returned by .
/// The number of bytes transfered during the operation.
/// Every call to must have a matching call to 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
+ /// 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 EndWrite will wait for the
/// operation to finish before returning.
public void EndWrite(IAsyncResult asyncResult)
{