public static unsafe void EnumerateDevices <TContext> ( string machine, DiGetClassFlags flags, string[] deviceClassNames, EnumerateDevicesFunc <TContext> callback, TContext context ) where TContext : class { DeviceInfoListHandle devs = null; var devInfo = new SP_DEVINFO_DATA(); var devInfoListDetail = new SP_DEVINFO_LIST_DETAIL_DATA(); Guid[] deviceClassGuids; try { int numClasses = 0; if (deviceClassNames != null) { deviceClassGuids = new Guid[deviceClassNames.Length]; foreach (var className in deviceClassNames) { UInt32 numResults; if ( !SetupDiClassGuidsFromNameEx( className, out deviceClassGuids[numClasses], 1, out numResults, machine, IntPtr.Zero ) && (Marshal.GetLastWin32Error() != ERROR_INSUFFICIENT_BUFFER) ) { throw new Exception("Unable to resolve class name '" + className + "'"); } numClasses += 1; } var newClassGuids = new Guid[numClasses]; Array.Copy(deviceClassGuids, newClassGuids, numClasses); deviceClassGuids = newClassGuids; } else { deviceClassGuids = new Guid[0]; } if (deviceClassGuids.Length > 0) { for (int i = 0; i < deviceClassGuids.Length; i++) { fixed(Guid *pGuid = &(deviceClassGuids[i])) { var existingPtr = IntPtr.Zero; if (devs != null) { existingPtr = devs.DangerousGetHandle(); } var result = SetupDiGetClassDevsEx( new IntPtr(pGuid), null, IntPtr.Zero, flags, existingPtr, machine, IntPtr.Zero ); var lastError = Marshal.GetLastWin32Error(); if (lastError != 0) { throw new Win32Exception(lastError); } if (devs == null) { devs = new DeviceInfoListHandle(result, true); } } } } else { devs = new DeviceInfoListHandle( SetupDiGetClassDevsEx( IntPtr.Zero, null, IntPtr.Zero, flags | DiGetClassFlags.DIGCF_ALLCLASSES, IntPtr.Zero, machine, IntPtr.Zero ), true ); var lastError = Marshal.GetLastWin32Error(); if (lastError != 0) { throw new Win32Exception(lastError); } } if (devs.IsInvalid) { throw new Exception("Failed to create device info list"); } devInfoListDetail.cbSize = (UInt32)Marshal.SizeOf(devInfoListDetail.GetType()); if (!SetupDiGetDeviceInfoListDetail(devs.DangerousGetHandle(), ref devInfoListDetail)) { var lastError = Marshal.GetLastWin32Error(); if (lastError != 0) { throw new Win32Exception(lastError); } return; } devInfo.cbSize = (UInt32)Marshal.SizeOf(devInfo.GetType()); for (UInt32 devIndex = 0; SetupDiEnumDeviceInfo(devs.DangerousGetHandle(), devIndex, ref devInfo); devIndex++) { callback(devs, ref devInfo, GetDeviceId(ref devInfo), context); } { var lastError = Marshal.GetLastWin32Error(); if ((lastError != 0) && (lastError != ERROR_NO_MORE_ITEMS)) { throw new Win32Exception(lastError); } } } finally { if (devs != null && !devs.IsClosed) { devs.Close(); } } }
public static extern bool SetupDiGetDeviceInfoListDetail(IntPtr DeviceInfoSet, ref SP_DEVINFO_LIST_DETAIL_DATA DeviceInfoSetDetailData);
public static extern bool SetupDiGetDeviceInfoListDetail( IntPtr deviceInfoSet, ref SP_DEVINFO_LIST_DETAIL_DATA output );