Pourquoi un seul message WM_DEVICECHANGE lorsqu'un périphérique USB à plusieurs volumes est supprimé?

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

  •  05-07-2019
  •  | 
  •  

Question

J'écris une application qui détecte quand un certain périphérique de stockage de masse USB est branché et quand il est débranché - en écoutant Messages WM_DEVICECHANGE .

J'ai également enregistré mon application pour écouter les messages WM_DEVICECHANGE pour DBT_DEVTYP_DEVICEINTERFACE (à l'aide de RegisterDeviceNotification (appel API) et j'obtiens à la fois le DBT_DEVICEARRIVAL et le DBT_DEVICEREMOVECOMPLETE des messages lorsqu'un périphérique de stockage de masse USB est branché ou débranché.

Maintenant, le problème se produit lorsqu'un périphérique USB dont a plusieurs volumes est branché, puis débranché.

Je reçois les messages suivants lorsque le périphérique est branché:

  • WM_DEVICECHANGE ( DBT_DEVICEARRIVAL de type DBT_DEVTYP_DEVICEINTERFACE )
  • WM_DEVICECHANGE ( DBT_DEVICEARRIVAL de type DBT_DEVTYP_VOLUME )
  • WM_DEVICECHANGE ( DBT_DEVICEARRIVAL de type DBT_DEVTYP_VOLUME )

Et les messages suivants lorsqu'il est branché:

  • WM_DEVICECHANGE ( DBT_DEVICEREMOVECOMPLETE de type DBT_DEVTYP_VOLUME )
  • WM_DEVICECHANGE ( DBT_DEVICEREMOVECOMPLETE de type DBT_DEVTYP_DEVICEINTERFACE )

Ainsi, un seul message de suppression , même s'il existe deux volumes . Pourquoi ??

J'ai deux questions:

  • Comment puis-je corréler les messages DBT_DEVTYP_DEVICEINTERFACE avec les messages DBT_DEVTYP_VOLUME (essentiellement, comment savoir quel message VOLUME correspond au message DEVICEINTERF - puisque je les ai tous les deux pour le périphérique)?
  • Existe-t-il un moyen de faire en sorte que Windows me prévienne des deux suppressions de volume?
Était-ce utile?

La solution

D'accord, j'ai donc pu répondre à l'une de mes propres questions: Y a-t-il un moyen de demander à Windows de m'avertir des deux suppressions de volumes?

Oui : bien que Windows n'envoie qu'un seul message DBT_DEVTYP_VOLUME WM_DEVICECHANGE , vous êtes effectivement informé des deux suppressions de volume - mais, comme toujours, la réponse est au fond enterré dans MSDN :

  

Bien que le membre dbcv_unitmask puisse spécifier plusieurs volumes dans un message, cela ne garantit pas qu'un seul message est généré pour un événement spécifié. Plusieurs composants système peuvent générer indépendamment des messages pour les volumes logiques simultanément.

Il ne me restait donc plus qu'à ignorer le exemple de fonction que Microsoft donne dans l'un de ses exemples,

char FirstDriveFromMask (ULONG unitmask)
{
   char i;

   for (i = 0; i < 26; ++i)
   {
      if (unitmask & 0x1)
         break;
      unitmask = unitmask >> 1;
   }

   return (i + 'A');
}

Et remplacez-le par une fonction qui interprète le masque pour tous les lecteurs affectés. Le message que je recevais était donc bien pour les deux volumes et les deux lettres de lecteur de volume étaient disponibles dans le masque.

// [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
}

Il me reste toujours l’autre question à répondre: comment mettre en corrélation les deux messages ( DBT_DEVTYP_DEVICEINTERFACE et DBT_DEVTYP_VOLUME )?

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top