Mercurial > hg > ucis.core
view USBLib/Windows/Devices/DeviceNode.cs @ 21:dcfec2be27c9
Added USBLib
author | Ivo Smits <Ivo@UCIS.nl> |
---|---|
date | Mon, 15 Apr 2013 01:04:59 +0200 |
parents | |
children | 556b4fb511bd |
line wrap: on
line source
???using System; using System.Collections.Generic; using System.ComponentModel; using System.Runtime.InteropServices; using System.Text; using Microsoft.Win32; using UCIS.USBLib.Internal.Windows; namespace UCIS.HWLib.Windows.Devices { public class CMException : Exception { internal CMException(CR result, String method) : base(method + " returned " + result.ToString()) { } internal static void Throw(CR result, String method) { if (result == CR.SUCCESS) return; throw new CMException(result, method); } } public class DeviceNode { public static DeviceNode Root { get { UInt32 node; CR ret = SetupApi.CM_Locate_DevNode(out node, null, 0); CMException.Throw(ret, "CM_Locate_DevNode"); return new DeviceNode(node); } } public static DeviceNode GetDevice(String deviceID) { UInt32 node; CR ret = SetupApi.CM_Locate_DevNode(out node, deviceID, 0); CMException.Throw(ret, "CM_Locate_DevNode"); return new DeviceNode(node); } private static IList<DeviceNode> GetDevicesInSet(SafeDeviceInfoSetHandle dis) { List<DeviceNode> list = new List<DeviceNode>(); if (dis.IsInvalid) throw new Win32Exception(Marshal.GetLastWin32Error()); SP_DEVINFO_DATA dd = new SP_DEVINFO_DATA(true); for (int index = 0; ; index++) { if (!SetupApi.SetupDiEnumDeviceInfo(dis, index, ref dd)) break; list.Add(new DeviceNode(dd.DevInst)); } return list; } public static IList<DeviceNode> GetDevices() { using (SafeDeviceInfoSetHandle dis = SetupApi.SetupDiGetClassDevsA(IntPtr.Zero, null, IntPtr.Zero, DICFG.PRESENT | DICFG.ALLCLASSES)) { return GetDevicesInSet(dis); } } public static IList<DeviceNode> GetDevices(Guid classGuid) { using (SafeDeviceInfoSetHandle dis = SetupApi.SetupDiGetClassDevsA(ref classGuid, null, IntPtr.Zero, DICFG.PRESENT | DICFG.DEVICEINTERFACE)) { return GetDevicesInSet(dis); } } public static IList<DeviceNode> GetDevices(String enumerator) { using (SafeDeviceInfoSetHandle dis = SetupApi.SetupDiGetClassDevsA(IntPtr.Zero, enumerator, IntPtr.Zero, DICFG.PRESENT | DICFG.ALLCLASSES)) { //using (SafeDeviceInfoSetHandle dis = SetupApi.SetupDiGetClassDevsA(IntPtr.Zero, enumerator, IntPtr.Zero, DICFG.ALLCLASSES | DICFG.DEVICEINTERFACE)) { return GetDevicesInSet(dis); } } public UInt32 DevInst { get; private set; } private String _DeviceID = null; internal DeviceNode(UInt32 node) { DevInst = node; } public String DeviceID { get { if (_DeviceID == null) { uint deviceidlen; CR ret = SetupApi.CM_Get_Device_ID_Size(out deviceidlen, DevInst, 0); CMException.Throw(ret, "CM_Get_Device_ID_Size"); StringBuilder deviceid = new StringBuilder((int)deviceidlen); ret = SetupApi.CM_Get_Device_ID(DevInst, deviceid, deviceid.MaxCapacity, 0); CMException.Throw(ret, "CM_Get_Device_ID"); _DeviceID = deviceid.ToString(); } return _DeviceID; } } public Byte[] GetProperty(SPDRP property) { using (SafeDeviceInfoSetHandle dis = SetupApi.SetupDiGetClassDevsA(IntPtr.Zero, DeviceID, IntPtr.Zero, DICFG.DEVICEINTERFACE | DICFG.ALLCLASSES)) { if (dis.IsInvalid) throw new Win32Exception(Marshal.GetLastWin32Error()); SP_DEVINFO_DATA dd = new SP_DEVINFO_DATA(true); if (!SetupApi.SetupDiEnumDeviceInfo(dis, 0, ref dd)) return null; //throw new Win32Exception(Marshal.GetLastWin32Error()); RegistryValueKind propertyType; byte[] propBuffer = new byte[256]; int requiredSize; if (!SetupApi.SetupDiGetDeviceRegistryProperty(dis, ref dd, property, out propertyType, propBuffer, propBuffer.Length, out requiredSize)) return null; if (requiredSize > propBuffer.Length) { propBuffer = new Byte[requiredSize]; if (!SetupApi.SetupDiGetDeviceRegistryProperty(dis, ref dd, property, out propertyType, propBuffer, propBuffer.Length, out requiredSize)) throw new Win32Exception(Marshal.GetLastWin32Error()); } if (requiredSize < propBuffer.Length) Array.Resize(ref propBuffer, requiredSize); return propBuffer; } } public String GetPropertyString(SPDRP property) { Byte[] buffer = GetProperty(property); if (buffer == null) return null; return SetupApi.GetAsString(buffer, buffer.Length); } public Byte[] GetProperty(CMRDP property) { uint proplength = 0; uint proptype; CR ret = SetupApi.CM_Get_DevNode_Registry_Property(DevInst, property, out proptype, null, ref proplength, 0); if (ret == CR.NO_SUCH_VALUE) return null; if (ret != CR.BUFFER_SMALL) CMException.Throw(ret, "CM_Get_DevNode_Registry_Property"); Byte[] propbuffer = new Byte[proplength]; ret = SetupApi.CM_Get_DevNode_Registry_Property(DevInst, property, out proptype, propbuffer, ref proplength, 0); CMException.Throw(ret, "CM_Get_DevNode_Registry_Property"); if (propbuffer.Length > proplength) Array.Resize(ref propbuffer, (int)proplength); return propbuffer; } public String GetPropertyString(CMRDP property) { Byte[] buffer = GetProperty(property); if (buffer == null) return null; return SetupApi.GetAsString(buffer, buffer.Length); } public String[] GetPropertyStringArray(CMRDP property) { Byte[] buffer = GetProperty(property); if (buffer == null) return null; return SetupApi.GetAsStringArray(buffer, buffer.Length); } public Byte[] GetCustomProperty(String name) { using (SafeDeviceInfoSetHandle dis = SetupApi.SetupDiGetClassDevsA(IntPtr.Zero, DeviceID, IntPtr.Zero, DICFG.DEVICEINTERFACE | DICFG.ALLCLASSES)) { if (dis.IsInvalid) throw new Win32Exception(Marshal.GetLastWin32Error()); SP_DEVINFO_DATA dd = new SP_DEVINFO_DATA(true); if (!SetupApi.SetupDiEnumDeviceInfo(dis, 0, ref dd)) return null; //throw new Win32Exception(Marshal.GetLastWin32Error()); RegistryValueKind propertyType; byte[] propBuffer = new byte[256]; int requiredSize; if (!SetupApi.SetupDiGetCustomDeviceProperty(dis, ref dd, name, DICUSTOMDEVPROP.NONE, out propertyType, propBuffer, propBuffer.Length, out requiredSize)) return null; if (requiredSize > propBuffer.Length) { propBuffer = new Byte[requiredSize]; if (!SetupApi.SetupDiGetCustomDeviceProperty(dis, ref dd, name, DICUSTOMDEVPROP.NONE, out propertyType, propBuffer, propBuffer.Length, out requiredSize)) throw new Win32Exception(Marshal.GetLastWin32Error()); } if (requiredSize < propBuffer.Length) Array.Resize(ref propBuffer, requiredSize); return propBuffer; } } public String GetCustomPropertyString(String name) { Byte[] buffer = GetCustomProperty(name); if (buffer == null) return null; return SetupApi.GetAsString(buffer, buffer.Length); } public String[] GetCustomPropertyStringArray(String name) { Byte[] buffer = GetCustomProperty(name); if (buffer == null) return null; return SetupApi.GetAsStringArray(buffer, buffer.Length); } public String DeviceDescription { get { return GetPropertyString(CMRDP.DEVICEDESC); } } public String[] HardwareID { get { return GetPropertyStringArray(CMRDP.HARDWAREID); } } public String[] CompatibleIDs { get { return GetPropertyStringArray(CMRDP.COMPATIBLEIDS); } } public String Service { get { return GetPropertyString(CMRDP.SERVICE); } } public String Class { get { return GetPropertyString(CMRDP.CLASS); } } public String ClassGuid { get { return GetPropertyString(CMRDP.CLASSGUID); } } public String DriverKey { get { return GetPropertyString(CMRDP.DRIVER); } } public String Manufacturer { get { return GetPropertyString(CMRDP.MFG); } } public String FriendlyName { get { return GetPropertyString(CMRDP.FRIENDLYNAME); } } public String LocationInformation { get { return GetPropertyString(CMRDP.LOCATION_INFORMATION); } } public String PhysicalDeviceObjectName { get { return GetPropertyString(CMRDP.PHYSICAL_DEVICE_OBJECT_NAME); } } public Guid? BusTypeGuid { get { return SetupApi.GetAsGuid(GetProperty(CMRDP.BUSTYPEGUID)); } } public Int32? BusNumber { get { return SetupApi.GetAsInt32(GetProperty(CMRDP.BUSNUMBER)); } } public String EnumeratorName { get { return GetPropertyString(CMRDP.ENUMERATOR_NAME); } } public String[] GetInterfaces(String classGuid) { return GetInterfaces(new Guid(classGuid)); } public String[] GetInterfaces(Guid classGuid) { uint len; CR ret = SetupApi.CM_Get_Device_Interface_List_Size(out len, ref classGuid, DeviceID, 0); CMException.Throw(ret, "CM_Get_Device_Interface_List_Size"); if (len <= 1) return null; Byte[] buffer = new Byte[2 * len]; ret = SetupApi.CM_Get_Device_Interface_List(ref classGuid, DeviceID, buffer, len, 0); CMException.Throw(ret, "CM_Get_Device_Interface_List"); return SetupApi.GetAsStringArray(buffer, 2 * (int)len); } public Boolean SupportsInterface(Guid classGuid) { uint len; CR ret = SetupApi.CM_Get_Device_Interface_List_Size(out len, ref classGuid, DeviceID, 0); CMException.Throw(ret, "CM_Get_Device_Interface_List_Size"); return len > 2; } public IList<DeviceNode> GetChildren() { UInt32 child; CR ret = SetupApi.CM_Get_Child(out child, DevInst, 0); if (ret == CR.NO_SUCH_DEVNODE) return null; CMException.Throw(ret, "CM_Get_Child"); List<DeviceNode> list = new List<DeviceNode>(); while (true) { list.Add(new DeviceNode(child)); ret = SetupApi.CM_Get_Sibling(out child, child, 0); if (ret == CR.NO_SUCH_DEVNODE) break; CMException.Throw(ret, "CM_Get_Sibling"); } return list; } public DeviceNode GetParent() { UInt32 node; CR ret = SetupApi.CM_Get_Parent(out node, DevInst, 0); if (ret == CR.NO_SUCH_DEVNODE) return null; CMException.Throw(ret, "CM_Get_Parent"); return new DeviceNode(node); } public Boolean Present { get { UInt32 status, problem; CR ret = SetupApi.CM_Get_DevNode_Status(out status, out problem, DevInst, 0); if (ret == CR.NO_SUCH_DEVNODE) return false; CMException.Throw(ret, "CM_Get_DevNode_Status"); if (status == 25174016) return false; return true; } } public override bool Equals(object obj) { DeviceNode other = obj as DeviceNode; if (ReferenceEquals(other, null)) return false; return DevInst == other.DevInst; } public override int GetHashCode() { return (int)DevInst; } public static Boolean operator ==(DeviceNode x, DeviceNode y) { if (ReferenceEquals(x, y)) return true; if (ReferenceEquals(x, null)) return false; if (ReferenceEquals(y, null)) return false; return x.DevInst == y.DevInst; } public static Boolean operator !=(DeviceNode x, DeviceNode y) { return !(x == y); } public void SetEnabled(Boolean enabled) { using (SafeDeviceInfoSetHandle dis = SetupApi.SetupDiGetClassDevsA(IntPtr.Zero, DeviceID, IntPtr.Zero, DICFG.DEVICEINTERFACE | DICFG.ALLCLASSES)) { if (dis.IsInvalid) throw new Win32Exception(Marshal.GetLastWin32Error()); SP_DEVINFO_DATA dd = new SP_DEVINFO_DATA(true); if (!SetupApi.SetupDiEnumDeviceInfo(dis, 0, ref dd)) throw new Win32Exception(Marshal.GetLastWin32Error()); SP_PROPCHANGE_PARAMS PropChangeParams = new SP_PROPCHANGE_PARAMS(); PropChangeParams.ClassInstallHeader.cbSize = Marshal.SizeOf(PropChangeParams.ClassInstallHeader); PropChangeParams.ClassInstallHeader.InstallFunction = UsbApi.DIF_PROPERTYCHANGE; PropChangeParams.Scope = UsbApi.DICS_FLAG_GLOBAL; // or use DICS_FLAG_CONFIGSPECIFIC to limit to current HW profile PropChangeParams.HwProfile = 0; //Current hardware profile PropChangeParams.StateChange = enabled ? UsbApi.DICS_ENABLE : UsbApi.DICS_DISABLE; if (!SetupApi.SetupDiSetClassInstallParams(dis, ref dd, ref PropChangeParams.ClassInstallHeader, Marshal.SizeOf(PropChangeParams))) throw new Win32Exception(Marshal.GetLastWin32Error()); if (!SetupApi.SetupDiCallClassInstaller(UsbApi.DIF_PROPERTYCHANGE, dis, ref dd)) throw new Win32Exception(Marshal.GetLastWin32Error()); } } } }