3

WM_DEVICECHANGE メッセージをリッスンして、特定の USB 大容量記憶装置が接続されているときと接続されていないときを検出するアプリケーションを作成しています。

また、( RegisterDeviceNotification API 呼び出しを使用して)WM_DEVICECHANGEメッセージをリッスンするようにアプリケーションを登録しました。USB 大容量記憶装置デバイスが接続または切断されたときに、とメッセージの両方を受け取ります。DBT_DEVTYP_DEVICEINTERFACEDBT_DEVICEARRIVALDBT_DEVICEREMOVECOMPLETE

この問題は、複数のボリュームを持つUSB デバイスを接続してから取り外すと発生します。

デバイスが接続されると、次のメッセージが表示されます。

  • 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)

そのため、ボリュームが 2 つあるにもかかわらず、削除メッセージは 1 つだけです。どうして??

2 つの質問があります。

  • DBT_DEVTYP_DEVICEINTERFACEメッセージとメッセージを関連付けるにはどうすればよいDBT_DEVTYP_VOLUMEですか (本質的に、どのVOLUMEメッセージがどのDEVICEINTERFACEメッセージに対応しているかを知るにはどうすればよいですか? デバイスの両方を取得するため)。
  • 両方のボリュームの削除を Windows に通知させる方法はありますか?
4

1 に答える 1

6

わかりましたので、私自身の質問の 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');
}

そして、影響を受けるすべてのドライブのマスクを解釈する関数に置き換えます。したがって、私が受け取ったメッセージは実際には両方のボリュームに関するものであり、両方のボリュームのドライブ文字がマスクで利用可能でした.

// [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_DEVICEINTERFACEDBT_DEVTYP_VOLUME) をどのように関連付けることができますか?

于 2009-10-22T21:10:49.060 に答える