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