/TrueLib3/SystemDevices.cs

https://github.com/nefarius/TrueMount-3 · C# · 333 lines · 199 code · 36 blank · 98 comment · 36 complexity · 3ce48a73800c1ab1e08f105c43ce97a8 MD5 · raw file

  1. using System;
  2. using System.Collections.Generic;
  3. using System.Linq;
  4. using System.Management;
  5. using System.Text.RegularExpressions;
  6. namespace TrueLib
  7. {
  8. /// <summary>
  9. /// Static wrapper for windows system devices.
  10. /// </summary>
  11. // TODO: on release BACK TO INTERNAL!!!
  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 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. /// <returns>True or false.</returns>
  103. public static bool IsDiskOnline(string caption, uint signature)
  104. {
  105. var query =
  106. from ManagementObject disk in diskDrives.GetInstances()
  107. where (string)disk["Caption"] == caption
  108. && (uint)disk["Signature"] == signature
  109. select disk;
  110. return (query.Count() > 0);
  111. }
  112. /// <summary>
  113. /// Checks if a given disk drive partition is online.
  114. /// </summary>
  115. /// <param name="caption">The caption of the disk drive.</param>
  116. /// <param name="signature">The signature of the disk drive.</param>
  117. /// <param name="partitionIndex">The zero-based partition index.</param>
  118. /// <returns>Returns true if partition is online, else false.</returns>
  119. public static bool IsPartitionOnline(string caption, uint signature, uint partitionIndex)
  120. {
  121. var partitionQuery =
  122. from ManagementObject disk in diskDrives.GetInstances()
  123. where (string)disk["Caption"] == caption
  124. && (uint)disk["Signature"] == signature
  125. from ManagementObject partition in disk.GetRelated(Win32_DiskPartition)
  126. where (uint)partition["Index"] == partitionIndex
  127. select partition;
  128. return (partitionQuery.Count() > 0);
  129. }
  130. /// <summary>
  131. /// Contains all disks of the system.
  132. /// </summary>
  133. public static ManagementObjectCollection DiskDrives
  134. {
  135. get { return diskDrives.GetInstances(); }
  136. }
  137. /// <summary>
  138. /// Gets a partition by its disk index and partition index.
  139. /// </summary>
  140. /// <param name="DiskIndex">Disk index (zero based).</param>
  141. /// <param name="Index">Partition index (zero based).</param>
  142. /// <returns>Returns a found partition or null.</returns>
  143. public static ManagementObject GetPartitionByIndex(uint DiskIndex, uint Index)
  144. {
  145. try
  146. {
  147. var partQuery =
  148. from ManagementObject partition in DiskPartitions
  149. where (uint)partition["DiskIndex"] == DiskIndex
  150. && (uint)partition["Index"] == Index
  151. select partition;
  152. if (partQuery.Count() > 0)
  153. return partQuery.First();
  154. else
  155. return null;
  156. }
  157. catch { return null; }
  158. }
  159. /// <summary>
  160. /// Contains all partitions of the system.
  161. /// </summary>
  162. public static ManagementObjectCollection DiskPartitions
  163. {
  164. get { return diskPartitions.GetInstances(); }
  165. }
  166. /// <summary>
  167. /// Contains all logical disks of the system.
  168. /// </summary>
  169. public static ManagementObjectCollection LogicalDisks
  170. {
  171. get { return logicalDisks.GetInstances(); }
  172. }
  173. /// <summary>
  174. /// Contains all usb controller devices.
  175. /// </summary>
  176. public static ManagementObjectCollection USBControllerDevices
  177. {
  178. get { return usbControllerDevices.GetInstances(); }
  179. }
  180. /// <summary>
  181. /// Gets the drive letter of a logical disk identified by its caption, signature and partition number.
  182. /// </summary>
  183. /// <param name="caption">Caption (title, name) of the disk.</param>
  184. /// <param name="signature">Signature (10 digit unsigned integer) of the disk.</param>
  185. /// <param name="partitionNr">Partition number (zero based).</param>
  186. /// <returns>Returns the drive letter of the logical disk.</returns>
  187. public static String GetDriveLetterBySignature(String caption, uint signature, uint partitionNr)
  188. {
  189. var devQuery =
  190. from ManagementObject disk in DiskDrives
  191. where (string)disk["Caption"] == caption
  192. && (uint)disk["Signature"] == signature
  193. from ManagementObject partition in disk.GetRelated(SystemDevices.Win32_DiskPartition)
  194. where (uint)partition["Index"] == partitionNr
  195. from ManagementObject ldisk in partition.GetRelated(SystemDevices.Win32_LogicalDisk)
  196. select (string)ldisk["Name"];
  197. if (devQuery.Count() > 0)
  198. return (string)devQuery.First();
  199. else
  200. return null;
  201. }
  202. /// <summary>
  203. /// Gets a logical disk by a drive letter an disk type.
  204. /// </summary>
  205. /// <param name="letter">Drive letter of the disk.</param>
  206. /// <param name="drive_type">Optional drive type (3 = local, 2 = removable).</param>
  207. /// <returns>Returns the disk or null.</returns>
  208. public static ManagementObject GetLogicalDisk(String letter, int drive_type = 3)
  209. {
  210. var ldQuery =
  211. from ManagementObject ldisk in LogicalDisks
  212. where int.Parse(ldisk["DriveType"].ToString()) == drive_type
  213. && ldisk["Name"].ToString().StartsWith(letter)
  214. select ldisk;
  215. if (ldQuery.Count() > 0)
  216. return ldQuery.First();
  217. else
  218. return null;
  219. }
  220. /// <summary>
  221. /// Gets the disk caption, signature and partition number by the drive letter.
  222. /// </summary>
  223. /// <param name="letter">Drive letter of the logical disk.</param>
  224. /// <param name="caption">Caption of the disk.</param>
  225. /// <param name="signature">Signature of the disk.</param>
  226. /// <param name="partitionNr">Partition number (zero based).</param>
  227. public static void GetDiskSignatureFromLetter(String letter,
  228. ref string caption, ref uint signature, ref uint partitionNr)
  229. {
  230. var ldiskQuery =
  231. from ManagementObject ldisk in LogicalDisks
  232. where ldisk["Name"].ToString().StartsWith(letter)
  233. select ldisk;
  234. var partQuery =
  235. from ManagementObject part in ldiskQuery.First().GetRelated(SystemDevices.Win32_DiskPartition)
  236. select part;
  237. if (partQuery.Count() > 0)
  238. partitionNr = (uint)partQuery.First()["Index"];
  239. var diskQuery =
  240. from ManagementObject disk in partQuery.First().GetRelated(Win32_DiskDrive)
  241. select disk;
  242. if (diskQuery.Count() > 0)
  243. {
  244. ManagementObject disk_drive = diskQuery.First();
  245. caption = (string)disk_drive["Caption"];
  246. signature = (uint)disk_drive["Signature"];
  247. }
  248. }
  249. /// <summary>
  250. /// For debugging: returns identity information about all attached disks.
  251. /// </summary>
  252. /// <returns>A list of disk information.</returns>
  253. public static List<string> GetLocalDiskPartitions()
  254. {
  255. List<string> values = new List<string>();
  256. foreach (ManagementObject disk in DiskDrives)
  257. {
  258. foreach (ManagementObject partition in disk.GetRelated(Win32_DiskPartition))
  259. {
  260. values.Add(string.Format("Disk caption({0}), signature({1}); Partition index({2})",
  261. disk["Caption"], disk["Signature"], partition["Index"]));
  262. }
  263. }
  264. return values;
  265. }
  266. /// <summary>
  267. /// Converts the device id into a TrueCrypt compatible path.
  268. /// </summary>
  269. /// <param name="deviceid">Device ID</param>
  270. /// <returns>Returns a string with the device path.</returns>
  271. public static String GetTCCompatibleName(String deviceid)
  272. {
  273. return Regex.Replace(deviceid, "Disk #([0-9]*), Partition #([0-9]*)", ReplaceEvaluator);
  274. }
  275. /// <summary>
  276. /// Contains logic to build a TC compatible device path.
  277. /// </summary>
  278. /// <param name="m"></param>
  279. /// <returns></returns>
  280. private static string ReplaceEvaluator(Match m)
  281. {
  282. return @"\Device\Harddisk" +
  283. (int.Parse(m.Groups[1].Value)).ToString() +
  284. @"\Partition" +
  285. (int.Parse(m.Groups[2].Value) + 1).ToString();
  286. }
  287. /// <summary>
  288. /// Returns a TC compatible path to an encrypted hard disk.
  289. /// </summary>
  290. /// <param name="index"></param>
  291. /// <returns></returns>
  292. public static string GetTCCompatibleDiskPath(uint index)
  293. {
  294. return string.Format(@"\Device\Harddisk{0}\Partition0", index.ToString());
  295. }
  296. }
  297. }