PageRenderTime 45ms CodeModel.GetById 18ms RepoModel.GetById 0ms app.codeStats 0ms

/CBR/CBR.Core/Helpers/WMI/WMIEventWatcher.cs

#
C# | 343 lines | 263 code | 42 blank | 38 comment | 9 complexity | a5f491a47add82a215810bcf19d808c2 MD5 | raw file
  1. using System;
  2. using System.Management;
  3. using System.Collections.Generic;
  4. using System.Linq;
  5. using System.Text;
  6. using System.Collections.ObjectModel;
  7. using System.Windows;
  8. using System.Windows.Threading;
  9. using System.Threading;
  10. namespace CBR.Core.Helpers
  11. {
  12. #region ----------------EVENTS----------------
  13. public enum WMIActions
  14. {
  15. Added,
  16. Removed
  17. }
  18. public class WMIEventArgs : EventArgs
  19. {
  20. public USBDiskInfo Disk { get; set; }
  21. public WMIActions EventType { get; set; }
  22. }
  23. public delegate void WMIEventArrived(object sender, WMIEventArgs e);
  24. #endregion
  25. /// <summary>
  26. ///
  27. /// </summary>
  28. public class WMIEventWatcher
  29. {
  30. #region ----------------CONSTRUCTOR----------------
  31. /// <summary>
  32. /// constructor
  33. /// </summary>
  34. public WMIEventWatcher()
  35. {
  36. Devices = GetExistingDevices();
  37. }
  38. #endregion
  39. #region ----------------INTERNALS----------------
  40. /// <summary>
  41. /// internal watcher for add event
  42. /// </summary>
  43. private ManagementEventWatcher addedWatcher = null;
  44. /// <summary>
  45. /// internal watcher for remove event
  46. /// </summary>
  47. private ManagementEventWatcher removedWatcher = null;
  48. #endregion
  49. #region ----------------PROPERTIES----------------
  50. /// <summary>
  51. /// List of founded devices
  52. /// </summary>
  53. public List<USBDiskInfo> Devices { get; set; }
  54. #endregion
  55. #region ----------------EVENTS----------------
  56. /// <summary>
  57. /// signaled when watched events occurs
  58. /// </summary>
  59. public event WMIEventArrived EventArrived;
  60. #endregion
  61. #region ----------------METHODS----------------
  62. /// <summary>
  63. /// start watching for logical device events
  64. /// </summary>
  65. public void StartWatchUSB()
  66. {
  67. try
  68. {
  69. addedWatcher = new ManagementEventWatcher("SELECT * FROM __InstanceCreationEvent WITHIN 5 WHERE TargetInstance ISA \"Win32_USBControllerDevice\"");
  70. addedWatcher.EventArrived += new EventArrivedEventHandler(HandleAddedEvent);
  71. addedWatcher.Start();
  72. removedWatcher = new ManagementEventWatcher("SELECT * FROM __InstanceDeletionEvent WITHIN 5 WHERE TargetInstance ISA \"Win32_USBControllerDevice\"");
  73. removedWatcher.EventArrived += new EventArrivedEventHandler(HandleRemovedEvent);
  74. removedWatcher.Start();
  75. }
  76. catch (ManagementException err)
  77. {
  78. ExceptionHelper.Manage("WMIEventWatcher:StartWatchUSB", err);
  79. }
  80. }
  81. /// <summary>
  82. /// stop watching for logical device events
  83. /// </summary>
  84. public void StopWatchUSB()
  85. {
  86. try
  87. {
  88. // Stop listening for events
  89. if (addedWatcher != null)
  90. addedWatcher.Stop();
  91. if (removedWatcher != null)
  92. removedWatcher.Stop();
  93. }
  94. catch (ManagementException err)
  95. {
  96. ExceptionHelper.Manage("WMIEventWatcher:StopWatchUSB", err);
  97. }
  98. }
  99. /// <summary>
  100. /// handle the add event
  101. /// </summary>
  102. /// <param name="sender"></param>
  103. /// <param name="e"></param>
  104. private void HandleAddedEvent(object sender, EventArrivedEventArgs e)
  105. {
  106. USBDiskInfo device = null;
  107. try
  108. {
  109. ManagementBaseObject targetInstance = e.NewEvent["TargetInstance"] as ManagementBaseObject;
  110. DebugPrint(targetInstance);
  111. // get the device name in the dependent property Dependent: extract the last part
  112. // \\FR-L25676\root\cimv2:Win32_PnPEntity.DeviceID="USBSTOR\\DISK&VEN_USB&PROD_FLASH_DISK&REV_1100\\AA04012700076941&0"
  113. string PNP_deviceID = Convert.ToString(targetInstance["Dependent"]).Split('=').Last().Replace("\"", "").Replace("\\", "");
  114. string device_name = Convert.ToString(targetInstance["Dependent"]).Split('\\').Last().Replace("\"", "");
  115. // query that device entity
  116. ObjectQuery query = new ObjectQuery(string.Format("Select * from Win32_PnPEntity Where DeviceID like \"%{0}%\"", device_name));
  117. // check if match usb removable disk
  118. using (ManagementObjectSearcher searcher = new ManagementObjectSearcher(query))
  119. {
  120. ManagementObjectCollection entities = searcher.Get();
  121. //first loop to check USBSTOR
  122. foreach (var entity in entities)
  123. {
  124. string service = Convert.ToString(entity["Service"]);
  125. if (service == "USBSTOR")
  126. device = new USBDiskInfo();
  127. }
  128. if (device != null)
  129. {
  130. foreach (var entity in entities)
  131. {
  132. string service = Convert.ToString(entity["Service"]);
  133. if (service == "disk")
  134. {
  135. GetDiskInformation(device, device_name);
  136. Devices.Add(device);
  137. if (EventArrived != null)
  138. EventArrived(this, new WMIEventArgs() { Disk = device, EventType = WMIActions.Added });
  139. }
  140. }
  141. }
  142. }
  143. }
  144. catch (ManagementException err)
  145. {
  146. ExceptionHelper.Manage("WMIEventWatcher:HandleAddedEvent", err);
  147. }
  148. }
  149. private ManagementObjectSearcher GetDiskInformation(USBDiskInfo device, string device_name)
  150. {
  151. ManagementObjectSearcher searcher2 = null;
  152. ObjectQuery query1 = new ObjectQuery("SELECT * FROM Win32_DiskDrive where PNPDeviceID like '%" + device_name + "%'");
  153. searcher2 = new ManagementObjectSearcher(query1);
  154. ManagementObjectCollection disks = searcher2.Get();
  155. foreach (var disk in disks)
  156. {
  157. DebugPrint(disk);
  158. //Use the disk drive device id to find associated partition
  159. ObjectQuery query2 = new ObjectQuery("ASSOCIATORS OF {Win32_DiskDrive.DeviceID='" + Convert.ToString(disk["DeviceID"]).Replace("\"", "\\") + "'} WHERE AssocClass=Win32_DiskDriveToDiskPartition");
  160. searcher2 = new ManagementObjectSearcher(query2);
  161. ManagementObjectCollection partitions = searcher2.Get();
  162. foreach (var part in partitions)
  163. {
  164. DebugPrint(part);
  165. //Use partition device id to find logical disk
  166. ObjectQuery query3 = new ObjectQuery("ASSOCIATORS OF {Win32_DiskPartition.DeviceID='" + Convert.ToString(part["DeviceID"]).Replace("\"", "\\") + "'} WHERE AssocClass=Win32_LogicalDiskToPartition");
  167. searcher2 = new ManagementObjectSearcher(query3);
  168. ManagementObjectCollection logic = searcher2.Get();
  169. foreach (var disklogic in logic)
  170. {
  171. DebugPrint(disklogic);
  172. ParseDiskDriveInfo(device, disk);
  173. ParseDiskLogicalInfo(device, disklogic);
  174. }
  175. }
  176. }
  177. return searcher2;
  178. }
  179. /// <summary>
  180. /// handle the remove event
  181. /// </summary>
  182. /// <param name="sender"></param>
  183. /// <param name="e"></param>
  184. private void HandleRemovedEvent(object sender, EventArrivedEventArgs e)
  185. {
  186. try
  187. {
  188. ManagementBaseObject targetInstance = e.NewEvent["TargetInstance"] as ManagementBaseObject;
  189. DebugPrint(targetInstance);
  190. string PNP_deviceID = Convert.ToString(targetInstance["Dependent"]).Split('=').Last().Replace("\"", "").Replace("\\", "");
  191. USBDiskInfo device = Devices.Find(x => x.PNPDeviceID == PNP_deviceID);
  192. if( device != null )
  193. {
  194. Devices.Remove( device );
  195. if (EventArrived != null)
  196. EventArrived(this, new WMIEventArgs() { Disk = device, EventType = WMIActions.Removed });
  197. }
  198. }
  199. catch (ManagementException err)
  200. {
  201. ExceptionHelper.Manage("WMIEventWatcher:HandleRemovedEvent", err);
  202. }
  203. }
  204. /// <summary>
  205. /// when starting, get a list of all existing logical disk
  206. /// </summary>
  207. /// <returns></returns>
  208. private List<USBDiskInfo> GetExistingDevices()
  209. {
  210. try
  211. {
  212. List<USBDiskInfo> devices = new List<USBDiskInfo>();
  213. ObjectQuery diskQuery = new ObjectQuery("Select * from Win32_DiskDrive where InterfaceType='USB'");
  214. foreach (ManagementObject drive in new ManagementObjectSearcher(diskQuery).Get())
  215. {
  216. ObjectQuery partQuery = new ObjectQuery(
  217. String.Format("associators of {{Win32_DiskDrive.DeviceID='{0}'}} where AssocClass = Win32_DiskDriveToDiskPartition", drive["DeviceID"])
  218. );
  219. DebugPrint(drive);
  220. foreach (ManagementObject partition in new ManagementObjectSearcher(partQuery).Get())
  221. {
  222. // associate partitions with logical disks (drive letter volumes)
  223. ObjectQuery logicalQuery = new ObjectQuery(
  224. String.Format("associators of {{Win32_DiskPartition.DeviceID='{0}'}} where AssocClass = Win32_LogicalDiskToPartition", partition["DeviceID"])
  225. );
  226. DebugPrint(partition);
  227. foreach (ManagementObject logical in new ManagementObjectSearcher(logicalQuery).Get())
  228. {
  229. DebugPrint(logical);
  230. USBDiskInfo disk = new USBDiskInfo();
  231. ParseDiskDriveInfo(disk, drive);
  232. ParseDiskLogicalInfo(disk, logical);
  233. devices.Add(disk);
  234. }
  235. }
  236. }
  237. return devices;
  238. }
  239. catch (ManagementException err)
  240. {
  241. ExceptionHelper.Manage("WMIEventWatcher:GetDevices", err);
  242. return null;
  243. }
  244. }
  245. private void ParseDiskDriveInfo(USBDiskInfo disk, ManagementBaseObject drive)
  246. {
  247. disk.PNPDeviceID = drive["PNPDeviceID"].ToString().Replace("\\", "");
  248. disk.Model = drive["Model"].ToString();
  249. disk.Caption = drive["Caption"].ToString();
  250. }
  251. private void ParseDiskLogicalInfo(USBDiskInfo disk, ManagementBaseObject logical)
  252. {
  253. disk.Name = logical["Name"].ToString();
  254. disk.Path = logical["Name"].ToString();
  255. disk.VolumeName = logical["VolumeName"].ToString();
  256. disk.FreeSpace = (ulong)logical["FreeSpace"];
  257. disk.Size = (ulong)logical["Size"];
  258. }
  259. /// <summary>
  260. /// internal function to trace properties
  261. /// </summary>
  262. /// <param name="e"></param>
  263. private void DebugPrint(ManagementBaseObject e)
  264. {
  265. Console.WriteLine("--------------------------------------------------------------");
  266. Console.WriteLine("ClassPath : {0}", e.ClassPath);
  267. Console.WriteLine("Site : {0}", e.Site);
  268. foreach (PropertyData prop in e.Properties)
  269. Console.WriteLine("PROPERTY : {0} - {1}", prop.Name, prop.Value);
  270. foreach (PropertyData prop in e.SystemProperties)
  271. Console.WriteLine("SYSTEM : {0} - {1}", prop.Name, prop.Value);
  272. foreach (QualifierData prop in e.Qualifiers)
  273. Console.WriteLine("QUALIFIER : {0} - {1}", prop.Name, prop.Value);
  274. Console.WriteLine("--------------------------------------------------------------");
  275. }
  276. #endregion
  277. }
  278. }