MaxSandi Ответов: 2

Как я могу закрыть usb-устройство, когда оно уже извлечено


Я подключаюсь к своему USB устройству через функцию
HANDLE hDevice = CreateFile("\\\\.\\dev_name",
  GENERIC_READ | GENERIC_WRITE,
  0,
  NULL,
  OPEN_EXISTING,
  FILE_ATTRIBUTE_NORMAL,
  NULL);
Если мое usb-устройство было неожиданно удалено, и после этого я попытался закрыть Windows crash to BSOD. Что я могу сделать, чтобы ручка закрылась правильно?

Что я уже пробовал:

Я попытался использовать RegisterDeviceNotification для отслеживания события устройства DBT_DEVICEQUERYREMOVE, но это событие, похоже, не срабатывает, если устройство было неожиданно удалено.

11917640 Member

Попробуйте DBT_DEVICEREMOVECOMPLETE.

MaxSandi

DBT_DEVICEREMOVECOMPLETE вызывается после удаления usb-устройства, и если я использовал CloseHandle Windows, то он разбился.

0x01AA

Только идея: например, Process Explorer от Sysinternals показывает вам все дескрипторы, используемые процессом. Поэтому я бы проверил с помощью Process Explorer, исчезает ли ручка, Если usb удален.
Если дескриптор исчезает в Process Explorer, вам "только" нужен способ получить список дескрипторов, используемых программно, и проверить, находится ли ваш дескриптор все еще в списке.
Я понимаю, что это безумная идея ;)

[Редактировать]
Это, возможно, поможет получить список дескрипторов: Список Использованных Файлов[^]

2 Ответов

Рейтинг:
2

KarstenK

Убедитесь, что дескриптор действителен с помощью GetHandleInformation Прочтите его для получения более подробной информации.


Рейтинг:
1

Leo Chapiro

Если USB - устройство было отключено от сети, ваша ручка будет недействительной, ничего не поделаешь!
Я бы поместил CloseHandle в блок try/catch и установил дескриптор в INVALID_HANDLE, если он потерпит неудачу.
Попробуйте что-нибудь вроде этого:

HANDLE hDevice = CreateFile("\\\\.\\dev_name",
    GENERIC_READ | GENERIC_WRITE,
    0,
    NULL,
    OPEN_EXISTING,
    FILE_ATTRIBUTE_NORMAL,
    NULL);

// Do something with it (ReadFile/WriteFile) ...

try
{
  if (hDevice != INVALID_HANDLE_VALUE)
       CloseHandle(hDevice);
}
catch(...)
{
  hDevice = INVALID_HANDLE_VALUE;
}


MaxSandi

Ничего не вышло. В любом случае сбой в BSOD с исключениями NO_MORE_IRP_STACK_LOCATIONS или SYSTEM_SERVICE_EXCEPTION после CloseHandle