Project Maintenance

This commit is contained in:
Gustave Monce
2021-08-09 20:21:09 +02:00
parent 9865ef7f79
commit 847ce0506d
411 changed files with 5922 additions and 54941 deletions
-4
View File
@@ -9,7 +9,6 @@ using System;
using System.ComponentModel;
using System.Runtime.InteropServices;
namespace MadWizard.WinUSBNet.API
{
/// <summary>
@@ -21,7 +20,6 @@ namespace MadWizard.WinUSBNet.API
public APIException(string message) :
base(message)
{
}
public APIException(string message, Exception innerException) : base(message, innerException)
{
@@ -41,8 +39,6 @@ namespace MadWizard.WinUSBNet.API
public static APIException Win32(string message, int errorCode)
{
return new APIException(message, new Win32Exception(errorCode));
}
}
}
+50 -37
View File
@@ -21,7 +21,6 @@ namespace MadWizard.WinUSBNet.API
/// </summary>
internal static partial class DeviceManagement
{
// Get device name from notification message.
// Also checks checkGuid with the GUID from the message to check the notification
// is for a relevant device. Other messages might be received.
@@ -29,14 +28,14 @@ namespace MadWizard.WinUSBNet.API
{
int stringSize;
DEV_BROADCAST_DEVICEINTERFACE_1 devBroadcastDeviceInterface = new DEV_BROADCAST_DEVICEINTERFACE_1();
DEV_BROADCAST_HDR devBroadcastHeader = new DEV_BROADCAST_HDR();
DEV_BROADCAST_DEVICEINTERFACE_1 devBroadcastDeviceInterface = new();
DEV_BROADCAST_HDR devBroadcastHeader = new();
// The LParam parameter of Message is a pointer to a DEV_BROADCAST_HDR structure.
Marshal.PtrToStructure(pDevBroadcastHeader, devBroadcastHeader);
if ((devBroadcastHeader.dbch_devicetype == DBT_DEVTYP_DEVICEINTERFACE))
if (devBroadcastHeader.dbch_devicetype == DBT_DEVTYP_DEVICEINTERFACE)
{
// The dbch_devicetype parameter indicates that the event applies to a device interface.
// So the structure in LParam is actually a DEV_BROADCAST_INTERFACE structure,
@@ -60,16 +59,18 @@ namespace MadWizard.WinUSBNet.API
// Check if message is for the GUID
if (devBroadcastDeviceInterface.dbcc_classguid != checkGuid)
{
return null;
}
// Store the device name in a String.
string deviceNameString = new String(devBroadcastDeviceInterface.dbcc_name, 0, stringSize);
string deviceNameString = new(devBroadcastDeviceInterface.dbcc_name, 0, stringSize);
return deviceNameString;
}
else if ((devBroadcastHeader.dbch_devicetype == DBT_DEVTYP_VOLUME))
else if (devBroadcastHeader.dbch_devicetype == DBT_DEVTYP_VOLUME)
{
DEV_BROADCAST_VOLUME vol = new DEV_BROADCAST_VOLUME();
DEV_BROADCAST_VOLUME vol = new();
Marshal.PtrToStructure(pDevBroadcastHeader, vol);
Int32 Mask = vol.dbcv_unitmask;
Int32 DriveInt = Convert.ToInt32('A') - 1;
@@ -86,18 +87,20 @@ namespace MadWizard.WinUSBNet.API
private static byte[] GetProperty(IntPtr deviceInfoSet, SP_DEVINFO_DATA deviceInfoData, SPDRP property, out int regType)
{
uint requiredSize;
if (!SetupDiGetDeviceRegistryProperty(deviceInfoSet, ref deviceInfoData, property, IntPtr.Zero, IntPtr.Zero, 0, out requiredSize))
if (!SetupDiGetDeviceRegistryProperty(deviceInfoSet, ref deviceInfoData, property, IntPtr.Zero, IntPtr.Zero, 0, out uint requiredSize))
{
if (Marshal.GetLastWin32Error() != ERROR_INSUFFICIENT_BUFFER)
{
throw APIException.Win32("Failed to get buffer size for device registry property.");
}
}
byte[] buffer = new byte[requiredSize];
if (!SetupDiGetDeviceRegistryProperty(deviceInfoSet, ref deviceInfoData, property, out regType, buffer, (uint)buffer.Length, out requiredSize))
{
throw APIException.Win32("Failed to get device registry property.");
}
return buffer;
}
@@ -113,18 +116,20 @@ namespace MadWizard.WinUSBNet.API
// Heathcliff74
private static byte[] GetProperty(IntPtr deviceInfoSet, SP_DEVINFO_DATA deviceInfoData, DEVPROPKEY property, out uint propertyType)
{
int requiredSize;
if (!SetupDiGetDeviceProperty(deviceInfoSet, ref deviceInfoData, ref property, out propertyType, null, 0, out requiredSize, 0))
if (!SetupDiGetDeviceProperty(deviceInfoSet, ref deviceInfoData, ref property, out propertyType, null, 0, out int requiredSize, 0))
{
if (Marshal.GetLastWin32Error() != ERROR_INSUFFICIENT_BUFFER)
{
throw APIException.Win32("Failed to get buffer size for device registry property.");
}
}
byte[] buffer = new byte[requiredSize];
if (!SetupDiGetDeviceProperty(deviceInfoSet, ref deviceInfoData, ref property, out propertyType, buffer, buffer.Length, out requiredSize, 0))
{
throw APIException.Win32("Failed to get device registry property.");
}
return buffer;
}
@@ -132,10 +137,11 @@ namespace MadWizard.WinUSBNet.API
// todo: is the queried data always available, or should we check ERROR_INVALID_DATA?
private static string GetStringProperty(IntPtr deviceInfoSet, SP_DEVINFO_DATA deviceInfoData, SPDRP property)
{
int regType;
byte[] buffer = GetProperty(deviceInfoSet, deviceInfoData, property, out regType);
byte[] buffer = GetProperty(deviceInfoSet, deviceInfoData, property, out int regType);
if (regType != (int)RegTypes.REG_SZ)
{
throw new APIException("Invalid registry type returned for device property.");
}
// sizof(char), 2 bytes, are removed to leave out the string terminator
return System.Text.Encoding.Unicode.GetString(buffer, 0, buffer.Length - sizeof(char));
@@ -145,10 +151,11 @@ namespace MadWizard.WinUSBNet.API
// todo: is the queried data always available, or should we check ERROR_INVALID_DATA?
private static string GetStringProperty(IntPtr deviceInfoSet, SP_DEVINFO_DATA deviceInfoData, DEVPROPKEY property)
{
uint propertyType;
byte[] buffer = GetProperty(deviceInfoSet, deviceInfoData, property, out propertyType);
byte[] buffer = GetProperty(deviceInfoSet, deviceInfoData, property, out uint propertyType);
if (propertyType != 0x00000012) // DEVPROP_TYPE_STRING
{
throw new APIException("Invalid registry type returned for device property.");
}
// sizof(char), 2 bytes, are removed to leave out the string terminator
return System.Text.Encoding.Unicode.GetString(buffer, 0, buffer.Length - sizeof(char));
@@ -156,19 +163,19 @@ namespace MadWizard.WinUSBNet.API
private static string[] GetMultiStringProperty(IntPtr deviceInfoSet, SP_DEVINFO_DATA deviceInfoData, SPDRP property)
{
int regType;
byte[] buffer = GetProperty(deviceInfoSet, deviceInfoData, property, out regType);
byte[] buffer = GetProperty(deviceInfoSet, deviceInfoData, property, out int regType);
if (regType != (int)RegTypes.REG_MULTI_SZ)
{
throw new APIException("Invalid registry type returned for device property.");
}
string fullString = System.Text.Encoding.Unicode.GetString(buffer);
return fullString.Split(new char[] { '\0' }, StringSplitOptions.RemoveEmptyEntries);
}
private static DeviceDetails GetDeviceDetails(string devicePath, IntPtr deviceInfoSet, SP_DEVINFO_DATA deviceInfoData)
{
DeviceDetails details = new DeviceDetails();
DeviceDetails details = new();
details.DevicePath = devicePath;
details.DeviceDescription = GetStringProperty(deviceInfoSet, deviceInfoData, SPDRP.SPDRP_DEVICEDESC);
details.Manufacturer = GetStringProperty(deviceInfoSet, deviceInfoData, SPDRP.SPDRP_MFG);
@@ -183,7 +190,7 @@ namespace MadWizard.WinUSBNet.API
string[] hardwareIDs = GetMultiStringProperty(deviceInfoSet, deviceInfoData, SPDRP.SPDRP_HARDWAREID);
Regex regex = new Regex("^USB\\\\VID_([0-9A-F]{4})&PID_([0-9A-F]{4})", RegexOptions.IgnoreCase);
Regex regex = new("^USB\\\\VID_([0-9A-F]{4})&PID_([0-9A-F]{4})", RegexOptions.IgnoreCase);
foreach (string hardwareID in hardwareIDs)
{
Match match = regex.Match(hardwareID);
@@ -204,39 +211,41 @@ namespace MadWizard.WinUSBNet.API
return details;
}
public static DeviceDetails[] FindDevicesFromGuid(Guid guid)
{
IntPtr deviceInfoSet = IntPtr.Zero;
List<DeviceDetails> deviceList = new List<DeviceDetails>();
List<DeviceDetails> deviceList = new();
try
{
deviceInfoSet = SetupDiGetClassDevs(ref guid, IntPtr.Zero, IntPtr.Zero,
DIGCF_PRESENT | DIGCF_DEVICEINTERFACE);
if (deviceInfoSet == FileIO.INVALID_HANDLE_VALUE)
{
throw APIException.Win32("Failed to enumerate devices.");
}
int memberIndex = 0;
while (true)
{
// Begin with 0 and increment through the device information set until
// no more devices are available.
SP_DEVICE_INTERFACE_DATA deviceInterfaceData = new SP_DEVICE_INTERFACE_DATA();
SP_DEVICE_INTERFACE_DATA deviceInterfaceData = new();
// The cbSize element of the deviceInterfaceData structure must be set to
// the structure's size in bytes.
// The size is 28 bytes for 32-bit code and 32 bytes for 64-bit code.
deviceInterfaceData.cbSize = Marshal.SizeOf(deviceInterfaceData);
bool success;
success = SetupDiEnumDeviceInterfaces(deviceInfoSet, IntPtr.Zero, ref guid, memberIndex, ref deviceInterfaceData);
bool success = SetupDiEnumDeviceInterfaces(deviceInfoSet, IntPtr.Zero, ref guid, memberIndex, ref deviceInterfaceData);
// Find out if a device information set was retrieved.
if (!success)
{
int lastError = Marshal.GetLastWin32Error();
if (lastError == ERROR_NO_MORE_ITEMS)
{
break;
}
throw APIException.Win32("Failed to get device interface.");
}
@@ -255,13 +264,14 @@ namespace MadWizard.WinUSBNet.API
if (!success)
{
if (Marshal.GetLastWin32Error() != ERROR_INSUFFICIENT_BUFFER)
{
throw APIException.Win32("Failed to get interface details buffer size.");
}
}
IntPtr detailDataBuffer = IntPtr.Zero;
try
{
// Allocate memory for the SP_DEVICE_INTERFACE_DETAIL_DATA structure using the returned buffer size.
detailDataBuffer = Marshal.AllocHGlobal(bufferSize);
@@ -274,10 +284,9 @@ namespace MadWizard.WinUSBNet.API
// and the returned required buffer size.
// build a DevInfo Data structure
SP_DEVINFO_DATA da = new SP_DEVINFO_DATA();
SP_DEVINFO_DATA da = new();
da.cbSize = Marshal.SizeOf(da);
success = SetupDiGetDeviceInterfaceDetail
(deviceInfoSet,
ref deviceInterfaceData,
@@ -287,19 +296,19 @@ namespace MadWizard.WinUSBNet.API
ref da);
if (!success)
{
throw APIException.Win32("Failed to get device interface details.");
}
// Skip over cbsize (4 bytes) to get the address of the devicePathName.
IntPtr pDevicePathName = new IntPtr(detailDataBuffer.ToInt64() + 4);
IntPtr pDevicePathName = new(detailDataBuffer.ToInt64() + 4);
string pathName = Marshal.PtrToStringUni(pDevicePathName);
// Get the String containing the devicePathName.
DeviceDetails details = GetDeviceDetails(pathName, deviceInfoSet, da);
deviceList.Add(details);
}
finally
@@ -323,11 +332,9 @@ namespace MadWizard.WinUSBNet.API
return deviceList.ToArray();
}
public static void RegisterForDeviceNotifications(IntPtr controlHandle, Guid classGuid, ref IntPtr deviceNotificationHandle)
{
DEV_BROADCAST_DEVICEINTERFACE devBroadcastDeviceInterface = new DEV_BROADCAST_DEVICEINTERFACE();
DEV_BROADCAST_DEVICEINTERFACE devBroadcastDeviceInterface = new();
IntPtr devBroadcastDeviceInterfaceBuffer = IntPtr.Zero;
try
{
@@ -345,7 +352,9 @@ namespace MadWizard.WinUSBNet.API
deviceNotificationHandle = RegisterDeviceNotification(controlHandle, devBroadcastDeviceInterfaceBuffer, DEVICE_NOTIFY_WINDOW_HANDLE);
if (deviceNotificationHandle == IntPtr.Zero)
{
throw APIException.Win32("Failed to register device notification");
}
// Marshal data from the unmanaged block devBroadcastDeviceInterfaceBuffer to
// the managed object devBroadcastDeviceInterface
@@ -355,14 +364,18 @@ namespace MadWizard.WinUSBNet.API
{
// Free the memory allocated previously by AllocHGlobal.
if (devBroadcastDeviceInterfaceBuffer != IntPtr.Zero)
{
Marshal.FreeHGlobal(devBroadcastDeviceInterfaceBuffer);
}
}
}
public static void StopDeviceDeviceNotifications(IntPtr deviceNotificationHandle)
{
if (!DeviceManagement.UnregisterDeviceNotification(deviceNotificationHandle))
{
throw APIException.Win32("Failed to unregister device notification");
}
}
}
}
+7 -8
View File
@@ -15,10 +15,9 @@ using System.Runtime.InteropServices;
namespace MadWizard.WinUSBNet.API
{
/// <summary>
/// API declarations relating to device management (SetupDixxx and
/// RegisterDeviceNotification functions).
/// API declarations relating to device management (SetupDixxx and
/// RegisterDeviceNotification functions).
/// </summary>
internal static partial class DeviceManagement
{
// from dbt.h
@@ -86,14 +85,14 @@ namespace MadWizard.WinUSBNet.API
private struct SP_DEVICE_INTERFACE_DATA
{
internal Int32 cbSize;
internal System.Guid InterfaceClassGuid;
internal Guid InterfaceClassGuid;
internal Int32 Flags;
internal IntPtr Reserved;
}
private struct SP_DEVINFO_DATA
{
internal Int32 cbSize;
internal System.Guid ClassGuid;
internal Guid ClassGuid;
internal Int32 DevInst;
internal IntPtr Reserved;
}
@@ -152,7 +151,7 @@ namespace MadWizard.WinUSBNet.API
private static extern Int32 SetupDiDestroyDeviceInfoList(IntPtr DeviceInfoSet);
[DllImport("setupapi.dll", SetLastError = true)]
private static extern bool SetupDiEnumDeviceInterfaces(IntPtr DeviceInfoSet, IntPtr DeviceInfoData, ref System.Guid InterfaceClassGuid, Int32 MemberIndex, ref SP_DEVICE_INTERFACE_DATA DeviceInterfaceData);
private static extern bool SetupDiEnumDeviceInterfaces(IntPtr DeviceInfoSet, IntPtr DeviceInfoData, ref Guid InterfaceClassGuid, Int32 MemberIndex, ref SP_DEVICE_INTERFACE_DATA DeviceInterfaceData);
[DllImport("setupapi.dll", CharSet = CharSet.Unicode, SetLastError = true)]
private static extern bool SetupDiGetDeviceRegistryProperty(IntPtr DeviceInfoSet, ref SP_DEVINFO_DATA DeviceInfoData, SPDRP Property, out int PropertyRegDataType, byte[] PropertyBuffer, uint PropertyBufferSize, out UInt32 RequiredSize);
@@ -161,10 +160,10 @@ namespace MadWizard.WinUSBNet.API
private static extern bool SetupDiGetDeviceRegistryProperty(IntPtr DeviceInfoSet, ref SP_DEVINFO_DATA DeviceInfoData, SPDRP Property, IntPtr PropertyRegDataType, IntPtr PropertyBuffer, uint PropertyBufferSize, out UInt32 RequiredSize);
[DllImport("setupapi.dll", CharSet = CharSet.Unicode, SetLastError = true)]
static extern unsafe bool SetupDiGetDeviceProperty(IntPtr deviceInfoSet, ref SP_DEVINFO_DATA DeviceInfoData, ref DEVPROPKEY propertyKey, out UInt32 propertyType, byte[] propertyBuffer, Int32 propertyBufferSize, out int requiredSize, UInt32 flags);
private static extern unsafe bool SetupDiGetDeviceProperty(IntPtr deviceInfoSet, ref SP_DEVINFO_DATA DeviceInfoData, ref DEVPROPKEY propertyKey, out UInt32 propertyType, byte[] propertyBuffer, Int32 propertyBufferSize, out int requiredSize, UInt32 flags);
[DllImport("setupapi.dll", SetLastError = true, CharSet = CharSet.Unicode)]
private static extern IntPtr SetupDiGetClassDevs(ref System.Guid ClassGuid, IntPtr Enumerator, IntPtr hwndParent, Int32 Flags);
private static extern IntPtr SetupDiGetClassDevs(ref Guid ClassGuid, IntPtr Enumerator, IntPtr hwndParent, Int32 Flags);
[DllImport("setupapi.dll", SetLastError = true, CharSet = CharSet.Unicode)]
private static extern bool SetupDiGetDeviceInterfaceDetail(IntPtr DeviceInfoSet, ref SP_DEVICE_INTERFACE_DATA DeviceInterfaceData, IntPtr DeviceInterfaceDetailData, Int32 DeviceInterfaceDetailDataSize, ref Int32 RequiredSize, ref SP_DEVINFO_DATA DeviceInfoData);
+1 -3
View File
@@ -18,7 +18,6 @@ namespace MadWizard.WinUSBNet.API
/// <summary>
/// API declarations relating to file I/O (and used by WinUsb).
/// </summary>
sealed internal class FileIO
{
public const Int32 FILE_ATTRIBUTE_NORMAL = 0X80;
@@ -27,7 +26,7 @@ namespace MadWizard.WinUSBNet.API
public const Int32 FILE_SHARE_WRITE = 2;
public const UInt32 GENERIC_READ = 0X80000000;
public const UInt32 GENERIC_WRITE = 0X40000000;
public static readonly IntPtr INVALID_HANDLE_VALUE = new IntPtr(-1);
public static readonly IntPtr INVALID_HANDLE_VALUE = new(-1);
public const Int32 OPEN_EXISTING = 3;
public const Int32 ERROR_IO_PENDING = 997;
@@ -35,5 +34,4 @@ namespace MadWizard.WinUSBNet.API
[DllImport("kernel32.dll", SetLastError = true, CharSet = CharSet.Unicode)]
public static extern SafeFileHandle CreateFile(String lpFileName, UInt32 dwDesiredAccess, Int32 dwShareMode, IntPtr lpSecurityAttributes, Int32 dwCreationDisposition, Int32 dwFlagsAndAttributes, Int32 hTemplateFile);
}
}
+77 -37
View File
@@ -20,7 +20,7 @@ namespace MadWizard.WinUSBNet.API
/// <summary>
/// Wrapper for a WinUSB device dealing with the WinUSB and additional interface handles
/// </summary>
partial class WinUSBDevice : IDisposable
internal partial class WinUSBDevice : IDisposable
{
private bool _disposed = false;
private SafeFileHandle _deviceHandle;
@@ -44,7 +44,9 @@ namespace MadWizard.WinUSBNet.API
private void CheckNotDisposed()
{
if (_disposed)
{
throw new ObjectDisposedException("USB device object has been disposed.");
}
}
// TODO: check if not disposed on methods (although this is already checked by USBDevice)
@@ -52,13 +54,18 @@ namespace MadWizard.WinUSBNet.API
protected virtual void Dispose(bool disposing)
{
if (_disposed)
{
return;
}
if (disposing)
{
// Dispose managed resources
if (_deviceHandle != null && !_deviceHandle.IsInvalid)
if (_deviceHandle?.IsInvalid == false)
{
_deviceHandle.Dispose();
}
_deviceHandle = null;
}
@@ -77,40 +84,51 @@ namespace MadWizard.WinUSBNet.API
_addInterfaces = null;
}
if (_winUsbHandle != IntPtr.Zero)
{
WinUsb_Free(_winUsbHandle);
}
_winUsbHandle = IntPtr.Zero;
}
public USB_DEVICE_DESCRIPTOR GetDeviceDescriptor()
{
USB_DEVICE_DESCRIPTOR deviceDesc;
uint transfered;
uint size = (uint)Marshal.SizeOf(typeof(USB_DEVICE_DESCRIPTOR));
bool success = WinUsb_GetDescriptor(_winUsbHandle, USB_DEVICE_DESCRIPTOR_TYPE,
0, 0, out deviceDesc, size, out transfered);
0, 0, out USB_DEVICE_DESCRIPTOR deviceDesc, size, out uint transfered);
if (!success)
{
throw APIException.Win32("Failed to get USB device descriptor.");
}
if (transfered != size)
{
throw APIException.Win32("Incomplete USB device descriptor.");
}
return deviceDesc;
}
private int ReadStringDescriptor(byte index, ushort languageID, byte[] buffer)
{
uint transfered;
bool success = WinUsb_GetDescriptor(_winUsbHandle, USB_STRING_DESCRIPTOR_TYPE,
index, languageID, buffer, (uint)buffer.Length, out transfered);
index, languageID, buffer, (uint)buffer.Length, out uint transfered);
if (!success)
{
throw APIException.Win32("Failed to get USB string descriptor (" + index + ").");
}
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;
}
@@ -120,7 +138,9 @@ namespace MadWizard.WinUSBNet.API
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);
@@ -133,7 +153,10 @@ namespace MadWizard.WinUSBNet.API
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);
}
@@ -151,26 +174,30 @@ 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;
}
public void OpenDevice(string devicePathName)
{
try
{
_deviceHandle = FileIO.CreateFile(devicePathName,
(FileIO.GENERIC_WRITE | FileIO.GENERIC_READ),
FileIO.GENERIC_WRITE | FileIO.GENERIC_READ,
FileIO.FILE_SHARE_READ | FileIO.FILE_SHARE_WRITE,
IntPtr.Zero,
FileIO.OPEN_EXISTING,
FileIO.FILE_ATTRIBUTE_NORMAL | FileIO.FILE_FLAG_OVERLAPPED,
0);
if (_deviceHandle.IsInvalid)
{
throw APIException.Win32("Failed to open WinUSB device handle.");
InitializeDevice();
}
InitializeDevice();
}
catch (Exception)
{
@@ -187,7 +214,10 @@ namespace MadWizard.WinUSBNet.API
private IntPtr InterfaceHandle(int index)
{
if (index == 0)
{
return _winUsbHandle;
}
return _addInterfaces[index - 1];
}
@@ -195,7 +225,7 @@ namespace MadWizard.WinUSBNet.API
{
get
{
return 1 + (_addInterfaces == null ? 0 : _addInterfaces.Length);
return 1 + ((_addInterfaces?.Length) ?? 0);
}
}
@@ -204,31 +234,33 @@ namespace MadWizard.WinUSBNet.API
var pipeList = new List<WINUSB_PIPE_INFORMATION>();
bool success = WinUsb_QueryInterfaceSettings(InterfaceHandle(interfaceIndex), 0, out descriptor);
if (!success)
{
throw APIException.Win32("Failed to get WinUSB device interface descriptor.");
}
IntPtr interfaceHandle = InterfaceHandle(interfaceIndex);
for (byte pipeIdx = 0; pipeIdx < descriptor.bNumEndpoints; pipeIdx++)
{
WINUSB_PIPE_INFORMATION pipeInfo;
success = WinUsb_QueryPipe(interfaceHandle, 0, pipeIdx, out pipeInfo);
success = WinUsb_QueryPipe(interfaceHandle, 0, pipeIdx, out WINUSB_PIPE_INFORMATION pipeInfo);
pipeList.Add(pipeInfo);
if (!success)
{
throw APIException.Win32("Failed to get WinUSB device pipe information.");
}
}
pipes = pipeList.ToArray();
}
private void InitializeDevice()
{
bool success;
success = WinUsb_Initialize(_deviceHandle, ref _winUsbHandle);
bool success = WinUsb_Initialize(_deviceHandle, ref _winUsbHandle);
if (!success)
{
throw APIException.Win32("Failed to initialize WinUSB handle. Device might not be connected.");
}
List<IntPtr> interfaces = new List<IntPtr>();
List<IntPtr> interfaces = new();
byte numAddInterfaces = 0;
byte idx = 0;
@@ -241,7 +273,9 @@ namespace MadWizard.WinUSBNet.API
if (!success)
{
if (Marshal.GetLastWin32Error() == ERROR_NO_MORE_ITEMS)
{
break;
}
throw APIException.Win32("Failed to enumerate interfaces for WinUSB device.");
}
@@ -278,7 +312,9 @@ namespace MadWizard.WinUSBNet.API
}
}
if (!success)
{
throw APIException.Win32("Failed to read pipe on WinUSB device.");
}
}
private unsafe void HandleOverlappedAPI(bool success, string errorMessage, NativeOverlapped* pOverlapped, USBAsyncResult result, int bytesTransfered)
@@ -301,12 +337,11 @@ namespace MadWizard.WinUSBNet.API
result.OnCompletion(true, null, bytesTransfered, false);
// is the callback still called in this case?? todo
}
}
public void ReadPipeOverlapped(int ifaceIndex, byte pipeID, byte[] buffer, int offset, int bytesToRead, USBAsyncResult result)
{
Overlapped overlapped = new Overlapped();
Overlapped overlapped = new();
overlapped.AsyncResult = result;
@@ -329,7 +364,7 @@ namespace MadWizard.WinUSBNet.API
public void WriteOverlapped(int ifaceIndex, byte pipeID, byte[] buffer, int offset, int bytesToWrite, USBAsyncResult result)
{
Overlapped overlapped = new Overlapped();
Overlapped overlapped = new();
overlapped.AsyncResult = result;
unsafe
@@ -347,12 +382,9 @@ namespace MadWizard.WinUSBNet.API
out bytesWritten, pOverlapped);
}
HandleOverlappedAPI(success, "Failed to asynchronously write pipe on WinUSB device.", pOverlapped, result, (int)bytesWritten);
}
}
public void ControlTransferOverlapped(byte requestType, byte request, ushort value, ushort index, ushort length, byte[] data, USBAsyncResult result)
{
uint bytesReturned = 0;
@@ -364,7 +396,7 @@ namespace MadWizard.WinUSBNet.API
setupPacket.Index = index;
setupPacket.Length = length;
Overlapped overlapped = new Overlapped();
Overlapped overlapped = new();
overlapped.AsyncResult = result;
unsafe
@@ -405,16 +437,18 @@ namespace MadWizard.WinUSBNet.API
{
bool success = WinUsb_AbortPipe(InterfaceHandle(ifaceIndex), pipeID);
if (!success)
{
throw APIException.Win32("Failed to abort pipe on WinUSB device.");
}
}
public void ResetPipe(int ifaceIndex, byte pipeID)
{
bool success = WinUsb_ResetPipe(InterfaceHandle(ifaceIndex), pipeID);
if (!success)
{
throw APIException.Win32("Failed to reset pipe on WinUSB device.");
}
}
public void WritePipe(int ifaceIndex, byte pipeID, byte[] buffer, int offset, int length)
@@ -432,15 +466,18 @@ namespace MadWizard.WinUSBNet.API
}
}
if (!success || (bytesWritten != length))
{
throw APIException.Win32("Failed to write pipe on WinUSB device.");
}
}
public void FlushPipe(int ifaceIndex, byte pipeID)
{
bool success = WinUsb_FlushPipe(InterfaceHandle(ifaceIndex), pipeID);
if (!success)
{
throw APIException.Win32("Failed to flush pipe on WinUSB device.");
}
}
public void SetPipePolicy(int ifaceIndex, byte pipeID, POLICY_TYPE policyType, bool value)
@@ -448,41 +485,44 @@ namespace MadWizard.WinUSBNet.API
byte byteVal = (byte)(value ? 1 : 0);
bool success = WinUsb_SetPipePolicy(InterfaceHandle(ifaceIndex), pipeID, (uint)policyType, 1, ref byteVal);
if (!success)
{
throw APIException.Win32("Failed to set WinUSB pipe policy.");
}
}
public void SetPipePolicy(int ifaceIndex, byte pipeID, POLICY_TYPE policyType, uint value)
{
bool success = WinUsb_SetPipePolicy(InterfaceHandle(ifaceIndex), pipeID, (uint)policyType, 4, ref value);
if (!success)
{
throw APIException.Win32("Failed to set WinUSB pipe policy.");
}
}
public bool GetPipePolicyBool(int ifaceIndex, byte pipeID, POLICY_TYPE policyType)
{
byte result;
uint length = 1;
bool success = WinUsb_GetPipePolicy(InterfaceHandle(ifaceIndex), pipeID, (uint)policyType, ref length, out result);
bool success = WinUsb_GetPipePolicy(InterfaceHandle(ifaceIndex), pipeID, (uint)policyType, ref length, out byte result);
if (!success || length != 1)
{
throw APIException.Win32("Failed to get WinUSB pipe policy.");
}
return result != 0;
}
public uint GetPipePolicyUInt(int ifaceIndex, byte pipeID, POLICY_TYPE policyType)
{
uint result;
uint length = 4;
bool success = WinUsb_GetPipePolicy(InterfaceHandle(ifaceIndex), pipeID, (uint)policyType, ref length, out result);
bool success = WinUsb_GetPipePolicy(InterfaceHandle(ifaceIndex), pipeID, (uint)policyType, ref length, out uint result);
if (!success || length != 4)
{
throw APIException.Win32("Failed to get WinUSB pipe policy.");
}
return result;
}
}
+8 -14
View File
@@ -17,7 +17,7 @@ using System.Threading;
namespace MadWizard.WinUSBNet.API
{
[StructLayout(LayoutKind.Sequential)]
struct USB_DEVICE_DESCRIPTOR
internal struct USB_DEVICE_DESCRIPTOR
{
public byte bLength;
public byte bDescriptorType;
@@ -36,7 +36,7 @@ namespace MadWizard.WinUSBNet.API
};
[StructLayout(LayoutKind.Sequential)]
struct USB_CONFIGURATION_DESCRIPTOR
internal struct USB_CONFIGURATION_DESCRIPTOR
{
public byte bLength;
public byte bDescriptorType;
@@ -49,7 +49,7 @@ namespace MadWizard.WinUSBNet.API
}
[StructLayout(LayoutKind.Sequential)]
struct USB_INTERFACE_DESCRIPTOR
internal struct USB_INTERFACE_DESCRIPTOR
{
public byte bLength;
public byte bDescriptorType;
@@ -61,7 +61,7 @@ namespace MadWizard.WinUSBNet.API
public byte bInterfaceProtocol;
public byte iInterface;
};
enum USBD_PIPE_TYPE : int
internal enum USBD_PIPE_TYPE : int
{
UsbdPipeTypeControl,
UsbdPipeTypeIsochronous,
@@ -69,7 +69,7 @@ namespace MadWizard.WinUSBNet.API
UsbdPipeTypeInterrupt,
}
[StructLayout(LayoutKind.Sequential)]
struct WINUSB_PIPE_INFORMATION
internal struct WINUSB_PIPE_INFORMATION
{
public USBD_PIPE_TYPE PipeType;
public byte PipeId;
@@ -77,7 +77,7 @@ namespace MadWizard.WinUSBNet.API
public byte Interval;
}
enum POLICY_TYPE : int
internal enum POLICY_TYPE : int
{
SHORT_PACKET_TERMINATE = 1,
AUTO_CLEAR_STALL,
@@ -88,10 +88,9 @@ namespace MadWizard.WinUSBNet.API
RAW_IO,
}
partial class WinUSBDevice
internal partial class WinUSBDevice
{
private const UInt32 DEVICE_SPEED = ((UInt32)(1));
private const UInt32 DEVICE_SPEED = 1;
private enum USB_DEVICE_SPEED : int
{
@@ -163,19 +162,15 @@ namespace MadWizard.WinUSBNet.API
[DllImport("winusb.dll", SetLastError = true)]
private static unsafe extern bool WinUsb_WritePipe(IntPtr InterfaceHandle, byte PipeID, byte* pBuffer, uint BufferLength, out uint LengthTransferred, NativeOverlapped* pOverlapped);
[DllImport("kernel32.dll", SetLastError = true)]
private static unsafe extern bool CancelIo(IntPtr hFile);
[DllImport("kernel32.dll", SetLastError = true)]
private static unsafe extern bool CancelIoEx(IntPtr hFile, NativeOverlapped* pOverlapped);
[DllImport("winusb.dll", SetLastError = true)]
private static unsafe extern bool WinUsb_ResetPipe(IntPtr InterfaceHandle, byte PipeID);
[DllImport("winusb.dll", SetLastError = true)]
private static extern bool WinUsb_FlushPipe(IntPtr InterfaceHandle, byte PipeID);
@@ -200,6 +195,5 @@ namespace MadWizard.WinUSBNet.API
private const int USB_STRING_DESCRIPTOR_TYPE = 0x03;
private const int ERROR_NO_MORE_ITEMS = 259;
}
}