/// <summary> /// Set device state. /// </summary> /// <param name="match"></param> /// <param name="enable"></param> /// <returns>Success state.</returns> /// <remarks> /// This is nearly identical to the method above except it /// tries to match the hardware description against the criteria /// passed in. If a match is found, that device will the be /// enabled or disabled based on bEnable. /// Errors: This method may throw the following exceptions. /// Failed to enumerate device tree! /// </remarks> public static bool SetDeviceState(string deviceId, bool enable) { try { Guid myGUID = System.Guid.Empty; IntPtr deviceInfoSet = SetupDiGetClassDevs(myGUID, null, IntPtr.Zero, DIGCF.DIGCF_ALLCLASSES | DIGCF.DIGCF_PRESENT); if (deviceInfoSet.ToInt32() == INVALID_HANDLE_VALUE) { return(false); } var deviceInfoData = new SP_DEVINFO_DATA(); deviceInfoData.Initialize(); deviceInfoData.DevInst = 0; deviceInfoData.ClassGuid = System.Guid.Empty; deviceInfoData.Reserved = IntPtr.Zero; for (var i = 0; SetupDiEnumDeviceInfo(deviceInfoSet, i, ref deviceInfoData); i++) { var currentDeviceId = GetDeviceId(deviceInfoData.DevInst); if (deviceId == currentDeviceId) { SetDeviceState(deviceInfoSet, deviceInfoData, enable); } } SetupDiDestroyDeviceInfoList(deviceInfoSet); } catch (Exception ex) { throw new Exception("Failed to enumerate device tree!", ex); //return false; } return(true); }
/// <summary> /// Get list of devices. /// </summary> /// <param name="classGuid">Filter devices by class.</param> /// <param name="flags">Filter devices by options.</param> /// <param name="deviceId">Filter results by Device ID.</param> /// <param name="vid">Filter results by Vendor ID.</param> /// <param name="pid">Filter results by Product ID.</param> /// <param name="rev">Filter results by Revision ID.</param> /// <returns>List of devices</returns> /// <remarks> /// This is code I cobbled together from a number of newsgroup threads /// as well as some C++ stuff I translated off of MSDN. Seems to work. /// The idea is to come up with a list of devices, same as the device /// manager does. Currently it uses the actual "system" names for the /// hardware. It is also possible to use hardware IDs. See the docs /// for SetupDiGetDeviceRegistryProperty in the MS SDK for more details. /// Errors: This method may throw the following errors. /// Failed to enumerate device tree! /// Invalid handle! /// </remarks> public static DeviceInfo[] GetDevices(Guid?classGuid = null, DIGCF flags = DIGCF.DIGCF_ALLCLASSES, string deviceId = null, int vid = 0, int pid = 0, int rev = 0) { if (!classGuid.HasValue) { classGuid = Guid.Empty; } lock (GetDevicesLock) { // https://msdn.microsoft.com/en-us/library/windows/hardware/ff541247%28v=vs.85%29.aspx // // [Device Information Set] // ├──[Device Information] // │ ├──[Device Node] // │ └──[Device Interface], [Device Interface], ... // ├──[Device Information] // │ ├──[Device Node] // │ └──[Device Interface], [Device Interface], ... // // Create a device information set composed of all devices associated with a specified device setup class or device interface class. IntPtr deviceInfoSet = NativeMethods.SetupDiGetClassDevs(classGuid.Value, IntPtr.Zero, IntPtr.Zero, flags); if (deviceInfoSet.ToInt64() == ERROR_INVALID_HANDLE_VALUE) { throw new Exception("Invalid Handle"); } var list = new List <DeviceInfo>(); var deviceInfoData = new SP_DEVINFO_DATA(); deviceInfoData.Initialize(); // Enumerating Device Nodes. for (var i = 0; NativeMethods.SetupDiEnumDeviceInfo(deviceInfoSet, i, ref deviceInfoData); i++) { var currentDeviceId = GetDeviceId(deviceInfoData.DevInst); if (!string.IsNullOrEmpty(deviceId) && deviceId != currentDeviceId) { continue; } var device = GetDeviceInfo(deviceInfoSet, deviceInfoData); if (vid > 0 && device.VendorId != vid) { continue; } if (pid > 0 && device.ProductId != pid) { continue; } if (rev > 0 && device.Revision != rev) { continue; } list.Add(device); } NativeMethods.SetupDiDestroyDeviceInfoList(deviceInfoSet); return(list.OrderBy(x => x.ClassDescription).ThenBy(x => x.Description).ToArray()); } }
/// <summary> /// Enumerate devices. /// </summary> /// <param name="classGuid">Filter devices by class.</param> /// <param name="flags">Filter devices by options.</param> public static void _EnumDeviceInfo(Guid?classGuid, DIGCF?flags, string deviceInstanceId, Func <IntPtr, SP_DEVINFO_DATA, bool> callback) { if (!classGuid.HasValue) { classGuid = Guid.Empty; } if (!flags.HasValue) { flags = DIGCF.DIGCF_ALLCLASSES; } lock (GetDevicesLock) { // https://docs.microsoft.com/en-gb/windows-hardware/drivers/install/device-information-sets // // [Device Information Set] // ├──[Device Information] // │ ├──[Device Node] // │ └──[Device Interface], [Device Interface], ... // ├──[Device Information] // │ ├──[Device Node] // │ └──[Device Interface], [Device Interface], ... // // Create a device information set composed of all devices associated with a specified device setup class or device interface class. var infoSet = NativeMethods.SetupDiGetClassDevs(classGuid.Value, IntPtr.Zero, IntPtr.Zero, flags.Value); if (infoSet.ToInt64() == ERROR_INVALID_HANDLE_VALUE) { throw new Exception("Invalid Handle"); } var infoData = new SP_DEVINFO_DATA(); infoData.Initialize(); // If one device was requersted then... if (!string.IsNullOrEmpty(deviceInstanceId)) { var result = NativeMethods.SetupDiOpenDeviceInfo(infoSet, deviceInstanceId, IntPtr.Zero, 0, ref infoData); if (result) { callback.Invoke(infoSet, infoData); } } else { // Enumerating Device Nodes. for (var i = 0; NativeMethods.SetupDiEnumDeviceInfo(infoSet, i, ref infoData); i++) { if (!callback.Invoke(infoSet, infoData)) { break; } } } NativeMethods.SetupDiDestroyDeviceInfoList(infoSet); } }
public static SP_DEVINFO_DATA?GetDeviceInfo(IntPtr deviceInfoSet, string deviceInstanceId) { var da = new SP_DEVINFO_DATA(); da.Initialize(); var result = SetupDiOpenDeviceInfo(deviceInfoSet, deviceInstanceId, IntPtr.Zero, 0, ref da); if (!result) { return(null); } return(da); }
public static SP_DEVINFO_DATA?GetDeviceInfo(string deviceInstanceId, IntPtr deviceInfoSet) { var di = new SP_DEVINFO_DATA(); di.Initialize(); var result = NativeMethods.SetupDiOpenDeviceInfo(deviceInfoSet, deviceInstanceId, IntPtr.Zero, 0, ref di); if (!result) { return(null); } return(di); }
public static DeviceInfo GetParentDevice(Guid classGuid, DIGCF flags, string deviceId) { lock (GetDevicesLock) { IntPtr deviceInfoSet = NativeMethods.SetupDiGetClassDevs(classGuid, IntPtr.Zero, IntPtr.Zero, flags); // | DIGCF.DIGCF_PRESENT if (deviceInfoSet.ToInt64() == ERROR_INVALID_HANDLE_VALUE) { throw new Exception("Invalid Handle"); } DeviceInfo device = null; var deviceInfoData = new SP_DEVINFO_DATA(); deviceInfoData.Initialize(); int i; for (i = 0; NativeMethods.SetupDiEnumDeviceInfo(deviceInfoSet, i, ref deviceInfoData); i++) { if (deviceId == GetDeviceId(deviceInfoData.DevInst)) { uint parentDeviceInstance = 0; var CRResult = NativeMethods.CM_Get_Parent(out parentDeviceInstance, deviceInfoData.DevInst, 0); if (CRResult == CR.CR_NO_SUCH_DEVNODE) { break; } if (CRResult != CR.CR_SUCCESS) { break; } var parentDeviceId = GetDeviceId(parentDeviceInstance); var devices = GetDevices(classGuid, flags, parentDeviceId); if (devices.Length > 0) { device = devices[0]; } break; } } NativeMethods.SetupDiDestroyDeviceInfoList(deviceInfoSet); return(device); } }
public static DeviceInfo[] GetDevices(Guid classGuid, DIGCF flags, string deviceId, int vid, int pid, int rev) { lock (GetDevicesLock) { IntPtr deviceInfoSet = SetupDiGetClassDevs(classGuid, null, IntPtr.Zero, flags); // | DIGCF.DIGCF_PRESENT if (deviceInfoSet.ToInt32() == ERROR_INVALID_HANDLE_VALUE) { throw new Exception("Invalid Handle"); } var list = new List <DeviceInfo>(); var deviceInfoData = new SP_DEVINFO_DATA(); deviceInfoData.Initialize(); int i; for (i = 0; SetupDiEnumDeviceInfo(deviceInfoSet, i, ref deviceInfoData); i++) { var currentDeviceId = GetDeviceId(deviceInfoData.DevInst); if (!string.IsNullOrEmpty(deviceId) && deviceId != currentDeviceId) { continue; } var device = GetDeviceInfo(deviceInfoSet, deviceInfoData, deviceId); if (vid > 0 && device.VendorId != vid) { continue; } if (pid > 0 && device.ProductId != pid) { continue; } if (rev > 0 && device.Revision != rev) { continue; } list.Add(device); } SetupDiDestroyDeviceInfoList(deviceInfoSet); return(list.OrderBy(x => x.ClassDescription).ThenBy(x => x.Description).ToArray()); } }
public static SP_DRVINFO_DATA[] GetDrivers(Guid?classGuid = null, DIGCF flags = DIGCF.DIGCF_ALLCLASSES, SPDIT driverType = SPDIT.SPDIT_COMPATDRIVER, string deviceId = null, string hardwareId = null) { var drvInfoList = new List <SP_DRVINFO_DATA>(); var deviceInfoSet = NativeMethods.SetupDiGetClassDevs(classGuid ?? Guid.Empty, IntPtr.Zero, IntPtr.Zero, flags); if (deviceInfoSet.ToInt64() == ERROR_INVALID_HANDLE_VALUE) { return(drvInfoList.ToArray()); } // Loop through device info. var deviceInfoData = new SP_DEVINFO_DATA(); deviceInfoData.Initialize(); for (int i = 0; NativeMethods.SetupDiEnumDeviceInfo(deviceInfoSet, i, ref deviceInfoData); i++) { if (!string.IsNullOrEmpty(deviceId)) { var currentDeviceId = GetDeviceId(deviceInfoData.DevInst); if (string.Compare(deviceId, currentDeviceId, true) != 0) { continue; } } if (!string.IsNullOrEmpty(hardwareId)) { var currentHardwareId = GetStringPropertyForDevice(deviceInfoSet, deviceInfoData, SPDRP.SPDRP_HARDWAREID); if (string.Compare(hardwareId, currentHardwareId, true) != 0) { continue; } } var drivers = GetDrivers(deviceInfoSet, ref deviceInfoData, driverType); drvInfoList.AddRange(drivers); } NativeMethods.SetupDiDestroyDeviceInfoList(deviceInfoSet); return(drvInfoList.ToArray()); }
public static DeviceInfo[] GetInterfaces() { var list = new List <DeviceInfo>(); Guid hidGuid = Guid.Empty; NativeMethods.HidD_GetHidGuid(ref hidGuid); int requiredSize3 = 0; var interfaceData = new SP_DEVICE_INTERFACE_DATA(); interfaceData.Initialize(); List <string> serials = new List <string>(); var deviceInfoSet = NativeMethods.SetupDiGetClassDevs(hidGuid, IntPtr.Zero, IntPtr.Zero, DIGCF.DIGCF_DEVICEINTERFACE); for (int i2 = 0; NativeMethods.SetupDiEnumDeviceInterfaces(deviceInfoSet, IntPtr.Zero, ref hidGuid, i2, ref interfaceData); i2++) { var deviceInfoData = new SP_DEVINFO_DATA(); deviceInfoData.Initialize(); bool success = NativeMethods.SetupDiGetDeviceInterfaceDetail(deviceInfoSet, ref interfaceData, IntPtr.Zero, 0, ref requiredSize3, IntPtr.Zero); IntPtr ptrDetails = Marshal.AllocHGlobal(requiredSize3); Marshal.WriteInt32(ptrDetails, (IntPtr.Size == 4) ? (4 + Marshal.SystemDefaultCharSize) : 8); success = NativeMethods.SetupDiGetDeviceInterfaceDetail(deviceInfoSet, ref interfaceData, ptrDetails, requiredSize3, ref requiredSize3, ref deviceInfoData); var interfaceDetail = (SP_DEVICE_INTERFACE_DETAIL_DATA)Marshal.PtrToStructure(ptrDetails, typeof(SP_DEVICE_INTERFACE_DETAIL_DATA)); var di = GetDeviceInfo(deviceInfoSet, deviceInfoData); di.DevicePath = interfaceDetail.DevicePath; var deviceHandle = deviceInfoData.DevInst; Marshal.FreeHGlobal(ptrDetails); // Open the device as a file so that we can query it with HID and read/write to it. var devHandle = NativeMethods.CreateFile( interfaceDetail.DevicePath, 0, FileShare.ReadWrite, IntPtr.Zero, FileMode.Open, 0, //WinNT.Overlapped IntPtr.Zero ); if (devHandle.IsInvalid) { continue; } var ha = new HIDD_ATTRIBUTES(); ha.Size = Marshal.SizeOf(ha); var success2 = NativeMethods.HidD_GetAttributes(devHandle, ref ha); string serial = ""; string phdesc = ""; if (success2) { IntPtr preparsedDataPtr = new IntPtr(); HIDP_CAPS caps = new HIDP_CAPS(); // Read out the 'pre-parsed data'. NativeMethods.HidD_GetPreparsedData(devHandle, ref preparsedDataPtr); // feed that to GetCaps. NativeMethods.HidP_GetCaps(preparsedDataPtr, ref caps); // Free the 'pre-parsed data'. NativeMethods.HidD_FreePreparsedData(ref preparsedDataPtr); // This could fail if the device was recently attached. // Maximum string length is 126 wide characters (2 bytes each) (not including the terminating NULL character). ulong capacity = (uint)(126 * Marshal.SystemDefaultCharSize + 2); var sb = new StringBuilder((int)capacity, (int)capacity); // Override manufacturer if found. if (NativeMethods.HidD_GetManufacturerString(devHandle, sb, sb.Capacity) && sb.Length > 0) { di.Manufacturer = sb.ToString(); } // Override ProductName if Found. if (NativeMethods.HidD_GetProductString(devHandle, sb, sb.Capacity) && sb.Length > 0) { di.Description = sb.ToString(); } serial = NativeMethods.HidD_GetSerialNumberString(devHandle, sb, sb.Capacity) ? sb.ToString() : ""; phdesc = NativeMethods.HidD_GetPhysicalDescriptor(devHandle, sb, sb.Capacity) ? sb.ToString() : ""; } uint parentDeviceInstance = 0; string parentDeviceId = null; var CRResult = NativeMethods.CM_Get_Parent(out parentDeviceInstance, deviceHandle, 0); if (CRResult == CR.CR_SUCCESS) { parentDeviceId = GetDeviceId(parentDeviceInstance); } list.Add(di); serials.Add(phdesc); devHandle.Close(); } NativeMethods.SetupDiDestroyDeviceInfoList(deviceInfoSet); deviceInfoSet = IntPtr.Zero; return(list.ToArray()); }
public static DeviceInfo[] GetInterfaces() { var list = new List <DeviceInfo>(); var hidGuid = Guid.Empty; NativeMethods.HidD_GetHidGuid(ref hidGuid); var requiredSize3 = 0; // serialNumbers and physicalDescriptors for debug purposes only. var serialNumbers = new List <string>(); var physicalDescriptors = new List <string>(); _EnumDeviceInterfaces((deviceInfoSet, interfaceData) => { bool success; var deviceInfoData = new SP_DEVINFO_DATA(); deviceInfoData.Initialize(); // Call 1: Retrieve data size. Note: Returns ERROR_INSUFFICIENT_BUFFER = 122, which is normal. success = NativeMethods.SetupDiGetDeviceInterfaceDetail(deviceInfoSet, ref interfaceData, IntPtr.Zero, 0, ref requiredSize3, ref deviceInfoData); // Allocate memory for results. var ptrDetails = Marshal.AllocHGlobal(requiredSize3); Marshal.WriteInt32(ptrDetails, IntPtr.Size == 4 ? 4 + Marshal.SystemDefaultCharSize : 8); // Call 2: Retrieve data. success = NativeMethods.SetupDiGetDeviceInterfaceDetail(deviceInfoSet, ref interfaceData, ptrDetails, requiredSize3, ref requiredSize3, ref deviceInfoData); var interfaceDetail = (SP_DEVICE_INTERFACE_DETAIL_DATA)Marshal.PtrToStructure(ptrDetails, typeof(SP_DEVICE_INTERFACE_DETAIL_DATA)); var di = GetDeviceInfo(deviceInfoSet, deviceInfoData); di.DevicePath = interfaceDetail.DevicePath; Marshal.FreeHGlobal(ptrDetails); // Note: Interfaces don't have vendor or product, therefore must get from parent device. // Open the device as a file so that we can query it with HID and read/write to it. var devHandle = NativeMethods.CreateFile( interfaceDetail.DevicePath, 0, FileShare.ReadWrite, IntPtr.Zero, FileMode.Open, 0, //WinNT.Overlapped IntPtr.Zero ); if (devHandle.IsInvalid) { return(true); } // Get vendor product and version from device. var ha = new HIDD_ATTRIBUTES(); ha.Size = Marshal.SizeOf(ha); var success2 = NativeMethods.HidD_GetAttributes(devHandle, ref ha); di.VendorId = ha.VendorID; di.ProductId = ha.ProductID; di.Revision = ha.VersionNumber; // Get other options. if (success2) { var preparsedDataPtr = new IntPtr(); var caps = new HIDP_CAPS(); // Read out the 'pre-parsed data'. NativeMethods.HidD_GetPreparsedData(devHandle, ref preparsedDataPtr); // feed that to GetCaps. NativeMethods.HidP_GetCaps(preparsedDataPtr, ref caps); // Free the 'pre-parsed data'. NativeMethods.HidD_FreePreparsedData(ref preparsedDataPtr); // This could fail if the device was recently attached. // Maximum string length is 126 wide characters (2 bytes each) (not including the terminating NULL character). var capacity = (uint)(126 * Marshal.SystemDefaultCharSize + 2); var sb = new StringBuilder((int)capacity, (int)capacity); // Override manufacturer if found. if (NativeMethods.HidD_GetManufacturerString(devHandle, sb, sb.Capacity) && sb.Length > 0) { di.Manufacturer = sb.ToString(); } // Override ProductName if Found. if (NativeMethods.HidD_GetProductString(devHandle, sb, sb.Capacity) && sb.Length > 0) { di.Description = sb.ToString(); } // Get Serial number. var serialNumber = NativeMethods.HidD_GetSerialNumberString(devHandle, sb, sb.Capacity) ? sb.ToString() : ""; serialNumbers.Add(serialNumber); // Get physical descriptor. var physicalDescriptor = NativeMethods.HidD_GetPhysicalDescriptor(devHandle, sb, sb.Capacity) ? sb.ToString() : ""; physicalDescriptors.Add(physicalDescriptor); } list.Add(di); devHandle.Close(); return(true); }); return(list.ToArray()); }
public static DeviceInfo[] GetInterfaces(string[] devicePaths = null) { var list = new List <DeviceInfo>(); Guid hidGuid = Guid.Empty; NativeMethods.HidD_GetHidGuid(ref hidGuid); int requiredSize3 = 0; List <string> devicePathNames3 = new List <string>(); var interfaceData = new SP_DEVICE_INTERFACE_DATA(); List <string> serials = new List <string>(); interfaceData.Initialize(); var deviceInfoSet = NativeMethods.SetupDiGetClassDevs(hidGuid, IntPtr.Zero, IntPtr.Zero, DIGCF.DIGCF_DEVICEINTERFACE); for (int i2 = 0; NativeMethods.SetupDiEnumDeviceInterfaces(deviceInfoSet, IntPtr.Zero, ref hidGuid, i2, ref interfaceData); i2++) { var deviceInfoData = new SP_DEVINFO_DATA(); deviceInfoData.Initialize(); bool success = NativeMethods.SetupDiGetDeviceInterfaceDetail(deviceInfoSet, ref interfaceData, IntPtr.Zero, 0, ref requiredSize3, IntPtr.Zero); IntPtr ptrDetails = Marshal.AllocHGlobal(requiredSize3); Marshal.WriteInt32(ptrDetails, (IntPtr.Size == 4) ? (4 + Marshal.SystemDefaultCharSize) : 8); success = NativeMethods.SetupDiGetDeviceInterfaceDetail(deviceInfoSet, ref interfaceData, ptrDetails, requiredSize3, ref requiredSize3, ref deviceInfoData); var interfaceDetail = (SP_DEVICE_INTERFACE_DETAIL_DATA)Marshal.PtrToStructure(ptrDetails, typeof(SP_DEVICE_INTERFACE_DETAIL_DATA)); var devicePath = interfaceDetail.DevicePath; if (devicePaths != null && !devicePaths.Contains(devicePath)) { continue; } var deviceHandle = deviceInfoData.DevInst; var deviceId = GetDeviceId(deviceHandle); devicePathNames3.Add(devicePath); Marshal.FreeHGlobal(ptrDetails); var accessRights = WinNT.GENERIC_READ | WinNT.GENERIC_WRITE; var shareModes = WinNT.FILE_SHARE_READ | WinNT.FILE_SHARE_WRITE; // Open the device as a file so that we can query it with HID and read/write to it. var devHandle = NativeMethods.CreateFile( interfaceDetail.DevicePath, accessRights, shareModes, IntPtr.Zero, WinNT.OPEN_EXISTING, WinNT.Overlapped, IntPtr.Zero ); if (devHandle.IsInvalid) { continue; } var ha = new HIDD_ATTRIBUTES(); ha.Size = Marshal.SizeOf(ha); var success2 = NativeMethods.HidD_GetAttributes(devHandle, ref ha); string serial = ""; string vendor = ""; string product = ""; string phdesc = ""; if (success2) { IntPtr preparsedDataPtr = new IntPtr(); HIDP_CAPS caps = new HIDP_CAPS(); // Read out the 'preparsed data'. NativeMethods.HidD_GetPreparsedData(devHandle, ref preparsedDataPtr); // feed that to GetCaps. NativeMethods.HidP_GetCaps(preparsedDataPtr, ref caps); // Free the 'preparsed data'. NativeMethods.HidD_FreePreparsedData(ref preparsedDataPtr); // This could fail if the device was recently attached. uint capacity = 126; IntPtr buffer = Marshal.AllocHGlobal((int)capacity); serial = NativeMethods.HidD_GetSerialNumberString(devHandle, buffer, capacity) ? Marshal.PtrToStringAuto(buffer) : ""; vendor = NativeMethods.HidD_GetManufacturerString(devHandle, buffer, capacity) ? Marshal.PtrToStringAuto(buffer) : ""; product = NativeMethods.HidD_GetProductString(devHandle, buffer, capacity) ? Marshal.PtrToStringAuto(buffer) : ""; phdesc = NativeMethods.HidD_GetPhysicalDescriptor(devHandle, buffer, capacity) ? Marshal.PtrToStringAuto(buffer) : ""; // Free resources. Marshal.FreeHGlobal(buffer); } uint parentDeviceInstance = 0; string parentDeviceId = null; var CRResult = NativeMethods.CM_Get_Parent(out parentDeviceInstance, deviceHandle, 0); if (CRResult == CR.CR_SUCCESS) { parentDeviceId = GetDeviceId(parentDeviceInstance); } var di = new DeviceInfo(deviceId, deviceHandle, parentDeviceId, devicePath, vendor, product, hidGuid, "", DeviceNodeStatus.DN_MANUAL, ha.VendorID, ha.ProductID, ha.VersionNumber); list.Add(di); serials.Add(phdesc); devHandle.Close(); } NativeMethods.SetupDiDestroyDeviceInfoList(deviceInfoSet); deviceInfoSet = IntPtr.Zero; return(list.ToArray()); }