/// <summary> /// Gets the list of devices. /// </summary> /// <param name="token">The cancellation token.</param> /// <returns>List of detected devices</returns> /// <exception cref="System.ComponentModel.Win32Exception"> /// Could not execute SetupDi functions /// </exception> protected IEnumerable<SystemDevice> GetListOfDevices(CancellationToken token) { List<SystemDevice> listOfDevices = new List<SystemDevice>(); int flags = (int) (SetupDiGetClassDevsFlags.DIGCF_ALLCLASSES |SetupDiGetClassDevsFlags.DIGCF_DEVICEINTERFACE| SetupDiGetClassDevsFlags.DIGCF_PRESENT); Guid aquireGuid = Guid.Empty; IntPtr deviceHandle = UnsafeNativeMethods.SetupDiGetClassDevs(ref aquireGuid, IntPtr.Zero, IntPtr.Zero, flags); int win32Error = Marshal.GetLastWin32Error(); if (deviceHandle.ToInt32() == UnsafeNativeMethods.INVALID_HANDLE_VALUE) { throw new Win32Exception("Could not execute SetupDi functions", new Win32Exception(win32Error)); } SP_DEVICE_INTERFACE_DATA spDeviceInterfaceData = new SP_DEVICE_INTERFACE_DATA(); spDeviceInterfaceData.cbSize = Marshal.SizeOf(typeof(SP_DEVICE_INTERFACE_DATA)); Guid classGuid = SetupDiInterfacesGuid.GUID_DEVINTERFACE_DISK; uint memberIndex = 0; bool functionResult = false; do { token.ThrowIfCancellationRequested(); functionResult = UnsafeNativeMethods.SetupDiEnumDeviceInterfaces(deviceHandle, IntPtr.Zero, ref classGuid, memberIndex, ref spDeviceInterfaceData); if (functionResult == false) { int nativeError = Marshal.GetLastWin32Error(); UnsafeNativeMethods.SetupDiDestroyDeviceInfoList(deviceHandle); if (nativeError == UnsafeNativeMethods.ERROR_NO_MORE_ITEMS) { // all done break; } else { // Other error occurred throw new Win32Exception("Error occurred while enumerating devices", new Win32Exception(Marshal.GetLastWin32Error())); } } SP_DEVINFO_DATA spDevInfoData = new SP_DEVINFO_DATA(); spDevInfoData.cbSize = Marshal.SizeOf(typeof(SP_DEVINFO_DATA)); spDevInfoData.DevInst = 0; spDevInfoData.Reserved = IntPtr.Zero; SP_DEVICE_INTERFACE_DETAIL_DATA spDeviceInterfaceDetailedData = new SP_DEVICE_INTERFACE_DETAIL_DATA(); if (IntPtr.Size == 8) { // for 64 bit operating systems spDeviceInterfaceDetailedData.cbSize = 8; } else { // for 32 bit systems spDeviceInterfaceDetailedData.cbSize = 4 + Marshal.SystemDefaultCharSize; } uint nRequiredSize = 0; uint bufferSize = 200; bool success = false; // // Should send twice - first time it's only return the 'nRequiredSize' value (but we already calculated it) success = UnsafeNativeMethods.SetupDiGetDeviceInterfaceDetail(deviceHandle, ref spDeviceInterfaceData, ref spDeviceInterfaceDetailedData, bufferSize, out nRequiredSize, ref spDevInfoData); success = UnsafeNativeMethods.SetupDiGetDeviceInterfaceDetail(deviceHandle, ref spDeviceInterfaceData, ref spDeviceInterfaceDetailedData, nRequiredSize, out nRequiredSize, ref spDevInfoData); if (success == false) { // // Still 'false' after sending twice // UnsafeNativeMethods.SetupDiDestroyDeviceInfoList(deviceHandle); // throw new Win32Exception("Could not receive details about device", new Win32Exception(Marshal.GetLastWin32Error())); } // Device listOfDevices.Add(new SystemDevice(spDeviceInterfaceDetailedData.DevicePath) { FriendlyName = SetupDiGetDeviceProperty.GetProperty(deviceHandle, spDevInfoData, SetupDiGetDeviceRegistryPropertyEnum.SPDRP_FRIENDLYNAME), DeviceClass = SetupDiGetDeviceProperty.GetProperty(deviceHandle, spDevInfoData, SetupDiGetDeviceRegistryPropertyEnum.SPDRP_CLASS) }); // Next device memberIndex++; } while (true); deviceHandle = IntPtr.Zero; return listOfDevices; }
public static extern Boolean SetupDiGetDeviceInterfaceDetail(IntPtr hDevInfo, ref SP_DEVICE_INTERFACE_DATA deviceInterfaceData, ref SP_DEVICE_INTERFACE_DETAIL_DATA deviceInterfaceDetailData, UInt32 deviceInterfaceDetailDataSize, out UInt32 requiredSize, ref SP_DEVINFO_DATA deviceInfoData);