public static extern bool SetupDiGetDeviceInstanceId( IntPtr DeviceInfoSet, ref DeviceInfoData did, [MarshalAs(UnmanagedType.LPTStr)] StringBuilder DeviceInstanceId, int DeviceInstanceIdSize, out int RequiredSize );
public static extern bool SetupDiEnumDeviceInfo(SafeDeviceInfoSetHandle deviceInfoSet, int memberIndex, ref DeviceInfoData deviceInfoData);
private static bool GetInstanceMatch(SafeHandle handle, DeviceInfoData diData, string instanceId) { int requiredSize; StringBuilder sb = new StringBuilder(1); bool result = NativeMethods.SetupDiGetDeviceInstanceId(handle.DangerousGetHandle(), ref diData, sb, sb.Capacity, out requiredSize); if (!result && Marshal.GetLastWin32Error() == ERROR_INSUFFICIENT_BUFFER) { sb.Capacity = requiredSize; result = NativeMethods.SetupDiGetDeviceInstanceId(handle.DangerousGetHandle(), ref diData, sb, sb.Capacity, out requiredSize); } if (!result) { throw new Win32Exception(); } // Using .Contains since it's more lenient return sb.ToString().Contains(instanceId); }
// Find the index of the particular DeviceInfoData for the instanceId. private static int GetIndexOfInstance(SafeDeviceInfoSetHandle handle, DeviceInfoData[] diData, string instanceId) { for (int index = 0; index < diData.Length; index++) { if (GetInstanceMatch(handle, diData[index], instanceId)) return index; } // not found return -1; }
private static DeviceInfoData[] GetDeviceInfoData(SafeDeviceInfoSetHandle handle) { List<DeviceInfoData> data = new List<DeviceInfoData>(); DeviceInfoData did = new DeviceInfoData(); int index = 0; int didSize = Marshal.SizeOf(did); did.Size = didSize; while (NativeMethods.SetupDiEnumDeviceInfo(handle, index, ref did)) { data.Add(did); index += 1; did = new DeviceInfoData { Size = didSize }; } return data.ToArray(); }
// enable/disable... private static void EnableDevice(SafeDeviceInfoSetHandle handle, DeviceInfoData diData, bool enable) { PropertyChangeParameters parameters = new PropertyChangeParameters { Size = 8, DiFunction = DiFunction.PropertyChange, Scope = Scopes.Global, StateChange = enable ? StateChangeAction.Enable : StateChangeAction.Disable }; // The size is just the size of the header, but we've flattened the structure. // The header comprises the first two fields, both integer. bool result = NativeMethods.SetupDiSetClassInstallParams(handle, ref diData, ref parameters, Marshal.SizeOf(parameters)); if (result == false) throw new Win32Exception(); result = NativeMethods.SetupDiCallClassInstaller(DiFunction.PropertyChange, handle, ref diData); if (result) { return; } int err = Marshal.GetLastWin32Error(); if (err == (int)SetupApiError.NotDisableable) throw new ArgumentException("Device can't be disabled (programmatically or in Device Manager)."); if (err >= (int)SetupApiError.NoAssociatedClass && err <= (int)SetupApiError.OnlyValidateViaAuthenticode) throw new Win32Exception("SetupAPI error: " + ((SetupApiError)err)); throw new Win32Exception(); }