Files
MPF/MPF.Library/Data/Drive.cs

107 lines
3.1 KiB
C#
Raw Permalink Normal View History

using System.IO;
2021-03-29 11:55:29 -07:00
namespace MPF.Data
2019-05-20 22:14:53 -07:00
{
/// <summary>
/// Represents information for a single drive
/// </summary>
public class Drive
{
/// <summary>
/// Represents drive type
2019-05-20 22:14:53 -07:00
/// </summary>
public InternalDriveType? InternalDriveType { get; set; }
2019-05-20 22:14:53 -07:00
/// <summary>
2021-02-04 21:38:57 -08:00
/// Drive partition format
2019-05-20 22:14:53 -07:00
/// </summary>
2021-02-04 21:38:57 -08:00
public string DriveFormat { get { return driveInfo.DriveFormat; } }
2019-05-20 22:14:53 -07:00
/// <summary>
/// Windows drive letter
2019-05-20 22:14:53 -07:00
/// </summary>
2021-02-04 21:38:57 -08:00
public char Letter { get { return driveInfo?.Name[0] ?? '\0'; } }
/// <summary>
/// Represents if Windows has marked the drive as active
/// </summary>
public bool MarkedActive { get { return driveInfo.IsReady; } }
2019-05-20 22:14:53 -07:00
/// <summary>
/// Media label as read by Windows
2019-05-20 22:14:53 -07:00
/// </summary>
public string VolumeLabel
2019-05-20 22:14:53 -07:00
{
get
{
string volumeLabel = Template.DiscNotDetected;
2021-02-04 21:38:57 -08:00
if (driveInfo.IsReady)
{
2021-02-04 21:38:57 -08:00
if (string.IsNullOrWhiteSpace(driveInfo.VolumeLabel))
volumeLabel = "track";
else
2021-02-04 21:38:57 -08:00
volumeLabel = driveInfo.VolumeLabel;
}
foreach (char c in Path.GetInvalidFileNameChars())
volumeLabel = volumeLabel.Replace(c, '_');
return volumeLabel;
}
2019-05-20 22:14:53 -07:00
}
/// <summary>
2021-02-04 21:38:57 -08:00
/// DriveInfo object representing the drive, if possible
2019-05-20 22:14:53 -07:00
/// </summary>
2021-03-29 11:55:29 -07:00
private readonly DriveInfo driveInfo;
public Drive(InternalDriveType? driveType, DriveInfo driveInfo)
{
this.InternalDriveType = driveType;
2021-02-04 21:38:57 -08:00
this.driveInfo = driveInfo;
}
/// <summary>
/// Read a sector with a specified size from the drive
/// </summary>
/// <param name="num">Sector number, non-negative</param>
/// <param name="size">Size of a sector in bytes</param>
/// <returns>Byte array representing the sector, null on error</returns>
public byte[] ReadSector(long num, int size = 2048)
{
// Missing drive leter is not supported
2021-02-04 21:38:57 -08:00
if (string.IsNullOrEmpty(this.driveInfo?.Name))
return null;
// We don't support negative sectors
if (num < 0)
return null;
// Wrap the following in case of device access errors
Stream fs = null;
try
{
// Open the drive as a device
fs = File.OpenRead($"\\\\?\\{this.Letter}:");
// Seek to the start of the sector, if possible
long start = num * size;
fs.Seek(start, SeekOrigin.Begin);
// Read and return the sector
byte[] buffer = new byte[size];
fs.Read(buffer, 0, size);
return buffer;
}
catch
{
return null;
}
finally
{
2021-03-15 22:06:14 -07:00
fs?.Dispose();
}
}
2019-05-20 22:14:53 -07:00
}
}