/// <summary> /// Gets the property for SetupDiXXX function /// </summary> /// <param name="deviceHandle">The device handle.</param> /// <param name="deviceInformationData">The device information data.</param> /// <param name="property">The property.</param> /// <returns>String representation of the property</returns> internal static string GetProperty(IntPtr deviceHandle, SP_DEVINFO_DATA deviceInformationData, SetupDiGetDeviceRegistryPropertyEnum property) { bool functionAnswer = false; UInt32 propertyRegDataType = 0; IntPtr propertyBuffer = IntPtr.Zero; uint requireSize = 0; uint propertyMaximumSize = 1024; string actualData = string.Empty; try { propertyBuffer = Marshal.AllocHGlobal((int)propertyMaximumSize); functionAnswer = UnsafeNativeMethods.SetupDiGetDeviceRegistryProperty(deviceHandle, ref deviceInformationData, (uint)property, out propertyRegDataType, propertyBuffer, propertyMaximumSize, out requireSize); if (functionAnswer == false) { if (Marshal.GetLastWin32Error() == UnsafeNativeMethods.ERROR_INVALID_DATA) { Marshal.ThrowExceptionForHR(UnsafeNativeMethods.ERROR_INVALID_DATA); } } // We have the answer actualData = Marshal.PtrToStringAuto(propertyBuffer); return actualData; } catch (Exception exp_gen) { throw new Win32Exception("Could not receive property", exp_gen); } finally { if (propertyBuffer != IntPtr.Zero) Marshal.FreeHGlobal(propertyBuffer); } }
/// <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; }
internal static extern bool SetupDiGetDeviceRegistryProperty(IntPtr DeviceInfoSet, ref SP_DEVINFO_DATA DeviceInfoData, uint Property, out UInt32 PropertyRegDataType, IntPtr PropertyBuffer, uint PropertyBufferSize, out UInt32 RequiredSize);
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);