Compartilhar via


Estudo de Caso: Solução de problemas de um dispositivo USB desconhecido usando ETW e Netmon

Este tópico fornece um exemplo de como usar o ETW USB e o Netmon para solucionar problemas de um dispositivo USB que o Windows não reconhece.

Para este exemplo, conectamos um dispositivo e ele apareceu como um dispositivo desconhecido no Gerenciador de Dispositivos e em outras partes da interface do usuário. A ID de hardware era USB\UNKNOWN. Para diagnosticar mais, desconectamos o dispositivo, iniciamos um rastreamento ETW e conectamos o dispositivo novamente. Depois que o dispositivo apareceu como um dispositivo desconhecido, interrompemos o rastreamento.

Sobre o problema do dispositivo desconhecido

Para depurar um problema de dispositivo USB desconhecido, ajuda a entender o que a pilha de driver USB faz para enumerar um dispositivo quando um usuário o conecta ao sistema. Para obter informações sobre a enumeração USB, consulte a postagem no blog intitulada Como a pilha USB enumera um dispositivo?

Normalmente, quando a pilha de driver USB não consegue enumerar um dispositivo, o driver do hub ainda relata a chegada do dispositivo ao Windows e o dispositivo USB é marcado como um dispositivo desconhecido no Gerenciador de Dispositivos. O dispositivo tem uma ID do dispositivo usb\VID_0000&PID_0000 e uma ID de hardware e ID compatível de USB\UNKNOWN. Os eventos a seguir fazem com que o driver do hub USB enumere um dispositivo USB como um dispositivo desconhecido:

  • Uma solicitação de redefinição de porta atingiu o tempo limite durante a enumeração.
  • Falha na solicitação Definir Endereço para o dispositivo USB.
  • Falha na solicitação do Descritor de Dispositivo do dispositivo USB.
  • O Descritor de Dispositivo USB foi malformado e falhou na validação.
  • Falha na solicitação do Descritor de Configuração.
  • O Descritor de Configuração USB foi malformado e falhou na validação.

No Windows 7, dispositivos desconhecidos que falham na enumeração são marcados com falha Código 43 em Gerenciador de Dispositivos.

Se um dispositivo for marcado com falha Código 28 em Gerenciador de Dispositivos, o dispositivo enumerou com êxito, mas ainda é um dispositivo desconhecido. Esse código de falha indica que o dispositivo não forneceu uma cadeia de caracteres de ID do Produto durante a enumeração e o Windows não pôde encontrar um INF correspondente para o dispositivo instalar um driver.

Iniciando a análise de rastreamento de eventos

Como essa é uma falha de dispositivo, recomendamos que você use o Netmon com o analisador USB para analisar o arquivo de log.

Para exibir o log de rastreamento de eventos

  1. Execute o Netmon, clique em Arquivo -> Abrir -> Capturar e selecione o arquivo.

  2. Selecione o primeiro evento no painel Resumo do Quadro , que tem a descrição SystemTrace. Esta imagem mostra a aparência da tela quando você seleciona o primeiro evento.

    Captura de tela que mostra a janela

  3. Para personalizar as colunas exibidas pelo Netmon, clique com o botão direito do mouse em um nome de coluna e selecione Escolher Colunas.

  4. O primeiro evento, identificado como o tipo SystemTrace, contém informações gerais sobre o log. Você pode expandir a árvore de informações no painel Detalhes do Quadro para ver informações como o número de eventos perdidos e a hora de início do rastreamento.

Eventos de resumo do dispositivo USB

O evento 2 é o primeiro evento USB no log. Esse e vários eventos subsequentes descrevem os controladores de host USB, hubs e dispositivos que estavam conectados ao sistema quando iniciamos o rastreamento. Podemos chamar esse grupo de eventos de eventos de resumo do dispositivo ou apenas eventos de resumo. Como o primeiro evento, os eventos de resumo não descrevem a atividade do driver. Os eventos de resumo registram o estado dos dispositivos no início de uma sessão de registro em log. Outros eventos representam algo acontecendo no barramento, interações com drivers cliente ou o sistema ou alterações de estado interno.

O hub USB e os drivers de porta USB registram eventos de resumo. O driver que registrou um evento é identificado na coluna Nome do Protocolo. Por exemplo, um evento registrado pelo driver de porta USB tem o nome do protocolo USBPort_MicrosoftWindowsUSBPORT. Um rastreamento de eventos USB normalmente contém uma sequência de eventos de resumo de porta, seguida por uma sequência de eventos de resumo do hub. Muitos dos eventos de resumo da porta USB e do hub USB têm as palavras "Informações" ou "Atributos" em sua descrição.

Como identificar o final dos eventos de resumo? Se houver uma quebra significativa no padrão de carimbo de data/hora entre os eventos do hub USB no início do log, essa interrupção provavelmente será o final do resumo do dispositivo. Caso contrário, o primeiro evento de porta USB após qualquer evento de hub USB provavelmente será o primeiro evento não resumido. A Figura 3 na página a seguir mostra o primeiro evento não resumo neste rastreamento de exemplo.

Neste exemplo, o dispositivo de interesse não estava conectado ao sistema quando iniciamos o rastreamento, para que você possa ignorar os eventos de resumo do dispositivo por enquanto.

Captura de tela que mostra um dispositivo de interesse selecionado no

Conteúdo de dados e descrição do evento

No log de exemplo, o primeiro evento após os eventos de resumo do dispositivo é um evento Desativar IRP de Espera do Hub USB Concluído. Conectamos um dispositivo e um controlador de host ou um hub está acordando em resposta. Para determinar qual componente está acordando, examine os dados do evento. Os dados estão no painel Detalhes do Quadro, que é mostrado em uma estrutura de árvore aproximadamente na seguinte forma:

Frame information
ETW event header information
    ETW event descriptor (Constant information about the event ID such
    as error level)
Event payload (Data logged at the time of the event)
    Name of a USB-specific structure
        Structure members and their values (Types: numbers, strings,
        or arrays)
    ...

Expanda os dados de conteúdo para o evento IRP Completed de Espera do Hub USB e você verá uma estrutura ETW chamada fid_USBHUB_Hub. O nome da estrutura tem os seguintes componentes:

Termo Descrição
Fid_ Um prefixo típico para uma estrutura ETW USB.
USBHUB_ Uma indicação de que o driver do hub USB registrou o evento.
O restante da cadeia de caracteres O nome do objeto que os dados da estrutura descrevem. Para esse evento, ele é um objeto Hub.

O driver do hub USB usa a estrutura fid_USBHUB_Hub para descrever um hub USB. Os eventos que têm essa estrutura de hub em seu conteúdo de dados referem-se a um hub e podemos identificar o hub específico usando o conteúdo da estrutura. A Figura 4 mostra o painel Detalhes do Quadro, com a estrutura fid_USBHUB_Hub expandida para mostrar seus campos.

monitor de rede da Microsoft – detalhes do quadro.

A estrutura do hub é muito semelhante a duas outras estruturas que normalmente aparecem em eventos ETW USB:fid_USBHUB_Device e fid_USBPORT_Device. Os seguintes campos importantes são comuns a todas as três estruturas:

Campo Descrição
fid_idVendor A VID (ID do Fornecedor USB) do dispositivo
fid_idProduct A ID do Produto USB (PID) do dispositivo
fid_PortPath A lista de números de porta de hub baseados em um por meio dos quais um dispositivo USB está anexado. O número de números de porta na lista está contido no campo PortPathDepth . Para os dispositivos de hub raiz, essa lista é de zeros. Para um dispositivo USB conectado diretamente a uma porta de hub raiz, o valor em PortPath[0] é o número da porta do hub raiz da porta à qual o dispositivo está anexado.

Para um dispositivo USB conectado por meio de um ou mais hubs USB adicionais, a lista de números de porta do hub começa com a porta do hub raiz e continua com os hubs adicionais (na ordem de distância do hub raiz). Ignorar zeros. Por exemplo:

Valor de exemplo Descrição
[0, 0, 0, 0, 0, 0] O evento refere-se a um hub raiz (uma porta no computador, controlada diretamente por um controlador de host USB).
[3, 0, 0, 0, 0, 0] O evento refere-se a um hub ou um dispositivo conectado à porta 3 de um hub raiz.
[3, 1, 0, 0, 0, 0] Um hub é conectado à porta 3 de um hub raiz. O evento refere-se a um hub ou um dispositivo conectado à porta 1 desse hub externo.

Você deve monitorar os caminhos de porta de qualquer dispositivo de interesse. Quando um dispositivo está sendo enumerado, o VID e o PID são desconhecidos e registrados como 0. A VID e o PID não aparecem durante algumas solicitações de dispositivo de baixo nível, como redefinição e suspensão. Essas solicitações são enviadas para o hub ao qual o dispositivo está conectado.

Em nosso log de exemplo, o evento de conclusão Wait Wake tem um caminho de porta com seis zeros. O evento indica uma ação Aguardar Ativação em um hub raiz. Isso é lógico devido às nossas ações: conectamos o dispositivo a uma porta do hub raiz, portanto, o hub raiz está acordando.

Filtros do USB Netmon

Você pode examinar cada evento em um log em ordem cronológica, se tiver tempo. Mesmo com a experiência, é difícil identificar rapidamente os eventos importantes examinando a lista de descrições do evento. Para encontrar a causa do Dispositivo Desconhecido mais rapidamente, você pode usar o recurso de filtro Netmon.

O filtro de erro USB

Para ativar o filtro de erro USB no Netmon, clique em Filtro -> Filtro de Exibição -> Filtro de Carga -> Filtros Padrão -> USB -> Erros do Hub USB e clique em Aplicar no painel Filtro de Exibição .

O filtro de erro USB restringe a lista de eventos somente àqueles que atendem aos critérios mostrados na tabela a seguir.

Filtrar texto Descrição
(USBPort_MicrosoftWindowsUSBUSBPORT AND NetEvent.Header.Descriptor.Opcode == 34) Eventos de porta USB que têm opcode 34 são erros de porta.
(USBHub_MicrosoftWindowsUSBUSBHUB AND NetEvent.Header.Descriptor.Opcode == 11) Eventos de hub USB que têm opcode 11 são erros de hub.
(NetEvent.Header.Descriptor.Level == 0x2) Eventos que têm 0x2 de nível geralmente são erros.
(USBHub_MicrosoftWindowsUSBUSBHUB AND NetEvent.Header.Descriptor.Id == 210) Eventos de hub USB com ID 210 são eventos "Log de Exceção do Hub USB". Para obter mais informações, consulte Noções básicas sobre eventos de erro e códigos de status.

Esta imagem mostra o conjunto menor de eventos que aparecem no painel Resumo do Quadro depois que aplicamos o filtro de erro USB ao nosso log de rastreamento de exemplo.

Captura de tela que mostra um conjunto de eventos no painel

Para ver uma visão geral da sequência de erros, você pode exibir brevemente cada evento de erro. Campos importantes a serem observados incluem fid_NtStatus, fid_UsbdStatus e fid_DebugText. Para obter mais informações, consulte Noções básicas sobre eventos de erro e códigos de status. Para desativar um filtro, clique no botão Remover no painel Exibir Filtro .

Filtros Personalizados do Netmon

Você pode criar filtros personalizados no Netmon. O método mais fácil é criar um filtro de dados na tela de uma das seguintes maneiras:

  • Clique com o botão direito do mouse em um campo no painel Detalhes do Quadro e selecione Adicionar Valor Selecionado ao Filtro de Exibição.
  • Clique com o botão direito do mouse em um campo no painel Resumo do Quadro e selecione Adicionar [nome do campo] ao Filtro de Exibição.

Você pode alterar os operadores (como OR, AND e ==) e os valores de filtro para criar as expressões de filtro apropriadas.

Noções básicas sobre eventos de erro e códigos de status

Em nosso exemplo de dispositivo desconhecido, a maioria das exceções de hub USB tem um fid_DebugText dados de CreateDeviceFailure. Não está claro a gravidade da exceção, mas o texto de depuração dá uma dica sobre a causa: uma operação relacionada ao novo dispositivo falhou. Por enquanto, suponha que os eventos adjacentes Criar Dispositivo com Falha sejam redundantes. As duas últimas exceções são CreateDeviceFailure_Popup e GenErr_UserIoctlFailed. A exceção pop-up soa como um erro que foi exposto ao usuário, mas qualquer e todos esses erros podem estar relacionados ao problema desconhecido do dispositivo.

Eventos de erro USB e outros eventos têm status valores em seus dados que fornecem informações valiosas sobre o problema. Você pode encontrar informações sobre status valores usando os recursos na tabela a seguir.

Tipo de status Recurso
fid_NtStatus Confira Valores NTSTATUS.
O campo status de um URB (bloco de solicitação USB) ou fid_UsbdStatus Pesquise o valor como um USBD_STATUS em inc\api\usb.h no WDK (Kit de Driver do Windows). Você também pode usar o USBD_STATUS. Este tópico lista os nomes simbólicos e os significados dos valores de USBD_STATUS.

Lendo para trás de eventos de problema

Os eventos registrados antes dos eventos de erro podem fornecer pistas importantes sobre a causa do erro. Você deve examinar os eventos registrados antes dos erros para tentar determinar a causa raiz do dispositivo desconhecido. Neste exemplo, comece a olhar para trás do evento CreateDeviceFailure_Popup, a última exceção. Selecione esse evento enquanto o filtro de erro USB estiver habilitado e clique em Remover no painel Filtro de Exibição . O filtro de erro USB ainda aparece no painel Filtro de Exibição e você pode aplicá-lo novamente mais tarde. Mas agora o filtro está desabilitado e o painel Resumo do Quadro exibe todos os eventos, conforme mostrado nesta imagem.

monitor de rede da Microsoft.

Os dois eventos que são registrados logo antes do evento CreateDeviceFailure_Popup são um Dispatch e um Complete de uma transferência de controle USB. O campo fid_USBPORT_Device caminho da porta é zero para ambos os eventos, o que indica que o destino da transferência é o hub raiz. Na estrutura fid_USBPORT_URB_CONTROL_TRANSFER do evento de conclusão, o status é zero (USBD_STATUS_SUCCESS), o que indica que a transferência foi bem-sucedida. Continue examinando os eventos anteriores.

Os dois próximos eventos anteriores são o quarto (final) evento Create Device Failed e a quarta (final) exceção CreateDeviceFailure, que examinamos anteriormente.

O próximo evento anterior é Endpoint Close. Esse evento significa que um ponto de extremidade não é mais utilizável. Os dados do evento descrevem o dispositivo e o ponto de extremidade nesse dispositivo. O caminho da porta do dispositivo é [1, 0, 0, 0, 0]. O sistema no qual executamos o rastreamento tem apenas controladores de host (hubs raiz) mais o dispositivo que estávamos conectando, portanto, esse caminho de porta não descreve um hub. O ponto de extremidade fechado deve estar no único dispositivo que conectamos e agora sabemos que o caminho do dispositivo é 1. É provável que os drivers tornaram o ponto de extremidade do dispositivo inacessível devido a um problema que foi encontrado anteriormente. Continue examinando os eventos anteriores.

O próximo evento anterior é uma transferência de controle USB concluída. Os dados do evento mostram que o destino da transferência é o dispositivo (o caminho da porta é 1). A estrutura fid_USBPORT_Endpoint_Descriptor indica que o endereço do ponto de extremidade é 0, portanto, esse é o ponto de extremidade de controle padrão definido por USB. A status URB é 0xC0000004. Como a status não é zero, a transferência provavelmente não foi bem-sucedida. Para obter mais detalhes sobre esse valor de USBD_STATUS, consulte usb.h e Noções básicas sobre eventos de erro e códigos de status.

#define USBD_STATUS_STALL_PID ((USBD_STATUS)0xC0000004L)

Ou seja: o dispositivo retornou um identificador de pacote de parada. Qual solicitação foi paralisada pelo ponto de extremidade? Os outros dados que foram registrados para o evento indicam que a solicitação foi uma solicitação de controle de dispositivo padrão. Esta é a solicitação analisada:

  Frame: Number = 184, Captured Frame Length = 252, MediaType = NetEvent
+ NetEvent:
- MicrosoftWindowsUSBUSBPORT: Complete Internal URB_FUNCTION_CONTROL_TRANSFER
  - USBPORT_ETW_EVENT_COMPLETE_INTERNAL_URB_FUNCTION_CONTROL_TRANSFER: Complete Internal URB_FUNCTION_CONTROL_TRANSFER
   + fid_USBPORT_HC:
   + fid_USBPORT_Device:
   + fid_USBPORT_Endpoint:
   + fid_USBPORT_Endpoint_Descriptor:
   + fid_URB_Ptr: 0x84539008
   - ControlTransfer:
    + Urb: Status = 0xc0000004, Flags 0x3, Length = 0
    - SetupPacket: GET_DESCRIPTOR
     + bmRequestType: (Standard request) 0x80
       bRequest: (6) GET_DESCRIPTOR
       Value_DescriptorIndex: 0 (0x0)
       Value_DescriptorType: (1) DEVICE
       _wIndex: 0 (0x0)
       wLength: 64 (0x40)

Combine o bRequest (GET_DESCRIPTOR) com o Value_DescriptorType (DEVICE) e você pode determinar que a solicitação foi o descritor get-device.

Para que a enumeração USB continue, o dispositivo deve ter respondido a essa solicitação com seu descritor de dispositivo. Em vez disso, o dispositivo parou a solicitação, o que fez com que a enumeração falhasse. Portanto, todas as quatro falhas de criação de dispositivo foram causadas por solicitações paralisadas para o descritor de dispositivo. Você determinou que o dispositivo é desconhecido porque a enumeração falhou e essa enumeração falhou porque o dispositivo não concluiu a solicitação para o descritor do dispositivo.