mirror of
https://github.com/aaru-dps/Aaru.git
synced 2025-12-16 19:24:25 +00:00
Added code to retrieve USB IDs and strings for Windows.
This commit is contained in:
@@ -341,7 +341,26 @@ namespace DiscImageChef.Devices
|
|||||||
}
|
}
|
||||||
else if(platformID == Interop.PlatformID.Win32NT)
|
else if(platformID == Interop.PlatformID.Win32NT)
|
||||||
{
|
{
|
||||||
|
Windows.Usb.USBDevice usbDevice = null;
|
||||||
|
|
||||||
|
// I have to search for USB disks, floppies and CD-ROMs as separate device types
|
||||||
|
foreach(string devGuid in new [] { Windows.Usb.GUID_DEVINTERFACE_FLOPPY, Windows.Usb.GUID_DEVINTERFACE_CDROM , Windows.Usb.GUID_DEVINTERFACE_DISK })
|
||||||
|
{
|
||||||
|
usbDevice = Windows.Usb.FindDrivePath(devicePath, devGuid);
|
||||||
|
if (usbDevice != null)
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
if(usbDevice != null)
|
||||||
|
{
|
||||||
|
// TODO: Get binary descriptors
|
||||||
|
usbVendor = (ushort)usbDevice.DeviceDescriptor.idVendor;
|
||||||
|
usbProduct = (ushort)usbDevice.DeviceDescriptor.idProduct;
|
||||||
|
usbManufacturerString = usbDevice.Manufacturer;
|
||||||
|
usbProductString = usbDevice.Product;
|
||||||
|
usbSerialString = usbDevice.SerialNumber; // This is incorrect filled by Windows with SCSI/ATA serial number
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
// TODO: Implement for other operating systems
|
// TODO: Implement for other operating systems
|
||||||
else
|
else
|
||||||
|
|||||||
@@ -84,6 +84,8 @@
|
|||||||
<Compile Include="Device\ScsiCommands\Kreon.cs" />
|
<Compile Include="Device\ScsiCommands\Kreon.cs" />
|
||||||
<Compile Include="Device\List.cs" />
|
<Compile Include="Device\List.cs" />
|
||||||
<Compile Include="Linux\ListDevices.cs" />
|
<Compile Include="Linux\ListDevices.cs" />
|
||||||
|
<Compile Include="Windows\Usb.cs" />
|
||||||
|
<Compile Include="Windows\UsbFunctions.cs" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<Import Project="$(MSBuildBinPath)\Microsoft.CSharp.targets" />
|
<Import Project="$(MSBuildBinPath)\Microsoft.CSharp.targets" />
|
||||||
<ItemGroup />
|
<ItemGroup />
|
||||||
|
|||||||
@@ -42,70 +42,141 @@ namespace DiscImageChef.Devices.Windows
|
|||||||
/// FILE_ATTRIBUTE_ARCHIVE
|
/// FILE_ATTRIBUTE_ARCHIVE
|
||||||
/// </summary>
|
/// </summary>
|
||||||
Archive = 0x20,
|
Archive = 0x20,
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// FILE_ATTRIBUTE_COMPRESSED
|
/// FILE_ATTRIBUTE_COMPRESSED
|
||||||
/// </summary>
|
/// </summary>
|
||||||
Compressed = 0x800,
|
Compressed = 0x800,
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// FILE_ATTRIBUTE_DEVICE
|
/// FILE_ATTRIBUTE_DEVICE
|
||||||
/// </summary>
|
/// </summary>
|
||||||
Device = 0x40,
|
Device = 0x40,
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// FILE_ATTRIBUTE_DIRECTORY
|
/// FILE_ATTRIBUTE_DIRECTORY
|
||||||
/// </summary>
|
/// </summary>
|
||||||
Directory = 0x10,
|
Directory = 0x10,
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// FILE_ATTRIBUTE_ENCRYPTED
|
/// FILE_ATTRIBUTE_ENCRYPTED
|
||||||
/// </summary>
|
/// </summary>
|
||||||
Encrypted = 0x4000,
|
Encrypted = 0x4000,
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// FILE_ATTRIBUTE_HIDDEN
|
/// FILE_ATTRIBUTE_HIDDEN
|
||||||
/// </summary>
|
/// </summary>
|
||||||
Hidden = 0x02,
|
Hidden = 0x02,
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// FILE_ATTRIBUTE_INTEGRITY_STREAM
|
/// FILE_ATTRIBUTE_INTEGRITY_STREAM
|
||||||
/// </summary>
|
/// </summary>
|
||||||
IntegrityStream = 0x8000,
|
IntegrityStream = 0x8000,
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// FILE_ATTRIBUTE_NORMAL
|
/// FILE_ATTRIBUTE_NORMAL
|
||||||
/// </summary>
|
/// </summary>
|
||||||
Normal = 0x80,
|
Normal = 0x80,
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// FILE_ATTRIBUTE_NOT_CONTENT_INDEXED
|
/// FILE_ATTRIBUTE_NOT_CONTENT_INDEXED
|
||||||
/// </summary>
|
/// </summary>
|
||||||
NotContentIndexed = 0x2000,
|
NotContentIndexed = 0x2000,
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// FILE_ATTRIBUTE_NO_SCRUB_DATA
|
/// FILE_ATTRIBUTE_NO_SCRUB_DATA
|
||||||
/// </summary>
|
/// </summary>
|
||||||
NoScrubData = 0x20000,
|
NoScrubData = 0x20000,
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// FILE_ATTRIBUTE_OFFLINE
|
/// FILE_ATTRIBUTE_OFFLINE
|
||||||
/// </summary>
|
/// </summary>
|
||||||
Offline = 0x1000,
|
Offline = 0x1000,
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// FILE_ATTRIBUTE_READONLY
|
/// FILE_ATTRIBUTE_READONLY
|
||||||
/// </summary>
|
/// </summary>
|
||||||
Readonly = 0x01,
|
Readonly = 0x01,
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// FILE_ATTRIBUTE_REPARSE_POINT
|
/// FILE_ATTRIBUTE_REPARSE_POINT
|
||||||
/// </summary>
|
/// </summary>
|
||||||
ReparsePoint = 0x400,
|
ReparsePoint = 0x400,
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// FILE_ATTRIBUTE_SPARSE_FILE
|
/// FILE_ATTRIBUTE_SPARSE_FILE
|
||||||
/// </summary>
|
/// </summary>
|
||||||
SparseFile = 0x200,
|
SparseFile = 0x200,
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// FILE_ATTRIBUTE_SYSTEM
|
/// FILE_ATTRIBUTE_SYSTEM
|
||||||
/// </summary>
|
/// </summary>
|
||||||
System = 0x04,
|
System = 0x04,
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// FILE_ATTRIBUTE_TEMPORARY
|
/// FILE_ATTRIBUTE_TEMPORARY
|
||||||
/// </summary>
|
/// </summary>
|
||||||
Temporary = 0x100,
|
Temporary = 0x100,
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// FILE_ATTRIBUTE_VIRTUAL
|
/// FILE_ATTRIBUTE_VIRTUAL
|
||||||
/// </summary>
|
/// </summary>
|
||||||
Virtual = 0x10000,
|
Virtual = 0x10000,
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// FILE_FLAG_BACKUP_SEMANTICS
|
||||||
|
/// </summary>
|
||||||
|
BackupSemantics = 0x02000000,
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// FILE_FLAG_DELETE_ON_CLOSE
|
||||||
|
/// </summary>
|
||||||
|
DeleteOnClose = 0x04000000,
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// FILE_FLAG_NO_BUFFERING
|
||||||
|
/// </summary>
|
||||||
|
NoBuffering = 0x20000000,
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// FILE_FLAG_OPEN_NO_RECALL
|
||||||
|
/// </summary>
|
||||||
|
OpenNoRecall = 0x00100000,
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// FILE_FLAG_OPEN_REPARSE_POINT
|
||||||
|
/// </summary>
|
||||||
|
OpenReparsePoint = 0x00200000,
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// FILE_FLAG_OVERLAPPED
|
||||||
|
/// </summary>
|
||||||
|
Overlapped = 0x40000000,
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// FILE_FLAG_POSIX_SEMANTICS
|
||||||
|
/// </summary>
|
||||||
|
PosixSemantics = 0x0100000,
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// FILE_FLAG_RANDOM_ACCESS
|
||||||
|
/// </summary>
|
||||||
|
RandomAccess = 0x10000000,
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// FILE_FLAG_SESSION_AWARE
|
||||||
|
/// </summary>
|
||||||
|
SessionAware = 0x00800000,
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// FILE_FLAG_SEQUENTIAL_SCAN
|
||||||
|
/// </summary>
|
||||||
|
SequentialScan = 0x08000000,
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// FILE_FLAG_WRITE_THROUGH
|
||||||
|
/// </summary>
|
||||||
|
WriteThrough = 0x80000000,
|
||||||
}
|
}
|
||||||
|
|
||||||
[Flags]
|
[Flags]
|
||||||
|
|||||||
@@ -140,7 +140,7 @@ namespace DiscImageChef.Devices.Windows
|
|||||||
|
|
||||||
[DllImport("setupapi.dll", CharSet = CharSet.Auto, SetLastError = true)]
|
[DllImport("setupapi.dll", CharSet = CharSet.Auto, SetLastError = true)]
|
||||||
public static extern bool SetupDiDestroyDeviceInfoList(SafeFileHandle hDevInfo);
|
public static extern bool SetupDiDestroyDeviceInfoList(SafeFileHandle hDevInfo);
|
||||||
|
|
||||||
[DllImport("Kernel32.dll", SetLastError = true, CharSet = CharSet.Auto)]
|
[DllImport("Kernel32.dll", SetLastError = true, CharSet = CharSet.Auto)]
|
||||||
internal static extern bool CloseHandle(SafeFileHandle hDevice);
|
internal static extern bool CloseHandle(SafeFileHandle hDevice);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -238,5 +238,22 @@ namespace DiscImageChef.Devices.Windows
|
|||||||
public uint flags;
|
public uint flags;
|
||||||
private IntPtr reserved;
|
private IntPtr reserved;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
[StructLayout(LayoutKind.Sequential)]
|
||||||
|
struct USB_SETUP_PACKET
|
||||||
|
{
|
||||||
|
public byte bmRequest;
|
||||||
|
public byte bRequest;
|
||||||
|
public short wValue;
|
||||||
|
public short wIndex;
|
||||||
|
public short wLength;
|
||||||
|
}
|
||||||
|
[StructLayout(LayoutKind.Sequential)]
|
||||||
|
struct USB_DESCRIPTOR_REQUEST
|
||||||
|
{
|
||||||
|
public int ConnectionIndex;
|
||||||
|
public USB_SETUP_PACKET SetupPacket;
|
||||||
|
//public byte[] Data;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
1260
DiscImageChef.Devices/Windows/Usb.cs
Normal file
1260
DiscImageChef.Devices/Windows/Usb.cs
Normal file
File diff suppressed because it is too large
Load Diff
316
DiscImageChef.Devices/Windows/UsbFunctions.cs
Normal file
316
DiscImageChef.Devices/Windows/UsbFunctions.cs
Normal file
@@ -0,0 +1,316 @@
|
|||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Text;
|
||||||
|
using System.Runtime.InteropServices;
|
||||||
|
using System.Diagnostics;
|
||||||
|
|
||||||
|
// Copyright "Fort Hood TX", public 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
|
||||||
|
//
|
||||||
|
public partial class Usb
|
||||||
|
{
|
||||||
|
|
||||||
|
//
|
||||||
|
// Get a list of all connected devices
|
||||||
|
//
|
||||||
|
static public List<USBDevice> GetConnectedDevices()
|
||||||
|
{
|
||||||
|
List<USBDevice> DevList = new List<USBDevice>();
|
||||||
|
|
||||||
|
foreach(USBController Controller in GetHostControllers())
|
||||||
|
{
|
||||||
|
ListHub(Controller.GetRootHub(), DevList);
|
||||||
|
}
|
||||||
|
return DevList;
|
||||||
|
}
|
||||||
|
|
||||||
|
// private routine for enumerating a hub
|
||||||
|
static void ListHub(USBHub Hub, List<USBDevice> DevList)
|
||||||
|
{
|
||||||
|
foreach(USBPort Port in Hub.GetPorts())
|
||||||
|
{
|
||||||
|
if(Port.IsHub)
|
||||||
|
{
|
||||||
|
// recursive
|
||||||
|
ListHub(Port.GetHub(), DevList);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if(Port.IsDeviceConnected)
|
||||||
|
{
|
||||||
|
DevList.Add(Port.GetDevice());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// Find a device based upon it's DriverKeyName
|
||||||
|
//
|
||||||
|
static public USBDevice FindDeviceByDriverKeyName(string DriverKeyName)
|
||||||
|
{
|
||||||
|
USBDevice FoundDevice = null;
|
||||||
|
|
||||||
|
foreach(USBController Controller in GetHostControllers())
|
||||||
|
{
|
||||||
|
SearchHubDriverKeyName(Controller.GetRootHub(), ref FoundDevice, DriverKeyName);
|
||||||
|
if(FoundDevice != null)
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
return FoundDevice;
|
||||||
|
}
|
||||||
|
|
||||||
|
// private routine for enumerating a hub
|
||||||
|
static void SearchHubDriverKeyName(USBHub Hub, ref USBDevice FoundDevice, string DriverKeyName)
|
||||||
|
{
|
||||||
|
foreach(USBPort Port in Hub.GetPorts())
|
||||||
|
{
|
||||||
|
if(Port.IsHub)
|
||||||
|
{
|
||||||
|
// recursive
|
||||||
|
SearchHubDriverKeyName(Port.GetHub(), ref FoundDevice, DriverKeyName);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if(Port.IsDeviceConnected)
|
||||||
|
{
|
||||||
|
USBDevice Device = Port.GetDevice();
|
||||||
|
if(Device.DeviceDriverKey == DriverKeyName)
|
||||||
|
{
|
||||||
|
FoundDevice = Device;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// Find a device based upon it's Instance ID
|
||||||
|
//
|
||||||
|
static public USBDevice FindDeviceByInstanceID(string InstanceID)
|
||||||
|
{
|
||||||
|
USBDevice FoundDevice = null;
|
||||||
|
|
||||||
|
foreach(USBController Controller in GetHostControllers())
|
||||||
|
{
|
||||||
|
SearchHubInstanceID(Controller.GetRootHub(), ref FoundDevice, InstanceID);
|
||||||
|
if(FoundDevice != null)
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
return FoundDevice;
|
||||||
|
}
|
||||||
|
|
||||||
|
// private routine for enumerating a hub
|
||||||
|
static void SearchHubInstanceID(USBHub Hub, ref USBDevice FoundDevice, string InstanceID)
|
||||||
|
{
|
||||||
|
foreach(USBPort Port in Hub.GetPorts())
|
||||||
|
{
|
||||||
|
if(Port.IsHub)
|
||||||
|
{
|
||||||
|
// recursive
|
||||||
|
SearchHubInstanceID(Port.GetHub(), ref FoundDevice, InstanceID);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if(Port.IsDeviceConnected)
|
||||||
|
{
|
||||||
|
USBDevice Device = Port.GetDevice();
|
||||||
|
if(Device.InstanceID == InstanceID)
|
||||||
|
{
|
||||||
|
FoundDevice = Device;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
const int IOCTL_STORAGE_GET_DEVICE_NUMBER = 0x2D1080;
|
||||||
|
public const string GUID_DEVINTERFACE_DISK = "53f56307-b6bf-11d0-94f2-00a0c91efb8b";
|
||||||
|
public const string GUID_DEVINTERFACE_CDROM = "53f56308-b6bf-11d0-94f2-00a0c91efb8b";
|
||||||
|
public const string GUID_DEVINTERFACE_FLOPPY = "53f56311-b6bf-11d0-94f2-00a0c91efb8b";
|
||||||
|
|
||||||
|
//typedef struct _STORAGE_DEVICE_NUMBER {
|
||||||
|
// DEVICE_TYPE DeviceType;
|
||||||
|
// ULONG DeviceNumber;
|
||||||
|
// ULONG PartitionNumber;
|
||||||
|
//} STORAGE_DEVICE_NUMBER, *PSTORAGE_DEVICE_NUMBER;
|
||||||
|
[StructLayout(LayoutKind.Sequential)]
|
||||||
|
struct STORAGE_DEVICE_NUMBER
|
||||||
|
{
|
||||||
|
public int DeviceType;
|
||||||
|
public int DeviceNumber;
|
||||||
|
public int PartitionNumber;
|
||||||
|
}
|
||||||
|
|
||||||
|
//CMAPI CONFIGRET WINAPI CM_Get_Parent(
|
||||||
|
// OUT PDEVINST pdnDevInst,
|
||||||
|
// IN DEVINST dnDevInst,
|
||||||
|
// IN ULONG ulFlags
|
||||||
|
//);
|
||||||
|
[DllImport("setupapi.dll")]
|
||||||
|
static extern int CM_Get_Parent(
|
||||||
|
out IntPtr pdnDevInst,
|
||||||
|
IntPtr dnDevInst,
|
||||||
|
int ulFlags
|
||||||
|
);
|
||||||
|
|
||||||
|
//CMAPI CONFIGRET WINAPI CM_Get_Device_ID(
|
||||||
|
// IN DEVINST dnDevInst,
|
||||||
|
// OUT PTCHAR Buffer,
|
||||||
|
// IN ULONG BufferLen,
|
||||||
|
// IN ULONG ulFlags
|
||||||
|
//);
|
||||||
|
[DllImport("setupapi.dll", CharSet = CharSet.Auto)]
|
||||||
|
static extern int CM_Get_Device_ID(
|
||||||
|
IntPtr dnDevInst,
|
||||||
|
IntPtr Buffer,
|
||||||
|
int BufferLen,
|
||||||
|
int ulFlags
|
||||||
|
);
|
||||||
|
|
||||||
|
//
|
||||||
|
// Find a device based upon a Drive Letter
|
||||||
|
//
|
||||||
|
static public 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);
|
||||||
|
}
|
||||||
|
|
||||||
|
static public 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);
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// Find a device based upon a Drive Letter
|
||||||
|
//
|
||||||
|
static public USBDevice FindDeviceNumber(int DevNum, string deviceGuid)
|
||||||
|
{
|
||||||
|
USBDevice FoundDevice = null;
|
||||||
|
string InstanceID = "";
|
||||||
|
|
||||||
|
Guid 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.ToInt32() != INVALID_HANDLE_VALUE)
|
||||||
|
{
|
||||||
|
bool Success = true;
|
||||||
|
int i = 0;
|
||||||
|
do
|
||||||
|
{
|
||||||
|
// create a Device Interface Data structure
|
||||||
|
SP_DEVICE_INTERFACE_DATA dia = new SP_DEVICE_INTERFACE_DATA();
|
||||||
|
dia.cbSize = Marshal.SizeOf(dia);
|
||||||
|
|
||||||
|
// start the enumeration
|
||||||
|
Success = SetupDiEnumDeviceInterfaces(h, IntPtr.Zero, ref DiskGUID, i, ref dia);
|
||||||
|
if(Success)
|
||||||
|
{
|
||||||
|
// build a DevInfo Data structure
|
||||||
|
SP_DEVINFO_DATA da = new SP_DEVINFO_DATA();
|
||||||
|
da.cbSize = Marshal.SizeOf(da);
|
||||||
|
|
||||||
|
// build a Device Interface Detail Data structure
|
||||||
|
SP_DEVICE_INTERFACE_DETAIL_DATA didd = new SP_DEVICE_INTERFACE_DETAIL_DATA();
|
||||||
|
didd.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))
|
||||||
|
{
|
||||||
|
// Now that we have a DevicePath... we can use it to
|
||||||
|
// generate another DeviceNumber to see if it matches
|
||||||
|
// the one we're looking for.
|
||||||
|
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);
|
||||||
|
|
||||||
|
// Now we get the InstanceID of the USB level device
|
||||||
|
IntPtr ptrInstanceBuf = Marshal.AllocHGlobal(nBytes);
|
||||||
|
CM_Get_Device_ID(ptrPrevious, ptrInstanceBuf, nBytes, 0);
|
||||||
|
InstanceID = Marshal.PtrToStringAuto(ptrInstanceBuf);
|
||||||
|
|
||||||
|
Marshal.FreeHGlobal(ptrInstanceBuf);
|
||||||
|
System.Console.WriteLine("InstanceId: {0}", InstanceID);
|
||||||
|
//break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
i++;
|
||||||
|
} while(Success);
|
||||||
|
SetupDiDestroyDeviceInfoList(h);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Did we find an InterfaceID of a USB device?
|
||||||
|
if(InstanceID.StartsWith("USB\\"))
|
||||||
|
{
|
||||||
|
FoundDevice = FindDeviceByInstanceID(InstanceID);
|
||||||
|
}
|
||||||
|
return FoundDevice;
|
||||||
|
}
|
||||||
|
|
||||||
|
// return a unique device number for the given device path
|
||||||
|
private static int GetDeviceNumber(string DevicePath)
|
||||||
|
{
|
||||||
|
int ans = -1;
|
||||||
|
|
||||||
|
IntPtr h = CreateFile(DevicePath.TrimEnd('\\'), 0, 0, IntPtr.Zero, OPEN_EXISTING, 0, IntPtr.Zero);
|
||||||
|
if(h.ToInt32() != INVALID_HANDLE_VALUE)
|
||||||
|
{
|
||||||
|
int requiredSize;
|
||||||
|
STORAGE_DEVICE_NUMBER Sdn = new STORAGE_DEVICE_NUMBER();
|
||||||
|
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,
|
||||||
|
IntPtr.Zero))
|
||||||
|
{
|
||||||
|
Sdn = (STORAGE_DEVICE_NUMBER)Marshal.PtrToStructure(ptrSdn, typeof(STORAGE_DEVICE_NUMBER));
|
||||||
|
// just my way of combining the relevant parts of the
|
||||||
|
// STORAGE_DEVICE_NUMBER into a single number
|
||||||
|
ans = (Sdn.DeviceType << 8) + Sdn.DeviceNumber;
|
||||||
|
}
|
||||||
|
Marshal.FreeHGlobal(ptrSdn);
|
||||||
|
CloseHandle(h);
|
||||||
|
}
|
||||||
|
return ans;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user