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 );
static DeviceInfoData[] GetDeviceInfoData( SafeDeviceInfoSetHandle handle ) { List<DeviceInfoData> data = new List<DeviceInfoData>(); DeviceInfoData did = new DeviceInfoData(); int didSize = Marshal.SizeOf( did ); did.Size = didSize; int index = 0; while ( NativeMethods.SetupDiEnumDeviceInfo( handle, index, ref did ) ) { data.Add( did ); index += 1; did = new DeviceInfoData(); did.Size = didSize; } return data.ToArray(); }
/// <summary> /// Find the index of the particular DeviceInfoData for the instanceId. /// </summary> /// <param name="handle"></param> /// <param name="diData"></param> /// <param name="instanceId"></param> /// <returns></returns> static int GetIndexOfInstance( SafeDeviceInfoSetHandle handle, DeviceInfoData[] diData, string instanceId ) { const int ERROR_INSUFFICIENT_BUFFER = 122; for ( int index = 0; index <= diData.Length - 1; index++ ) { StringBuilder sb = new StringBuilder( 1 ); int requiredSize = 0; bool result = NativeMethods.SetupDiGetDeviceInstanceId( handle.DangerousGetHandle(), ref diData[ index ], sb, sb.Capacity, out requiredSize ); if ( result == false && Marshal.GetLastWin32Error() == ERROR_INSUFFICIENT_BUFFER ) { sb.Capacity = requiredSize; result = NativeMethods.SetupDiGetDeviceInstanceId( handle.DangerousGetHandle(), ref diData[ index ], sb, sb.Capacity, out requiredSize ); } if ( result == false ) throw new Win32Exception(); if ( instanceId.Equals( sb.ToString() ) ) { return index; } } // not found return -1; }
// enable/disable... static void EnableDevice( SafeDeviceInfoSetHandle handle, DeviceInfoData diData, bool enable ) { PropertyChangeParameters @params = new PropertyChangeParameters(); // The size is just the size of the header, but we've flattened the structure. // The header comprises the first two fields, both integer. @params.Size = 8; @params.DiFunction = DiFunction.PropertyChange; @params.Scope = Scopes.Global; if ( enable ) { @params.StateChange = StateChangeAction.Enable; } else { @params.StateChange = StateChangeAction.Disable; } bool result = NativeMethods.SetupDiSetClassInstallParams( handle, ref diData, ref @params, Marshal.SizeOf( @params ) ); if ( result == false ) { throw new Win32Exception( Marshal.GetLastWin32Error() ); } result = NativeMethods.SetupDiCallClassInstaller( DiFunction.PropertyChange, handle, ref diData ); if ( result == false ) { int err = Marshal.GetLastWin32Error(); if ( err == (int)SetupApiError.NotDisableable ) { throw new ArgumentException( "Device can't be disabled (programmatically or in Device Manager)." ); } else if ( err <= (int)SetupApiError.NoAssociatedClass && err >= (int)SetupApiError.OnlyValidateViaAuthenticode ) { throw new Win32Exception( "SetupAPI error: " + ( (SetupApiError)err ).ToString() ); } else { throw new Win32Exception( err ); } } }