Por que apenas uma mensagem WM_DEVICECHANGE quando um dispositivo multi-volume de USB é removido?

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

  •  05-07-2019
  •  | 
  •  

Pergunta

Eu estou escrevendo um aplicativo que detecta quando um determinado USB Mass Storage Device está conectado-in, e quando ele está desligado - por ouvir para WM_DEVICECHANGE mensagens .

Eu também ter registado o meu pedido para escutar mensagens WM_DEVICECHANGE para DBT_DEVTYP_DEVICEINTERFACE (usando o RegisterDeviceNotification chamada API) e fico com ambas as mensagens DBT_DEVICEARRIVAL e DBT_DEVICEREMOVECOMPLETE quando um USB Mass Storage Device é conectado-in ou desconectado.

Agora, o problema ocorre quando um dispositivo USB que tem vários volumes está conectado-in, e em seguida, desligado.

Eu recebo as seguintes mensagens quando o dispositivo está conectado:

  • WM_DEVICECHANGE (DBT_DEVICEARRIVAL do tipo DBT_DEVTYP_DEVICEINTERFACE)
  • WM_DEVICECHANGE (DBT_DEVICEARRIVAL do tipo DBT_DEVTYP_VOLUME)
  • WM_DEVICECHANGE (DBT_DEVICEARRIVAL do tipo DBT_DEVTYP_VOLUME)

E o seguinte mensagens quando ele está conectado a:

  • WM_DEVICECHANGE (DBT_DEVICEREMOVECOMPLETE do tipo DBT_DEVTYP_VOLUME)
  • WM_DEVICECHANGE (DBT_DEVICEREMOVECOMPLETE do tipo DBT_DEVTYP_DEVICEINTERFACE)

Assim, apenas uma mensagem Remover , embora existam dois volumes . Porque ??

Eu tenho duas perguntas:

  • Como posso mensagens DBT_DEVTYP_DEVICEINTERFACE correlacionam com mensagens DBT_DEVTYP_VOLUME (essencialmente, como eu sei que VOLUME corresponde mensagem à qual DEVICEINTERFACE Mensagem - desde que eu levá-los tanto para o dispositivo )?
  • Existe uma maneira de tornar o Windows Notificar-me de ambas as remoções de volume?
Foi útil?

Solução

Ok, então eu era capaz de responder a uma das minhas próprias perguntas: Existe uma maneira de tornar o Windows Notificar-me de ambas as remoções de volume

?

Sim - mesmo que o Windows envia apenas mensagens em uma DBT_DEVTYP_VOLUME WM_DEVICECHANGE, você realmente ser notificado de ambas as remoções de volume - mas, como sempre, as mentiras resposta, no fundo, enterrados no MSDN :

Embora o membro dbcv_unitmask pode especificar mais de um volume em qualquer mensagem, isso não garante que apenas uma mensagem é gerada para um evento especificado. Vários componentes do sistema pode gerar independentemente mensagens para volumes lógicos ao mesmo tempo.

Assim, tudo o que eu tinha a fazer era ignorar a exemplo função que a Microsoft dá em uma de suas amostras,

char FirstDriveFromMask (ULONG unitmask)
{
   char i;

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

   return (i + 'A');
}

E substituí-lo com uma função que interpreta a máscara para todas unidades afetadas. Então, a única mensagem que eu estava ficando era de fato para ambos os volumes, e ambas as letras de unidade de volume estavam disponíveis na máscara.

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

Ainda tenho outra pergunta a resposta embora - como podem as duas mensagens (DBT_DEVTYP_DEVICEINTERFACE e DBT_DEVTYP_VOLUME) ser correlacionados

?
Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top