Почему при удалении многотомного USB-устройства отображается только одно сообщение WM_DEVICECHANGE?

StackOverflow https://stackoverflow.com/questions/1608915

  •  05-07-2019
  •  | 
  •  

Вопрос

Я пишу приложение, которое определяет, когда подключено определенное USB-запоминающее устройство, а когда оно отключено от сети, путем прослушивания Сообщения WM_DEVICECHANGE.

Я также зарегистрировал свое приложение для прослушивания WM_DEVICECHANGE сообщения для DBT_DEVTYP_DEVICEINTERFACE (используя Уведомление о регистрации устройства Вызов API), и я получаю оба DBT_DEVICEARRIVAL и DBT_DEVICEREMOVECOMPLETE сообщения при подключении или отключении USB-накопителя.

Сейчас, проблема возникает, когда USB-устройство, которое имеет несколько томов подключается, а затем вынимается из розетки.

Я получаю следующие сообщения, когда устройство подключено:

  • WM_DEVICECHANGE (DBT_DEVICEARRIVAL типа DBT_DEVTYP_DEVICEINTERFACE)
  • WM_DEVICECHANGE (DBT_DEVICEARRIVAL типа DBT_DEVTYP_VOLUME)
  • WM_DEVICECHANGE (DBT_DEVICEARRIVAL типа DBT_DEVTYP_VOLUME)

И следующие сообщения при его отключении:

  • WM_DEVICECHANGE (DBT_DEVICEREMOVECOMPLETE типа DBT_DEVTYP_VOLUME)
  • WM_DEVICECHANGE (DBT_DEVICEREMOVECOMPLETE типа DBT_DEVTYP_DEVICEINTERFACE)

Итак, только одно сообщение об удалении даже несмотря на то , что есть два тома.Почему??

У меня есть два вопроса:

  • Как я могу соотнести DBT_DEVTYP_DEVICEINTERFACE сообщения с DBT_DEVTYP_VOLUME сообщения (по сути, как мне узнать, какие ОБЪЕМ сообщение, соответствующее которому ИНТЕРФЕЙС УСТРОЙСТВА сообщение - поскольку я получаю их оба для устройства)?
  • Есть ли способ заставить Windows уведомлять меня об удалении обоих томов?
Это было полезно?

Решение

Итак, я смог ответить на один из своих собственных вопросов: Есть ли способ заставить Windows уведомлять меня об удалении обоих томов?

ДА - даже если Windows отправляет только один DBT_DEVTYP_VOLUME WM_DEVICECHANGE Сообщение, вы действительно получаете уведомления об обоих удалениях томов - но, как всегда, ответ лежит глубоко внутри, скрытый в MSDN:

Хотя элемент dbcv_unitmask может указывать более одного тома в любом сообщении, это не гарантирует, что для указанного события будет сгенерировано только одно сообщение.Несколько системных компонентов могут независимо генерировать сообщения для логических томов одновременно.

Итак, все, что мне нужно было сделать, это проигнорировать пример функции это Microsoft приводит в одном из своих примеров,

char FirstDriveFromMask (ULONG unitmask)
{
   char i;

   for (i = 0; i < 26; ++i)
   {
      if (unitmask & 0x1)
         break;
      unitmask = unitmask >> 1;
   }

   return (i + 'A');
}

И замените его функцией, которая интерпретирует маску для ВСЕ затронуты приводы.Таким образом, единственное сообщение, которое я получал, действительно было для обоих томов, и в маске были доступны буквы дисков обоих томов.

// [IN] ULONG unitmask
// [IN/OUT] char* outDriveLetters  - an array of characters to be passed in
//                                   that is filled out with the drive letters
//                                   in the mask (this must be 26 bytes to be safe)
// RETURNS the number of drive letters in the mask
int MaskToDriveLetters (ULONG unitmask, char* outDriveLetters)
{
   int cnt = 0;
   for (i = 0; i < 26; ++i)
   {
      if (unitmask & 0x1)
      {
         outDriveLetters[cnt++] = 'A' + i;
         cnt++;
      }
      unitmask = unitmask >> 1;
   }

   outDriveLetters[cnt] = 0; // set the last character to \0 (optional)
   return cnt;  // the number of drives that were set in the mask
}

Однако мне все еще нужно ответить на другой вопрос - как эти два сообщения могут (DBT_DEVTYP_DEVICEINTERFACE и DBT_DEVTYP_VOLUME) быть коррелированным?

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top