Por que apenas uma mensagem WM_DEVICECHANGE quando um dispositivo multi-volume de USB é removido?
-
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 tipoDBT_DEVTYP_DEVICEINTERFACE
) -
WM_DEVICECHANGE
(DBT_DEVICEARRIVAL
do tipoDBT_DEVTYP_VOLUME
) -
WM_DEVICECHANGE
(DBT_DEVICEARRIVAL
do tipoDBT_DEVTYP_VOLUME
)
E o seguinte mensagens quando ele está conectado a:
-
WM_DEVICECHANGE
(DBT_DEVICEREMOVECOMPLETE
do tipoDBT_DEVTYP_VOLUME
) -
WM_DEVICECHANGE
(DBT_DEVICEREMOVECOMPLETE
do tipoDBT_DEVTYP_DEVICEINTERFACE
)
Assim, apenas uma mensagem Remover , embora existam dois volumes . Porque ??
Eu tenho duas perguntas:
- Como posso mensagens
DBT_DEVTYP_DEVICEINTERFACE
correlacionam com mensagensDBT_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?
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