/TrueMount/SystemDevices.cs

https://github.com/nefarius/TrueMount-2 · C# · 342 lines · 220 code · 38 blank · 84 comment · 38 complexity · a24f1748cf9902501019cb8397bc8458 MD5 · raw file

  1. using System;
  2. using System.Collections.Generic;
  3. using System.IO;
  4. using System.Linq;
  5. using System.Management;
  6. using System.Text.RegularExpressions;
  7. namespace TrueMount
  8. {
  9. /// <summary>
  10. /// Static wrapper for windows system devices.
  11. /// </summary>
  12. static class SystemDevices
  13. {
  14. // WMI class names
  15. public const string Win32_LogicalDisk = "Win32_LogicalDisk";
  16. public const string Win32_DiskDrive = "Win32_DiskDrive";
  17. public const string Win32_DiskPartition = "Win32_DiskPartition";
  18. public const string Win32_USBControllerDevice = "Win32_USBControllerDevice";
  19. private static ManagementClass logicalDisks = new ManagementClass(Win32_LogicalDisk);
  20. private static ManagementClass diskDrives = new ManagementClass(Win32_DiskDrive);
  21. private static ManagementClass diskPartitions = new ManagementClass(Win32_DiskPartition);
  22. private static ManagementClass usbControllerDevices = new ManagementClass(Win32_USBControllerDevice);
  23. /// <summary>
  24. /// Checks if logical device is online (=plugged in and mounted with drive letter).
  25. /// </summary>
  26. /// <param name="letter">Drive letter of the device.</param>
  27. /// <returns>Returns true if device with given drive letter is online, else false.</returns>
  28. public static bool IsLogicalDiskOnline(String letter, int type = 2)
  29. {
  30. var ldQuery =
  31. from ManagementObject ldisk in logicalDisks.GetInstances()
  32. where ldisk["Name"].ToString() == letter &&
  33. int.Parse(ldisk["DriveType"].ToString()) == type
  34. select ldisk;
  35. if (ldQuery.Count() > 0)
  36. return true;
  37. else
  38. return false;
  39. }
  40. /// <summary>
  41. /// Gets a device with given caption and signature.
  42. /// </summary>
  43. /// <param name="caption">Caption (title, name) of the device.</param>
  44. /// <param name="signature">Signature (10 digit unsigned integer) of the device. May be 0 in some cases.</param>
  45. /// <returns>Returns the device with the given parameters.</returns>
  46. public static ManagementObject GetDiskDriveBySignature(String caption, uint signature)
  47. {
  48. var diskQuery =
  49. from ManagementObject disk in diskDrives.GetInstances()
  50. where (string)disk["Caption"] == caption
  51. && (uint)disk["Signature"] == signature
  52. select disk;
  53. if (diskQuery.Count() > 0)
  54. return diskQuery.First();
  55. else
  56. return null;
  57. }
  58. /// <summary>
  59. /// Gets a partition with a given drive signature and partition index.
  60. /// </summary>
  61. /// <param name="caption">The disk drive caption.</param>
  62. /// <param name="signature">The disk drive signature.</param>
  63. /// <param name="partitionNr">The zero-based partition number.</param>
  64. /// <returns>Returns a found partition, else null.</returns>
  65. public static ManagementObject GetPartitionBySignature(String caption, uint signature, uint partitionNr)
  66. {
  67. var partQiery =
  68. from ManagementObject disk in diskDrives.GetInstances()
  69. where (string)disk["Caption"] == caption
  70. && (uint)disk["Signature"] == signature
  71. from ManagementObject partition in disk.GetRelated(Win32_DiskPartition)
  72. where (uint)partition["Index"] == partitionNr
  73. select partition;
  74. if (partQiery.Count() > 0)
  75. return partQiery.First();
  76. else
  77. return null;
  78. }
  79. /// <summary>
  80. /// Checks if a partition with given DeviceID is removable.
  81. /// </summary>
  82. /// <param name="deviceId">The disk partition DeviceID.</param>
  83. /// <returns>Returns true if partition is removable, else false.</returns>
  84. public static bool IsRemovablePartition(string deviceId)
  85. {
  86. var ldiskQuery =
  87. from ManagementObject partition in diskPartitions.GetInstances()
  88. where (string)partition["DeviceID"] == deviceId
  89. from ManagementObject ldisk in partition.GetRelated(Win32_LogicalDisk)
  90. where (uint)ldisk["DriveType"] == 2
  91. select ldisk;
  92. if (ldiskQuery.Count() > 0)
  93. return true;
  94. else
  95. return false;
  96. }
  97. /// <summary>
  98. /// Checks if a given disk drive partition is online.
  99. /// </summary>
  100. /// <param name="caption">The caption of the disk drive.</param>
  101. /// <param name="signature">The signature of the disk drive.</param>
  102. /// <param name="partitionIndex">The zero-based partition index.</param>
  103. /// <param name="partitionDeviceId">The partition DeviceID to check.</param>
  104. /// <returns>Returns true if partition is online, else false.</returns>
  105. public static bool IsPartitionOnline(string caption, uint signature, uint partitionIndex, string partitionDeviceId)
  106. {
  107. var partitionQuery =
  108. from ManagementObject disk in diskDrives.GetInstances()
  109. where (string)disk["Caption"] == caption
  110. && (uint)disk["Signature"] == signature
  111. from ManagementObject partition in disk.GetRelated(Win32_DiskPartition)
  112. where (uint)partition["Index"] == partitionIndex
  113. && (string)partition["DeviceID"] == partitionDeviceId
  114. select partition;
  115. if (partitionQuery.Count() > 0)
  116. return true;
  117. else
  118. return false;
  119. }
  120. /// <summary>
  121. /// Contains all disks of the system.
  122. /// </summary>
  123. public static ManagementObjectCollection DiskDrives
  124. {
  125. get { return diskDrives.GetInstances(); }
  126. }
  127. /// <summary>
  128. /// Gets a partition by its disk index and partition index.
  129. /// </summary>
  130. /// <param name="DiskIndex">Disk index (zero based).</param>
  131. /// <param name="Index">Partition index (zero based).</param>
  132. /// <returns>Returns a found partition or null.</returns>
  133. public static ManagementObject GetPartitionByIndex(uint DiskIndex, uint Index)
  134. {
  135. try
  136. {
  137. var partQuery =
  138. from ManagementObject partition in DiskPartitions
  139. where (uint)partition["DiskIndex"] == DiskIndex
  140. && (uint)partition["Index"] == Index
  141. select partition;
  142. if (partQuery.Count() > 0)
  143. return partQuery.First();
  144. else
  145. return null;
  146. }
  147. catch { return null; }
  148. }
  149. /// <summary>
  150. /// Contains all partitions of the system.
  151. /// </summary>
  152. public static ManagementObjectCollection DiskPartitions
  153. {
  154. get { return diskPartitions.GetInstances(); }
  155. }
  156. /// <summary>
  157. /// Contains all logical disks of the system.
  158. /// </summary>
  159. public static ManagementObjectCollection LogicalDisks
  160. {
  161. get { return logicalDisks.GetInstances(); }
  162. }
  163. /// <summary>
  164. /// Contains all usb controller devices.
  165. /// </summary>
  166. public static ManagementObjectCollection USBControllerDevices
  167. {
  168. get { return usbControllerDevices.GetInstances(); }
  169. }
  170. /// <summary>
  171. /// Gets the drive letter of a logical disk identified by its caption, signature and partition number.
  172. /// </summary>
  173. /// <param name="caption">Caption (title, name) of the disk.</param>
  174. /// <param name="signature">Signature (10 digit unsigned integer) of the disk.</param>
  175. /// <param name="partitionNr">Partition number (zero based).</param>
  176. /// <returns>Returns the drive letter of the logical disk.</returns>
  177. public static String GetDriveLetterBySignature(String caption, uint signature, uint partitionNr)
  178. {
  179. var devQuery =
  180. from ManagementObject disk in DiskDrives
  181. where (string)disk["Caption"] == caption
  182. && (uint)disk["Signature"] == signature
  183. from ManagementObject partition in disk.GetRelated(SystemDevices.Win32_DiskPartition)
  184. where (uint)partition["Index"] == partitionNr
  185. from ManagementObject ldisk in partition.GetRelated(SystemDevices.Win32_LogicalDisk)
  186. select (string)ldisk["Name"];
  187. if (devQuery.Count() > 0)
  188. return (string)devQuery.First();
  189. else
  190. return null;
  191. }
  192. /// <summary>
  193. /// Gets a logical disk by a drive letter an disk type.
  194. /// </summary>
  195. /// <param name="letter">Drive letter of the disk.</param>
  196. /// <param name="drive_type">Optional drive type (3 = local, 2 = removable).</param>
  197. /// <returns>Returns the disk or null.</returns>
  198. public static ManagementObject GetLogicalDisk(String letter, int drive_type = 3)
  199. {
  200. var ldQuery =
  201. from ManagementObject ldisk in LogicalDisks
  202. where int.Parse(ldisk["DriveType"].ToString()) == drive_type
  203. && ldisk["Name"].ToString().StartsWith(letter)
  204. select ldisk;
  205. if (ldQuery.Count() > 0)
  206. return ldQuery.First();
  207. else
  208. return null;
  209. }
  210. /// <summary>
  211. /// Gets the disk caption, signature and partition number by the drive letter.
  212. /// </summary>
  213. /// <param name="letter">Drive letter of the logical disk.</param>
  214. /// <param name="caption">Caption of the disk.</param>
  215. /// <param name="signature">Signature of the disk.</param>
  216. /// <param name="partitionNr">Partition number (zero based).</param>
  217. public static void GetDiskSignatureFromLetter(String letter,
  218. ref string caption, ref uint signature, ref uint partitionNr)
  219. {
  220. var ldiskQuery =
  221. from ManagementObject ldisk in LogicalDisks
  222. where ldisk["Name"].ToString().StartsWith(letter)
  223. select ldisk;
  224. var partQuery =
  225. from ManagementObject part in ldiskQuery.First().GetRelated(SystemDevices.Win32_DiskPartition)
  226. select part;
  227. if (partQuery.Count() > 0)
  228. partitionNr = (uint)partQuery.First()["Index"];
  229. var diskQuery =
  230. from ManagementObject disk in partQuery.First().GetRelated(Win32_DiskDrive)
  231. select disk;
  232. if (diskQuery.Count() > 0)
  233. {
  234. ManagementObject disk_drive = diskQuery.First();
  235. caption = (string)disk_drive["Caption"];
  236. signature = (uint)disk_drive["Signature"];
  237. }
  238. }
  239. /// <summary>
  240. /// Converts the device id into a TrueCrypt compatible path.
  241. /// </summary>
  242. /// <param name="deviceid">Device ID</param>
  243. /// <returns>Returns a string with the device path.</returns>
  244. public static String GetTCCompatibleName(String deviceid)
  245. {
  246. return Regex.Replace(deviceid, "Disk #([0-9]*), Partition #([0-9]*)", ReplaceEvaluator);
  247. }
  248. private static string ReplaceEvaluator(Match m)
  249. {
  250. return @"\Device\Harddisk" +
  251. (int.Parse(m.Groups[1].Value)).ToString() +
  252. @"\Partition" +
  253. (int.Parse(m.Groups[2].Value) + 1).ToString();
  254. }
  255. public static string GetTCCompatibleDiskPath(uint index)
  256. {
  257. return string.Format(@"\Device\Harddisk{0}\Partition0", index.ToString());
  258. }
  259. /// <summary>
  260. /// Contains all available drive letters (gets refreshed every call).
  261. /// </summary>
  262. public static List<string> FreeDriveLetters
  263. {
  264. get
  265. {
  266. List<string> alphabet = AllDriveLetters;
  267. foreach (DriveInfo drive in DriveInfo.GetDrives())
  268. alphabet.Remove(drive.Name.Substring(0, 1).ToUpper());
  269. if (alphabet.Count > 0)
  270. return alphabet;
  271. else
  272. return null;
  273. }
  274. }
  275. /// <summary>
  276. /// Contains all drive letters.
  277. /// </summary>
  278. public static List<string> AllDriveLetters
  279. {
  280. get
  281. {
  282. List<string> alphabet = new List<string>();
  283. int lowerBound = Convert.ToInt16('C');
  284. int upperBound = Convert.ToInt16('Z');
  285. int index = 0;
  286. for (index = lowerBound; index <= upperBound; index++)
  287. {
  288. char driveLetter = (char)index;
  289. alphabet.Add(driveLetter.ToString());
  290. }
  291. return alphabet;
  292. }
  293. }
  294. public static string RandomFreeDriveLetter
  295. {
  296. get
  297. {
  298. Random r = new Random();
  299. List<string> dLetters = FreeDriveLetters;
  300. return dLetters[r.Next(dLetters.Count)];
  301. }
  302. }
  303. }
  304. }