我正在编写一个应用程序,通过监听WM_DEVICECHANGE messages来检测何时插入某个USB大容量存储设备以及何时拔下插头。
我还注册了我的应用程序来监听WM_DEVICECHANGE
的{{1}}消息(使用RegisterDeviceNotification API调用),我得到DBT_DEVTYP_DEVICEINTERFACE
和{{1插入或拔出USB大容量存储设备时的消息。
现在,当插入多个卷的USB设备,然后拔下插头时,会出现问题。
插入设备时收到以下消息:
DBT_DEVICEARRIVAL
(DBT_DEVICEREMOVECOMPLETE
类型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
条消息相关联(实际上,我如何知道哪条 VOLUME 消息对应于 DEVICEINTERFACE 消息 - 既然我把它们都拿到设备上了??答案 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_DEVICEINTERFACE
和DBT_DEVTYP_VOLUME
)如何相关?