mirror of
https://github.com/aaru-dps/Aaru.Server.git
synced 2025-12-16 19:24:27 +00:00
REFACTOR: All refactor in DiscImageChef.Devices.
This commit is contained in:
@@ -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();
|
||||
|
||||
@@ -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,
|
||||
|
||||
@@ -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()};
|
||||
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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));
|
||||
|
||||
Reference in New Issue
Block a user