マルチボリュームUSBデバイスが削除されたときに、WM_DEVICECHANGEメッセージが1つだけになるのはなぜですか?

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

  •  05-07-2019
  •  | 
  •  

質問

WM_DEVICECHANGEメッセージ

DBT_DEVTYP_DEVICEINTERFACE WM_DEVICECHANGE メッセージをリッスンするようにアプリケーションを登録しました( RegisterDeviceNotification API呼び出し)と DBT_DEVICEARRIVAL DBT_DEVICEREMOVECOMPLETE 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 )をどのように相関させることができますか?

ライセンス: CC-BY-SA帰属
所属していません StackOverflow
scroll top