mirror of
https://github.com/aaru-dps/Aaru.git
synced 2025-12-16 19:24:25 +00:00
Refactor USB functions classes.
This commit is contained in:
@@ -1,4 +1,4 @@
|
||||
// /***************************************************************************
|
||||
// /***************************************************************************
|
||||
// The Disc Image Chef
|
||||
// ----------------------------------------------------------------------------
|
||||
//
|
||||
@@ -45,7 +45,7 @@ namespace DiscImageChef.Devices.Windows
|
||||
/// <summary>
|
||||
/// Implements functions for getting and accesing information from the USB bus
|
||||
/// </summary>
|
||||
static partial class Usb
|
||||
internal static partial class Usb
|
||||
{
|
||||
private const int IOCTL_STORAGE_GET_DEVICE_NUMBER = 0x2D1080;
|
||||
internal const string GuidDevinterfaceDisk = "53f56307-b6bf-11d0-94f2-00a0c91efb8b";
|
||||
@@ -59,9 +59,9 @@ namespace DiscImageChef.Devices.Windows
|
||||
/// <returns>List of usb devices</returns>
|
||||
internal static List<UsbDevice> GetConnectedDevices()
|
||||
{
|
||||
List<UsbDevice> devList = new List<UsbDevice>();
|
||||
var devList = new List<UsbDevice>();
|
||||
|
||||
foreach(UsbController controller in GetHostControllers()) ListHub(controller.GetRootHub(), devList);
|
||||
foreach (var controller in GetHostControllers()) ListHub(controller.GetRootHub(), devList);
|
||||
|
||||
return devList;
|
||||
}
|
||||
@@ -71,14 +71,16 @@ namespace DiscImageChef.Devices.Windows
|
||||
/// </summary>
|
||||
/// <param name="hub">Hub</param>
|
||||
/// <param name="devList">Device list</param>
|
||||
static void ListHub(UsbHub hub, ICollection<UsbDevice> devList)
|
||||
private static void ListHub(UsbHub hub, ICollection<UsbDevice> devList)
|
||||
{
|
||||
foreach(UsbPort port in hub.GetPorts())
|
||||
if(port.IsHub)
|
||||
foreach (var port in hub.GetPorts())
|
||||
if (port.IsHub)
|
||||
{
|
||||
ListHub(port.GetHub(), devList);
|
||||
}
|
||||
else
|
||||
{
|
||||
if(port.IsDeviceConnected) devList.Add(port.GetDevice());
|
||||
if (port.IsDeviceConnected) devList.Add(port.GetDevice());
|
||||
}
|
||||
}
|
||||
|
||||
@@ -91,10 +93,10 @@ namespace DiscImageChef.Devices.Windows
|
||||
{
|
||||
UsbDevice foundDevice = null;
|
||||
|
||||
foreach(UsbController controller in GetHostControllers())
|
||||
foreach (var controller in GetHostControllers())
|
||||
{
|
||||
SearchHubDriverKeyName(controller.GetRootHub(), ref foundDevice, driverKeyName);
|
||||
if(foundDevice != null) break;
|
||||
if (foundDevice != null) break;
|
||||
}
|
||||
|
||||
return foundDevice;
|
||||
@@ -106,17 +108,19 @@ namespace DiscImageChef.Devices.Windows
|
||||
/// <param name="hub">Hub</param>
|
||||
/// <param name="foundDevice">UsbDevice</param>
|
||||
/// <param name="driverKeyName">DriverKeyName</param>
|
||||
static void SearchHubDriverKeyName(UsbHub hub, ref UsbDevice foundDevice, string driverKeyName)
|
||||
private static void SearchHubDriverKeyName(UsbHub hub, ref UsbDevice foundDevice, string driverKeyName)
|
||||
{
|
||||
foreach(UsbPort port in hub.GetPorts())
|
||||
if(port.IsHub)
|
||||
foreach (var port in hub.GetPorts())
|
||||
if (port.IsHub)
|
||||
{
|
||||
SearchHubDriverKeyName(port.GetHub(), ref foundDevice, driverKeyName);
|
||||
}
|
||||
else
|
||||
{
|
||||
if(!port.IsDeviceConnected) continue;
|
||||
if (!port.IsDeviceConnected) continue;
|
||||
|
||||
UsbDevice device = port.GetDevice();
|
||||
if(device.DeviceDriverKey != driverKeyName) continue;
|
||||
var device = port.GetDevice();
|
||||
if (device.DeviceDriverKey != driverKeyName) continue;
|
||||
|
||||
foundDevice = device;
|
||||
break;
|
||||
@@ -128,14 +132,14 @@ namespace DiscImageChef.Devices.Windows
|
||||
/// </summary>
|
||||
/// <param name="instanceId">Device instance ID</param>
|
||||
/// <returns>USB device</returns>
|
||||
static UsbDevice FindDeviceByInstanceId(string instanceId)
|
||||
private static UsbDevice FindDeviceByInstanceId(string instanceId)
|
||||
{
|
||||
UsbDevice foundDevice = null;
|
||||
|
||||
foreach(UsbController controller in GetHostControllers())
|
||||
foreach (var controller in GetHostControllers())
|
||||
{
|
||||
SearchHubInstanceId(controller.GetRootHub(), ref foundDevice, instanceId);
|
||||
if(foundDevice != null) break;
|
||||
if (foundDevice != null) break;
|
||||
}
|
||||
|
||||
return foundDevice;
|
||||
@@ -147,17 +151,19 @@ namespace DiscImageChef.Devices.Windows
|
||||
/// <param name="hub">Hub</param>
|
||||
/// <param name="foundDevice">USB device</param>
|
||||
/// <param name="instanceId">Device instance ID</param>
|
||||
static void SearchHubInstanceId(UsbHub hub, ref UsbDevice foundDevice, string instanceId)
|
||||
private static void SearchHubInstanceId(UsbHub hub, ref UsbDevice foundDevice, string instanceId)
|
||||
{
|
||||
foreach(UsbPort port in hub.GetPorts())
|
||||
if(port.IsHub)
|
||||
foreach (var port in hub.GetPorts())
|
||||
if (port.IsHub)
|
||||
{
|
||||
SearchHubInstanceId(port.GetHub(), ref foundDevice, instanceId);
|
||||
}
|
||||
else
|
||||
{
|
||||
if(!port.IsDeviceConnected) continue;
|
||||
if (!port.IsDeviceConnected) continue;
|
||||
|
||||
UsbDevice device = port.GetDevice();
|
||||
if(device.InstanceId != instanceId) continue;
|
||||
var device = port.GetDevice();
|
||||
if (device.InstanceId != instanceId) continue;
|
||||
|
||||
foundDevice = device;
|
||||
break;
|
||||
@@ -165,10 +171,10 @@ namespace DiscImageChef.Devices.Windows
|
||||
}
|
||||
|
||||
[DllImport("setupapi.dll")]
|
||||
static extern int CM_Get_Parent(out IntPtr pdnDevInst, IntPtr dnDevInst, int ulFlags);
|
||||
private static extern int CM_Get_Parent(out IntPtr pdnDevInst, IntPtr dnDevInst, int ulFlags);
|
||||
|
||||
[DllImport("setupapi.dll", CharSet = CharSet.Auto)]
|
||||
static extern int CM_Get_Device_ID(IntPtr dnDevInst, IntPtr buffer, int bufferLen, int ulFlags);
|
||||
private static extern int CM_Get_Device_ID(IntPtr dnDevInst, IntPtr buffer, int bufferLen, int ulFlags);
|
||||
|
||||
/// <summary>
|
||||
/// Find a device based upon a Drive Letter
|
||||
@@ -181,7 +187,7 @@ namespace DiscImageChef.Devices.Windows
|
||||
// We start by getting the unique DeviceNumber of the given
|
||||
// DriveLetter. We'll use this later to find a matching
|
||||
// DevicePath "symbolic name"
|
||||
int devNum = GetDeviceNumber(@"\\.\" + driveLetter.TrimEnd('\\'));
|
||||
var devNum = GetDeviceNumber(@"\\.\" + driveLetter.TrimEnd('\\'));
|
||||
return devNum < 0 ? null : FindDeviceNumber(devNum, deviceGuid);
|
||||
}
|
||||
|
||||
@@ -196,7 +202,7 @@ namespace DiscImageChef.Devices.Windows
|
||||
// We start by getting the unique DeviceNumber of the given
|
||||
// DriveLetter. We'll use this later to find a matching
|
||||
// DevicePath "symbolic name"
|
||||
int devNum = GetDeviceNumber(drivePath);
|
||||
var devNum = GetDeviceNumber(drivePath);
|
||||
return devNum < 0 ? null : FindDeviceNumber(devNum, deviceGuid);
|
||||
}
|
||||
|
||||
@@ -206,50 +212,50 @@ namespace DiscImageChef.Devices.Windows
|
||||
/// <param name="devNum">Device Number</param>
|
||||
/// <param name="deviceGuid">Device GUID</param>
|
||||
/// <returns>USB device</returns>
|
||||
static UsbDevice FindDeviceNumber(int devNum, string deviceGuid)
|
||||
private static UsbDevice FindDeviceNumber(int devNum, string deviceGuid)
|
||||
{
|
||||
UsbDevice foundDevice = null;
|
||||
string instanceId = "";
|
||||
var instanceId = "";
|
||||
|
||||
Guid diskGuid = new Guid(deviceGuid);
|
||||
var diskGuid = new Guid(deviceGuid);
|
||||
|
||||
// We start at the "root" of the device tree and look for all
|
||||
// devices that match the interface GUID of a disk
|
||||
IntPtr h = SetupDiGetClassDevs(ref diskGuid, 0, IntPtr.Zero, DIGCF_PRESENT | DIGCF_DEVICEINTERFACE);
|
||||
if(h != INVALID_HANDLE_VALUE)
|
||||
var h = SetupDiGetClassDevs(ref diskGuid, 0, IntPtr.Zero, DIGCF_PRESENT | DIGCF_DEVICEINTERFACE);
|
||||
if (h != INVALID_HANDLE_VALUE)
|
||||
{
|
||||
bool success;
|
||||
int i = 0;
|
||||
var i = 0;
|
||||
do
|
||||
{
|
||||
// create a Device Interface Data structure
|
||||
SpDeviceInterfaceData dia = new SpDeviceInterfaceData();
|
||||
var dia = new SpDeviceInterfaceData();
|
||||
dia.cbSize = Marshal.SizeOf(dia);
|
||||
|
||||
// start the enumeration
|
||||
success = SetupDiEnumDeviceInterfaces(h, IntPtr.Zero, ref diskGuid, i, ref dia);
|
||||
if(success)
|
||||
if (success)
|
||||
{
|
||||
// build a DevInfo Data structure
|
||||
SpDevinfoData da = new SpDevinfoData();
|
||||
var da = new SpDevinfoData();
|
||||
da.cbSize = Marshal.SizeOf(da);
|
||||
|
||||
// build a Device Interface Detail Data structure
|
||||
SpDeviceInterfaceDetailData didd =
|
||||
var didd =
|
||||
new SpDeviceInterfaceDetailData {cbSize = 4 + Marshal.SystemDefaultCharSize}; // trust me :)
|
||||
|
||||
// now we can get some more detailed information
|
||||
int nRequiredSize = 0;
|
||||
const int N_BYTES = BUFFER_SIZE;
|
||||
if(SetupDiGetDeviceInterfaceDetail(h, ref dia, ref didd, N_BYTES, ref nRequiredSize, ref da))
|
||||
if(GetDeviceNumber(didd.DevicePath) == devNum)
|
||||
var nRequiredSize = 0;
|
||||
const int N_BYTES = BUFFER_SIZE;
|
||||
if (SetupDiGetDeviceInterfaceDetail(h, ref dia, ref didd, N_BYTES, ref nRequiredSize, ref da))
|
||||
if (GetDeviceNumber(didd.DevicePath) == devNum)
|
||||
{
|
||||
// current InstanceID is at the "USBSTOR" level, so we
|
||||
// need up "move up" one level to get to the "USB" level
|
||||
CM_Get_Parent(out IntPtr ptrPrevious, da.DevInst, 0);
|
||||
CM_Get_Parent(out var ptrPrevious, da.DevInst, 0);
|
||||
|
||||
// Now we get the InstanceID of the USB level device
|
||||
IntPtr ptrInstanceBuf = Marshal.AllocHGlobal(N_BYTES);
|
||||
var ptrInstanceBuf = Marshal.AllocHGlobal(N_BYTES);
|
||||
CM_Get_Device_ID(ptrPrevious, ptrInstanceBuf, N_BYTES, 0);
|
||||
instanceId = Marshal.PtrToStringAuto(ptrInstanceBuf);
|
||||
|
||||
@@ -260,14 +266,13 @@ namespace DiscImageChef.Devices.Windows
|
||||
}
|
||||
|
||||
i++;
|
||||
}
|
||||
while(success);
|
||||
} while (success);
|
||||
|
||||
SetupDiDestroyDeviceInfoList(h);
|
||||
}
|
||||
|
||||
// Did we find an InterfaceID of a USB device?
|
||||
if(instanceId?.StartsWith("USB\\", StringComparison.Ordinal) == true)
|
||||
if (instanceId?.StartsWith("USB\\", StringComparison.Ordinal) == true)
|
||||
foundDevice = FindDeviceByInstanceId(instanceId);
|
||||
return foundDevice;
|
||||
}
|
||||
@@ -277,20 +282,20 @@ namespace DiscImageChef.Devices.Windows
|
||||
/// </summary>
|
||||
/// <param name="devicePath">Device path</param>
|
||||
/// <returns>Device number</returns>
|
||||
static int GetDeviceNumber(string devicePath)
|
||||
private static int GetDeviceNumber(string devicePath)
|
||||
{
|
||||
int ans = -1;
|
||||
var ans = -1;
|
||||
|
||||
IntPtr h = CreateFile(devicePath.TrimEnd('\\'), 0, 0, IntPtr.Zero, OPEN_EXISTING, 0, IntPtr.Zero);
|
||||
if(h == INVALID_HANDLE_VALUE) return ans;
|
||||
var h = CreateFile(devicePath.TrimEnd('\\'), 0, 0, IntPtr.Zero, OPEN_EXISTING, 0, IntPtr.Zero);
|
||||
if (h == INVALID_HANDLE_VALUE) return ans;
|
||||
|
||||
StorageDeviceNumber sdn = new StorageDeviceNumber();
|
||||
int nBytes = Marshal.SizeOf(sdn);
|
||||
IntPtr ptrSdn = Marshal.AllocHGlobal(nBytes);
|
||||
var sdn = new StorageDeviceNumber();
|
||||
var nBytes = Marshal.SizeOf(sdn);
|
||||
var ptrSdn = Marshal.AllocHGlobal(nBytes);
|
||||
|
||||
if(DeviceIoControl(h, IOCTL_STORAGE_GET_DEVICE_NUMBER, IntPtr.Zero, 0, ptrSdn, nBytes, out _, IntPtr.Zero))
|
||||
if (DeviceIoControl(h, IOCTL_STORAGE_GET_DEVICE_NUMBER, IntPtr.Zero, 0, ptrSdn, nBytes, out _, IntPtr.Zero))
|
||||
{
|
||||
sdn = (StorageDeviceNumber)Marshal.PtrToStructure(ptrSdn, typeof(StorageDeviceNumber));
|
||||
sdn = (StorageDeviceNumber) Marshal.PtrToStructure(ptrSdn, typeof(StorageDeviceNumber));
|
||||
// just my way of combining the relevant parts of the
|
||||
// STORAGE_DEVICE_NUMBER into a single number
|
||||
ans = (sdn.DeviceType << 8) + sdn.DeviceNumber;
|
||||
@@ -302,11 +307,11 @@ namespace DiscImageChef.Devices.Windows
|
||||
}
|
||||
|
||||
[StructLayout(LayoutKind.Sequential)]
|
||||
struct StorageDeviceNumber
|
||||
private struct StorageDeviceNumber
|
||||
{
|
||||
internal int DeviceType;
|
||||
internal int DeviceNumber;
|
||||
internal int PartitionNumber;
|
||||
internal readonly int DeviceType;
|
||||
internal readonly int DeviceNumber;
|
||||
internal readonly int PartitionNumber;
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user