REFACTOR: All refactor in DiscImageChef.Devices.

This commit is contained in:
2017-12-22 03:13:43 +00:00
parent 49144eeb01
commit e87e058a11
40 changed files with 671 additions and 854 deletions

View File

@@ -32,6 +32,7 @@
// ****************************************************************************/
using System;
using System.Diagnostics.CodeAnalysis;
using System.Runtime.InteropServices;
using System.Text;
using DiscImageChef.Decoders.ATA;
@@ -39,6 +40,7 @@ using Microsoft.Win32.SafeHandles;
namespace DiscImageChef.Devices.Windows
{
[SuppressMessage("ReSharper", "UnusedParameter.Global")]
static class Command
{
/// <summary>
@@ -63,19 +65,23 @@ namespace DiscImageChef.Devices.Windows
if(buffer == null) return -1;
ScsiPassThroughDirectAndSenseBuffer sptdSb = new ScsiPassThroughDirectAndSenseBuffer();
sptdSb.sptd = new ScsiPassThroughDirect();
sptdSb.SenseBuf = new byte[32];
sptdSb.sptd.Cdb = new byte[16];
Array.Copy(cdb, sptdSb.sptd.Cdb, cdb.Length);
ScsiPassThroughDirectAndSenseBuffer sptdSb = new ScsiPassThroughDirectAndSenseBuffer
{
SenseBuf = new byte[32],
sptd = new ScsiPassThroughDirect
{
Cdb = new byte[16],
CdbLength = (byte)cdb.Length,
SenseInfoLength = 32,
DataIn = direction,
DataTransferLength = (uint)buffer.Length,
TimeOutValue = timeout,
DataBuffer = Marshal.AllocHGlobal(buffer.Length)
}
};
sptdSb.sptd.Length = (ushort)Marshal.SizeOf(sptdSb.sptd);
sptdSb.sptd.CdbLength = (byte)cdb.Length;
sptdSb.sptd.SenseInfoLength = (byte)sptdSb.SenseBuf.Length;
sptdSb.sptd.DataIn = direction;
sptdSb.sptd.DataTransferLength = (uint)buffer.Length;
sptdSb.sptd.TimeOutValue = timeout;
sptdSb.sptd.DataBuffer = Marshal.AllocHGlobal(buffer.Length);
sptdSb.sptd.SenseInfoOffset = (uint)Marshal.SizeOf(sptdSb.sptd);
Array.Copy(cdb, sptdSb.sptd.Cdb, cdb.Length);
uint k = 0;
int error = 0;
@@ -454,8 +460,6 @@ namespace DiscImageChef.Devices.Windows
if(buffer == null) return -1;
uint offsetForBuffer = (uint)(Marshal.SizeOf(typeof(AtaPassThroughDirect)) + Marshal.SizeOf(typeof(uint)));
IdePassThroughDirect iptd = new IdePassThroughDirect
{
CurrentTaskFile = new AtaTaskFile
@@ -504,10 +508,9 @@ namespace DiscImageChef.Devices.Windows
return error;
}
internal static uint GetDeviceNumber(SafeFileHandle deviceHandle)
static uint GetDeviceNumber(SafeFileHandle deviceHandle)
{
StorageDeviceNumber sdn = new StorageDeviceNumber();
sdn.deviceNumber = -1;
StorageDeviceNumber sdn = new StorageDeviceNumber {deviceNumber = -1};
uint k = 0;
if(!Extern.DeviceIoControlGetDeviceNumber(deviceHandle, WindowsIoctl.IoctlStorageGetDeviceNumber,
IntPtr.Zero, 0, ref sdn, (uint)Marshal.SizeOf(sdn), ref k,
@@ -533,11 +536,9 @@ namespace DiscImageChef.Devices.Windows
DeviceInterfaceData spdid = new DeviceInterfaceData();
spdid.cbSize = Marshal.SizeOf(spdid);
byte[] buffer;
while(true)
{
buffer = new byte[2048];
byte[] buffer = new byte[2048];
if(!Extern.SetupDiEnumDeviceInterfaces(hDevInfo, IntPtr.Zero, ref Consts.GuidDevinterfaceDisk, index,
ref spdid)) break;
@@ -595,9 +596,8 @@ namespace DiscImageChef.Devices.Windows
{
SffdiskQueryDeviceProtocolData queryData1 = new SffdiskQueryDeviceProtocolData();
queryData1.size = (ushort)Marshal.SizeOf(queryData1);
uint bytesReturned;
Extern.DeviceIoControl(fd, WindowsIoctl.IoctlSffdiskQueryDeviceProtocol, IntPtr.Zero, 0, ref queryData1,
queryData1.size, out bytesReturned, IntPtr.Zero);
queryData1.size, out _, IntPtr.Zero);
return queryData1.protocolGuid.Equals(Consts.GuidSffProtocolSd);
}
@@ -660,12 +660,11 @@ namespace DiscImageChef.Devices.Windows
Marshal.Copy(hBuf, commandB, 0, commandB.Length);
Marshal.FreeHGlobal(hBuf);
uint bytesReturned;
int error = 0;
DateTime start = DateTime.Now;
sense = !Extern.DeviceIoControl(fd, WindowsIoctl.IoctlSffdiskDeviceCommand, commandB,
(uint)commandB.Length, commandB, (uint)commandB.Length,
out bytesReturned, IntPtr.Zero);
out _, IntPtr.Zero);
DateTime end = DateTime.Now;
if(sense) error = Marshal.GetLastWin32Error();

View File

@@ -32,6 +32,7 @@
// ****************************************************************************/
using System;
using System.Diagnostics.CodeAnalysis;
namespace DiscImageChef.Devices.Windows
{
@@ -403,6 +404,7 @@ namespace DiscImageChef.Devices.Windows
Max = 3
}
[SuppressMessage("ReSharper", "InconsistentNaming")]
enum StorageBusType
{
Unknown = 0,
@@ -471,6 +473,7 @@ namespace DiscImageChef.Devices.Windows
MultiBlockNoCmd12
}
[SuppressMessage("ReSharper", "InconsistentNaming")]
enum SdResponseType : uint
{
Unspecified,

View File

@@ -32,6 +32,7 @@
using System;
using System.Collections.Generic;
using System.Diagnostics.CodeAnalysis;
using System.Linq;
using System.Management;
using System.Runtime.InteropServices;
@@ -42,16 +43,17 @@ namespace DiscImageChef.Devices.Windows
{
static class ListDevices
{
internal static string HexStringToString(string hex)
static string HexStringToString(string hex)
{
StringBuilder result = new StringBuilder();
const string hextable = "0123456789abcdef";
const string HEXTABLE = "0123456789abcdef";
for(int i = 0; i < hex.Length / 2; i++) result.Append((char)(16 * hextable.IndexOf(hex[2 * i]) + hextable.IndexOf(hex[2 * i + 1])));
for(int i = 0; i < hex.Length / 2; i++) result.Append((char)(16 * HEXTABLE.IndexOf(hex[2 * i]) + HEXTABLE.IndexOf(hex[2 * i + 1])));
return result.ToString();
}
[SuppressMessage("ReSharper", "RedundantCatchClause")]
internal static DeviceInfo[] GetList()
{
List<string> deviceIDs = new List<string>();
@@ -74,7 +76,7 @@ namespace DiscImageChef.Devices.Windows
deviceIDs.AddRange(from ManagementObject drive in objCol select (string)drive["Drive"]);
}
catch(Exception ex)
catch(Exception)
{
#if DEBUG
throw;
@@ -94,10 +96,12 @@ namespace DiscImageChef.Devices.Windows
FileMode.OpenExisting, 0, IntPtr.Zero);
if(fd.IsInvalid) continue;
StoragePropertyQuery query = new StoragePropertyQuery();
query.PropertyId = StoragePropertyId.Device;
query.QueryType = StorageQueryType.Standard;
query.AdditionalParameters = new byte[1];
StoragePropertyQuery query = new StoragePropertyQuery
{
PropertyId = StoragePropertyId.Device,
QueryType = StorageQueryType.Standard,
AdditionalParameters = new byte[1]
};
//StorageDeviceDescriptor descriptor = new StorageDeviceDescriptor();
//descriptor.RawDeviceProperties = new byte[16384];
@@ -118,19 +122,21 @@ namespace DiscImageChef.Devices.Windows
if(hasError && error != 0) continue;
StorageDeviceDescriptor descriptor = new StorageDeviceDescriptor();
descriptor.Version = BitConverter.ToUInt32(descriptorB, 0);
descriptor.Size = BitConverter.ToUInt32(descriptorB, 4);
descriptor.DeviceType = descriptorB[8];
descriptor.DeviceTypeModifier = descriptorB[9];
descriptor.RemovableMedia = BitConverter.ToBoolean(descriptorB, 10);
descriptor.CommandQueueing = BitConverter.ToBoolean(descriptorB, 11);
descriptor.VendorIdOffset = BitConverter.ToInt32(descriptorB, 12);
descriptor.ProductIdOffset = BitConverter.ToInt32(descriptorB, 16);
descriptor.ProductRevisionOffset = BitConverter.ToInt32(descriptorB, 20);
descriptor.SerialNumberOffset = BitConverter.ToInt32(descriptorB, 24);
descriptor.BusType = (StorageBusType)BitConverter.ToUInt32(descriptorB, 28);
descriptor.RawPropertiesLength = BitConverter.ToUInt32(descriptorB, 32);
StorageDeviceDescriptor descriptor = new StorageDeviceDescriptor
{
Version = BitConverter.ToUInt32(descriptorB, 0),
Size = BitConverter.ToUInt32(descriptorB, 4),
DeviceType = descriptorB[8],
DeviceTypeModifier = descriptorB[9],
RemovableMedia = BitConverter.ToBoolean(descriptorB, 10),
CommandQueueing = BitConverter.ToBoolean(descriptorB, 11),
VendorIdOffset = BitConverter.ToInt32(descriptorB, 12),
ProductIdOffset = BitConverter.ToInt32(descriptorB, 16),
ProductRevisionOffset = BitConverter.ToInt32(descriptorB, 20),
SerialNumberOffset = BitConverter.ToInt32(descriptorB, 24),
BusType = (StorageBusType)BitConverter.ToUInt32(descriptorB, 28),
RawPropertiesLength = BitConverter.ToUInt32(descriptorB, 32)
};
DeviceInfo info = new DeviceInfo {Path = physId, Bus = descriptor.BusType.ToString()};

View File

@@ -32,11 +32,13 @@
// ****************************************************************************/
using System;
using System.Diagnostics.CodeAnalysis;
using System.Runtime.InteropServices;
namespace DiscImageChef.Devices.Windows
{
[StructLayout(LayoutKind.Sequential)]
[SuppressMessage("ReSharper", "MemberCanBePrivate.Global")]
struct ScsiPassThroughDirect
{
public ushort Length;
@@ -62,6 +64,7 @@ namespace DiscImageChef.Devices.Windows
}
[StructLayout(LayoutKind.Sequential)]
[SuppressMessage("ReSharper", "MemberCanBePrivate.Global")]
struct AtaPassThroughDirect
{
/// <summary>
@@ -115,6 +118,7 @@ namespace DiscImageChef.Devices.Windows
}
[StructLayout(LayoutKind.Sequential)]
[SuppressMessage("ReSharper", "MemberCanBePrivate.Global")]
struct AtaPassThroughDirectWithBuffer
{
public AtaPassThroughDirect aptd;
@@ -123,6 +127,7 @@ namespace DiscImageChef.Devices.Windows
}
[StructLayout(LayoutKind.Explicit)]
[SuppressMessage("ReSharper", "MemberCanBePrivate.Global")]
struct AtaTaskFile
{
// Fields for commands sent
@@ -151,6 +156,7 @@ namespace DiscImageChef.Devices.Windows
}
[StructLayout(LayoutKind.Sequential)]
[SuppressMessage("ReSharper", "MemberCanBePrivate.Global")]
struct StorageDescriptorHeader
{
public uint Version;
@@ -193,6 +199,7 @@ namespace DiscImageChef.Devices.Windows
}
[StructLayout(LayoutKind.Sequential)]
[SuppressMessage("ReSharper", "MemberCanBePrivate.Global")]
struct StorageDeviceNumber
{
public int deviceType;
@@ -201,6 +208,7 @@ namespace DiscImageChef.Devices.Windows
}
[StructLayout(LayoutKind.Sequential)]
[SuppressMessage("ReSharper", "MemberCanBePrivate.Global")]
struct DeviceInfoData
{
public int cbSize;
@@ -210,6 +218,7 @@ namespace DiscImageChef.Devices.Windows
}
[StructLayout(LayoutKind.Sequential)]
[SuppressMessage("ReSharper", "MemberCanBePrivate.Global")]
struct DeviceInterfaceData
{
public int cbSize;
@@ -219,6 +228,7 @@ namespace DiscImageChef.Devices.Windows
}
[StructLayout(LayoutKind.Sequential)]
[SuppressMessage("ReSharper", "MemberCanBePrivate.Global")]
struct UsbSetupPacket
{
public byte bmRequest;
@@ -229,6 +239,7 @@ namespace DiscImageChef.Devices.Windows
}
[StructLayout(LayoutKind.Sequential)]
[SuppressMessage("ReSharper", "MemberCanBePrivate.Global")]
struct UsbDescriptorRequest
{
public int ConnectionIndex;
@@ -237,6 +248,7 @@ namespace DiscImageChef.Devices.Windows
}
[StructLayout(LayoutKind.Sequential)]
[SuppressMessage("ReSharper", "MemberCanBePrivate.Global")]
struct SffdiskQueryDeviceProtocolData
{
public ushort size;
@@ -245,6 +257,7 @@ namespace DiscImageChef.Devices.Windows
}
[StructLayout(LayoutKind.Sequential)]
[SuppressMessage("ReSharper", "MemberCanBePrivate.Global")]
struct SffdiskDeviceCommandData
{
public ushort size;

View File

@@ -28,18 +28,20 @@
//
// ----------------------------------------------------------------------------
// Copyright © 2011-2018 Natalia Portillo
// Copyright © 2007 Fort Hood TX, herethen, Public Domain
// ****************************************************************************/
using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Diagnostics.CodeAnalysis;
using System.Runtime.InteropServices;
using System.Text;
// Copyright "Fort Hood TX", internal domain, 2007
namespace DiscImageChef.Devices.Windows
{
partial class Usb
// TODO: Even after cleaning, refactoring and xml-documenting, this code needs some love
static partial class Usb
{
#region "API Region"
// ********************** Constants ************************
@@ -276,6 +278,7 @@ namespace DiscImageChef.Devices.Windows
// UCHAR bNumConfigurations;
//} USB_DEVICE_DESCRIPTOR, *PUSB_DEVICE_DESCRIPTOR ;
[StructLayout(LayoutKind.Sequential, Pack = 1)]
[SuppressMessage("ReSharper", "MemberCanBePrivate.Global")]
internal struct UsbDeviceDescriptor
{
internal byte bLength;
@@ -487,7 +490,7 @@ namespace DiscImageChef.Devices.Windows
//
// Return a list of USB Host Controllers
//
static internal ReadOnlyCollection<UsbController> GetHostControllers()
static IEnumerable<UsbController> GetHostControllers()
{
List<UsbController> hostList = new List<UsbController>();
Guid hostGuid = new Guid(GUID_DEVINTERFACE_HUBCONTROLLER);
@@ -503,8 +506,7 @@ namespace DiscImageChef.Devices.Windows
int i = 0;
do
{
UsbController host = new UsbController();
host.ControllerIndex = i;
UsbController host = new UsbController {ControllerIndex = i};
// create a Device Interface Data structure
SpDeviceInterfaceData dia = new SpDeviceInterfaceData();
@@ -519,13 +521,14 @@ namespace DiscImageChef.Devices.Windows
da.cbSize = Marshal.SizeOf(da);
// build a Device Interface Detail Data structure
SpDeviceInterfaceDetailData didd = new SpDeviceInterfaceDetailData();
didd.cbSize = 4 + Marshal.SystemDefaultCharSize; // trust me :)
SpDeviceInterfaceDetailData didd =
new SpDeviceInterfaceDetailData {cbSize = 4 + Marshal.SystemDefaultCharSize};
// trust me :)
// now we can get some more detailed information
int nRequiredSize = 0;
int nBytes = BUFFER_SIZE;
if(SetupDiGetDeviceInterfaceDetail(h, ref dia, ref didd, nBytes, ref nRequiredSize, ref da))
const int N_BYTES = BUFFER_SIZE;
if(SetupDiGetDeviceInterfaceDetail(h, ref dia, ref didd, N_BYTES, ref nRequiredSize, ref da))
{
host.ControllerDevicePath = didd.DevicePath;
@@ -554,7 +557,7 @@ namespace DiscImageChef.Devices.Windows
//
// The USB Host Controller Class
//
internal class UsbController
class UsbController
{
internal int ControllerIndex;
internal string ControllerDriverKeyName, ControllerDevicePath, ControllerDeviceDesc;
@@ -569,50 +572,35 @@ namespace DiscImageChef.Devices.Windows
}
// Return the index of the instance
internal int Index
{
get { return ControllerIndex; }
}
internal int Index => ControllerIndex;
// Return the Device Path, such as "\\?\pci#ven_10de&dev_005a&subsys_815a1043&rev_a2#3&267a616a&0&58#{3abf6f2d-71c4-462a-8a92-1e6861e6af27}"
internal string DevicePath
{
get { return ControllerDevicePath; }
}
internal string DevicePath => ControllerDevicePath;
// The DriverKeyName may be useful as a search key
internal string DriverKeyName
{
get { return ControllerDriverKeyName; }
}
internal string DriverKeyName => ControllerDriverKeyName;
// Return the Friendly Name, such as "VIA USB Enhanced Host Controller"
internal string Name
{
get { return ControllerDeviceDesc; }
}
internal string Name => ControllerDeviceDesc;
// Return Root Hub for this Controller
internal UsbHub GetRootHub()
{
IntPtr h, h2;
UsbHub root = new UsbHub();
root.HubIsRootHub = true;
root.HubDeviceDesc = "Root Hub";
UsbHub root = new UsbHub {HubIsRootHub = true, HubDeviceDesc = "Root Hub"};
// Open a handle to the Host Controller
h = CreateFile(ControllerDevicePath, GENERIC_WRITE, FILE_SHARE_WRITE, IntPtr.Zero, OPEN_EXISTING, 0,
IntPtr.Zero);
if(h.ToInt32() == INVALID_HANDLE_VALUE) return root;
int nBytesReturned;
UsbRootHubName hubName = new UsbRootHubName();
int nBytes = Marshal.SizeOf(hubName);
IntPtr ptrHubName = Marshal.AllocHGlobal(nBytes);
// get the Hub Name
if(DeviceIoControl(h, IOCTL_USB_GET_ROOT_HUB_NAME, ptrHubName, nBytes, ptrHubName, nBytes,
out nBytesReturned, IntPtr.Zero))
out _, IntPtr.Zero))
{
hubName = (UsbRootHubName)Marshal.PtrToStructure(ptrHubName, typeof(UsbRootHubName));
root.HubDevicePath = @"\\.\" + hubName.RootHubName;
@@ -625,15 +613,14 @@ namespace DiscImageChef.Devices.Windows
IntPtr.Zero);
if(h2.ToInt32() != INVALID_HANDLE_VALUE)
{
UsbNodeInformation nodeInfo = new UsbNodeInformation();
nodeInfo.NodeType = (int)UsbHubNode.UsbHub;
UsbNodeInformation nodeInfo = new UsbNodeInformation {NodeType = (int)UsbHubNode.UsbHub};
nBytes = Marshal.SizeOf(nodeInfo);
IntPtr ptrNodeInfo = Marshal.AllocHGlobal(nBytes);
Marshal.StructureToPtr(nodeInfo, ptrNodeInfo, true);
// get the Hub Information
if(DeviceIoControl(h2, IOCTL_USB_GET_NODE_INFORMATION, ptrNodeInfo, nBytes, ptrNodeInfo, nBytes,
out nBytesReturned, IntPtr.Zero))
out _, IntPtr.Zero))
{
nodeInfo = (UsbNodeInformation)Marshal.PtrToStructure(ptrNodeInfo,
typeof(UsbNodeInformation));
@@ -676,64 +663,34 @@ namespace DiscImageChef.Devices.Windows
}
// return Port Count
internal int PortCount
{
get { return HubPortCount; }
}
internal int PortCount => HubPortCount;
// return the Device Path, such as "\\?\pci#ven_10de&dev_005a&subsys_815a1043&rev_a2#3&267a616a&0&58#{3abf6f2d-71c4-462a-8a92-1e6861e6af27}"
internal string DevicePath
{
get { return HubDevicePath; }
}
internal string DevicePath => HubDevicePath;
// The DriverKey may be useful as a search key
internal string DriverKey
{
get { return HubDriverKey; }
}
internal string DriverKey => HubDriverKey;
// return the Friendly Name, such as "VIA USB Enhanced Host Controller"
internal string Name
{
get { return HubDeviceDesc; }
}
internal string Name => HubDeviceDesc;
// the device path of this device
internal string InstanceId
{
get { return HubInstanceId; }
}
internal string InstanceId => HubInstanceId;
// is is this a self-powered hub?
internal bool IsBusPowered
{
get { return HubIsBusPowered; }
}
internal bool IsBusPowered => HubIsBusPowered;
// is this a root hub?
internal bool IsRootHub
{
get { return HubIsRootHub; }
}
internal bool IsRootHub => HubIsRootHub;
internal string Manufacturer
{
get { return HubManufacturer; }
}
internal string Manufacturer => HubManufacturer;
internal string Product
{
get { return HubProduct; }
}
internal string Product => HubProduct;
internal string SerialNumber
{
get { return HubSerialNumber; }
}
internal string SerialNumber => HubSerialNumber;
// return a list of the down stream ports
internal ReadOnlyCollection<UsbPort> GetPorts()
internal IEnumerable<UsbPort> GetPorts()
{
List<UsbPort> portList = new List<UsbPort>();
@@ -750,13 +707,12 @@ namespace DiscImageChef.Devices.Windows
// BTW: Ports are numbered starting at 1
for(int i = 1; i <= HubPortCount; i++)
{
int nBytesReturned;
UsbNodeConnectionInformationEx nodeConnection = new UsbNodeConnectionInformationEx();
nodeConnection.ConnectionIndex = i;
UsbNodeConnectionInformationEx nodeConnection =
new UsbNodeConnectionInformationEx {ConnectionIndex = i};
Marshal.StructureToPtr(nodeConnection, ptrNodeConnection, true);
if(!DeviceIoControl(h, IOCTL_USB_GET_NODE_CONNECTION_INFORMATION_EX, ptrNodeConnection, nBytes,
ptrNodeConnection, nBytes, out nBytesReturned, IntPtr.Zero)) continue;
ptrNodeConnection, nBytes, out _, IntPtr.Zero)) continue;
nodeConnection =
(UsbNodeConnectionInformationEx)Marshal.PtrToStructure(ptrNodeConnection,
@@ -765,17 +721,17 @@ namespace DiscImageChef.Devices.Windows
));
// load up the USBPort class
UsbPort port = new UsbPort();
port.PortPortNumber = i;
port.PortHubDevicePath = HubDevicePath;
UsbConnectionStatus status = (UsbConnectionStatus)nodeConnection.ConnectionStatus;
port.PortStatus = status.ToString();
UsbDeviceSpeed speed = (UsbDeviceSpeed)nodeConnection.Speed;
port.PortSpeed = speed.ToString();
port.PortIsDeviceConnected =
nodeConnection.ConnectionStatus == (int)UsbConnectionStatus.DeviceConnected;
port.PortIsHub = Convert.ToBoolean(nodeConnection.DeviceIsHub);
port.PortDeviceDescriptor = nodeConnection.DeviceDescriptor;
UsbPort port = new UsbPort
{
PortPortNumber = i,
PortHubDevicePath = HubDevicePath,
PortStatus = ((UsbConnectionStatus)nodeConnection.ConnectionStatus).ToString(),
PortSpeed = ((UsbDeviceSpeed)nodeConnection.Speed).ToString(),
PortIsDeviceConnected =
nodeConnection.ConnectionStatus == (int)UsbConnectionStatus.DeviceConnected,
PortIsHub = Convert.ToBoolean(nodeConnection.DeviceIsHub),
PortDeviceDescriptor = nodeConnection.DeviceDescriptor
};
// add it to the list
portList.Add(port);
@@ -810,53 +766,36 @@ namespace DiscImageChef.Devices.Windows
}
// return Port Index of the Hub
internal int PortNumber
{
get { return PortPortNumber; }
}
internal int PortNumber => PortPortNumber;
// return the Device Path of the Hub
internal string HubDevicePath
{
get { return PortHubDevicePath; }
}
internal string HubDevicePath => PortHubDevicePath;
// the status (see USB_CONNECTION_STATUS above)
internal string Status
{
get { return PortStatus; }
}
internal string Status => PortStatus;
// the speed of the connection (see USB_DEVICE_SPEED above)
internal string Speed
{
get { return PortSpeed; }
}
internal string Speed => PortSpeed;
// is this a downstream external hub?
internal bool IsHub
{
get { return PortIsHub; }
}
internal bool IsHub => PortIsHub;
// is anybody home?
internal bool IsDeviceConnected
{
get { return PortIsDeviceConnected; }
}
internal bool IsDeviceConnected => PortIsDeviceConnected;
// return a down stream external hub
internal UsbDevice GetDevice()
{
if(!PortIsDeviceConnected) return null;
UsbDevice device = new UsbDevice();
// Copy over some values from the Port class
// Ya know, I've given some thought about making Device a derived class...
device.DevicePortNumber = PortPortNumber;
device.DeviceHubDevicePath = PortHubDevicePath;
device.DeviceDescriptor = PortDeviceDescriptor;
UsbDevice device = new UsbDevice
{
DevicePortNumber = PortPortNumber,
DeviceHubDevicePath = PortHubDevicePath,
DeviceDescriptor = PortDeviceDescriptor
};
// Open a handle to the Hub device
IntPtr h = CreateFile(PortHubDevicePath, GENERIC_WRITE, FILE_SHARE_WRITE, IntPtr.Zero, OPEN_EXISTING, 0,
@@ -875,12 +814,17 @@ namespace DiscImageChef.Devices.Windows
if(PortDeviceDescriptor.iManufacturer > 0)
{
// build a request for string descriptor
UsbDescriptorRequest request = new UsbDescriptorRequest();
request.ConnectionIndex = PortPortNumber;
request.SetupPacket.wValue =
(short)((USB_STRING_DESCRIPTOR_TYPE << 8) + PortDeviceDescriptor.iManufacturer);
UsbDescriptorRequest request = new UsbDescriptorRequest
{
ConnectionIndex = PortPortNumber,
SetupPacket =
{
// Language Code
wIndex = 0x409,
wValue = (short)((USB_STRING_DESCRIPTOR_TYPE << 8) + PortDeviceDescriptor.iManufacturer)
}
};
request.SetupPacket.wLength = (short)(nBytes - Marshal.SizeOf(request));
request.SetupPacket.wIndex = 0x409; // Language Code
// Geez, I wish C# had a Marshal.MemSet() method
IntPtr ptrRequest = Marshal.StringToHGlobalAuto(nullString);
Marshal.StructureToPtr(request, ptrRequest, true);
@@ -904,12 +848,17 @@ namespace DiscImageChef.Devices.Windows
if(PortDeviceDescriptor.iProduct > 0)
{
// build a request for string descriptor
UsbDescriptorRequest request = new UsbDescriptorRequest();
request.ConnectionIndex = PortPortNumber;
request.SetupPacket.wValue =
(short)((USB_STRING_DESCRIPTOR_TYPE << 8) + PortDeviceDescriptor.iProduct);
UsbDescriptorRequest request = new UsbDescriptorRequest
{
ConnectionIndex = PortPortNumber,
SetupPacket =
{
// Language Code
wIndex = 0x409,
wValue = (short)((USB_STRING_DESCRIPTOR_TYPE << 8) + PortDeviceDescriptor.iProduct)
}
};
request.SetupPacket.wLength = (short)(nBytes - Marshal.SizeOf(request));
request.SetupPacket.wIndex = 0x409; // Language Code
// Geez, I wish C# had a Marshal.MemSet() method
IntPtr ptrRequest = Marshal.StringToHGlobalAuto(nullString);
Marshal.StructureToPtr(request, ptrRequest, true);
@@ -930,12 +879,17 @@ namespace DiscImageChef.Devices.Windows
if(PortDeviceDescriptor.iSerialNumber > 0)
{
// build a request for string descriptor
UsbDescriptorRequest request = new UsbDescriptorRequest();
request.ConnectionIndex = PortPortNumber;
request.SetupPacket.wValue =
(short)((USB_STRING_DESCRIPTOR_TYPE << 8) + PortDeviceDescriptor.iSerialNumber);
UsbDescriptorRequest request = new UsbDescriptorRequest
{
ConnectionIndex = PortPortNumber,
SetupPacket =
{
// Language Code
wIndex = 0x409,
wValue = (short)((USB_STRING_DESCRIPTOR_TYPE << 8) + PortDeviceDescriptor.iSerialNumber)
}
};
request.SetupPacket.wLength = (short)(nBytes - Marshal.SizeOf(request));
request.SetupPacket.wIndex = 0x409; // Language Code
// Geez, I wish C# had a Marshal.MemSet() method
IntPtr ptrRequest = Marshal.StringToHGlobalAuto(nullString);
Marshal.StructureToPtr(request, ptrRequest, true);
@@ -955,11 +909,12 @@ namespace DiscImageChef.Devices.Windows
}
// build a request for configuration descriptor
UsbDescriptorRequest dcrRequest = new UsbDescriptorRequest();
dcrRequest.ConnectionIndex = PortPortNumber;
dcrRequest.SetupPacket.wValue = USB_CONFIGURATION_DESCRIPTOR_TYPE << 8;
UsbDescriptorRequest dcrRequest = new UsbDescriptorRequest
{
ConnectionIndex = PortPortNumber,
SetupPacket = {wIndex = 0, wValue = USB_CONFIGURATION_DESCRIPTOR_TYPE << 8}
};
dcrRequest.SetupPacket.wLength = (short)(nBytes - Marshal.SizeOf(dcrRequest));
dcrRequest.SetupPacket.wIndex = 0;
// Geez, I wish C# had a Marshal.MemSet() method
IntPtr dcrPtrRequest = Marshal.StringToHGlobalAuto(nullString);
Marshal.StructureToPtr(dcrRequest, dcrPtrRequest, true);
@@ -975,8 +930,8 @@ namespace DiscImageChef.Devices.Windows
Marshal.FreeHGlobal(dcrPtrRequest);
// Get the Driver Key Name (usefull in locating a device)
UsbNodeConnectionDriverkeyName driverKey = new UsbNodeConnectionDriverkeyName();
driverKey.ConnectionIndex = PortPortNumber;
UsbNodeConnectionDriverkeyName driverKey =
new UsbNodeConnectionDriverkeyName {ConnectionIndex = PortPortNumber};
nBytes = Marshal.SizeOf(driverKey);
IntPtr ptrDriverKey = Marshal.AllocHGlobal(nBytes);
Marshal.StructureToPtr(driverKey, ptrDriverKey, true);
@@ -1015,16 +970,14 @@ namespace DiscImageChef.Devices.Windows
IntPtr.Zero);
if(h.ToInt32() == INVALID_HANDLE_VALUE) return hub;
// Get the DevicePath for downstream hub
int nBytesReturned;
UsbNodeConnectionName nodeName = new UsbNodeConnectionName();
nodeName.ConnectionIndex = PortPortNumber;
UsbNodeConnectionName nodeName = new UsbNodeConnectionName {ConnectionIndex = PortPortNumber};
int nBytes = Marshal.SizeOf(nodeName);
IntPtr ptrNodeName = Marshal.AllocHGlobal(nBytes);
Marshal.StructureToPtr(nodeName, ptrNodeName, true);
// Use an IOCTL call to request the Node Name
if(DeviceIoControl(h, IOCTL_USB_GET_NODE_CONNECTION_NAME, ptrNodeName, nBytes, ptrNodeName, nBytes,
out nBytesReturned, IntPtr.Zero))
out _, IntPtr.Zero))
{
nodeName = (UsbNodeConnectionName)Marshal.PtrToStructure(ptrNodeName,
typeof(UsbNodeConnectionName));
@@ -1036,15 +989,14 @@ namespace DiscImageChef.Devices.Windows
IntPtr.Zero);
if(h2.ToInt32() != INVALID_HANDLE_VALUE)
{
UsbNodeInformation nodeInfo = new UsbNodeInformation();
nodeInfo.NodeType = (int)UsbHubNode.UsbHub;
UsbNodeInformation nodeInfo = new UsbNodeInformation {NodeType = (int)UsbHubNode.UsbHub};
nBytes = Marshal.SizeOf(nodeInfo);
IntPtr ptrNodeInfo = Marshal.AllocHGlobal(nBytes);
Marshal.StructureToPtr(nodeInfo, ptrNodeInfo, true);
// get the Hub Information
if(DeviceIoControl(h2, IOCTL_USB_GET_NODE_INFORMATION, ptrNodeInfo, nBytes, ptrNodeInfo, nBytes,
out nBytesReturned, IntPtr.Zero))
out _, IntPtr.Zero))
{
nodeInfo = (UsbNodeInformation)Marshal.PtrToStructure(ptrNodeInfo,
typeof(UsbNodeInformation));
@@ -1096,54 +1048,27 @@ namespace DiscImageChef.Devices.Windows
}
// return Port Index of the Hub
internal int PortNumber
{
get { return DevicePortNumber; }
}
internal int PortNumber => DevicePortNumber;
// return the Device Path of the Hub (the parent device)
internal string HubDevicePath
{
get { return DeviceHubDevicePath; }
}
internal string HubDevicePath => DeviceHubDevicePath;
// useful as a search key
internal string DriverKey
{
get { return DeviceDriverKey; }
}
internal string DriverKey => DeviceDriverKey;
// the device path of this device
internal string InstanceId
{
get { return DeviceInstanceId; }
}
internal string InstanceId => DeviceInstanceId;
// the friendly name
internal string Name
{
get { return DeviceName; }
}
internal string Name => DeviceName;
internal string Manufacturer
{
get { return DeviceManufacturer; }
}
internal string Manufacturer => DeviceManufacturer;
internal string Product
{
get { return DeviceProduct; }
}
internal string Product => DeviceProduct;
internal string SerialNumber
{
get { return DeviceSerialNumber; }
}
internal string SerialNumber => DeviceSerialNumber;
internal byte[] BinaryDescriptors
{
get { return BinaryDeviceDescriptors; }
}
internal byte[] BinaryDescriptors => BinaryDeviceDescriptors;
}
//
@@ -1152,15 +1077,14 @@ namespace DiscImageChef.Devices.Windows
static string GetDescriptionByKeyName(string driverKeyName)
{
string ans = "";
string devEnum = REGSTR_KEY_USB;
const string DEV_ENUM = REGSTR_KEY_USB;
// Use the "enumerator form" of the SetupDiGetClassDevs API
// to generate a list of all USB devices
IntPtr h = SetupDiGetClassDevs(0, devEnum, IntPtr.Zero, DIGCF_PRESENT | DIGCF_ALLCLASSES);
IntPtr h = SetupDiGetClassDevs(0, DEV_ENUM, IntPtr.Zero, DIGCF_PRESENT | DIGCF_ALLCLASSES);
if(h.ToInt32() == INVALID_HANDLE_VALUE) return ans;
IntPtr ptrBuf = Marshal.AllocHGlobal(BUFFER_SIZE);
string keyName;
bool success;
int i = 0;
@@ -1176,7 +1100,7 @@ namespace DiscImageChef.Devices.Windows
{
int requiredSize = 0;
int regType = REG_SZ;
keyName = "";
string keyName = "";
if(SetupDiGetDeviceRegistryProperty(h, ref da, SPDRP_DRIVER, ref regType, ptrBuf, BUFFER_SIZE,
ref requiredSize)) keyName = Marshal.PtrToStringAuto(ptrBuf);
@@ -1206,15 +1130,14 @@ namespace DiscImageChef.Devices.Windows
static string GetInstanceIdByKeyName(string driverKeyName)
{
string ans = "";
string devEnum = REGSTR_KEY_USB;
const string DEV_ENUM = REGSTR_KEY_USB;
// Use the "enumerator form" of the SetupDiGetClassDevs API
// to generate a list of all USB devices
IntPtr h = SetupDiGetClassDevs(0, devEnum, IntPtr.Zero, DIGCF_PRESENT | DIGCF_ALLCLASSES);
IntPtr h = SetupDiGetClassDevs(0, DEV_ENUM, IntPtr.Zero, DIGCF_PRESENT | DIGCF_ALLCLASSES);
if(h.ToInt32() == INVALID_HANDLE_VALUE) return ans;
IntPtr ptrBuf = Marshal.AllocHGlobal(BUFFER_SIZE);
string keyName;
bool success;
int i = 0;
@@ -1231,16 +1154,16 @@ namespace DiscImageChef.Devices.Windows
int requiredSize = 0;
int regType = REG_SZ;
keyName = "";
string keyName = "";
if(SetupDiGetDeviceRegistryProperty(h, ref da, SPDRP_DRIVER, ref regType, ptrBuf, BUFFER_SIZE,
ref requiredSize)) keyName = Marshal.PtrToStringAuto(ptrBuf);
// is it a match?
if(keyName == driverKeyName)
{
int nBytes = BUFFER_SIZE;
StringBuilder sb = new StringBuilder(nBytes);
SetupDiGetDeviceInstanceId(h, ref da, sb, nBytes, out requiredSize);
const int N_BYTES = BUFFER_SIZE;
StringBuilder sb = new StringBuilder(N_BYTES);
SetupDiGetDeviceInstanceId(h, ref da, sb, N_BYTES, out requiredSize);
ans = sb.ToString();
break;
}

View File

@@ -28,25 +28,26 @@
//
// ----------------------------------------------------------------------------
// Copyright © 2011-2018 Natalia Portillo
// Copyright © 2007 Fort Hood TX, herethen, Public Domain
// ****************************************************************************/
using System;
using System.Collections.Generic;
using System.Runtime.InteropServices;
// Copyright "Fort Hood TX", internal domain, 2007
namespace DiscImageChef.Devices.Windows
{
//
// A place for "higher level" related functions
// You might not want to keep these in the USB class... your choice
//
partial class Usb
// TODO: Even after cleaning, refactoring and xml-documenting, this code needs some love
static partial class Usb
{
//
// Get a list of all connected devices
//
static internal List<UsbDevice> GetConnectedDevices()
internal static List<UsbDevice> GetConnectedDevices()
{
List<UsbDevice> devList = new List<UsbDevice>();
@@ -56,7 +57,7 @@ namespace DiscImageChef.Devices.Windows
}
// private routine for enumerating a hub
static void ListHub(UsbHub hub, List<UsbDevice> devList)
static void ListHub(UsbHub hub, ICollection<UsbDevice> devList)
{
foreach(UsbPort port in hub.GetPorts())
if(port.IsHub) ListHub(port.GetHub(), devList);
@@ -66,7 +67,7 @@ namespace DiscImageChef.Devices.Windows
//
// Find a device based upon it's DriverKeyName
//
static internal UsbDevice FindDeviceByDriverKeyName(string driverKeyName)
internal static UsbDevice FindDeviceByDriverKeyName(string driverKeyName)
{
UsbDevice foundDevice = null;
@@ -99,7 +100,7 @@ namespace DiscImageChef.Devices.Windows
//
// Find a device based upon it's Instance ID
//
static internal UsbDevice FindDeviceByInstanceId(string instanceId)
static UsbDevice FindDeviceByInstanceId(string instanceId)
{
UsbDevice foundDevice = null;
@@ -167,38 +168,28 @@ namespace DiscImageChef.Devices.Windows
//
// Find a device based upon a Drive Letter
//
static internal UsbDevice FindDriveLetter(string driveLetter, string deviceGuid)
internal static UsbDevice FindDriveLetter(string driveLetter, string deviceGuid)
{
UsbDevice foundDevice = null;
string instanceId = "";
// 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('\\'));
if(devNum < 0) return null;
return FindDeviceNumber(devNum, deviceGuid);
return devNum < 0 ? null : FindDeviceNumber(devNum, deviceGuid);
}
static internal UsbDevice FindDrivePath(string drivePath, string deviceGuid)
internal static UsbDevice FindDrivePath(string drivePath, string deviceGuid)
{
UsbDevice foundDevice = null;
string instanceId = "";
// 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);
if(devNum < 0) return null;
return FindDeviceNumber(devNum, deviceGuid);
return devNum < 0 ? null : FindDeviceNumber(devNum, deviceGuid);
}
//
// Find a device based upon a Drive Letter
//
static internal UsbDevice FindDeviceNumber(int devNum, string deviceGuid)
static UsbDevice FindDeviceNumber(int devNum, string deviceGuid)
{
UsbDevice foundDevice = null;
string instanceId = "";
@@ -227,23 +218,22 @@ namespace DiscImageChef.Devices.Windows
da.cbSize = Marshal.SizeOf(da);
// build a Device Interface Detail Data structure
SpDeviceInterfaceDetailData didd = new SpDeviceInterfaceDetailData();
didd.cbSize = 4 + Marshal.SystemDefaultCharSize; // trust me :)
SpDeviceInterfaceDetailData didd =
new SpDeviceInterfaceDetailData {cbSize = 4 + Marshal.SystemDefaultCharSize}; // trust me :)
// now we can get some more detailed information
int nRequiredSize = 0;
int nBytes = BUFFER_SIZE;
if(SetupDiGetDeviceInterfaceDetail(h, ref dia, ref didd, nBytes, ref nRequiredSize, ref da))
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
IntPtr ptrPrevious;
CM_Get_Parent(out ptrPrevious, da.DevInst, 0);
CM_Get_Parent(out IntPtr ptrPrevious, da.DevInst, 0);
// Now we get the InstanceID of the USB level device
IntPtr ptrInstanceBuf = Marshal.AllocHGlobal(nBytes);
CM_Get_Device_ID(ptrPrevious, ptrInstanceBuf, nBytes, 0);
IntPtr ptrInstanceBuf = Marshal.AllocHGlobal(N_BYTES);
CM_Get_Device_ID(ptrPrevious, ptrInstanceBuf, N_BYTES, 0);
instanceId = Marshal.PtrToStringAuto(ptrInstanceBuf);
Marshal.FreeHGlobal(ptrInstanceBuf);
@@ -271,12 +261,11 @@ namespace DiscImageChef.Devices.Windows
IntPtr h = CreateFile(devicePath.TrimEnd('\\'), 0, 0, IntPtr.Zero, OPEN_EXISTING, 0, IntPtr.Zero);
if(h.ToInt32() == INVALID_HANDLE_VALUE) return ans;
int requiredSize;
StorageDeviceNumber sdn = new StorageDeviceNumber();
int nBytes = Marshal.SizeOf(sdn);
IntPtr ptrSdn = Marshal.AllocHGlobal(nBytes);
if(DeviceIoControl(h, IOCTL_STORAGE_GET_DEVICE_NUMBER, IntPtr.Zero, 0, ptrSdn, nBytes, out requiredSize,
if(DeviceIoControl(h, IOCTL_STORAGE_GET_DEVICE_NUMBER, IntPtr.Zero, 0, ptrSdn, nBytes, out _,
IntPtr.Zero))
{
sdn = (StorageDeviceNumber)Marshal.PtrToStructure(ptrSdn, typeof(StorageDeviceNumber));