using System;
using System.Management;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Collections.ObjectModel;
using System.Windows;
using System.Windows.Threading;
using System.Threading;
namespace CBR.Core.Helpers
{
#region ----------------EVENTS----------------
public enum WMIActions
{
Added,
Removed
}
public class WMIEventArgs : EventArgs
{
public USBDiskInfo Disk { get; set; }
public WMIActions EventType { get; set; }
}
public delegate void WMIEventArrived(object sender, WMIEventArgs e);
#endregion
/// <summary>
///
/// </summary>
public class WMIEventWatcher
{
#region ----------------CONSTRUCTOR----------------
/// <summary>
/// constructor
/// </summary>
public WMIEventWatcher()
{
Devices = GetExistingDevices();
}
#endregion
#region ----------------INTERNALS----------------
/// <summary>
/// internal watcher for add event
/// </summary>
private ManagementEventWatcher addedWatcher = null;
/// <summary>
/// internal watcher for remove event
/// </summary>
private ManagementEventWatcher removedWatcher = null;
#endregion
#region ----------------PROPERTIES----------------
/// <summary>
/// List of founded devices
/// </summary>
public List<USBDiskInfo> Devices { get; set; }
#endregion
#region ----------------EVENTS----------------
/// <summary>
/// signaled when watched events occurs
/// </summary>
public event WMIEventArrived EventArrived;
#endregion
#region ----------------METHODS----------------
/// <summary>
/// start watching for logical device events
/// </summary>
public void StartWatchUSB()
{
try
{
addedWatcher = new ManagementEventWatcher("SELECT * FROM __InstanceCreationEvent WITHIN 5 WHERE TargetInstance ISA \"Win32_USBControllerDevice\"");
addedWatcher.EventArrived += new EventArrivedEventHandler(HandleAddedEvent);
addedWatcher.Start();
removedWatcher = new ManagementEventWatcher("SELECT * FROM __InstanceDeletionEvent WITHIN 5 WHERE TargetInstance ISA \"Win32_USBControllerDevice\"");
removedWatcher.EventArrived += new EventArrivedEventHandler(HandleRemovedEvent);
removedWatcher.Start();
}
catch (ManagementException err)
{
ExceptionHelper.Manage("WMIEventWatcher:StartWatchUSB", err);
}
}
/// <summary>
/// stop watching for logical device events
/// </summary>
public void StopWatchUSB()
{
try
{
// Stop listening for events
if (addedWatcher != null)
addedWatcher.Stop();
if (removedWatcher != null)
removedWatcher.Stop();
}
catch (ManagementException err)
{
ExceptionHelper.Manage("WMIEventWatcher:StopWatchUSB", err);
}
}
/// <summary>
/// handle the add event
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void HandleAddedEvent(object sender, EventArrivedEventArgs e)
{
USBDiskInfo device = null;
try
{
ManagementBaseObject targetInstance = e.NewEvent["TargetInstance"] as ManagementBaseObject;
DebugPrint(targetInstance);
// get the device name in the dependent property Dependent: extract the last part
// \\FR-L25676\root\cimv2:Win32_PnPEntity.DeviceID="USBSTOR\\DISK&VEN_USB&PROD_FLASH_DISK&REV_1100\\AA04012700076941&0"
string PNP_deviceID = Convert.ToString(targetInstance["Dependent"]).Split('=').Last().Replace("\"", "").Replace("\\", "");
string device_name = Convert.ToString(targetInstance["Dependent"]).Split('\\').Last().Replace("\"", "");
// query that device entity
ObjectQuery query = new ObjectQuery(string.Format("Select * from Win32_PnPEntity Where DeviceID like \"%{0}%\"", device_name));
// check if match usb removable disk
using (ManagementObjectSearcher searcher = new ManagementObjectSearcher(query))
{
ManagementObjectCollection entities = searcher.Get();
//first loop to check USBSTOR
foreach (var entity in entities)
{
string service = Convert.ToString(entity["Service"]);
if (service == "USBSTOR")
device = new USBDiskInfo();
}
if (device != null)
{
foreach (var entity in entities)
{
string service = Convert.ToString(entity["Service"]);
if (service == "disk")
{
GetDiskInformation(device, device_name);
Devices.Add(device);
if (EventArrived != null)
EventArrived(this, new WMIEventArgs() { Disk = device, EventType = WMIActions.Added });
}
}
}
}
}
catch (ManagementException err)
{
ExceptionHelper.Manage("WMIEventWatcher:HandleAddedEvent", err);
}
}
private ManagementObjectSearcher GetDiskInformation(USBDiskInfo device, string device_name)
{
ManagementObjectSearcher searcher2 = null;
ObjectQuery query1 = new ObjectQuery("SELECT * FROM Win32_DiskDrive where PNPDeviceID like '%" + device_name + "%'");
searcher2 = new ManagementObjectSearcher(query1);
ManagementObjectCollection disks = searcher2.Get();
foreach (var disk in disks)
{
DebugPrint(disk);
//Use the disk drive device id to find associated partition
ObjectQuery query2 = new ObjectQuery("ASSOCIATORS OF {Win32_DiskDrive.DeviceID='" + Convert.ToString(disk["DeviceID"]).Replace("\"", "\\") + "'} WHERE AssocClass=Win32_DiskDriveToDiskPartition");
searcher2 = new ManagementObjectSearcher(query2);
ManagementObjectCollection partitions = searcher2.Get();
foreach (var part in partitions)
{
DebugPrint(part);
//Use partition device id to find logical disk
ObjectQuery query3 = new ObjectQuery("ASSOCIATORS OF {Win32_DiskPartition.DeviceID='" + Convert.ToString(part["DeviceID"]).Replace("\"", "\\") + "'} WHERE AssocClass=Win32_LogicalDiskToPartition");
searcher2 = new ManagementObjectSearcher(query3);
ManagementObjectCollection logic = searcher2.Get();
foreach (var disklogic in logic)
{
DebugPrint(disklogic);
ParseDiskDriveInfo(device, disk);
ParseDiskLogicalInfo(device, disklogic);
}
}
}
return searcher2;
}
/// <summary>
/// handle the remove event
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void HandleRemovedEvent(object sender, EventArrivedEventArgs e)
{
try
{
ManagementBaseObject targetInstance = e.NewEvent["TargetInstance"] as ManagementBaseObject;
DebugPrint(targetInstance);
string PNP_deviceID = Convert.ToString(targetInstance["Dependent"]).Split('=').Last().Replace("\"", "").Replace("\\", "");
USBDiskInfo device = Devices.Find(x => x.PNPDeviceID == PNP_deviceID);
if( device != null )
{
Devices.Remove( device );
if (EventArrived != null)
EventArrived(this, new WMIEventArgs() { Disk = device, EventType = WMIActions.Removed });
}
}
catch (ManagementException err)
{
ExceptionHelper.Manage("WMIEventWatcher:HandleRemovedEvent", err);
}
}
/// <summary>
/// when starting, get a list of all existing logical disk
/// </summary>
/// <returns></returns>
private List<USBDiskInfo> GetExistingDevices()
{
try
{
List<USBDiskInfo> devices = new List<USBDiskInfo>();
ObjectQuery diskQuery = new ObjectQuery("Select * from Win32_DiskDrive where InterfaceType='USB'");
foreach (ManagementObject drive in new ManagementObjectSearcher(diskQuery).Get())
{
ObjectQuery partQuery = new ObjectQuery(
String.Format("associators of {{Win32_DiskDrive.DeviceID='{0}'}} where AssocClass = Win32_DiskDriveToDiskPartition", drive["DeviceID"])
);
DebugPrint(drive);
foreach (ManagementObject partition in new ManagementObjectSearcher(partQuery).Get())
{
// associate partitions with logical disks (drive letter volumes)
ObjectQuery logicalQuery = new ObjectQuery(
String.Format("associators of {{Win32_DiskPartition.DeviceID='{0}'}} where AssocClass = Win32_LogicalDiskToPartition", partition["DeviceID"])
);
DebugPrint(partition);
foreach (ManagementObject logical in new ManagementObjectSearcher(logicalQuery).Get())
{
DebugPrint(logical);
USBDiskInfo disk = new USBDiskInfo();
ParseDiskDriveInfo(disk, drive);
ParseDiskLogicalInfo(disk, logical);
devices.Add(disk);
}
}
}
return devices;
}
catch (ManagementException err)
{
ExceptionHelper.Manage("WMIEventWatcher:GetDevices", err);
return null;
}
}
private void ParseDiskDriveInfo(USBDiskInfo disk, ManagementBaseObject drive)
{
disk.PNPDeviceID = drive["PNPDeviceID"].ToString().Replace("\\", "");
disk.Model = drive["Model"].ToString();
disk.Caption = drive["Caption"].ToString();
}
private void ParseDiskLogicalInfo(USBDiskInfo disk, ManagementBaseObject logical)
{
disk.Name = logical["Name"].ToString();
disk.Path = logical["Name"].ToString();
disk.VolumeName = logical["VolumeName"].ToString();
disk.FreeSpace = (ulong)logical["FreeSpace"];
disk.Size = (ulong)logical["Size"];
}
/// <summary>
/// internal function to trace properties
/// </summary>
/// <param name="e"></param>
private void DebugPrint(ManagementBaseObject e)
{
Console.WriteLine("--------------------------------------------------------------");
Console.WriteLine("ClassPath : {0}", e.ClassPath);
Console.WriteLine("Site : {0}", e.Site);
foreach (PropertyData prop in e.Properties)
Console.WriteLine("PROPERTY : {0} - {1}", prop.Name, prop.Value);
foreach (PropertyData prop in e.SystemProperties)
Console.WriteLine("SYSTEM : {0} - {1}", prop.Name, prop.Value);
foreach (QualifierData prop in e.Qualifiers)
Console.WriteLine("QUALIFIER : {0} - {1}", prop.Name, prop.Value);
Console.WriteLine("--------------------------------------------------------------");
}
#endregion
}
}