DOCUMENTATION: Added XML documentation to DiscImageChef.Devices.

This commit is contained in:
2017-12-23 02:32:02 +00:00
parent 01d34e1823
commit 27da8f2227
9 changed files with 443 additions and 271 deletions

View File

@@ -54,6 +54,7 @@ namespace DiscImageChef.Devices
/// <param name="direction">SCSI command transfer direction</param> /// <param name="direction">SCSI command transfer direction</param>
/// <param name="duration">Time it took to execute the command in milliseconds</param> /// <param name="duration">Time it took to execute the command in milliseconds</param>
/// <param name="sense"><c>True</c> if SCSI error returned non-OK status and <paramref name="senseBuffer"/> contains SCSI sense</param> /// <param name="sense"><c>True</c> if SCSI error returned non-OK status and <paramref name="senseBuffer"/> contains SCSI sense</param>
/// <exception cref="InvalidOperationException">If the specified platform is not supported</exception>
internal static int SendScsiCommand(object fd, byte[] cdb, ref byte[] buffer, out byte[] senseBuffer, internal static int SendScsiCommand(object fd, byte[] cdb, ref byte[] buffer, out byte[] senseBuffer,
uint timeout, ScsiDirection direction, out double duration, out bool sense) uint timeout, ScsiDirection direction, out double duration, out bool sense)
{ {
@@ -76,6 +77,7 @@ namespace DiscImageChef.Devices
/// <param name="direction">SCSI command transfer direction</param> /// <param name="direction">SCSI command transfer direction</param>
/// <param name="duration">Time it took to execute the command in milliseconds</param> /// <param name="duration">Time it took to execute the command in milliseconds</param>
/// <param name="sense"><c>True</c> if SCSI error returned non-OK status and <paramref name="senseBuffer"/> contains SCSI sense</param> /// <param name="sense"><c>True</c> if SCSI error returned non-OK status and <paramref name="senseBuffer"/> contains SCSI sense</param>
/// <exception cref="InvalidOperationException">If the specified platform is not supported</exception>
internal static int SendScsiCommand(PlatformID ptId, object fd, byte[] cdb, ref byte[] buffer, internal static int SendScsiCommand(PlatformID ptId, object fd, byte[] cdb, ref byte[] buffer,
out byte[] senseBuffer, uint timeout, ScsiDirection direction, out byte[] senseBuffer, uint timeout, ScsiDirection direction,
out double duration, out bool sense) out double duration, out bool sense)
@@ -158,6 +160,21 @@ namespace DiscImageChef.Devices
} }
} }
/// <summary>
/// Sends an ATA command in CHS format
/// </summary>
/// <returns>0 if no error occurred, otherwise, errno</returns>
/// <param name="fd">File handle</param>
/// <param name="buffer">Buffer for SCSI command response</param>
/// <param name="timeout">Timeout in seconds</param>
/// <param name="duration">Time it took to execute the command in milliseconds</param>
/// <param name="sense"><c>True</c> if ATA returned non-OK status</param>
/// <param name="registers">Registers to send to the device</param>
/// <param name="errorRegisters">Registers returned by the device</param>
/// <param name="protocol">ATA protocol to use</param>
/// <param name="transferRegister">What register contains the transfer length</param>
/// <param name="transferBlocks">Set to <c>true</c> if the transfer length is in block, otherwise it is in bytes</param>
/// <exception cref="InvalidOperationException">If the specified platform is not supported</exception>
internal static int SendAtaCommand(object fd, AtaRegistersChs registers, out AtaErrorRegistersChs errorRegisters, internal static int SendAtaCommand(object fd, AtaRegistersChs registers, out AtaErrorRegistersChs errorRegisters,
AtaProtocol protocol, AtaTransferRegister transferRegister, ref byte[] buffer, AtaProtocol protocol, AtaTransferRegister transferRegister, ref byte[] buffer,
uint timeout, bool transferBlocks, out double duration, out bool sense) uint timeout, bool transferBlocks, out double duration, out bool sense)
@@ -168,6 +185,22 @@ namespace DiscImageChef.Devices
timeout, transferBlocks, out duration, out sense); timeout, transferBlocks, out duration, out sense);
} }
/// <summary>
/// Sends an ATA command in CHS format
/// </summary>
/// <returns>0 if no error occurred, otherwise, errno</returns>
/// <param name="ptId">Platform ID for executing the command</param>
/// <param name="fd">File handle</param>
/// <param name="buffer">Buffer for SCSI command response</param>
/// <param name="timeout">Timeout in seconds</param>
/// <param name="duration">Time it took to execute the command in milliseconds</param>
/// <param name="sense"><c>True</c> if ATA returned non-OK status</param>
/// <param name="registers">Registers to send to the device</param>
/// <param name="errorRegisters">Registers returned by the device</param>
/// <param name="protocol">ATA protocol to use</param>
/// <param name="transferRegister">What register contains the transfer length</param>
/// <param name="transferBlocks">Set to <c>true</c> if the transfer length is in block, otherwise it is in bytes</param>
/// <exception cref="InvalidOperationException">If the specified platform is not supported</exception>
internal static int SendAtaCommand(PlatformID ptId, object fd, AtaRegistersChs registers, internal static int SendAtaCommand(PlatformID ptId, object fd, AtaRegistersChs registers,
out AtaErrorRegistersChs errorRegisters, AtaProtocol protocol, out AtaErrorRegistersChs errorRegisters, AtaProtocol protocol,
AtaTransferRegister transferRegister, ref byte[] buffer, uint timeout, AtaTransferRegister transferRegister, ref byte[] buffer, uint timeout,
@@ -205,6 +238,21 @@ namespace DiscImageChef.Devices
} }
} }
/// <summary>
/// Sends an ATA command in CHS format
/// </summary>
/// <returns>0 if no error occurred, otherwise, errno</returns>
/// <param name="fd">File handle</param>
/// <param name="buffer">Buffer for SCSI command response</param>
/// <param name="timeout">Timeout in seconds</param>
/// <param name="duration">Time it took to execute the command in milliseconds</param>
/// <param name="sense"><c>True</c> if ATA returned non-OK status</param>
/// <param name="registers">Registers to send to the device</param>
/// <param name="errorRegisters">Registers returned by the device</param>
/// <param name="protocol">ATA protocol to use</param>
/// <param name="transferRegister">What register contains the transfer length</param>
/// <param name="transferBlocks">Set to <c>true</c> if the transfer length is in block, otherwise it is in bytes</param>
/// <exception cref="InvalidOperationException">If the specified platform is not supported</exception>
internal static int SendAtaCommand(object fd, AtaRegistersLba28 registers, internal static int SendAtaCommand(object fd, AtaRegistersLba28 registers,
out AtaErrorRegistersLba28 errorRegisters, AtaProtocol protocol, out AtaErrorRegistersLba28 errorRegisters, AtaProtocol protocol,
AtaTransferRegister transferRegister, ref byte[] buffer, uint timeout, AtaTransferRegister transferRegister, ref byte[] buffer, uint timeout,
@@ -216,6 +264,22 @@ namespace DiscImageChef.Devices
timeout, transferBlocks, out duration, out sense); timeout, transferBlocks, out duration, out sense);
} }
/// <summary>
/// Sends an ATA command in 28-bit LBA format
/// </summary>
/// <returns>0 if no error occurred, otherwise, errno</returns>
/// <param name="ptId">Platform ID for executing the command</param>
/// <param name="fd">File handle</param>
/// <param name="buffer">Buffer for SCSI command response</param>
/// <param name="timeout">Timeout in seconds</param>
/// <param name="duration">Time it took to execute the command in milliseconds</param>
/// <param name="sense"><c>True</c> if ATA returned non-OK status</param>
/// <param name="registers">Registers to send to the device</param>
/// <param name="errorRegisters">Registers returned by the device</param>
/// <param name="protocol">ATA protocol to use</param>
/// <param name="transferRegister">What register contains the transfer length</param>
/// <param name="transferBlocks">Set to <c>true</c> if the transfer length is in block, otherwise it is in bytes</param>
/// <exception cref="InvalidOperationException">If the specified platform is not supported</exception>
internal static int SendAtaCommand(PlatformID ptId, object fd, AtaRegistersLba28 registers, internal static int SendAtaCommand(PlatformID ptId, object fd, AtaRegistersLba28 registers,
out AtaErrorRegistersLba28 errorRegisters, AtaProtocol protocol, out AtaErrorRegistersLba28 errorRegisters, AtaProtocol protocol,
AtaTransferRegister transferRegister, ref byte[] buffer, uint timeout, AtaTransferRegister transferRegister, ref byte[] buffer, uint timeout,
@@ -253,6 +317,21 @@ namespace DiscImageChef.Devices
} }
} }
/// <summary>
/// Sends an ATA command in 48-bit LBA format
/// </summary>
/// <returns>0 if no error occurred, otherwise, errno</returns>
/// <param name="fd">File handle</param>
/// <param name="buffer">Buffer for SCSI command response</param>
/// <param name="timeout">Timeout in seconds</param>
/// <param name="duration">Time it took to execute the command in milliseconds</param>
/// <param name="sense"><c>True</c> if ATA returned non-OK status</param>
/// <param name="registers">Registers to send to the device</param>
/// <param name="errorRegisters">Registers returned by the device</param>
/// <param name="protocol">ATA protocol to use</param>
/// <param name="transferRegister">What register contains the transfer length</param>
/// <param name="transferBlocks">Set to <c>true</c> if the transfer length is in block, otherwise it is in bytes</param>
/// <exception cref="InvalidOperationException">If the specified platform is not supported</exception>
internal static int SendAtaCommand(object fd, AtaRegistersLba48 registers, internal static int SendAtaCommand(object fd, AtaRegistersLba48 registers,
out AtaErrorRegistersLba48 errorRegisters, AtaProtocol protocol, out AtaErrorRegistersLba48 errorRegisters, AtaProtocol protocol,
AtaTransferRegister transferRegister, ref byte[] buffer, uint timeout, AtaTransferRegister transferRegister, ref byte[] buffer, uint timeout,
@@ -264,6 +343,22 @@ namespace DiscImageChef.Devices
timeout, transferBlocks, out duration, out sense); timeout, transferBlocks, out duration, out sense);
} }
/// <summary>
/// Sends an ATA command in 48-bit format
/// </summary>
/// <returns>0 if no error occurred, otherwise, errno</returns>
/// <param name="ptId">Platform ID for executing the command</param>
/// <param name="fd">File handle</param>
/// <param name="buffer">Buffer for SCSI command response</param>
/// <param name="timeout">Timeout in seconds</param>
/// <param name="duration">Time it took to execute the command in milliseconds</param>
/// <param name="sense"><c>True</c> if ATA returned non-OK status</param>
/// <param name="registers">Registers to send to the device</param>
/// <param name="errorRegisters">Registers returned by the device</param>
/// <param name="protocol">ATA protocol to use</param>
/// <param name="transferRegister">What register contains the transfer length</param>
/// <param name="transferBlocks">Set to <c>true</c> if the transfer length is in block, otherwise it is in bytes</param>
/// <exception cref="InvalidOperationException">If the specified platform is not supported</exception>
internal static int SendAtaCommand(PlatformID ptId, object fd, AtaRegistersLba48 registers, internal static int SendAtaCommand(PlatformID ptId, object fd, AtaRegistersLba48 registers,
out AtaErrorRegistersLba48 errorRegisters, AtaProtocol protocol, out AtaErrorRegistersLba48 errorRegisters, AtaProtocol protocol,
AtaTransferRegister transferRegister, ref byte[] buffer, uint timeout, AtaTransferRegister transferRegister, ref byte[] buffer, uint timeout,
@@ -292,6 +387,24 @@ namespace DiscImageChef.Devices
} }
} }
/// <summary>
/// Sends a MMC/SD command
/// </summary>
/// <returns>The result of the command.</returns>
/// <param name="fd">File handle</param>
/// <param name="command">MMC/SD opcode</param>
/// <param name="buffer">Buffer for MMC/SD command response</param>
/// <param name="timeout">Timeout in seconds</param>
/// <param name="duration">Time it took to execute the command in milliseconds</param>
/// <param name="sense"><c>True</c> if MMC/SD returned non-OK status</param>
/// <param name="write"><c>True</c> if data is sent from host to card</param>
/// <param name="isApplication"><c>True</c> if command should be preceded with CMD55</param>
/// <param name="flags">Flags indicating kind and place of response</param>
/// <param name="blocks">How many blocks to transfer</param>
/// <param name="argument">Command argument</param>
/// <param name="response">Response registers</param>
/// <param name="blockSize">Size of block in bytes</param>
/// <exception cref="InvalidOperationException">If the specified platform is not supported</exception>
internal static int SendMmcCommand(object fd, MmcCommands command, bool write, bool isApplication, MmcFlags flags, internal static int SendMmcCommand(object fd, MmcCommands command, bool write, bool isApplication, MmcFlags flags,
uint argument, uint blockSize, uint blocks, ref byte[] buffer, uint argument, uint blockSize, uint blocks, ref byte[] buffer,
out uint[] response, out double duration, out bool sense, uint timeout = 0) out uint[] response, out double duration, out bool sense, uint timeout = 0)
@@ -302,6 +415,25 @@ namespace DiscImageChef.Devices
ref buffer, out response, out duration, out sense, timeout); ref buffer, out response, out duration, out sense, timeout);
} }
/// <summary>
/// Sends a MMC/SD command
/// </summary>
/// <returns>The result of the command.</returns>
/// <param name="ptId">Platform ID for executing the command</param>
/// <param name="fd">File handle</param>
/// <param name="command">MMC/SD opcode</param>
/// <param name="buffer">Buffer for MMC/SD command response</param>
/// <param name="timeout">Timeout in seconds</param>
/// <param name="duration">Time it took to execute the command in milliseconds</param>
/// <param name="sense"><c>True</c> if MMC/SD returned non-OK status</param>
/// <param name="write"><c>True</c> if data is sent from host to card</param>
/// <param name="isApplication"><c>True</c> if command should be preceded with CMD55</param>
/// <param name="flags">Flags indicating kind and place of response</param>
/// <param name="blocks">How many blocks to transfer</param>
/// <param name="argument">Command argument</param>
/// <param name="response">Response registers</param>
/// <param name="blockSize">Size of block in bytes</param>
/// <exception cref="InvalidOperationException">If the specified platform is not supported</exception>
internal static int SendMmcCommand(PlatformID ptId, object fd, MmcCommands command, bool write, internal static int SendMmcCommand(PlatformID ptId, object fd, MmcCommands command, bool write,
bool isApplication, MmcFlags flags, uint argument, uint blockSize, uint blocks, bool isApplication, MmcFlags flags, uint argument, uint blockSize, uint blocks,
ref byte[] buffer, out uint[] response, out double duration, out bool sense, ref byte[] buffer, out uint[] response, out double duration, out bool sense,

View File

@@ -255,6 +255,11 @@ namespace DiscImageChef.Devices.FreeBSD
return error; return error;
} }
/// <summary>
/// Converts ATA protocol to CAM flags
/// </summary>
/// <param name="protocol">ATA protocol</param>
/// <returns>CAM flags</returns>
static CcbFlags AtaProtocolToCamFlags(AtaProtocol protocol) static CcbFlags AtaProtocolToCamFlags(AtaProtocol protocol)
{ {
switch(protocol) switch(protocol)
@@ -273,6 +278,18 @@ namespace DiscImageChef.Devices.FreeBSD
} }
} }
/// <summary>
/// Sends an ATA command in CHS mode
/// </summary>
/// <returns>0 if no error occurred, otherwise, errno</returns>
/// <param name="dev">CAM device</param>
/// <param name="buffer">Buffer for SCSI command response</param>
/// <param name="timeout">Timeout in seconds</param>
/// <param name="duration">Time it took to execute the command in milliseconds</param>
/// <param name="sense"><c>True</c> if ATA error returned non-OK status</param>
/// <param name="registers">Registers to send to drive</param>
/// <param name="errorRegisters">Registers returned by drive</param>
/// <param name="protocol">ATA protocol to use</param>
internal static int SendAtaCommand(IntPtr dev, AtaRegistersChs registers, internal static int SendAtaCommand(IntPtr dev, AtaRegistersChs registers,
out AtaErrorRegistersChs errorRegisters, AtaProtocol protocol, out AtaErrorRegistersChs errorRegisters, AtaProtocol protocol,
ref byte[] buffer, uint timeout, out double duration, out bool sense) ref byte[] buffer, uint timeout, out double duration, out bool sense)
@@ -359,6 +376,18 @@ namespace DiscImageChef.Devices.FreeBSD
return error; return error;
} }
/// <summary>
/// Sends an ATA command in 28-bit LBA mode
/// </summary>
/// <returns>0 if no error occurred, otherwise, errno</returns>
/// <param name="dev">CAM device</param>
/// <param name="buffer">Buffer for SCSI command response</param>
/// <param name="timeout">Timeout in seconds</param>
/// <param name="duration">Time it took to execute the command in milliseconds</param>
/// <param name="sense"><c>True</c> if ATA error returned non-OK status</param>
/// <param name="registers">Registers to send to drive</param>
/// <param name="errorRegisters">Registers returned by drive</param>
/// <param name="protocol">ATA protocol to use</param>
internal static int SendAtaCommand(IntPtr dev, AtaRegistersLba28 registers, internal static int SendAtaCommand(IntPtr dev, AtaRegistersLba28 registers,
out AtaErrorRegistersLba28 errorRegisters, AtaProtocol protocol, out AtaErrorRegistersLba28 errorRegisters, AtaProtocol protocol,
ref byte[] buffer, uint timeout, out double duration, out bool sense) ref byte[] buffer, uint timeout, out double duration, out bool sense)
@@ -445,6 +474,18 @@ namespace DiscImageChef.Devices.FreeBSD
return error; return error;
} }
/// <summary>
/// Sends an ATA command in 48-bit mode
/// </summary>
/// <returns>0 if no error occurred, otherwise, errno</returns>
/// <param name="dev">CAM device</param>
/// <param name="buffer">Buffer for SCSI command response</param>
/// <param name="timeout">Timeout in seconds</param>
/// <param name="duration">Time it took to execute the command in milliseconds</param>
/// <param name="sense"><c>True</c> if ATA error returned non-OK status</param>
/// <param name="registers">Registers to send to drive</param>
/// <param name="errorRegisters">Registers returned by drive</param>
/// <param name="protocol">ATA protocol to use</param>
internal static int SendAtaCommand(IntPtr dev, AtaRegistersLba48 registers, internal static int SendAtaCommand(IntPtr dev, AtaRegistersLba48 registers,
out AtaErrorRegistersLba48 errorRegisters, AtaProtocol protocol, out AtaErrorRegistersLba48 errorRegisters, AtaProtocol protocol,
ref byte[] buffer, uint timeout, out double duration, out bool sense) ref byte[] buffer, uint timeout, out double duration, out bool sense)

View File

@@ -43,6 +43,10 @@ namespace DiscImageChef.Devices.FreeBSD
{ {
static class ListDevices static class ListDevices
{ {
/// <summary>
/// Gets a list of all known storage devices on FreeBSD
/// </summary>
/// <returns>List of devices</returns>
internal static DeviceInfo[] GetList() internal static DeviceInfo[] GetList()
{ {
string[] passDevices = Directory.GetFiles("/dev/", "pass*", SearchOption.TopDirectoryOnly); string[] passDevices = Directory.GetFiles("/dev/", "pass*", SearchOption.TopDirectoryOnly);

View File

@@ -101,6 +101,11 @@ namespace DiscImageChef.Devices.Linux
return error; return error;
} }
/// <summary>
/// Converts ATA protocol to SG_IO direction
/// </summary>
/// <param name="protocol">ATA protocol</param>
/// <returns>SG_IO direction</returns>
static ScsiIoctlDirection AtaProtocolToScsiDirection(AtaProtocol protocol) static ScsiIoctlDirection AtaProtocolToScsiDirection(AtaProtocol protocol)
{ {
switch(protocol) switch(protocol)
@@ -119,6 +124,20 @@ namespace DiscImageChef.Devices.Linux
} }
} }
/// <summary>
/// Sends an ATA command in CHS mode
/// </summary>
/// <returns>0 if no error occurred, otherwise, errno</returns>
/// <param name="fd">File handle</param>
/// <param name="buffer">Buffer for SCSI command response</param>
/// <param name="timeout">Timeout in seconds</param>
/// <param name="duration">Time it took to execute the command in milliseconds</param>
/// <param name="sense"><c>True</c> if ATA error returned non-OK status</param>
/// <param name="registers">Registers to send to drive</param>
/// <param name="errorRegisters">Registers returned by drive</param>
/// <param name="protocol">ATA protocol to use</param>
/// <param name="transferRegister">Which register contains the transfer count</param>
/// <param name="transferBlocks">Set to <c>true</c> if the transfer count is in blocks, otherwise it is in bytes</param>
internal static int SendAtaCommand(int fd, AtaRegistersChs registers, out AtaErrorRegistersChs errorRegisters, internal static int SendAtaCommand(int fd, AtaRegistersChs registers, out AtaErrorRegistersChs errorRegisters,
AtaProtocol protocol, AtaTransferRegister transferRegister, AtaProtocol protocol, AtaTransferRegister transferRegister,
ref byte[] buffer, uint timeout, bool transferBlocks, out double duration, ref byte[] buffer, uint timeout, bool transferBlocks, out double duration,
@@ -180,6 +199,20 @@ namespace DiscImageChef.Devices.Linux
return error; return error;
} }
/// <summary>
/// Sends an ATA command in 28-bit LBA mode
/// </summary>
/// <returns>0 if no error occurred, otherwise, errno</returns>
/// <param name="fd">File handle</param>
/// <param name="buffer">Buffer for SCSI command response</param>
/// <param name="timeout">Timeout in seconds</param>
/// <param name="duration">Time it took to execute the command in milliseconds</param>
/// <param name="sense"><c>True</c> if ATA error returned non-OK status</param>
/// <param name="registers">Registers to send to drive</param>
/// <param name="errorRegisters">Registers returned by drive</param>
/// <param name="protocol">ATA protocol to use</param>
/// <param name="transferRegister">Which register contains the transfer count</param>
/// <param name="transferBlocks">Set to <c>true</c> if the transfer count is in blocks, otherwise it is in bytes</param>
internal static int SendAtaCommand(int fd, AtaRegistersLba28 registers, internal static int SendAtaCommand(int fd, AtaRegistersLba28 registers,
out AtaErrorRegistersLba28 errorRegisters, AtaProtocol protocol, out AtaErrorRegistersLba28 errorRegisters, AtaProtocol protocol,
AtaTransferRegister transferRegister, ref byte[] buffer, uint timeout, AtaTransferRegister transferRegister, ref byte[] buffer, uint timeout,
@@ -241,6 +274,20 @@ namespace DiscImageChef.Devices.Linux
return error; return error;
} }
/// <summary>
/// Sends an ATA command in 48-bit LBA mode
/// </summary>
/// <returns>0 if no error occurred, otherwise, errno</returns>
/// <param name="fd">File handle</param>
/// <param name="buffer">Buffer for SCSI command response</param>
/// <param name="timeout">Timeout in seconds</param>
/// <param name="duration">Time it took to execute the command in milliseconds</param>
/// <param name="sense"><c>True</c> if ATA error returned non-OK status</param>
/// <param name="registers">Registers to send to drive</param>
/// <param name="errorRegisters">Registers returned by drive</param>
/// <param name="protocol">ATA protocol to use</param>
/// <param name="transferRegister">Which register contains the transfer count</param>
/// <param name="transferBlocks">Set to <c>true</c> if the transfer count is in blocks, otherwise it is in bytes</param>
internal static int SendAtaCommand(int fd, AtaRegistersLba48 registers, internal static int SendAtaCommand(int fd, AtaRegistersLba48 registers,
out AtaErrorRegistersLba48 errorRegisters, AtaProtocol protocol, out AtaErrorRegistersLba48 errorRegisters, AtaProtocol protocol,
AtaTransferRegister transferRegister, ref byte[] buffer, uint timeout, AtaTransferRegister transferRegister, ref byte[] buffer, uint timeout,
@@ -375,7 +422,12 @@ namespace DiscImageChef.Devices.Linux
return error; return error;
} }
public static string ReadLink(string path) /// <summary>
/// Reads the contents of a symbolic link
/// </summary>
/// <param name="path">Path to the symbolic link</param>
/// <returns>Contents of the symbolic link</returns>
internal static string ReadLink(string path)
{ {
IntPtr buf = Marshal.AllocHGlobal(4096); IntPtr buf = Marshal.AllocHGlobal(4096);
int resultSize; int resultSize;

View File

@@ -40,6 +40,10 @@ namespace DiscImageChef.Devices.Linux
{ {
const string PATH_SYS_DEVBLOCK = "/sys/block/"; const string PATH_SYS_DEVBLOCK = "/sys/block/";
/// <summary>
/// Gets a list of all known storage devices on Linux
/// </summary>
/// <returns>List of devices</returns>
internal static DeviceInfo[] GetList() internal static DeviceInfo[] GetList()
{ {
string[] sysdevs = Directory.GetFileSystemEntries(PATH_SYS_DEVBLOCK, "*", SearchOption.TopDirectoryOnly); string[] sysdevs = Directory.GetFileSystemEntries(PATH_SYS_DEVBLOCK, "*", SearchOption.TopDirectoryOnly);

View File

@@ -110,6 +110,18 @@ namespace DiscImageChef.Devices.Windows
return error; return error;
} }
/// <summary>
/// Sends an ATA command in CHS mode
/// </summary>
/// <returns>0 if no error occurred, otherwise, errno</returns>
/// <param name="fd">File handle</param>
/// <param name="buffer">Buffer for SCSI command response</param>
/// <param name="timeout">Timeout in seconds</param>
/// <param name="duration">Time it took to execute the command in milliseconds</param>
/// <param name="sense"><c>True</c> if ATA error returned non-OK status</param>
/// <param name="registers">Registers to send to drive</param>
/// <param name="errorRegisters">Registers returned by drive</param>
/// <param name="protocol">ATA protocol to use</param>
internal static int SendAtaCommand(SafeFileHandle fd, AtaRegistersChs registers, internal static int SendAtaCommand(SafeFileHandle fd, AtaRegistersChs registers,
out AtaErrorRegistersChs errorRegisters, AtaProtocol protocol, out AtaErrorRegistersChs errorRegisters, AtaProtocol protocol,
ref byte[] buffer, uint timeout, out double duration, out bool sense) ref byte[] buffer, uint timeout, out double duration, out bool sense)
@@ -199,6 +211,18 @@ namespace DiscImageChef.Devices.Windows
return error; return error;
} }
/// <summary>
/// Sends an ATA command in 28-bit LBA mode
/// </summary>
/// <returns>0 if no error occurred, otherwise, errno</returns>
/// <param name="fd">File handle</param>
/// <param name="buffer">Buffer for SCSI command response</param>
/// <param name="timeout">Timeout in seconds</param>
/// <param name="duration">Time it took to execute the command in milliseconds</param>
/// <param name="sense"><c>True</c> if ATA error returned non-OK status</param>
/// <param name="registers">Registers to send to drive</param>
/// <param name="errorRegisters">Registers returned by drive</param>
/// <param name="protocol">ATA protocol to use</param>
internal static int SendAtaCommand(SafeFileHandle fd, AtaRegistersLba28 registers, internal static int SendAtaCommand(SafeFileHandle fd, AtaRegistersLba28 registers,
out AtaErrorRegistersLba28 errorRegisters, AtaProtocol protocol, out AtaErrorRegistersLba28 errorRegisters, AtaProtocol protocol,
ref byte[] buffer, uint timeout, out double duration, out bool sense) ref byte[] buffer, uint timeout, out double duration, out bool sense)
@@ -288,6 +312,18 @@ namespace DiscImageChef.Devices.Windows
return error; return error;
} }
/// <summary>
/// Sends an ATA command in 48-bit LBA mode
/// </summary>
/// <returns>0 if no error occurred, otherwise, errno</returns>
/// <param name="fd">File handle</param>
/// <param name="buffer">Buffer for SCSI command response</param>
/// <param name="timeout">Timeout in seconds</param>
/// <param name="duration">Time it took to execute the command in milliseconds</param>
/// <param name="sense"><c>True</c> if ATA error returned non-OK status</param>
/// <param name="registers">Registers to send to drive</param>
/// <param name="errorRegisters">Registers returned by drive</param>
/// <param name="protocol">ATA protocol to use</param>
internal static int SendAtaCommand(SafeFileHandle fd, AtaRegistersLba48 registers, internal static int SendAtaCommand(SafeFileHandle fd, AtaRegistersLba48 registers,
out AtaErrorRegistersLba48 errorRegisters, AtaProtocol protocol, out AtaErrorRegistersLba48 errorRegisters, AtaProtocol protocol,
ref byte[] buffer, uint timeout, out double duration, out bool sense) ref byte[] buffer, uint timeout, out double duration, out bool sense)
@@ -389,6 +425,18 @@ namespace DiscImageChef.Devices.Windows
return error; return error;
} }
/// <summary>
/// Sends an ATA command in CHS mode using undocumented Windows XP ioctl
/// </summary>
/// <returns>0 if no error occurred, otherwise, errno</returns>
/// <param name="fd">File handle</param>
/// <param name="buffer">Buffer for SCSI command response</param>
/// <param name="timeout">Timeout in seconds</param>
/// <param name="duration">Time it took to execute the command in milliseconds</param>
/// <param name="sense"><c>True</c> if ATA error returned non-OK status</param>
/// <param name="registers">Registers to send to drive</param>
/// <param name="errorRegisters">Registers returned by drive</param>
/// <param name="protocol">ATA protocol to use</param>
internal static int SendIdeCommand(SafeFileHandle fd, AtaRegistersChs registers, internal static int SendIdeCommand(SafeFileHandle fd, AtaRegistersChs registers,
out AtaErrorRegistersChs errorRegisters, AtaProtocol protocol, out AtaErrorRegistersChs errorRegisters, AtaProtocol protocol,
ref byte[] buffer, uint timeout, out double duration, out bool sense) ref byte[] buffer, uint timeout, out double duration, out bool sense)
@@ -446,6 +494,18 @@ namespace DiscImageChef.Devices.Windows
return error; return error;
} }
/// <summary>
/// Sends an ATA command in 28-bit LBA mode using undocumented Windows XP ioctl
/// </summary>
/// <returns>0 if no error occurred, otherwise, errno</returns>
/// <param name="fd">File handle</param>
/// <param name="buffer">Buffer for SCSI command response</param>
/// <param name="timeout">Timeout in seconds</param>
/// <param name="duration">Time it took to execute the command in milliseconds</param>
/// <param name="sense"><c>True</c> if ATA error returned non-OK status</param>
/// <param name="registers">Registers to send to drive</param>
/// <param name="errorRegisters">Registers returned by drive</param>
/// <param name="protocol">ATA protocol to use</param>
internal static int SendIdeCommand(SafeFileHandle fd, AtaRegistersLba28 registers, internal static int SendIdeCommand(SafeFileHandle fd, AtaRegistersLba28 registers,
out AtaErrorRegistersLba28 errorRegisters, AtaProtocol protocol, out AtaErrorRegistersLba28 errorRegisters, AtaProtocol protocol,
ref byte[] buffer, uint timeout, out double duration, out bool sense) ref byte[] buffer, uint timeout, out double duration, out bool sense)
@@ -503,6 +563,11 @@ namespace DiscImageChef.Devices.Windows
return error; return error;
} }
/// <summary>
/// Gets the device number for a specified handle
/// </summary>
/// <param name="deviceHandle">Device handle</param>
/// <returns>Device number</returns>
static uint GetDeviceNumber(SafeFileHandle deviceHandle) static uint GetDeviceNumber(SafeFileHandle deviceHandle)
{ {
StorageDeviceNumber sdn = new StorageDeviceNumber {deviceNumber = -1}; StorageDeviceNumber sdn = new StorageDeviceNumber {deviceNumber = -1};
@@ -514,6 +579,11 @@ namespace DiscImageChef.Devices.Windows
return (uint)sdn.deviceNumber; return (uint)sdn.deviceNumber;
} }
/// <summary>
/// Gets the internal device path for a specified handle
/// </summary>
/// <param name="fd">Device handle</param>
/// <returns>Device path</returns>
internal static string GetDevicePath(SafeFileHandle fd) internal static string GetDevicePath(SafeFileHandle fd)
{ {
uint devNumber = GetDeviceNumber(fd); uint devNumber = GetDeviceNumber(fd);
@@ -587,6 +657,11 @@ namespace DiscImageChef.Devices.Windows
return null; return null;
} }
/// <summary>
/// Returns true if the specified handle is controlled by a SFFDISK (aka SDHCI) driver
/// </summary>
/// <param name="fd">Device handle</param>
/// <returns><c>true</c> if SDHCI, false otherwise</returns>
internal static bool IsSdhci(SafeFileHandle fd) internal static bool IsSdhci(SafeFileHandle fd)
{ {
SffdiskQueryDeviceProtocolData queryData1 = new SffdiskQueryDeviceProtocolData(); SffdiskQueryDeviceProtocolData queryData1 = new SffdiskQueryDeviceProtocolData();

View File

@@ -43,6 +43,11 @@ namespace DiscImageChef.Devices.Windows
{ {
static class ListDevices static class ListDevices
{ {
/// <summary>
/// Converts a hex dump string to the ASCII string it represents
/// </summary>
/// <param name="hex">Hex dump</param>
/// <returns>Decoded string</returns>
static string HexStringToString(string hex) static string HexStringToString(string hex)
{ {
StringBuilder result = new StringBuilder(); StringBuilder result = new StringBuilder();
@@ -53,6 +58,10 @@ namespace DiscImageChef.Devices.Windows
return result.ToString(); return result.ToString();
} }
/// <summary>
/// Gets a list of all known storage devices on Windows
/// </summary>
/// <returns>List of devices</returns>
[SuppressMessage("ReSharper", "RedundantCatchClause")] [SuppressMessage("ReSharper", "RedundantCatchClause")]
internal static DeviceInfo[] GetList() internal static DeviceInfo[] GetList()
{ {

View File

@@ -41,6 +41,9 @@ using System.Text;
namespace DiscImageChef.Devices.Windows namespace DiscImageChef.Devices.Windows
{ {
// TODO: Even after cleaning, refactoring and xml-documenting, this code needs some love // TODO: Even after cleaning, refactoring and xml-documenting, this code needs some love
/// <summary>
/// Implements functions for getting and accesing information from the USB bus
/// </summary>
static partial class Usb static partial class Usb
{ {
#region "API Region" #region "API Region"
@@ -78,27 +81,12 @@ namespace DiscImageChef.Devices.Windows
// ********************** Enumerations ************************ // ********************** Enumerations ************************
//typedef enum _USB_HUB_NODE {
// UsbHub,
// UsbMIParent
//} USB_HUB_NODE;
enum UsbHubNode enum UsbHubNode
{ {
UsbHub, UsbHub,
UsbMiParent UsbMiParent
} }
//typedef enum _USB_CONNECTION_STATUS {
// NoDeviceConnected,
// DeviceConnected,
// DeviceFailedEnumeration,
// DeviceGeneralFailure,
// DeviceCausedOvercurrent,
// DeviceNotEnoughPower,
// DeviceNotEnoughBandwidth,
// DeviceHubNestedTooDeeply,
// DeviceInLegacyHub
//} USB_CONNECTION_STATUS, *PUSB_CONNECTION_STATUS;
enum UsbConnectionStatus enum UsbConnectionStatus
{ {
NoDeviceConnected, NoDeviceConnected,
@@ -112,11 +100,6 @@ namespace DiscImageChef.Devices.Windows
DeviceInLegacyHub DeviceInLegacyHub
} }
//typedef enum _USB_DEVICE_SPEED {
// UsbLowSpeed = 0,
// UsbFullSpeed,
// UsbHighSpeed
//} USB_DEVICE_SPEED;
enum UsbDeviceSpeed : byte enum UsbDeviceSpeed : byte
{ {
UsbLowSpeed, UsbLowSpeed,
@@ -126,12 +109,6 @@ namespace DiscImageChef.Devices.Windows
// ********************** Stuctures ************************ // ********************** Stuctures ************************
//typedef struct _SP_DEVINFO_DATA {
// DWORD cbSize;
// GUID ClassGuid;
// DWORD DevInst;
// ULONG_PTR Reserved;
//} SP_DEVINFO_DATA, *PSP_DEVINFO_DATA;
[StructLayout(LayoutKind.Sequential)] [StructLayout(LayoutKind.Sequential)]
struct SpDevinfoData struct SpDevinfoData
{ {
@@ -141,12 +118,6 @@ namespace DiscImageChef.Devices.Windows
internal IntPtr Reserved; internal IntPtr Reserved;
} }
//typedef struct _SP_DEVICE_INTERFACE_DATA {
// DWORD cbSize;
// GUID InterfaceClassGuid;
// DWORD Flags;
// ULONG_PTR Reserved;
//} SP_DEVICE_INTERFACE_DATA, *PSP_DEVICE_INTERFACE_DATA;
[StructLayout(LayoutKind.Sequential)] [StructLayout(LayoutKind.Sequential)]
struct SpDeviceInterfaceData struct SpDeviceInterfaceData
{ {
@@ -156,10 +127,6 @@ namespace DiscImageChef.Devices.Windows
internal IntPtr Reserved; internal IntPtr Reserved;
} }
//typedef struct _SP_DEVICE_INTERFACE_DETAIL_DATA {
// DWORD cbSize;
// TCHAR DevicePath[ANYSIZE_ARRAY];
//} SP_DEVICE_INTERFACE_DETAIL_DATA, *PSP_DEVICE_INTERFACE_DETAIL_DATA;
[StructLayout(LayoutKind.Sequential, CharSet = CharSet.Auto)] [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Auto)]
struct SpDeviceInterfaceDetailData struct SpDeviceInterfaceDetailData
{ {
@@ -167,10 +134,6 @@ namespace DiscImageChef.Devices.Windows
[MarshalAs(UnmanagedType.ByValTStr, SizeConst = BUFFER_SIZE)] internal string DevicePath; [MarshalAs(UnmanagedType.ByValTStr, SizeConst = BUFFER_SIZE)] internal string DevicePath;
} }
//typedef struct _USB_HCD_DRIVERKEY_NAME {
// ULONG ActualLength;
// WCHAR DriverKeyName[1];
//} USB_HCD_DRIVERKEY_NAME, *PUSB_HCD_DRIVERKEY_NAME;
[StructLayout(LayoutKind.Sequential, CharSet = CharSet.Auto)] [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Auto)]
struct UsbHcdDriverkeyName struct UsbHcdDriverkeyName
{ {
@@ -178,10 +141,6 @@ namespace DiscImageChef.Devices.Windows
[MarshalAs(UnmanagedType.ByValTStr, SizeConst = BUFFER_SIZE)] internal string DriverKeyName; [MarshalAs(UnmanagedType.ByValTStr, SizeConst = BUFFER_SIZE)] internal string DriverKeyName;
} }
//typedef struct _USB_ROOT_HUB_NAME {
// ULONG ActualLength;
// WCHAR RootHubName[1];
//} USB_ROOT_HUB_NAME, *PUSB_ROOT_HUB_NAME;
[StructLayout(LayoutKind.Sequential, CharSet = CharSet.Auto)] [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Auto)]
struct UsbRootHubName struct UsbRootHubName
{ {
@@ -189,15 +148,6 @@ namespace DiscImageChef.Devices.Windows
[MarshalAs(UnmanagedType.ByValTStr, SizeConst = BUFFER_SIZE)] internal string RootHubName; [MarshalAs(UnmanagedType.ByValTStr, SizeConst = BUFFER_SIZE)] internal string RootHubName;
} }
//typedef struct _USB_HUB_DESCRIPTOR {
// UCHAR bDescriptorLength;
// UCHAR bDescriptorType;
// UCHAR bNumberOfPorts;
// USHORT wHubCharacteristics;
// UCHAR bPowerOnToPowerGood;
// UCHAR bHubControlCurrent;
// UCHAR bRemoveAndPowerMask[64];
//} USB_HUB_DESCRIPTOR, *PUSB_HUB_DESCRIPTOR;
[StructLayout(LayoutKind.Sequential, Pack = 1)] [StructLayout(LayoutKind.Sequential, Pack = 1)]
struct UsbHubDescriptor struct UsbHubDescriptor
{ {
@@ -210,10 +160,6 @@ namespace DiscImageChef.Devices.Windows
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 64)] internal byte[] bRemoveAndPowerMask; [MarshalAs(UnmanagedType.ByValArray, SizeConst = 64)] internal byte[] bRemoveAndPowerMask;
} }
//typedef struct _USB_HUB_INFORMATION {
// USB_HUB_DESCRIPTOR HubDescriptor;
// BOOLEAN HubIsBusPowered;
//} USB_HUB_INFORMATION, *PUSB_HUB_INFORMATION;
[StructLayout(LayoutKind.Sequential)] [StructLayout(LayoutKind.Sequential)]
struct UsbHubInformation struct UsbHubInformation
{ {
@@ -221,13 +167,6 @@ namespace DiscImageChef.Devices.Windows
internal byte HubIsBusPowered; internal byte HubIsBusPowered;
} }
//typedef struct _USB_NODE_INFORMATION {
// USB_HUB_NODE NodeType;
// union {
// USB_HUB_INFORMATION HubInformation;
// USB_MI_PARENT_INFORMATION MiParentInformation;
// } u;
//} USB_NODE_INFORMATION, *PUSB_NODE_INFORMATION;
[StructLayout(LayoutKind.Sequential)] [StructLayout(LayoutKind.Sequential)]
struct UsbNodeInformation struct UsbNodeInformation
{ {
@@ -235,17 +174,6 @@ namespace DiscImageChef.Devices.Windows
internal UsbHubInformation HubInformation; // Yeah, I'm assuming we'll just use the first form internal UsbHubInformation HubInformation; // Yeah, I'm assuming we'll just use the first form
} }
//typedef struct _USB_NODE_CONNECTION_INFORMATION_EX {
// ULONG ConnectionIndex;
// USB_DEVICE_DESCRIPTOR DeviceDescriptor;
// UCHAR CurrentConfigurationValue;
// UCHAR Speed;
// BOOLEAN DeviceIsHub;
// USHORT DeviceAddress;
// ULONG NumberOfOpenPipes;
// USB_CONNECTION_STATUS ConnectionStatus;
// USB_PIPE_INFO PipeList[0];
//} USB_NODE_CONNECTION_INFORMATION_EX, *PUSB_NODE_CONNECTION_INFORMATION_EX;
[StructLayout(LayoutKind.Sequential, Pack = 1)] [StructLayout(LayoutKind.Sequential, Pack = 1)]
struct UsbNodeConnectionInformationEx struct UsbNodeConnectionInformationEx
{ {
@@ -261,22 +189,6 @@ namespace DiscImageChef.Devices.Windows
//internal IntPtr PipeList; //internal IntPtr PipeList;
} }
//typedef struct _USB_DEVICE_DESCRIPTOR {
// UCHAR bLength;
// UCHAR bDescriptorType;
// USHORT bcdUSB;
// UCHAR bDeviceClass;
// UCHAR bDeviceSubClass;
// UCHAR bDeviceProtocol;
// UCHAR bMaxPacketSize0;
// USHORT idVendor;
// USHORT idProduct;
// USHORT bcdDevice;
// UCHAR iManufacturer;
// UCHAR iProduct;
// UCHAR iSerialNumber;
// UCHAR bNumConfigurations;
//} USB_DEVICE_DESCRIPTOR, *PUSB_DEVICE_DESCRIPTOR ;
[StructLayout(LayoutKind.Sequential, Pack = 1)] [StructLayout(LayoutKind.Sequential, Pack = 1)]
[SuppressMessage("ReSharper", "MemberCanBePrivate.Global")] [SuppressMessage("ReSharper", "MemberCanBePrivate.Global")]
internal struct UsbDeviceDescriptor internal struct UsbDeviceDescriptor
@@ -297,11 +209,6 @@ namespace DiscImageChef.Devices.Windows
internal byte bNumConfigurations; internal byte bNumConfigurations;
} }
//typedef struct _USB_STRING_DESCRIPTOR {
// UCHAR bLength;
// UCHAR bDescriptorType;
// WCHAR bString[1];
//} USB_STRING_DESCRIPTOR, *PUSB_STRING_DESCRIPTOR;
[StructLayout(LayoutKind.Sequential, CharSet = CharSet.Auto)] [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Auto)]
struct UsbStringDescriptor struct UsbStringDescriptor
{ {
@@ -310,17 +217,6 @@ namespace DiscImageChef.Devices.Windows
[MarshalAs(UnmanagedType.ByValTStr, SizeConst = MAXIMUM_USB_STRING_LENGTH)] internal string bString; [MarshalAs(UnmanagedType.ByValTStr, SizeConst = MAXIMUM_USB_STRING_LENGTH)] internal string bString;
} }
//typedef struct _USB_DESCRIPTOR_REQUEST {
// ULONG ConnectionIndex;
// struct {
// UCHAR bmRequest;
// UCHAR bRequest;
// USHORT wValue;
// USHORT wIndex;
// USHORT wLength;
// } SetupPacket;
// UCHAR Data[0];
//} USB_DESCRIPTOR_REQUEST, *PUSB_DESCRIPTOR_REQUEST
[StructLayout(LayoutKind.Sequential)] [StructLayout(LayoutKind.Sequential)]
struct UsbSetupPacket struct UsbSetupPacket
{ {
@@ -340,11 +236,6 @@ namespace DiscImageChef.Devices.Windows
//internal byte[] Data; //internal byte[] Data;
} }
//typedef struct _USB_NODE_CONNECTION_NAME {
// ULONG ConnectionIndex;
// ULONG ActualLength;
// WCHAR NodeName[1];
//} USB_NODE_CONNECTION_NAME, *PUSB_NODE_CONNECTION_NAME;
[StructLayout(LayoutKind.Sequential, CharSet = CharSet.Auto)] [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Auto)]
struct UsbNodeConnectionName struct UsbNodeConnectionName
{ {
@@ -353,11 +244,6 @@ namespace DiscImageChef.Devices.Windows
[MarshalAs(UnmanagedType.ByValTStr, SizeConst = BUFFER_SIZE)] internal string NodeName; [MarshalAs(UnmanagedType.ByValTStr, SizeConst = BUFFER_SIZE)] internal string NodeName;
} }
//typedef struct _USB_NODE_CONNECTION_DRIVERKEY_NAME {
// ULONG ConnectionIndex;
// ULONG ActualLength;
// WCHAR DriverKeyName[1];
//} USB_NODE_CONNECTION_DRIVERKEY_NAME, *PUSB_NODE_CONNECTION_DRIVERKEY_NAME;
[StructLayout(LayoutKind.Sequential, CharSet = CharSet.Auto)] [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Auto)]
struct UsbNodeConnectionDriverkeyName // Yes, this is the same as the structure above... struct UsbNodeConnectionDriverkeyName // Yes, this is the same as the structure above...
{ {
@@ -368,12 +254,6 @@ namespace DiscImageChef.Devices.Windows
// ********************** API Definitions ************************ // ********************** API Definitions ************************
//HDEVINFO SetupDiGetClassDevs(
// const GUID* ClassGuid,
// PCTSTR Enumerator,
// HWND hwndParent,
// DWORD Flags
//);
[DllImport("setupapi.dll", CharSet = CharSet.Auto)] [DllImport("setupapi.dll", CharSet = CharSet.Auto)]
static extern IntPtr SetupDiGetClassDevs( // 1st form using a ClassGUID static extern IntPtr SetupDiGetClassDevs( // 1st form using a ClassGUID
ref Guid classGuid, int enumerator, IntPtr hwndParent, int flags); ref Guid classGuid, int enumerator, IntPtr hwndParent, int flags);
@@ -381,26 +261,11 @@ namespace DiscImageChef.Devices.Windows
[DllImport("setupapi.dll", CharSet = CharSet.Auto)] // 2nd form uses an Enumerator [DllImport("setupapi.dll", CharSet = CharSet.Auto)] // 2nd form uses an Enumerator
static extern IntPtr SetupDiGetClassDevs(int classGuid, string enumerator, IntPtr hwndParent, int flags); static extern IntPtr SetupDiGetClassDevs(int classGuid, string enumerator, IntPtr hwndParent, int flags);
//BOOL SetupDiEnumDeviceInterfaces(
// HDEVINFO DeviceInfoSet,
// PSP_DEVINFO_DATA DeviceInfoData,
// const GUID* InterfaceClassGuid,
// DWORD MemberIndex,
// PSP_DEVICE_INTERFACE_DATA DeviceInterfaceData
//);
[DllImport("setupapi.dll", SetLastError = true, CharSet = CharSet.Auto)] [DllImport("setupapi.dll", SetLastError = true, CharSet = CharSet.Auto)]
static extern bool SetupDiEnumDeviceInterfaces(IntPtr deviceInfoSet, IntPtr deviceInfoData, static extern bool SetupDiEnumDeviceInterfaces(IntPtr deviceInfoSet, IntPtr deviceInfoData,
ref Guid interfaceClassGuid, int memberIndex, ref Guid interfaceClassGuid, int memberIndex,
ref SpDeviceInterfaceData deviceInterfaceData); ref SpDeviceInterfaceData deviceInterfaceData);
//BOOL SetupDiGetDeviceInterfaceDetail(
// HDEVINFO DeviceInfoSet,
// PSP_DEVICE_INTERFACE_DATA DeviceInterfaceData,
// PSP_DEVICE_INTERFACE_DETAIL_DATA DeviceInterfaceDetailData,
// DWORD DeviceInterfaceDetailDataSize,
// PDWORD RequiredSize,
// PSP_DEVINFO_DATA DeviceInfoData
//);
[DllImport("setupapi.dll", SetLastError = true, CharSet = CharSet.Auto)] [DllImport("setupapi.dll", SetLastError = true, CharSet = CharSet.Auto)]
static extern bool SetupDiGetDeviceInterfaceDetail(IntPtr deviceInfoSet, static extern bool SetupDiGetDeviceInterfaceDetail(IntPtr deviceInfoSet,
ref SpDeviceInterfaceData deviceInterfaceData, ref SpDeviceInterfaceData deviceInterfaceData,
@@ -409,87 +274,42 @@ namespace DiscImageChef.Devices.Windows
int deviceInterfaceDetailDataSize, ref int requiredSize, int deviceInterfaceDetailDataSize, ref int requiredSize,
ref SpDevinfoData deviceInfoData); ref SpDevinfoData deviceInfoData);
//BOOL SetupDiGetDeviceRegistryProperty(
// HDEVINFO DeviceInfoSet,
// PSP_DEVINFO_DATA DeviceInfoData,
// DWORD Property,
// PDWORD PropertyRegDataType,
// PBYTE PropertyBuffer,
// DWORD PropertyBufferSize,
// PDWORD RequiredSize
//);
[DllImport("setupapi.dll", SetLastError = true, CharSet = CharSet.Auto)] [DllImport("setupapi.dll", SetLastError = true, CharSet = CharSet.Auto)]
static extern bool SetupDiGetDeviceRegistryProperty(IntPtr deviceInfoSet, ref SpDevinfoData deviceInfoData, static extern bool SetupDiGetDeviceRegistryProperty(IntPtr deviceInfoSet, ref SpDevinfoData deviceInfoData,
int iProperty, ref int propertyRegDataType, int iProperty, ref int propertyRegDataType,
IntPtr propertyBuffer, int propertyBufferSize, IntPtr propertyBuffer, int propertyBufferSize,
ref int requiredSize); ref int requiredSize);
//BOOL SetupDiEnumDeviceInfo(
// HDEVINFO DeviceInfoSet,
// DWORD MemberIndex,
// PSP_DEVINFO_DATA DeviceInfoData
//);
[DllImport("setupapi.dll", SetLastError = true, CharSet = CharSet.Auto)] [DllImport("setupapi.dll", SetLastError = true, CharSet = CharSet.Auto)]
static extern bool SetupDiEnumDeviceInfo(IntPtr deviceInfoSet, int memberIndex, static extern bool SetupDiEnumDeviceInfo(IntPtr deviceInfoSet, int memberIndex,
ref SpDevinfoData deviceInfoData); ref SpDevinfoData deviceInfoData);
//BOOL SetupDiDestroyDeviceInfoList(
// HDEVINFO DeviceInfoSet
//);
[DllImport("setupapi.dll", SetLastError = true)] [DllImport("setupapi.dll", SetLastError = true)]
static extern bool SetupDiDestroyDeviceInfoList(IntPtr deviceInfoSet); static extern bool SetupDiDestroyDeviceInfoList(IntPtr deviceInfoSet);
//WINSETUPAPI BOOL WINAPI SetupDiGetDeviceInstanceId(
// IN HDEVINFO DeviceInfoSet,
// IN PSP_DEVINFO_DATA DeviceInfoData,
// OUT PTSTR DeviceInstanceId,
// IN DWORD DeviceInstanceIdSize,
// OUT PDWORD RequiredSize OPTIONAL
//);
[DllImport("setupapi.dll", SetLastError = true, CharSet = CharSet.Auto)] [DllImport("setupapi.dll", SetLastError = true, CharSet = CharSet.Auto)]
static extern bool SetupDiGetDeviceInstanceId(IntPtr deviceInfoSet, ref SpDevinfoData deviceInfoData, static extern bool SetupDiGetDeviceInstanceId(IntPtr deviceInfoSet, ref SpDevinfoData deviceInfoData,
StringBuilder deviceInstanceId, int deviceInstanceIdSize, StringBuilder deviceInstanceId, int deviceInstanceIdSize,
out int requiredSize); out int requiredSize);
//BOOL DeviceIoControl(
// HANDLE hDevice,
// DWORD dwIoControlCode,
// LPVOID lpInBuffer,
// DWORD nInBufferSize,
// LPVOID lpOutBuffer,
// DWORD nOutBufferSize,
// LPDWORD lpBytesReturned,
// LPOVERLAPPED lpOverlapped
//);
[DllImport("kernel32.dll", SetLastError = true, CharSet = CharSet.Auto)] [DllImport("kernel32.dll", SetLastError = true, CharSet = CharSet.Auto)]
static extern bool DeviceIoControl(IntPtr hDevice, int dwIoControlCode, IntPtr lpInBuffer, int nInBufferSize, static extern bool DeviceIoControl(IntPtr hDevice, int dwIoControlCode, IntPtr lpInBuffer, int nInBufferSize,
IntPtr lpOutBuffer, int nOutBufferSize, out int lpBytesReturned, IntPtr lpOutBuffer, int nOutBufferSize, out int lpBytesReturned,
IntPtr lpOverlapped); IntPtr lpOverlapped);
//HANDLE CreateFile(
// LPCTSTR lpFileName,
// DWORD dwDesiredAccess,
// DWORD dwShareMode,
// LPSECURITY_ATTRIBUTES lpSecurityAttributes,
// DWORD dwCreationDisposition,
// DWORD dwFlagsAndAttributes,
// HANDLE hTemplateFile
//);
[DllImport("kernel32.dll", SetLastError = true, CharSet = CharSet.Auto)] [DllImport("kernel32.dll", SetLastError = true, CharSet = CharSet.Auto)]
static extern IntPtr CreateFile(string lpFileName, int dwDesiredAccess, int dwShareMode, static extern IntPtr CreateFile(string lpFileName, int dwDesiredAccess, int dwShareMode,
IntPtr lpSecurityAttributes, int dwCreationDisposition, IntPtr lpSecurityAttributes, int dwCreationDisposition,
int dwFlagsAndAttributes, IntPtr hTemplateFile); int dwFlagsAndAttributes, IntPtr hTemplateFile);
//BOOL CloseHandle(
// HANDLE hObject
//);
[DllImport("kernel32.dll", SetLastError = true, CharSet = CharSet.Auto)] [DllImport("kernel32.dll", SetLastError = true, CharSet = CharSet.Auto)]
static extern bool CloseHandle(IntPtr hObject); static extern bool CloseHandle(IntPtr hObject);
#endregion #endregion
// /// <summary>
// Return a list of USB Host Controllers /// Return a list of USB Host Controllers
// /// </summary>
/// <returns>List of USB Host Controllers</returns>
static IEnumerable<UsbController> GetHostControllers() static IEnumerable<UsbController> GetHostControllers()
{ {
List<UsbController> hostList = new List<UsbController>(); List<UsbController> hostList = new List<UsbController>();
@@ -554,15 +374,17 @@ namespace DiscImageChef.Devices.Windows
return new ReadOnlyCollection<UsbController>(hostList); return new ReadOnlyCollection<UsbController>(hostList);
} }
// /// <summary>
// The USB Host Controller Class /// Represents a USB Host Controller
// /// </summary>
class UsbController class UsbController
{ {
internal int ControllerIndex; internal int ControllerIndex;
internal string ControllerDriverKeyName, ControllerDevicePath, ControllerDeviceDesc; internal string ControllerDriverKeyName, ControllerDevicePath, ControllerDeviceDesc;
// A simple default constructor /// <summary>
/// A simple default constructor
/// </summary>
internal UsbController() internal UsbController()
{ {
ControllerIndex = 0; ControllerIndex = 0;
@@ -571,19 +393,19 @@ namespace DiscImageChef.Devices.Windows
ControllerDriverKeyName = ""; ControllerDriverKeyName = "";
} }
// Return the index of the instance /// <summary>Return the index of the instance</summary>
internal int Index => 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}" /// <summary>Return the Device Path, such as "\\?\pci#ven_10de&amp;dev_005a&amp;subsys_815a1043&amp;rev_a2#3&267a616a&0&58#{3abf6f2d-71c4-462a-8a92-1e6861e6af27}"</summary>
internal string DevicePath => ControllerDevicePath; internal string DevicePath => ControllerDevicePath;
// The DriverKeyName may be useful as a search key /// <summary>The DriverKeyName may be useful as a search key</summary>
internal string DriverKeyName => ControllerDriverKeyName; internal string DriverKeyName => ControllerDriverKeyName;
// Return the Friendly Name, such as "VIA USB Enhanced Host Controller" /// <summary>Return the Friendly Name, such as "VIA USB Enhanced Host Controller"</summary>
internal string Name => ControllerDeviceDesc; internal string Name => ControllerDeviceDesc;
// Return Root Hub for this Controller /// <summary>Return Root Hub for this Controller</summary>
internal UsbHub GetRootHub() internal UsbHub GetRootHub()
{ {
IntPtr h, h2; IntPtr h, h2;
@@ -637,9 +459,7 @@ namespace DiscImageChef.Devices.Windows
} }
} }
// /// <summary>The Hub class</summary>
// The Hub class
//
internal class UsbHub internal class UsbHub
{ {
internal int HubPortCount; internal int HubPortCount;
@@ -647,7 +467,7 @@ namespace DiscImageChef.Devices.Windows
internal string HubManufacturer, HubProduct, HubSerialNumber, HubInstanceId; internal string HubManufacturer, HubProduct, HubSerialNumber, HubInstanceId;
internal bool HubIsBusPowered, HubIsRootHub; internal bool HubIsBusPowered, HubIsRootHub;
// a simple default constructor /// <summary>a simple default constructor</summary>
internal UsbHub() internal UsbHub()
{ {
HubPortCount = 0; HubPortCount = 0;
@@ -662,25 +482,25 @@ namespace DiscImageChef.Devices.Windows
HubInstanceId = ""; HubInstanceId = "";
} }
// return Port Count /// <summary>return Port Count</summary>
internal int PortCount => 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}" /// <summary>return the Device Path, such as "\\?\pci#ven_10de&amp;dev_005a&amp;subsys_815a1043&amp;rev_a2#3&267a616a&0&58#{3abf6f2d-71c4-462a-8a92-1e6861e6af27}"</summary>
internal string DevicePath => HubDevicePath; internal string DevicePath => HubDevicePath;
// The DriverKey may be useful as a search key /// <summary>The DriverKey may be useful as a search key</summary>
internal string DriverKey => HubDriverKey; internal string DriverKey => HubDriverKey;
// return the Friendly Name, such as "VIA USB Enhanced Host Controller" /// <summary>return the Friendly Name, such as "VIA USB Enhanced Host Controller"</summary>
internal string Name => HubDeviceDesc; internal string Name => HubDeviceDesc;
// the device path of this device /// <summary>the device path of this device</summary>
internal string InstanceId => HubInstanceId; internal string InstanceId => HubInstanceId;
// is is this a self-powered hub? /// <summary>is is this a self-powered hub?</summary>
internal bool IsBusPowered => HubIsBusPowered; internal bool IsBusPowered => HubIsBusPowered;
// is this a root hub? /// <summary>is this a root hub?</summary>
internal bool IsRootHub => HubIsRootHub; internal bool IsRootHub => HubIsRootHub;
internal string Manufacturer => HubManufacturer; internal string Manufacturer => HubManufacturer;
@@ -689,7 +509,10 @@ namespace DiscImageChef.Devices.Windows
internal string SerialNumber => HubSerialNumber; internal string SerialNumber => HubSerialNumber;
// return a list of the down stream ports /// <summary>
/// return a list of the down stream ports
/// </summary>
/// <returns>List of downstream ports</returns>
internal IEnumerable<UsbPort> GetPorts() internal IEnumerable<UsbPort> GetPorts()
{ {
List<UsbPort> portList = new List<UsbPort>(); List<UsbPort> portList = new List<UsbPort>();
@@ -744,9 +567,9 @@ namespace DiscImageChef.Devices.Windows
} }
} }
// /// <summary>
// The Port Class /// Represents an USB port
// /// </summary>
internal class UsbPort internal class UsbPort
{ {
internal int PortPortNumber; internal int PortPortNumber;
@@ -754,7 +577,7 @@ namespace DiscImageChef.Devices.Windows
internal bool PortIsHub, PortIsDeviceConnected; internal bool PortIsHub, PortIsDeviceConnected;
internal UsbDeviceDescriptor PortDeviceDescriptor; internal UsbDeviceDescriptor PortDeviceDescriptor;
// a simple default constructor /// <summary>a simple default constructor</summary>
internal UsbPort() internal UsbPort()
{ {
PortPortNumber = 0; PortPortNumber = 0;
@@ -765,25 +588,28 @@ namespace DiscImageChef.Devices.Windows
PortIsDeviceConnected = false; PortIsDeviceConnected = false;
} }
// return Port Index of the Hub /// <summary>return Port Index of the Hub</summary>
internal int PortNumber => PortPortNumber; internal int PortNumber => PortPortNumber;
// return the Device Path of the Hub /// <summary>return the Device Path of the Hub</summary>
internal string HubDevicePath => PortHubDevicePath; internal string HubDevicePath => PortHubDevicePath;
// the status (see USB_CONNECTION_STATUS above) /// <summary>the status (see USB_CONNECTION_STATUS above)</summary>
internal string Status => PortStatus; internal string Status => PortStatus;
// the speed of the connection (see USB_DEVICE_SPEED above) /// <summary>the speed of the connection (see USB_DEVICE_SPEED above)</summary>
internal string Speed => PortSpeed; internal string Speed => PortSpeed;
// is this a downstream external hub? /// <summary>is this a downstream external hub?</summary>
internal bool IsHub => PortIsHub; internal bool IsHub => PortIsHub;
// is anybody home? /// <summary>is anybody home?</summary>
internal bool IsDeviceConnected => PortIsDeviceConnected; internal bool IsDeviceConnected => PortIsDeviceConnected;
// return a down stream external hub /// <summary>
/// return a down stream external hub
/// </summary>
/// <returns>Downstream external hub</returns>
internal UsbDevice GetDevice() internal UsbDevice GetDevice()
{ {
if(!PortIsDeviceConnected) return null; if(!PortIsDeviceConnected) return null;
@@ -955,7 +781,10 @@ namespace DiscImageChef.Devices.Windows
return device; return device;
} }
// return a down stream external hub /// <summary>
/// return a down stream external hub
/// </summary>
/// <returns>Downstream external hub</returns>
internal UsbHub GetHub() internal UsbHub GetHub()
{ {
if(!PortIsHub) return null; if(!PortIsHub) return null;
@@ -1022,9 +851,9 @@ namespace DiscImageChef.Devices.Windows
} }
} }
// /// <summary>
// The USB Device Class /// Represents an USB device
// /// </summary>
internal class UsbDevice internal class UsbDevice
{ {
internal int DevicePortNumber; internal int DevicePortNumber;
@@ -1033,7 +862,7 @@ namespace DiscImageChef.Devices.Windows
internal UsbDeviceDescriptor DeviceDescriptor; internal UsbDeviceDescriptor DeviceDescriptor;
internal byte[] BinaryDeviceDescriptors; internal byte[] BinaryDeviceDescriptors;
// a simple default constructor /// <summary>a simple default constructor</summary>
internal UsbDevice() internal UsbDevice()
{ {
DevicePortNumber = 0; DevicePortNumber = 0;
@@ -1047,19 +876,19 @@ namespace DiscImageChef.Devices.Windows
BinaryDeviceDescriptors = null; BinaryDeviceDescriptors = null;
} }
// return Port Index of the Hub /// <summary>return Port Index of the Hub</summary>
internal int PortNumber => DevicePortNumber; internal int PortNumber => DevicePortNumber;
// return the Device Path of the Hub (the parent device) /// <summary>return the Device Path of the Hub (the parent device)</summary>
internal string HubDevicePath => DeviceHubDevicePath; internal string HubDevicePath => DeviceHubDevicePath;
// useful as a search key /// <summary>useful as a search key</summary>
internal string DriverKey => DeviceDriverKey; internal string DriverKey => DeviceDriverKey;
// the device path of this device /// <summary>the device path of this device</summary>
internal string InstanceId => DeviceInstanceId; internal string InstanceId => DeviceInstanceId;
// the friendly name /// <summary>the friendly name</summary>
internal string Name => DeviceName; internal string Name => DeviceName;
internal string Manufacturer => DeviceManufacturer; internal string Manufacturer => DeviceManufacturer;
@@ -1071,9 +900,11 @@ namespace DiscImageChef.Devices.Windows
internal byte[] BinaryDescriptors => BinaryDeviceDescriptors; internal byte[] BinaryDescriptors => BinaryDeviceDescriptors;
} }
// /// <summary>
// private function for finding a USB device's Description /// private function for finding a USB device's Description
// /// </summary>
/// <param name="driverKeyName">Device driver key name</param>
/// <returns>USB device description</returns>
static string GetDescriptionByKeyName(string driverKeyName) static string GetDescriptionByKeyName(string driverKeyName)
{ {
string ans = ""; string ans = "";
@@ -1124,9 +955,11 @@ namespace DiscImageChef.Devices.Windows
return ans; return ans;
} }
// /// <summary>
// private function for finding a USB device's Instance ID /// private function for finding a USB device's Instance ID
// /// </summary>
/// <param name="driverKeyName">Device driver key name</param>
/// <returns>Device instance ID</returns>
static string GetInstanceIdByKeyName(string driverKeyName) static string GetInstanceIdByKeyName(string driverKeyName)
{ {
string ans = ""; string ans = "";

View File

@@ -42,11 +42,15 @@ namespace DiscImageChef.Devices.Windows
// You might not want to keep these in the USB class... your choice // You might not want to keep these in the USB class... your choice
// //
// TODO: Even after cleaning, refactoring and xml-documenting, this code needs some love // TODO: Even after cleaning, refactoring and xml-documenting, this code needs some love
/// <summary>
/// Implements functions for getting and accesing information from the USB bus
/// </summary>
static partial class Usb static partial class Usb
{ {
// /// <summary>
// Get a list of all connected devices /// Get a list of all connected devices
// /// </summary>
/// <returns>List of usb devices</returns>
internal static List<UsbDevice> GetConnectedDevices() internal static List<UsbDevice> GetConnectedDevices()
{ {
List<UsbDevice> devList = new List<UsbDevice>(); List<UsbDevice> devList = new List<UsbDevice>();
@@ -56,7 +60,11 @@ namespace DiscImageChef.Devices.Windows
return devList; return devList;
} }
// private routine for enumerating a hub /// <summary>
/// private routine for enumerating a hub
/// </summary>
/// <param name="hub">Hub</param>
/// <param name="devList">Device list</param>
static void ListHub(UsbHub hub, ICollection<UsbDevice> devList) static void ListHub(UsbHub hub, ICollection<UsbDevice> devList)
{ {
foreach(UsbPort port in hub.GetPorts()) foreach(UsbPort port in hub.GetPorts())
@@ -64,9 +72,11 @@ namespace DiscImageChef.Devices.Windows
else { if(port.IsDeviceConnected) devList.Add(port.GetDevice()); } else { if(port.IsDeviceConnected) devList.Add(port.GetDevice()); }
} }
// /// <summary>
// Find a device based upon it's DriverKeyName /// Find a device based upon it's DriverKeyName
// /// </summary>
/// <param name="driverKeyName">DriverKeyName</param>
/// <returns>USB device</returns>
internal static UsbDevice FindDeviceByDriverKeyName(string driverKeyName) internal static UsbDevice FindDeviceByDriverKeyName(string driverKeyName)
{ {
UsbDevice foundDevice = null; UsbDevice foundDevice = null;
@@ -80,7 +90,12 @@ namespace DiscImageChef.Devices.Windows
return foundDevice; return foundDevice;
} }
// private routine for enumerating a hub /// <summary>
/// Finds a device connected to a specified hub by it's DriverKeyName
/// </summary>
/// <param name="hub">Hub</param>
/// <param name="foundDevice">UsbDevice</param>
/// <param name="driverKeyName">DriverKeyName</param>
static void SearchHubDriverKeyName(UsbHub hub, ref UsbDevice foundDevice, string driverKeyName) static void SearchHubDriverKeyName(UsbHub hub, ref UsbDevice foundDevice, string driverKeyName)
{ {
foreach(UsbPort port in hub.GetPorts()) foreach(UsbPort port in hub.GetPorts())
@@ -97,9 +112,11 @@ namespace DiscImageChef.Devices.Windows
} }
} }
// /// <summary>
// Find a device based upon it's Instance ID /// Find a device based upon it's Instance ID
// /// </summary>
/// <param name="instanceId">Device instance ID</param>
/// <returns>USB device</returns>
static UsbDevice FindDeviceByInstanceId(string instanceId) static UsbDevice FindDeviceByInstanceId(string instanceId)
{ {
UsbDevice foundDevice = null; UsbDevice foundDevice = null;
@@ -113,7 +130,12 @@ namespace DiscImageChef.Devices.Windows
return foundDevice; return foundDevice;
} }
// private routine for enumerating a hub /// <summary>
/// private routine for enumerating a hub
/// </summary>
/// <param name="hub">Hub</param>
/// <param name="foundDevice">USB device</param>
/// <param name="instanceId">Device instance ID</param>
static void SearchHubInstanceId(UsbHub hub, ref UsbDevice foundDevice, string instanceId) static void SearchHubInstanceId(UsbHub hub, ref UsbDevice foundDevice, string instanceId)
{ {
foreach(UsbPort port in hub.GetPorts()) foreach(UsbPort port in hub.GetPorts())
@@ -135,11 +157,6 @@ namespace DiscImageChef.Devices.Windows
internal const string GuidDevinterfaceCdrom = "53f56308-b6bf-11d0-94f2-00a0c91efb8b"; internal const string GuidDevinterfaceCdrom = "53f56308-b6bf-11d0-94f2-00a0c91efb8b";
internal const string GuidDevinterfaceFloppy = "53f56311-b6bf-11d0-94f2-00a0c91efb8b"; internal const string GuidDevinterfaceFloppy = "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)] [StructLayout(LayoutKind.Sequential)]
struct StorageDeviceNumber struct StorageDeviceNumber
{ {
@@ -148,26 +165,18 @@ namespace DiscImageChef.Devices.Windows
internal int PartitionNumber; internal int PartitionNumber;
} }
//CMAPI CONFIGRET WINAPI CM_Get_Parent(
// OUT PDEVINST pdnDevInst,
// IN DEVINST dnDevInst,
// IN ULONG ulFlags
//);
[DllImport("setupapi.dll")] [DllImport("setupapi.dll")]
static extern int CM_Get_Parent(out IntPtr pdnDevInst, IntPtr dnDevInst, int ulFlags); 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)] [DllImport("setupapi.dll", CharSet = CharSet.Auto)]
static extern int CM_Get_Device_ID(IntPtr dnDevInst, IntPtr buffer, int bufferLen, int ulFlags); static extern int CM_Get_Device_ID(IntPtr dnDevInst, IntPtr buffer, int bufferLen, int ulFlags);
// /// <summary>
// Find a device based upon a Drive Letter /// Find a device based upon a Drive Letter
// /// </summary>
/// <param name="driveLetter">Drive letter</param>
/// <param name="deviceGuid">Device GUID</param>
/// <returns>USB device</returns>
internal static UsbDevice FindDriveLetter(string driveLetter, string deviceGuid) internal static UsbDevice FindDriveLetter(string driveLetter, string deviceGuid)
{ {
// We start by getting the unique DeviceNumber of the given // We start by getting the unique DeviceNumber of the given
@@ -177,6 +186,12 @@ namespace DiscImageChef.Devices.Windows
return devNum < 0 ? null : FindDeviceNumber(devNum, deviceGuid); return devNum < 0 ? null : FindDeviceNumber(devNum, deviceGuid);
} }
/// <summary>
/// Find a device based upon a Drive Path
/// </summary>
/// <param name="drivePath">Drive path</param>
/// <param name="deviceGuid">Device GUID</param>
/// <returns>USB device</returns>
internal static UsbDevice FindDrivePath(string drivePath, string deviceGuid) internal static UsbDevice FindDrivePath(string drivePath, string deviceGuid)
{ {
// We start by getting the unique DeviceNumber of the given // We start by getting the unique DeviceNumber of the given
@@ -186,9 +201,12 @@ namespace DiscImageChef.Devices.Windows
return devNum < 0 ? null : FindDeviceNumber(devNum, deviceGuid); return devNum < 0 ? null : FindDeviceNumber(devNum, deviceGuid);
} }
// /// <summary>
// Find a device based upon a Drive Letter /// Find a device based upon a Device Number
// /// </summary>
/// <param name="devNum">Device Number</param>
/// <param name="deviceGuid">Device GUID</param>
/// <returns>USB device</returns>
static UsbDevice FindDeviceNumber(int devNum, string deviceGuid) static UsbDevice FindDeviceNumber(int devNum, string deviceGuid)
{ {
UsbDevice foundDevice = null; UsbDevice foundDevice = null;
@@ -253,7 +271,11 @@ namespace DiscImageChef.Devices.Windows
return foundDevice; return foundDevice;
} }
// return a unique device number for the given device path /// <summary>
/// return a unique device number for the given device path
/// </summary>
/// <param name="devicePath">Device path</param>
/// <returns>Device number</returns>
static int GetDeviceNumber(string devicePath) static int GetDeviceNumber(string devicePath)
{ {
int ans = -1; int ans = -1;