マルチボリュームUSBデバイスが削除されたときに、WM_DEVICECHANGEメッセージが1つだけになるのはなぜですか?
-
05-07-2019 - |
質問
DBT_DEVTYP_DEVICEINTERFACE
の WM_DEVICECHANGE
メッセージをリッスンするようにアプリケーションを登録しました( RegisterDeviceNotification API呼び出し)と DBT_DEVICEARRIVAL
と DBT_DEVICEREMOVECOMPLETE の両方を取得しますcode> USB大容量記憶装置がプラグインまたはプラグを抜かれたときのメッセージ。
今、問題は、複数のボリュームを持っているUSBデバイスがプラグインされ、その後プラグが抜かれたときに発生します。
デバイスを接続すると、次のメッセージが表示されます。
-
WM_DEVICECHANGE
(タイプDBT_DEVTYP_DEVICEINTERFACE
のDBT_DEVICEARRIVAL
) -
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
)
したがって、 2つのボリュームがあっても、削除メッセージは1つだけです。なぜですか?
2つの質問があります:
-
DBT_DEVTYP_DEVICEINTERFACE
メッセージをDBT_DEVTYP_VOLUME
メッセージと関連付ける方法(基本的に、どの VOLUME メッセージがどの DEVICEINTERFACEに対応するかを知るにはどうすればよいですか? メッセージ-デバイス用に両方を取得しているため)? - 両方のボリュームが削除されたことをWindowsに通知する方法はありますか?
解決
わかりました、それで私は自分の質問の1つに答えることができました: Windowsに両方のボリュームの削除を通知する方法はありますか
はい-Windowsは DBT_DEVTYP_VOLUME
WM_DEVICECHANGE
メッセージを1つだけ送信しますが、実際には両方のボリュームが削除されたことが通知されます-しかし、いつものように、答えは深いところにありますMSDNに埋もれた:
dbcv_unitmaskメンバーは任意のメッセージで複数のボリュームを指定できますが、指定されたイベントに対して1つのメッセージのみが生成されることを保証するものではありません。複数のシステムコンポーネントが同時に論理ボリュームのメッセージを個別に生成する場合があります。
だから、を無視するだけでした。 Microsoftがサンプルの1つで提供している関数の例、
char FirstDriveFromMask (ULONG unitmask)
{
char i;
for (i = 0; i < 26; ++i)
{
if (unitmask & 0x1)
break;
unitmask = unitmask >> 1;
}
return (i + 'A');
}
そして、影響を受けるすべてのドライブのマスクを解釈する機能に置き換えます。ですから、私が得ていた1つのメッセージは、実際には両方のボリュームに対するものであり、両方のボリュームドライブ文字がマスクで使用可能でした。
// [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
}
まだ答える他の質問があります-2つのメッセージ( DBT_DEVTYP_DEVICEINTERFACE
と DBT_DEVTYP_VOLUME
)をどのように相関させることができますか?