Jinjinov / Usb.Events

Subscribe to the Inserted and Removed events to be notified when a USB drive is plugged in or unplugged, or when a USB device is connected or disconnected. Usb.Events is a .NET Standard 2.0 library and uses WMI on Windows, libudev on Linux and IOKit on macOS.
MIT License
95 stars 23 forks source link

Issue with USB 3.0 drives? #11

Closed cksoft0807 closed 3 years ago

cksoft0807 commented 3 years ago

Describe the bug I have a problem with some USB devices. Normally I get the UsbDriveMounted and UsbDeviceAdded messages within seconds. However, for 2 devices, minutes pass between messages, plus the mounted directory path parameter is then empty.

The problematic devices are USB 3.0 devices, the others are older. The devices otherwise work flawlessly and immediately (Explorer)

Normal: 03.02.2021 12:36:14 UsbDriveMounted on: F: 03.02.2021 12:36:15 UsbDeviceAdded : Device Name: F:\ Device System Path: USB\VID_090C&PID_1000\16092007001318 Mounted Directory Path: F: Product: Product Description: Product ID: 1000 Serial Number: 16092007001318 Vendor: Vendor Description: Vendor ID: 090C

Issue: 03.02.2021 12:36:25 UsbDriveMounted on: F: 03.02.2021 12:37:44 UsbDeviceAdded : Device Name: USB-Massenspeichergerät Device System Path: USB\VID_0781&PID_5591\0501DEDE8246E24347D1649F1F10436EBCAE8C977488E0B66FCFF5118298B533E94800000000000000000000CCFA9DFCFF0C041091558107A4A81936 Mounted Directory Path: Product: USB-Massenspeichergerät Product Description: USB-Massenspeichergerät Product ID: 5591 Serial Number: 0501DEDE8246E24347D1649F1F10436EBCAE8C977488E0B66FCFF5118298B533E94800000000000000000000CCFA9DFCFF0C041091558107A4A81936 Vendor: Kompatibles USB-Speichergerät Vendor Description: Kompatibles USB-Speichergerät Vendor ID: 0781

Jinjinov commented 3 years ago

This will be difficult to fix for two reasons:

Which OS exactly are you using?

Which USB 3.0 mass storage device exactly are you using?

Sind Sie aus Deutschland oder aus Österreich? :)

cksoft0807 commented 3 years ago

Thanks for the quick reply.

I use Windows and the problem occurs with all systems available here. As I found out in the meantime, it does not only affect USD 3.0 devices. I also have a high CPU load while waiting.

I am from Germany :-)

Jinjinov commented 3 years ago

Windows means WMI and WMI can be very problematic. Do you use Windows 7, 8, 10?

This will be very hard to debug for me, because all my USB devices work OK. Can you please list all the USB devices are you using?

In the past I have already changed the WMI code a few times. It would be very helpful if you could try all versions of Usb.Events - perhaps one of the older versions with different WMI code works - then I could at least see where the problem might be.

I visited Berlin in January 2020 :) Great city! :)

cksoft0807 commented 3 years ago

found it...

using ManagementObjectSearcher Win32_DiskDrive = new ManagementObjectSearcher( $"SELECT DeviceID FROM Win32_DiskDrive WHERE PNPDeviceID LIKE '%{serial}%'"); SerialNumber in Win32_DiskDrive holds only the first 20 chars. My USB 3.0 Sticks on error have much longer serials. So GetDevicePath returns every time null and we run all the loops in calling function.

-> Serial: 0501F3E04B26DCBD25FCCD682AEB3CEE13B090D4CC0EEECAA0CEDA20E82E407094C4000000000000000000001C68EEC2FF1B021091558107A4281CC9 Device System Path: USB\VID_0781&PID_5591\0501F3E04B26DCBD25FCCD682AEB3CEE13B090D4CC0EEECAA0CEDA20E82E407094C4000000000000000000001C68EEC2FF1B021091558107A4281CC9

In Win32_DiskDrive we have only: Name: SerialNumber Value: 0501f3e04b26dcbd25fc

I have another faulty stick with a interesting serial 5&1E7D8DB7&0&3. This one appears in Win32_DiskDrive only as null

Jinjinov commented 3 years ago

Do you use Windows 7, 8 or 10? This is really important, because I have personal experience with WMI behaving differently in different Win versions.

Can you please list all the USB devices are you using? Vendor and model? It would really help me a lot, so I can ask my friends if I can borrow something similar, so I can debug and reproduce the problem. I can't find a solution without that.

cksoft0807 commented 3 years ago

Windows 10, SanDisk Ultra Flair USB 3.0 Flash Drive 32 GB, 150MB/s (long Serial). The other is a KiWiBiRD SD Micro SD Adapter for USB 2.0.

Jinjinov commented 3 years ago

Thanks for the info, I will try to borrow something similar! :)

The biggest problem with WMI is that each USB device is registered in several different WMI classes and that these classes don't always share the same unique identifier, so it is difficult to match a device in two different WMI classes, but you have to, because different classes hold different useful information.

In the past I have tried a ManagementEventWatcher for Win32_PnPEntity and Win32_USBHub but now I am using Win32_USBControllerDevice

GetDevicePath is exactly the code that I have changed a few times in the past. Perhaps an older version of the library really would work without problems, because it is using Win32_PnPEntity or Win32_USBHub instead of Win32_USBControllerDevice.

EDIT: After a LOT of searching I found there is exactly ONE answer on stackoverflow that has exactly what we need: "To associate the values returned by the Win32_USBHub or Win32_USBControllerDevice WMI classes with a Disk Drive letter" - of course it is for Delphi: https://stackoverflow.com/questions/9525996/how-can-i-detect-whether-a-garmin-gps-device-is-connected-in-mass-storage-mode Good thing that I learned Delphi in 1995 :)

Jinjinov commented 3 years ago

I think I am getting closer to the solution.

Can you please copy/paste the debug output of the DebugOutput() method when you insert the USB?

There should be two, I need both:

First - DeviceID="USB

AccessState = 
Antecedent = \\URBAN-PC\root\cimv2:Win32_USBController.DeviceID="PCI\\VEN_8086&DEV_1C2D&SUBSYS_1C2D1849&REV_05\\3&11583659&0&D0"
Dependent = \\URBAN-PC\root\cimv2:Win32_PnPEntity.DeviceID="USB\\VID_0951&PID_1625\\0019E06B9C85F9A0F7550C20"
NegotiatedDataWidth = 
NegotiatedSpeed = 
NumberOfHardResets = 
NumberOfSoftResets = 

Second - DeviceID="USBSTOR

AccessState = 
Antecedent = \\URBAN-PC\root\cimv2:Win32_USBController.DeviceID="PCI\\VEN_8086&DEV_1C2D&SUBSYS_1C2D1849&REV_05\\3&11583659&0&D0"
Dependent = \\URBAN-PC\root\cimv2:Win32_PnPEntity.DeviceID="USBSTOR\\DISK&VEN_KINGSTON&PROD_DT_101_II&REV_1.00\\0019E06B9C85F9A0F7550C20&0"
NegotiatedDataWidth = 
NegotiatedSpeed = 
NumberOfHardResets = 
NumberOfSoftResets = 
cksoft0807 commented 3 years ago

AccessState = Antecedent = \DESKTOP-P0MP18K\root\cimv2:Win32_USBController.DeviceID="PCI\VEN_8086&DEV_A2AF&SUBSYS_86941043&REV_00\3&11583659&0&A0" Dependent = \DESKTOP-P0MP18K\root\cimv2:Win32_PnPEntity.DeviceID="USB\VID_0781&PID_5591\0501F3E04B26DCBD25FCCD682AEB3CEE13B090D4CC0EEECAA0CEDA20E82E407094C4000000000000000000001C68EEC2FF1B021091558107A4281CC9" NegotiatedDataWidth = NegotiatedSpeed = NumberOfHardResets = NumberOfSoftResets =

Availability = Caption = USB-Massenspeichergerät ClassGuid = {36fc9e60-c465-11cf-8056-444553540000} CompatibleID = System.String[] ConfigManagerErrorCode = 0 ConfigManagerUserConfig = False CreationClassName = Win32_PnPEntity Description = USB-Massenspeichergerät DeviceID = USB\VID_0781&PID_5591\0501F3E04B26DCBD25FCCD682AEB3CEE13B090D4CC0EEECAA0CEDA20E82E407094C4000000000000000000001C68EEC2FF1B021091558107A4281CC9 ErrorCleared = ErrorDescription = HardwareID = System.String[] InstallDate = LastErrorCode = Manufacturer = Kompatibles USB-Speichergerät Name = USB-Massenspeichergerät PNPClass = USB PNPDeviceID = USB\VID_0781&PID_5591\0501F3E04B26DCBD25FCCD682AEB3CEE13B090D4CC0EEECAA0CEDA20E82E407094C4000000000000000000001C68EEC2FF1B021091558107A4281CC9 PowerManagementCapabilities = PowerManagementSupported = Present = True Service = USBSTOR Status = OK StatusInfo = SystemCreationClassName = Win32_ComputerSystem

AccessState = Antecedent = \DESKTOP-P0MP18K\root\cimv2:Win32_USBController.DeviceID="PCI\VEN_8086&DEV_A2AF&SUBSYS_86941043&REV_00\3&11583659&0&A0" Dependent = \DESKTOP-P0MP18K\root\cimv2:Win32_PnPEntity.DeviceID="USB\VID_1908&PID_0226\5&1E7D8DB7&0&3" NegotiatedDataWidth = NegotiatedSpeed = NumberOfHardResets = NumberOfSoftResets =

Availability = Caption = USB-Massenspeichergerät ClassGuid = {36fc9e60-c465-11cf-8056-444553540000} CompatibleID = System.String[] ConfigManagerErrorCode = 0 ConfigManagerUserConfig = False CreationClassName = Win32_PnPEntity Description = USB-Massenspeichergerät DeviceID = USB\VID_1908&PID_0226\5&1E7D8DB7&0&3 ErrorCleared = ErrorDescription = HardwareID = System.String[] InstallDate = LastErrorCode = Manufacturer = Kompatibles USB-Speichergerät Name = USB-Massenspeichergerät PNPClass = USB PNPDeviceID = USB\VID_1908&PID_0226\5&1E7D8DB7&0&3 PowerManagementCapabilities = PowerManagementSupported = Present = True Service = USBSTOR Status = OK StatusInfo = SystemCreationClassName = Win32_ComputerSystem

Jinjinov commented 3 years ago

I committed some changes. Can you pull and check if it is working?

If it is not working, please copy paste the debug output for only one device: SanDisk Ultra Flair USB 3.0 Flash Drive

These are the important lines:

Dependent = \\URBAN-PC\root\cimv2:Win32_PnPEntity.DeviceID="USB\\VID_0951&PID_1625\\0019E06B9C85F9A0F7550C20"

Dependent = \\URBAN-PC\root\cimv2:Win32_PnPEntity.DeviceID="USBSTOR\\DISK&VEN_KINGSTON&PROD_DT_101_II&REV_1.00\\0019E06B9C85F9A0F7550C20&0"

So, for SanDisk I need one line that has USB\\ in the middle and another line that has USBSTOR\\ in the middle.

cksoft0807 commented 3 years ago

thanks for the effort. Unfortunately, I don't think much has changed in terms of behavior.

best regards, Carsten

AccessState = Antecedent = \DESKTOP-P0MP18K\root\cimv2:Win32_USBController.DeviceID="PCI\VEN_8086&DEV_A2AF&SUBSYS_86941043&REV_00\3&11583659&0&A0" Dependent = \DESKTOP-P0MP18K\root\cimv2:Win32_PnPEntity.DeviceID="USB\VID_0781&PID_5591\0501F3E04B26DCBD25FCCD682AEB3CEE13B090D4CC0EEECAA0CEDA20E82E407094C4000000000000000000001C68EEC2FF1B021091558107A4281CC9" NegotiatedDataWidth = NegotiatedSpeed = NumberOfHardResets = NumberOfSoftResets =

Availability = Caption = USB-Massenspeichergerät ClassGuid = {36fc9e60-c465-11cf-8056-444553540000} CompatibleID = System.String[] ConfigManagerErrorCode = 0 ConfigManagerUserConfig = False CreationClassName = Win32_PnPEntity Description = USB-Massenspeichergerät DeviceID = USB\VID_0781&PID_5591\0501F3E04B26DCBD25FCCD682AEB3CEE13B090D4CC0EEECAA0CEDA20E82E407094C4000000000000000000001C68EEC2FF1B021091558107A4281CC9 ErrorCleared = ErrorDescription = HardwareID = System.String[] InstallDate = LastErrorCode = Manufacturer = Kompatibles USB-Speichergerät Name = USB-Massenspeichergerät PNPClass = USB PNPDeviceID = USB\VID_0781&PID_5591\0501F3E04B26DCBD25FCCD682AEB3CEE13B090D4CC0EEECAA0CEDA20E82E407094C4000000000000000000001C68EEC2FF1B021091558107A4281CC9 PowerManagementCapabilities = PowerManagementSupported = Present = True Service = USBSTOR Status = OK StatusInfo = SystemCreationClassName = Win32_ComputerSystem SystemName = DESKTOP-P0MP18K

"Usb.Events.Test.exe" (CoreCLR: clrhost): "C:\Program Files\dotnet\shared\Microsoft.NETCore.App\3.1.11\System.ComponentModel.dll" geladen. Das Laden von Symbolen wurde übersprungen. Das Modul ist optimiert, und die Debugoption "Nur eigenen Code" ist aktiviert.

AccessState = Antecedent = \DESKTOP-P0MP18K\root\cimv2:Win32_USBController.DeviceID="PCI\VEN_8086&DEV_A2AF&SUBSYS_86941043&REV_00\3&11583659&0&A0" Dependent = \DESKTOP-P0MP18K\root\cimv2:Win32_PnPEntity.DeviceID="USBSTOR\DISK&VENUSB&PRODSANDISK_3.2GEN1&REV_1.00\0501F3E04B26DCBD25FCCD682AEB3CEE13B090D4CC0EEECAA0CEDA20E82E407" NegotiatedDataWidth = NegotiatedSpeed = NumberOfHardResets = NumberOfSoftResets =

Jinjinov commented 3 years ago

Thank you for the USBSTOR\ - now I know what the problem is! :)

USB\ has longer serial:

DeviceID="USB\VID_0781&PID_5591\0501F3E04B26DCBD25FCCD682AEB3CEE13B090D4CC0EEECAA0CEDA20E82E407094C4000000000000000000001C68EEC2FF1B021091558107A4281CC9"

and USBSTOR\ has shorter serial:

DeviceID="USBSTOR\DISK&VENUSB&PRODSANDISK_3.2GEN1&REV_1.00\0501F3E04B26DCBD25FCCD682AEB3CEE13B090D4CC0EEECAA0CEDA20E82E407"

and it is not the same as the serial in Win32_DiskDrive: 0501f3e04b26dcbd25fc

The USBSTOR\ is like a foreign key that connects Win32_USBController and Win32_DiskDrive, but my code is using the serial from USB\ and not from USBSTOR\ because for every device that I have, they are the same.

I hope that now I can fix this! :)

Jinjinov commented 3 years ago

@cksoft0807 It should work now! :) Can you check?

cksoft0807 commented 3 years ago

Hi Jinjinov. Works perfectly now with all my devices. Great work! Thanks and greetings,

Jinjinov commented 3 years ago

I am glad it works! :) Thank you for all your help and valuable feedback!