为什么在删除多卷USB设备时只有一条WM_DEVICECHANGE消息?

时间:2009-10-22 17:56:13

标签: winapi usb usb-mass-storage

我正在编写一个应用程序,通过监听WM_DEVICECHANGE messages来检测何时插入某个USB大容量存储设备以及何时拔下插头。

我还注册了我的应用程序来监听WM_DEVICECHANGE的{​​{1}}消息(使用RegisterDeviceNotification API调用),我得到DBT_DEVTYP_DEVICEINTERFACE和{{1插入或拔出USB大容量存储设备时的消息。

现在,当插入多个卷的USB设备,然后拔下插头时,会出现问题

插入设备时收到以下消息:

  • DBT_DEVICEARRIVALDBT_DEVICEREMOVECOMPLETE类型WM_DEVICECHANGE
  • DBT_DEVICEARRIVALDBT_DEVTYP_DEVICEINTERFACE类型WM_DEVICECHANGE
  • DBT_DEVICEARRIVALDBT_DEVTYP_VOLUME类型WM_DEVICECHANGE

插入时出现以下消息:

  • DBT_DEVICEARRIVALDBT_DEVTYP_VOLUME类型WM_DEVICECHANGE
  • DBT_DEVICEREMOVECOMPLETEDBT_DEVTYP_VOLUME类型WM_DEVICECHANGE

所以,只有一条删除邮件,即使有两个卷。为什么?

我有两个问题:

  • 如何将DBT_DEVICEREMOVECOMPLETE条消息与DBT_DEVTYP_DEVICEINTERFACE条消息相关联(实际上,我如何知道哪条 VOLUME 消息对应于 DEVICEINTERFACE 消息 - 既然我把它们都拿到设备上了??
  • 有没有办法让Windows通知我两个卷删除?

1 个答案:

答案 0 :(得分:6)

好的,所以我能够回答我自己的一个问题:有没有办法让Windows通知我两个卷删除?

- 即使Windows只发送一条DBT_DEVTYP_VOLUME WM_DEVICECHANGE条消息,您实际上会收到有关卷删除的通知 - 但是,总是,the answer lies deep down buried in MSDN

  

虽然dbcv_unitmask成员可以在任何消息中指定多个卷,但这并不能保证只为指定的事件生成一条消息。多个系统组件可以同时独立生成逻辑卷的消息。

所以,我所要做的就是忽略微软在其中一个样本中提供的example function

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_DEVICEINTERFACEDBT_DEVTYP_VOLUME)如何相关?