3

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

我还注册了我的应用程序来监听WM_DEVICECHANGE消息DBT_DEVTYP_DEVICEINTERFACE(使用RegisterDeviceNotification API 调用),当插入或拔出 USB 大容量存储设备时,我会同时收到DBT_DEVICEARRIVAL和消息。DBT_DEVICEREMOVECOMPLETE

现在,当插入具有多个卷的 USB 设备,然后再拔下时,就会出现问题。

插入设备后,我收到以下消息:

  • WM_DEVICECHANGEDBT_DEVICEARRIVAL类型DBT_DEVTYP_DEVICEINTERFACE
  • WM_DEVICECHANGEDBT_DEVICEARRIVAL类型DBT_DEVTYP_VOLUME
  • WM_DEVICECHANGEDBT_DEVICEARRIVAL类型DBT_DEVTYP_VOLUME

以及拔出时的以下消息:

  • WM_DEVICECHANGEDBT_DEVICEREMOVECOMPLETE类型DBT_DEVTYP_VOLUME
  • WM_DEVICECHANGEDBT_DEVICEREMOVECOMPLETE类型DBT_DEVTYP_DEVICEINTERFACE

因此,即使有两卷,也只有一条删除消息。为什么??

我有两个问题:

  • 如何将DBT_DEVTYP_DEVICEINTERFACE消息与DBT_DEVTYP_VOLUME消息相关联(本质上,我如何知道哪个VOLUME消息对应于哪个DEVICEINTERFACE消息 - 因为我为设备获取了它们)?
  • 有没有办法让 Windows 通知我两个卷删除?
4

1 回答 1

6

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

的- 尽管 Windows 只发送一条DBT_DEVTYP_VOLUME WM_DEVICECHANGE消息,但实际上您确实会收到有关两个卷删除的通知- 但是,与往常一样,答案深埋在 MSDN 中

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

所以,我所要做的就是忽略微软在他们的一个示例中提供的示例函数

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

于 2009-10-22T21:10:49.060 回答