Why is there only one WM_DEVICECHANGE message when deleting a multi-volume USB device?

I am writing an application that detects when a specific USB storage device is connected to the network and when it is disconnected - listening to the WM_DEVICECHANGE message .

I also registered a WM_DEVICECHANGEmessage listening application for DBT_DEVTYP_DEVICEINTERFACE(using the RegisterDeviceNotification API call ) and I will receive messages DBT_DEVICEARRIVALand DBT_DEVICEREMOVECOMPLETEwhen the USB flash drive is plugged in or unplugged.

Now the problem occurs when a USB device with several volumes is connected and then disconnected.

I get the following messages when the device is connected:

  • WM_DEVICECHANGE( DBT_DEVICEARRIVALtype DBT_DEVTYP_DEVICEINTERFACE)
  • WM_DEVICECHANGE( DBT_DEVICEARRIVALtype DBT_DEVTYP_VOLUME)
  • WM_DEVICECHANGE( DBT_DEVICEARRIVALtype DBT_DEVTYP_VOLUME)

And the following messages when they are connected:

  • WM_DEVICECHANGE( DBT_DEVICEREMOVECOMPLETEtype DBT_DEVTYP_VOLUME)
  • WM_DEVICECHANGE( DBT_DEVICEREMOVECOMPLETEtype DBT_DEVTYP_DEVICEINTERFACE)

So, delete only the message , although there are two volumes . Why??

I have two questions:

  • How can I match messages DBT_DEVTYP_DEVICEINTERFACEto messages DBT_DEVTYP_VOLUME(essentially, how do I know which VOLUME message matches a DEVICEINTERFACE message - since I receive both of them for the device)?
  • Is there a way to get Windows to notify me when volumes are deleted?
+3
source share
1 answer

Ok, so I was able to answer one of my own questions: is there a way to get Windows to notify me when volumes are deleted?

- DBT_DEVTYP_VOLUME WM_DEVICECHANGE, , , , , MSDN:

dbcv_unitmask , , . .

, , , , Microsoft ,

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

+6

Source: https://habr.com/ru/post/1720812/


All Articles