OC - ​​Windows 10 x64

How can you programmatically disable / block the USB port (so that the device is inactive at this time)?

At first I thought about ruSO off a specific device, tried several options with enSO and translated into ruSO , but it was all about the fact that it was impossible to disconnect some devices.

enter image description here

I thought that you can then simply disconnect the USB ports.

On enSO found about disabling all ports at once and that this method will work only after a reboot.

Is it possible to turn off the power / block a specific USB port without rebooting? Or disable non-disconnect devices?

  • one
    From the screen, of course, it is clear what OS we are talking about, but still it was worth adding information about it clearly to the question / tags) - Kir_Antipov
  • @Kir_Antipov ATP added. - Vipz 5:41 pm
  • When playing with USB in C #, I remember all the manipulations with USB ports were carried out via SetupAPI: by GUID (like {36FC9E60-C465-11CF-8056-444553540000}) we get ( SetupDiGetClassDevs ) the "root" of USB-devices, look for ( SetupDiEnumDeviceInfo , SetupDiGetDeviceRegistryProperty , SetupDiGetDeviceRegistryProperty , SetupDiGetDeviceRegistryProperty , SetupDiGetDeviceRegistryProperty , SetupDiGetDeviceRegistryProperty , SetupDiGetDeviceRegistryProperty , SetupDiGetDeviceRegistryProperty , SetupDiGetDeviceRegistryProperty , SetupDiGetDeviceRegistryProperty , SetupDiGetDeviceRegistryProperty , SetupDiGetDeviceRegistryProperty , SetupDiGetDeviceRegistryProperty , SetupDiGetDeviceRegistryProperty , SetupDiGetDeviceRegistryProperty , SetupDiGetDeviceRegistryProperty , SetupDiGetDeviceRegistryProperty , SetupDiGetDeviceRegistryProperty ) necessary, we will know its state ( CM_Get_DevNode_Status ) and the helmet CM_Request_Device_Eject . In general, play with SetupAPI first. - greg zakharov
  • I don't know C #, but I had to turn off the keyboard while the program was running. I did it on python via devcon.exe . - Rezvanov Maxim
  • @Vipz, why don't you use PowerShell? - isnullxbh

2 answers 2

Found a class on the internet:

 using System; using System.Text; using System.Collections.Generic; using DisableDevice; using System.Runtime.InteropServices; using System.ComponentModel; using Microsoft.Win32.SafeHandles; using System.Security; using System.Runtime.ConstrainedExecution; using System.Management; namespace DisableDevice { [Flags()] internal enum SetupDiGetClassDevsFlags { Default = 1, Present = 2, AllClasses = 4, Profile = 8, DeviceInterface = (int)0x10 } internal enum DiFunction { SelectDevice = 1, InstallDevice = 2, AssignResources = 3, Properties = 4, Remove = 5, FirstTimeSetup = 6, FoundDevice = 7, SelectClassDrivers = 8, ValidateClassDrivers = 9, InstallClassDrivers = (int)0xa, CalcDiskSpace = (int)0xb, DestroyPrivateData = (int)0xc, ValidateDriver = (int)0xd, Detect = (int)0xf, InstallWizard = (int)0x10, DestroyWizardData = (int)0x11, PropertyChange = (int)0x12, EnableClass = (int)0x13, DetectVerify = (int)0x14, InstallDeviceFiles = (int)0x15, UnRemove = (int)0x16, SelectBestCompatDrv = (int)0x17, AllowInstall = (int)0x18, RegisterDevice = (int)0x19, NewDeviceWizardPreSelect = (int)0x1a, NewDeviceWizardSelect = (int)0x1b, NewDeviceWizardPreAnalyze = (int)0x1c, NewDeviceWizardPostAnalyze = (int)0x1d, NewDeviceWizardFinishInstall = (int)0x1e, Unused1 = (int)0x1f, InstallInterfaces = (int)0x20, DetectCancel = (int)0x21, RegisterCoInstallers = (int)0x22, AddPropertyPageAdvanced = (int)0x23, AddPropertyPageBasic = (int)0x24, Reserved1 = (int)0x25, Troubleshooter = (int)0x26, PowerMessageWake = (int)0x27, AddRemotePropertyPageAdvanced = (int)0x28, UpdateDriverUI = (int)0x29, Reserved2 = (int)0x30 } internal enum StateChangeAction { Enable = 1, Disable = 2, PropChange = 3, Start = 4, Stop = 5 } [Flags()] internal enum Scopes { Global = 1, ConfigSpecific = 2, ConfigGeneral = 4 } internal enum SetupApiError { NoAssociatedClass = unchecked((int)0xe0000200), ClassMismatch = unchecked((int)0xe0000201), DuplicateFound = unchecked((int)0xe0000202), NoDriverSelected = unchecked((int)0xe0000203), KeyDoesNotExist = unchecked((int)0xe0000204), InvalidDevinstName = unchecked((int)0xe0000205), InvalidClass = unchecked((int)0xe0000206), DevinstAlreadyExists = unchecked((int)0xe0000207), DevinfoNotRegistered = unchecked((int)0xe0000208), InvalidRegProperty = unchecked((int)0xe0000209), NoInf = unchecked((int)0xe000020a), NoSuchHDevinst = unchecked((int)0xe000020b), CantLoadClassIcon = unchecked((int)0xe000020c), InvalidClassInstaller = unchecked((int)0xe000020d), DiDoDefault = unchecked((int)0xe000020e), DiNoFileCopy = unchecked((int)0xe000020f), InvalidHwProfile = unchecked((int)0xe0000210), NoDeviceSelected = unchecked((int)0xe0000211), DevinfolistLocked = unchecked((int)0xe0000212), DevinfodataLocked = unchecked((int)0xe0000213), DiBadPath = unchecked((int)0xe0000214), NoClassInstallParams = unchecked((int)0xe0000215), FileQueueLocked = unchecked((int)0xe0000216), BadServiceInstallSect = unchecked((int)0xe0000217), NoClassDriverList = unchecked((int)0xe0000218), NoAssociatedService = unchecked((int)0xe0000219), NoDefaultDeviceInterface = unchecked((int)0xe000021a), DeviceInterfaceActive = unchecked((int)0xe000021b), DeviceInterfaceRemoved = unchecked((int)0xe000021c), BadInterfaceInstallSect = unchecked((int)0xe000021d), NoSuchInterfaceClass = unchecked((int)0xe000021e), InvalidReferenceString = unchecked((int)0xe000021f), InvalidMachineName = unchecked((int)0xe0000220), RemoteCommFailure = unchecked((int)0xe0000221), MachineUnavailable = unchecked((int)0xe0000222), NoConfigMgrServices = unchecked((int)0xe0000223), InvalidPropPageProvider = unchecked((int)0xe0000224), NoSuchDeviceInterface = unchecked((int)0xe0000225), DiPostProcessingRequired = unchecked((int)0xe0000226), InvalidCOInstaller = unchecked((int)0xe0000227), NoCompatDrivers = unchecked((int)0xe0000228), NoDeviceIcon = unchecked((int)0xe0000229), InvalidInfLogConfig = unchecked((int)0xe000022a), DiDontInstall = unchecked((int)0xe000022b), InvalidFilterDriver = unchecked((int)0xe000022c), NonWindowsNTDriver = unchecked((int)0xe000022d), NonWindowsDriver = unchecked((int)0xe000022e), NoCatalogForOemInf = unchecked((int)0xe000022f), DevInstallQueueNonNative = unchecked((int)0xe0000230), NotDisableable = unchecked((int)0xe0000231), CantRemoveDevinst = unchecked((int)0xe0000232), InvalidTarget = unchecked((int)0xe0000233), DriverNonNative = unchecked((int)0xe0000234), InWow64 = unchecked((int)0xe0000235), SetSystemRestorePoint = unchecked((int)0xe0000236), IncorrectlyCopiedInf = unchecked((int)0xe0000237), SceDisabled = unchecked((int)0xe0000238), UnknownException = unchecked((int)0xe0000239), PnpRegistryError = unchecked((int)0xe000023a), RemoteRequestUnsupported = unchecked((int)0xe000023b), NotAnInstalledOemInf = unchecked((int)0xe000023c), InfInUseByDevices = unchecked((int)0xe000023d), DiFunctionObsolete = unchecked((int)0xe000023e), NoAuthenticodeCatalog = unchecked((int)0xe000023f), AuthenticodeDisallowed = unchecked((int)0xe0000240), AuthenticodeTrustedPublisher = unchecked((int)0xe0000241), AuthenticodeTrustNotEstablished = unchecked((int)0xe0000242), AuthenticodePublisherNotTrusted = unchecked((int)0xe0000243), SignatureOSAttributeMismatch = unchecked((int)0xe0000244), OnlyValidateViaAuthenticode = unchecked((int)0xe0000245) } [StructLayout(LayoutKind.Sequential)] internal struct DeviceInfoData { public int Size; public Guid ClassGuid; public int DevInst; public IntPtr Reserved; } [StructLayout(LayoutKind.Sequential)] internal struct PropertyChangeParameters { public int Size; // part of header. It's flattened out into 1 structure. public DiFunction DiFunction; public StateChangeAction StateChange; public Scopes Scope; public int HwProfile; } internal class NativeMethods { private const string setupapi = "setupapi.dll"; private NativeMethods() { } [DllImport(setupapi, CallingConvention = CallingConvention.Winapi, SetLastError = true)] [return: MarshalAs(UnmanagedType.Bool)] public static extern bool SetupDiCallClassInstaller(DiFunction installFunction, SafeDeviceInfoSetHandle deviceInfoSet, [In()] ref DeviceInfoData deviceInfoData); [DllImport(setupapi, CallingConvention = CallingConvention.Winapi, SetLastError = true)] [return: MarshalAs(UnmanagedType.Bool)] public static extern bool SetupDiEnumDeviceInfo(SafeDeviceInfoSetHandle deviceInfoSet, int memberIndex, ref DeviceInfoData deviceInfoData); [DllImport(setupapi, CallingConvention = CallingConvention.Winapi, CharSet = CharSet.Unicode, SetLastError = true)] public static extern SafeDeviceInfoSetHandle SetupDiGetClassDevs([In()] ref Guid classGuid, [MarshalAs(UnmanagedType.LPWStr)] string enumerator, IntPtr hwndParent, SetupDiGetClassDevsFlags flags); /* [DllImport(setupapi, CallingConvention = CallingConvention.Winapi, CharSet = CharSet.Unicode, SetLastError = true)] [return: MarshalAs(UnmanagedType.Bool)] public static extern bool SetupDiGetDeviceInstanceId(SafeDeviceInfoSetHandle deviceInfoSet, [In()] ref DeviceInfoData did, [MarshalAs(UnmanagedType.LPTStr)] StringBuilder deviceInstanceId, int deviceInstanceIdSize, [Out()] ref int requiredSize); */ [DllImport("setupapi.dll", SetLastError = true, CharSet = CharSet.Auto)] [return: MarshalAs(UnmanagedType.Bool)] public static extern bool SetupDiGetDeviceInstanceId( IntPtr DeviceInfoSet, ref DeviceInfoData did, [MarshalAs(UnmanagedType.LPTStr)] StringBuilder DeviceInstanceId, int DeviceInstanceIdSize, out int RequiredSize ); [SuppressUnmanagedCodeSecurity()] [ReliabilityContract(Consistency.WillNotCorruptState, Cer.Success)] [DllImport(setupapi, CallingConvention = CallingConvention.Winapi, SetLastError = true)] [return: MarshalAs(UnmanagedType.Bool)] public static extern bool SetupDiDestroyDeviceInfoList(IntPtr deviceInfoSet); [DllImport(setupapi, CallingConvention = CallingConvention.Winapi, SetLastError = true)] [return: MarshalAs(UnmanagedType.Bool)] public static extern bool SetupDiSetClassInstallParams(SafeDeviceInfoSetHandle deviceInfoSet, [In()] ref DeviceInfoData deviceInfoData, [In()] ref PropertyChangeParameters classInstallParams, int classInstallParamsSize); } internal class SafeDeviceInfoSetHandle : SafeHandleZeroOrMinusOneIsInvalid { public SafeDeviceInfoSetHandle() : base(true) { } protected override bool ReleaseHandle() { return NativeMethods.SetupDiDestroyDeviceInfoList(this.handle); } } public sealed class DeviceHelper { private DeviceHelper() { } /// <summary> /// Enable or disable a device. /// </summary> /// <param name="classGuid">The class guid of the device. Available in the device manager.</param> /// <param name="instanceId">The device instance id of the device. Available in the device manager.</param> /// <param name="enable">True to enable, False to disable.</param> /// <remarks>Will throw an exception if the device is not Disableable.</remarks> public static void SetDeviceEnabled(Guid classGuid, string instanceId, bool enable) { SafeDeviceInfoSetHandle diSetHandle = null; try { // Get the handle to a device information set for all devices matching classGuid that are present on the // system. diSetHandle = NativeMethods.SetupDiGetClassDevs(ref classGuid, null, IntPtr.Zero, SetupDiGetClassDevsFlags.Present); // Get the device information data for each matching device. DeviceInfoData[] diData = GetDeviceInfoData(diSetHandle); // Find the index of our instance. ie the touchpad mouse - I have 3 mice attached... int index = GetIndexOfInstance(diSetHandle, diData, instanceId); // Disable... EnableDevice(diSetHandle, diData[index], enable); } finally { if (diSetHandle != null) { if (diSetHandle.IsClosed == false) { diSetHandle.Close(); } diSetHandle.Dispose(); } } } private 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(); } // Find the index of the particular DeviceInfoData for the instanceId. private 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... private 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(); 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(); } } } } 

If you have a GUID and instancePath (that is, the path in the device manager), then the device can be disabled as follows:

 Guid deviceGuid = new Guid("{4D36E96F-E325-11CE-BFC1-08002BE10318}");//думаю это можно захардкодить string instancePath = @"HID\VID_062A&PID_4101&MI_01&COL01\8&14EA75C&0&0000";//это захардкодить вряд ли выйдет, нужно будет поискать в девайс менеджере через шарп нужный путь DeviceHelper.SetDeviceEnabled(deviceGuid, instancePath, false); //фалс отключает девайс / тру - включает 

It is with this code and specifically with these values ​​that I have turned off the mouse for the test myself :)

But this way it is also questionable whether to turn off a particular device. Not all devices support this.

I found the original code here: https://stackoverflow.com/questions/1438371/win32-api-function-to-programmatically-enable-disable-device

Also, judging by the text, you need to compile your prog in x64 (in that platform - in which you have an operating system).

Finding the GUID of the device is pretty simple: the device manager -> looking for the device you need -> permissions -> Events -> in the information block will be the "Class Guid".

With the search for the software path of a particular device, figure it out yourself. The question was about turning off the device :)


Is it possible to turn off the power

Suddenly (for me personally) , but it is possible .

https://stackoverflow.com/questions/14690157/turn-off-power-to-usb-port-programmatically

As can be seen from the second answer, the prog DevManView.exe can disable in runtime. So this is POSSIBLE (I personally thought that it was blocked at the hardware level) . But I will not tell you how to do this directly from Sharp. :) Only if you use the console capabilities of this program - again, according to the link described as.

to block a specific USB port without rebooting?

I do not understand what "blocking" is. If you’re talking about simply disabling your device as a device manager, then the implementation is higher. No reboot.

If you are talking about "blocking the manual switching on of the device" - you can simply arrange to spy on whether this device was turned on without your permission in a separate thread and automatically disconnect. Crooked, but will work as you need.

Or disable non-disconnect devices?

Probably they are disconnected for that, so that they are not disconnected. Hardly.

Only if the food is rubonut.

UPD: as outlined by MSDN.WhiteKnight in comments, it is quite possible that non-disconnected devices are "composite". That is, if you disable several children, then this non-switchable will be disabled.

  • 2
    According to my observations, "non-disconnected" devices are usually composite devices (for example, I see the keyboard as a composite device containing 2 HID devices). You can simply turn off all components, and there will be the same effect. - MSDN.WhiteKnight
  • Hmm, did not pay attention to this. It is possible that you are right. :) Thanks for the clarification :) - Andrew

I came to two options:

Option number 1: USB ports can be disconnected via regedit

 public void EnableUSB() => Regedit(3); public void DisableUSB() => Regedit(4); // key - это параметр включения или отключения // 4 - отключенно // 3 - включенно public static void Regedit(Int16 key) { const String keyname = @"HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\USBSTOR"; Microsoft.Win32.Registry.SetValue(keyname, "Start", key); } 

Option number 2: using the utility DevManView.exe (freeware) :

Go to the Device Manager and find out the name of the device on which the power will be chopped off or you can get the device name programmatically.

 public void EnableDevice(String nameDevice) => DevManView(nameDevice, "enable"); public void DisableDevice(String nameDevice) => DevManView(nameDevice, "disable"); public static void DevManView(String nameDevice, String command) { Process devManViewProc = new Process(); devManViewProc.StartInfo.FileName = @"<path to DevManView.exe>\DevManView.exe"; devManViewProc.StartInfo.Arguments = $"/{command} \"{nameDevice}\""; devManViewProc.Start(); devManViewProc.WaitForExit(); } 
  • And why in the first version DisableUsb accepts a string if it is simply ignored? - Kir_Antipov
  • Similarly, about the command in the second version - Kir_Antipov
  • And what does this DevManView use? What is its advantage over, say, the standard console utility DevCon? - MSDN.WhiteKnight
  • 1. Poorly read the question, the first option operates through the register. So it requires a reboot. And it is necessary for it in, about what he in a question wrote. 2. And the second answer is in my answer (albeit with a link) :) So I did not read my answer. - Andrew
  • one
    @Yaroslav on this link can be downloaded for dozens and for other versions of Windows: superuser.com/questions/1002950/… - Andrew