mirror of
https://github.com/aaru-dps/Aaru.git
synced 2025-12-16 19:24:25 +00:00
Added code to retrieve NT device path (will be needed later).
This commit is contained in:
@@ -33,6 +33,8 @@
|
|||||||
using System;
|
using System;
|
||||||
using Microsoft.Win32.SafeHandles;
|
using Microsoft.Win32.SafeHandles;
|
||||||
using System.Runtime.InteropServices;
|
using System.Runtime.InteropServices;
|
||||||
|
using System.Text;
|
||||||
|
using DiscImageChef.Console;
|
||||||
using DiscImageChef.Decoders.ATA;
|
using DiscImageChef.Decoders.ATA;
|
||||||
|
|
||||||
namespace DiscImageChef.Devices
|
namespace DiscImageChef.Devices
|
||||||
@@ -100,6 +102,7 @@ namespace DiscImageChef.Devices
|
|||||||
throw new SystemException(string.Format("Error {0} trying device.", lastError));
|
throw new SystemException(string.Format("Error {0} trying device.", lastError));
|
||||||
|
|
||||||
bool scsiSense = true;
|
bool scsiSense = true;
|
||||||
|
string ntDevicePath = null;
|
||||||
|
|
||||||
// Windows is answering SCSI INQUIRY for all device types so it needs to be detected first
|
// Windows is answering SCSI INQUIRY for all device types so it needs to be detected first
|
||||||
if(platformID == Interop.PlatformID.Win32NT)
|
if(platformID == Interop.PlatformID.Win32NT)
|
||||||
@@ -126,7 +129,20 @@ namespace DiscImageChef.Devices
|
|||||||
{
|
{
|
||||||
|
|
||||||
Windows.StorageDeviceDescriptor descriptor = new Windows.StorageDeviceDescriptor();
|
Windows.StorageDeviceDescriptor descriptor = new Windows.StorageDeviceDescriptor();
|
||||||
|
descriptor.Version = BitConverter.ToUInt32(descriptor_b, 0);
|
||||||
|
descriptor.Size = BitConverter.ToUInt32(descriptor_b, 4);
|
||||||
|
descriptor.DeviceType = descriptor_b[8];
|
||||||
|
descriptor.DeviceTypeModifier= descriptor_b[9];
|
||||||
|
descriptor.RemovableMedia = descriptor_b[10] > 0;
|
||||||
|
descriptor.CommandQueueing = descriptor_b[11] > 0;
|
||||||
|
descriptor.VendorIdOffset = BitConverter.ToUInt32(descriptor_b, 12);
|
||||||
|
descriptor.ProductIdOffset = BitConverter.ToUInt32(descriptor_b, 16);
|
||||||
|
descriptor.ProductRevisionOffset = BitConverter.ToUInt32(descriptor_b, 20);
|
||||||
|
descriptor.SerialNumberOffset = BitConverter.ToUInt32(descriptor_b, 24);
|
||||||
descriptor.BusType = (Windows.StorageBusType)BitConverter.ToUInt32(descriptor_b, 28);
|
descriptor.BusType = (Windows.StorageBusType)BitConverter.ToUInt32(descriptor_b, 28);
|
||||||
|
descriptor.RawPropertiesLength = BitConverter.ToUInt32(descriptor_b, 32);
|
||||||
|
descriptor.RawDeviceProperties = new byte[descriptor.RawPropertiesLength];
|
||||||
|
Array.Copy(descriptor_b, 36, descriptor.RawDeviceProperties, 0, descriptor.RawPropertiesLength);
|
||||||
|
|
||||||
switch(descriptor.BusType)
|
switch(descriptor.BusType)
|
||||||
{
|
{
|
||||||
@@ -180,9 +196,12 @@ namespace DiscImageChef.Devices
|
|||||||
else
|
else
|
||||||
manufacturer = "ATA";
|
manufacturer = "ATA";
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO: Get cached CID, CSD and SCR from kernel space
|
// TODO: Get cached CID, CSD and SCR from kernel space
|
||||||
}
|
}
|
||||||
|
|
||||||
|
ntDevicePath = Windows.Command.GetDevicePath((SafeFileHandle)fd);
|
||||||
|
DicConsole.DebugWriteLine("Windows devices", "NT device path: {0}", ntDevicePath);
|
||||||
Marshal.FreeHGlobal(descriptorPtr);
|
Marshal.FreeHGlobal(descriptorPtr);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
@@ -246,9 +265,12 @@ namespace DiscImageChef.Devices
|
|||||||
}
|
}
|
||||||
|
|
||||||
#region USB
|
#region USB
|
||||||
if (platformID == Interop.PlatformID.Linux)
|
|
||||||
|
if(platformID == Interop.PlatformID.Linux)
|
||||||
{
|
{
|
||||||
if(devicePath.StartsWith("/dev/sd", StringComparison.Ordinal) || devicePath.StartsWith("/dev/sr", StringComparison.Ordinal) || devicePath.StartsWith("/dev/st", StringComparison.Ordinal))
|
if(devicePath.StartsWith("/dev/sd", StringComparison.Ordinal) ||
|
||||||
|
devicePath.StartsWith("/dev/sr", StringComparison.Ordinal) ||
|
||||||
|
devicePath.StartsWith("/dev/st", StringComparison.Ordinal))
|
||||||
{
|
{
|
||||||
string devPath = devicePath.Substring(5);
|
string devPath = devicePath.Substring(5);
|
||||||
if(System.IO.Directory.Exists("/sys/block/" + devPath))
|
if(System.IO.Directory.Exists("/sys/block/" + devPath))
|
||||||
@@ -268,7 +290,8 @@ namespace DiscImageChef.Devices
|
|||||||
System.IO.StreamReader usbSr;
|
System.IO.StreamReader usbSr;
|
||||||
string usbTemp;
|
string usbTemp;
|
||||||
|
|
||||||
usbFs = new System.IO.FileStream(resolvedLink + "/descriptors", System.IO.FileMode.Open, System.IO.FileAccess.Read);
|
usbFs = new System.IO.FileStream(resolvedLink + "/descriptors",
|
||||||
|
System.IO.FileMode.Open, System.IO.FileAccess.Read);
|
||||||
byte[] usbBuf = new byte[65536];
|
byte[] usbBuf = new byte[65536];
|
||||||
int usbCount = usbFs.Read(usbBuf, 0, 65536);
|
int usbCount = usbFs.Read(usbBuf, 0, 65536);
|
||||||
usbDescriptors = new byte[usbCount];
|
usbDescriptors = new byte[usbCount];
|
||||||
@@ -277,12 +300,14 @@ namespace DiscImageChef.Devices
|
|||||||
|
|
||||||
usbSr = new System.IO.StreamReader(resolvedLink + "/idProduct");
|
usbSr = new System.IO.StreamReader(resolvedLink + "/idProduct");
|
||||||
usbTemp = usbSr.ReadToEnd();
|
usbTemp = usbSr.ReadToEnd();
|
||||||
ushort.TryParse(usbTemp, System.Globalization.NumberStyles.HexNumber, System.Globalization.CultureInfo.InvariantCulture, out usbProduct);
|
ushort.TryParse(usbTemp, System.Globalization.NumberStyles.HexNumber,
|
||||||
|
System.Globalization.CultureInfo.InvariantCulture, out usbProduct);
|
||||||
usbSr.Close();
|
usbSr.Close();
|
||||||
|
|
||||||
usbSr = new System.IO.StreamReader(resolvedLink + "/idVendor");
|
usbSr = new System.IO.StreamReader(resolvedLink + "/idVendor");
|
||||||
usbTemp = usbSr.ReadToEnd();
|
usbTemp = usbSr.ReadToEnd();
|
||||||
ushort.TryParse(usbTemp, System.Globalization.NumberStyles.HexNumber, System.Globalization.CultureInfo.InvariantCulture, out usbVendor);
|
ushort.TryParse(usbTemp, System.Globalization.NumberStyles.HexNumber,
|
||||||
|
System.Globalization.CultureInfo.InvariantCulture, out usbVendor);
|
||||||
usbSr.Close();
|
usbSr.Close();
|
||||||
|
|
||||||
if(System.IO.File.Exists(resolvedLink + "/manufacturer"))
|
if(System.IO.File.Exists(resolvedLink + "/manufacturer"))
|
||||||
@@ -313,6 +338,10 @@ namespace DiscImageChef.Devices
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
else if(platformID == Interop.PlatformID.Win32NT)
|
||||||
|
{
|
||||||
|
|
||||||
}
|
}
|
||||||
// TODO: Implement for other operating systems
|
// TODO: Implement for other operating systems
|
||||||
else
|
else
|
||||||
|
|||||||
@@ -32,8 +32,10 @@
|
|||||||
// ****************************************************************************/
|
// ****************************************************************************/
|
||||||
|
|
||||||
using System;
|
using System;
|
||||||
|
using System.Net.NetworkInformation;
|
||||||
using Microsoft.Win32.SafeHandles;
|
using Microsoft.Win32.SafeHandles;
|
||||||
using System.Runtime.InteropServices;
|
using System.Runtime.InteropServices;
|
||||||
|
using System.Text;
|
||||||
using DiscImageChef.Decoders.ATA;
|
using DiscImageChef.Decoders.ATA;
|
||||||
|
|
||||||
namespace DiscImageChef.Devices.Windows
|
namespace DiscImageChef.Devices.Windows
|
||||||
@@ -481,6 +483,93 @@ namespace DiscImageChef.Devices.Windows
|
|||||||
|
|
||||||
return error;
|
return error;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
internal static uint GetDeviceNumber(SafeFileHandle deviceHandle)
|
||||||
|
{
|
||||||
|
StorageDeviceNumber sdn = new StorageDeviceNumber();
|
||||||
|
sdn.deviceNumber = - 1;
|
||||||
|
uint k = 0;
|
||||||
|
if(!Extern.DeviceIoControlGetDeviceNumber(deviceHandle, WindowsIoctl.IOCTL_STORAGE_GET_DEVICE_NUMBER, IntPtr.Zero,
|
||||||
|
0, ref sdn, (uint)Marshal.SizeOf(sdn), ref k, IntPtr.Zero))
|
||||||
|
{
|
||||||
|
return uint.MaxValue;
|
||||||
|
}
|
||||||
|
|
||||||
|
return (uint)sdn.deviceNumber;
|
||||||
|
}
|
||||||
|
|
||||||
|
internal static string GetDevicePath(SafeFileHandle fd)
|
||||||
|
{
|
||||||
|
uint devNumber = GetDeviceNumber(fd);
|
||||||
|
|
||||||
|
if(devNumber == uint.MaxValue)
|
||||||
|
return null;
|
||||||
|
|
||||||
|
SafeFileHandle hDevInfo = Extern.SetupDiGetClassDevs(ref Consts.GUID_DEVINTERFACE_DISK, IntPtr.Zero,
|
||||||
|
IntPtr.Zero, DeviceGetClassFlags.Present | DeviceGetClassFlags.DeviceInterface);
|
||||||
|
|
||||||
|
if(hDevInfo.IsInvalid)
|
||||||
|
return null;
|
||||||
|
|
||||||
|
uint index = 0;
|
||||||
|
DeviceInterfaceData spdid = new DeviceInterfaceData();
|
||||||
|
spdid.cbSize = Marshal.SizeOf(spdid);
|
||||||
|
|
||||||
|
byte[] buffer;
|
||||||
|
|
||||||
|
while(true)
|
||||||
|
{
|
||||||
|
buffer = new byte[2048];
|
||||||
|
|
||||||
|
if(!Extern.SetupDiEnumDeviceInterfaces(hDevInfo, IntPtr.Zero, ref Consts.GUID_DEVINTERFACE_DISK, index,
|
||||||
|
ref spdid))
|
||||||
|
break;
|
||||||
|
|
||||||
|
uint size = 0;
|
||||||
|
|
||||||
|
Extern.SetupDiGetDeviceInterfaceDetail(hDevInfo, ref spdid, IntPtr.Zero, 0, ref size, IntPtr.Zero);
|
||||||
|
|
||||||
|
if(size > 0 && size < buffer.Length)
|
||||||
|
{
|
||||||
|
buffer[0] = (byte)(IntPtr.Size == 8 ? IntPtr.Size : IntPtr.Size + Marshal.SystemDefaultCharSize); // Funny...
|
||||||
|
|
||||||
|
IntPtr pspdidd = Marshal.AllocHGlobal(buffer.Length);
|
||||||
|
Marshal.Copy(buffer, 0, pspdidd, buffer.Length);
|
||||||
|
|
||||||
|
bool result =
|
||||||
|
Extern.SetupDiGetDeviceInterfaceDetail(hDevInfo, ref spdid, pspdidd, size, ref size, IntPtr.Zero);
|
||||||
|
|
||||||
|
buffer = new byte[size];
|
||||||
|
Marshal.Copy(pspdidd, buffer, 0, buffer.Length);
|
||||||
|
Marshal.FreeHGlobal(pspdidd);
|
||||||
|
|
||||||
|
if(result)
|
||||||
|
{
|
||||||
|
string devicePath = Encoding.Unicode.GetString(buffer, 4, (int)size - 4);
|
||||||
|
SafeFileHandle hDrive = Extern.CreateFile(devicePath, 0, FileShare.Read | FileShare.Write,
|
||||||
|
IntPtr.Zero, FileMode.OpenExisting, 0, IntPtr.Zero);
|
||||||
|
|
||||||
|
if(!hDrive.IsInvalid)
|
||||||
|
{
|
||||||
|
uint newDeviceNumber = GetDeviceNumber(hDrive);
|
||||||
|
|
||||||
|
if(newDeviceNumber == devNumber)
|
||||||
|
{
|
||||||
|
Extern.CloseHandle(hDrive);
|
||||||
|
return devicePath;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Extern.CloseHandle(hDrive);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
index++;
|
||||||
|
}
|
||||||
|
|
||||||
|
Extern.SetupDiDestroyDeviceInfoList(hDevInfo);
|
||||||
|
return null;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -105,7 +105,7 @@ namespace DiscImageChef.Devices.Windows
|
|||||||
/// <summary>
|
/// <summary>
|
||||||
/// FILE_ATTRIBUTE_VIRTUAL
|
/// FILE_ATTRIBUTE_VIRTUAL
|
||||||
/// </summary>
|
/// </summary>
|
||||||
Virtual = 0x10000
|
Virtual = 0x10000,
|
||||||
}
|
}
|
||||||
|
|
||||||
[Flags]
|
[Flags]
|
||||||
@@ -271,6 +271,7 @@ namespace DiscImageChef.Devices.Windows
|
|||||||
IOCTL_SCSI_GET_ADDRESS = 0x41018,
|
IOCTL_SCSI_GET_ADDRESS = 0x41018,
|
||||||
IOCTL_STORAGE_QUERY_PROPERTY = 0x2D1400,
|
IOCTL_STORAGE_QUERY_PROPERTY = 0x2D1400,
|
||||||
IOCTL_IDE_PASS_THROUGH = 0x4D028,
|
IOCTL_IDE_PASS_THROUGH = 0x4D028,
|
||||||
|
IOCTL_STORAGE_GET_DEVICE_NUMBER = 0x2D1080,
|
||||||
}
|
}
|
||||||
|
|
||||||
[Flags]
|
[Flags]
|
||||||
@@ -349,4 +350,34 @@ namespace DiscImageChef.Devices.Windows
|
|||||||
FileBackedVirtual = 0xF,
|
FileBackedVirtual = 0xF,
|
||||||
NVMe = 0x11,
|
NVMe = 0x11,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
[Flags]
|
||||||
|
enum DeviceGetClassFlags : uint
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// DIGCF_DEFAULT
|
||||||
|
/// </summary>
|
||||||
|
Default = 0x01,
|
||||||
|
/// <summary>
|
||||||
|
/// DIGCF_PRESENT
|
||||||
|
/// </summary>
|
||||||
|
Present = 0x02,
|
||||||
|
/// <summary>
|
||||||
|
/// DIGCF_ALLCLASSES
|
||||||
|
/// </summary>
|
||||||
|
AllClasses = 0x04,
|
||||||
|
/// <summary>
|
||||||
|
/// DIGCF_PROFILE
|
||||||
|
/// </summary>
|
||||||
|
Profile = 0x08,
|
||||||
|
/// <summary>
|
||||||
|
/// DIGCF_DEVICEINTERFACE
|
||||||
|
/// </summary>
|
||||||
|
DeviceInterface = 0x10,
|
||||||
|
}
|
||||||
|
|
||||||
|
static class Consts
|
||||||
|
{
|
||||||
|
public static Guid GUID_DEVINTERFACE_DISK = new Guid(0x53F56307, 0xB6BF, 0x11D0, 0x94, 0xF2, 0x00, 0xA0, 0xC9, 0x1E, 0xFB, 0x8B);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -98,6 +98,49 @@ namespace DiscImageChef.Devices.Windows
|
|||||||
IntPtr Overlapped
|
IntPtr Overlapped
|
||||||
);
|
);
|
||||||
|
|
||||||
|
|
||||||
|
[DllImport("Kernel32.dll", SetLastError = true, EntryPoint = "DeviceIoControl", CharSet = CharSet.Auto)]
|
||||||
|
internal static extern bool DeviceIoControlGetDeviceNumber(
|
||||||
|
SafeFileHandle hDevice,
|
||||||
|
WindowsIoctl IoControlCode,
|
||||||
|
IntPtr InBuffer,
|
||||||
|
uint nInBufferSize,
|
||||||
|
ref StorageDeviceNumber OutBuffer,
|
||||||
|
uint nOutBufferSize,
|
||||||
|
ref uint pBytesReturned,
|
||||||
|
IntPtr Overlapped
|
||||||
|
);
|
||||||
|
|
||||||
|
[DllImport("setupapi.dll", CharSet = CharSet.Auto)]
|
||||||
|
internal static extern SafeFileHandle SetupDiGetClassDevs(
|
||||||
|
ref Guid ClassGuid,
|
||||||
|
IntPtr Enumerator,
|
||||||
|
IntPtr hwndParent,
|
||||||
|
DeviceGetClassFlags Flags
|
||||||
|
);
|
||||||
|
|
||||||
|
[DllImport("setupapi.dll", CharSet = CharSet.Auto, SetLastError = true)]
|
||||||
|
public static extern bool SetupDiEnumDeviceInterfaces(
|
||||||
|
SafeFileHandle hDevInfo,
|
||||||
|
IntPtr devInfo,
|
||||||
|
ref Guid interfaceClassGuid,
|
||||||
|
uint memberIndex,
|
||||||
|
ref DeviceInterfaceData deviceInterfaceData
|
||||||
|
);
|
||||||
|
|
||||||
|
[DllImport("setupapi.dll", CharSet = CharSet.Auto, SetLastError = true)]
|
||||||
|
public static extern bool SetupDiGetDeviceInterfaceDetail(
|
||||||
|
SafeFileHandle hDevInfo,
|
||||||
|
ref DeviceInterfaceData deviceInterfaceData,
|
||||||
|
IntPtr deviceInterfaceDetailData,
|
||||||
|
UInt32 deviceInterfaceDetailDataSize,
|
||||||
|
ref UInt32 requiredSize,
|
||||||
|
IntPtr deviceInfoData
|
||||||
|
);
|
||||||
|
|
||||||
|
[DllImport("setupapi.dll", CharSet = CharSet.Auto, SetLastError = true)]
|
||||||
|
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);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -212,5 +212,31 @@ namespace DiscImageChef.Devices.Windows
|
|||||||
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 512)]
|
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 512)]
|
||||||
public byte[] DataBuffer;
|
public byte[] DataBuffer;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
[StructLayout(LayoutKind.Sequential)]
|
||||||
|
struct StorageDeviceNumber
|
||||||
|
{
|
||||||
|
public int deviceType;
|
||||||
|
public int deviceNumber;
|
||||||
|
public int partitionNumber;
|
||||||
|
}
|
||||||
|
|
||||||
|
[StructLayout(LayoutKind.Sequential)]
|
||||||
|
struct DeviceInfoData
|
||||||
|
{
|
||||||
|
public int cbSize;
|
||||||
|
public Guid classGuid;
|
||||||
|
public uint devInst;
|
||||||
|
public IntPtr reserved;
|
||||||
|
}
|
||||||
|
|
||||||
|
[StructLayout(LayoutKind.Sequential)]
|
||||||
|
struct DeviceInterfaceData
|
||||||
|
{
|
||||||
|
public int cbSize;
|
||||||
|
public Guid interfaceClassGuid;
|
||||||
|
public uint flags;
|
||||||
|
private IntPtr reserved;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user