Nota
O acesso a esta página requer autorização. Podes tentar iniciar sessão ou mudar de diretório.
O acesso a esta página requer autorização. Podes tentar mudar de diretório.
A opção Forçar solicitações de E/S pendentes retorna aleatoriamente o STATUS_PENDING em resposta às chamadas de um driver para IoCallDriver. Esta opção testa a lógica do driver para responder aos valores de retorno STATUS_PENDING de IoCallDriver.
Esta opção é suportada apenas no Windows Vista e em versões posteriores do sistema operativo Windows.
Atenção Não use esta opção num driver a menos que tenha conhecimento detalhado da operação do driver e tenha verificado que o driver foi projetado para lidar com valores de retorno STATUS_PENDING de todas as suas chamadas para IoCallDriver. Executar essa opção em um driver que não foi projetado para lidar com STATUS_PENDING de todas as chamadas pode resultar em falhas, corrupções de memória e comportamento incomum do sistema que pode ser difícil de depurar ou corrigir.
Por que obrigar solicitações pendentes de E/S?
Drivers de nível superior numa stack de drivers chamam IoCallDriver para passar um IRP para drivers de nível inferior na stack de drivers. A rotina de despacho do condutor no controlador de nível inferior que recebe o IRP pode completar o IRP imediatamente ou retornar STATUS_PENDING e concluir o IRP no instante posterior.
Normalmente, o chamador deve estar preparado para lidar com qualquer um dos resultados. No entanto, como a maioria das rotinas de despacho lida com o IRP imediatamente, a lógica STATUS_PENDING no chamador não é frequentemente utilizada, e erros graves de lógica podem não ser detetados. A opção Forçar solicitações de E/S pendentes interceta chamadas para IoCallDriver e retorna STATUS_PENDING para testar a lógica usada com pouca frequência do driver de chamada.
Quando você usa Forçar solicitações de E/S pendentes?
Antes de executar este teste, reveja o design do driver e o código-fonte e confirme que o driver está preparado para lidar com STATUS_PENDING em todas as suas chamadas IoCallDriver.
Muitos drivers não são projetados para lidar com STATUS_PENDING em todas as chamadas para IoCallDriver. Eles podem estar enviando o IRP para um driver específico e conhecido que tem a garantia de completar o IRP imediatamente. Enviar STATUS_PENDING para um driver que não o manipula pode causar falhas de driver e sistema e corrupção de memória.
Como os motoristas devem lidar com STATUS_PENDING?
O driver de nível superior que chama IoCallDriver deve manipular um valor de retorno STATUS_PENDING da seguinte maneira:
Antes de chamar IoCallDriver, o driver deve chamar IoBuildSynchronousFsdRequest para organizar o processamento síncrono do IRP.
Se IoCallDriver retornar STATUS_PENDING, o driver deve aguardar pela conclusão do IRP ao chamar KeWaitForSingleObject no evento especificado.
O driver deve antecipar que o IRP pode ser libertado antes que o Gestor de I/O sinalize o evento.
Depois de chamar IoCallDriver, o chamador não pode fazer referência ao IRP.
Quais erros são detetados pela solicitação de E/S pendente?
A opção Force Pending I/O Request deteta os seguintes erros no driver que chama IoCallDriver e recebe um valor de retorno STATUS_PENDING:
O driver não chama IoBuildSynchronousFsdRequest para organizar o processamento síncrono.
O driver não chama KeWaitForSingleObject.
O driver faz referência a um valor na estrutura IRP depois de chamar IoCallDriver. Depois de chamar IoCallDriver, o driver de nível superior não pode acessar o IRP a menos que tenha definido uma rotina de conclusão e, em seguida, somente quando todos os drivers de nível inferior tiverem concluído o IRP. Se o IRP for libertado, o controlador falhará.
O driver chama incorretamente uma função relacionada. Por exemplo, o driver chama KeWaitForSingleObject e passa um identificador para o evento (como o parâmetro Object), em vez de passar um ponteiro para um objeto de evento.
O motorista espera pelo evento errado. Por exemplo, o driver chama IoSetCompletionRoutine, mas aguarda um evento interno que é sinalizado por sua própria rotina de conclusão, em vez de aguardar o evento IRP que é sinalizado pelo Gerenciador de E/S quando o IRP é concluído.
Forçar alterações de solicitações de E/S pendentes introduzidas no Windows 7
A partir do Windows 7, a opção Forçar solicitações de E/S pendentes é mais eficaz na aplicação dos caminhos de código STATUS_PENDING em drivers verificados. Em versões anteriores do Windows, o Verificador de Drivers forçava que a conclusão de um IRP fosse atrasada somente quando a primeira IoCompleteRequest para esse IRP era executada. Isso significa que a eficácia da verificação de Driver1 pode ser reduzida pelo comportamento de Driver2 da mesma pilha de dispositivos. O Driver2 pode aguardar a conclusão de forma síncrona antes de retornar de sua rotina de despacho para o Driver1. O atraso forçado da conclusão do IRP ocorre precisamente antes que a solicitação de E/S volte para o driver verificado no caminho de conclusão. Isso significa que o caminho de código STATUS_PENDING do driver verificado é realmente exercido e o driver verificado percebe um atraso na conclusão.
#B0 #A1 Ativar Esta Opção
Para ativar Forçar solicitações de E/S pendentes, você também deve ativar a verificação de E/S. Você pode ativar a opção Forçar solicitações de E/S pendentes para um ou mais drivers usando o Gerenciador de Verificadores de Driver ou a linha de comando Verifier.exe. Para obter detalhes, consulte Selecionando Opções do Verificador de Controladores.
A opção Forçar solicitações de E/S pendentes é suportada apenas no Windows Vista e em versões posteriores do Windows.
Na linha de comando
Para ativar Forçar solicitações de E/S pendentes, use um valor de sinalizador de 0x210 ou adicione 0x210 ao valor do sinalizador. Esse valor ativa a Verificação de E/S (0x10) e a Força Solicitações de E/S Pendentes (0x200).
Por exemplo:
verifier /flags 0x210 /driver MyDriver.sysA opção estará ativa após a próxima inicialização.
Se tentar ativar apenas Forçar Solicitações de E/S Pendentes (verificador /sinalizadores 0x200), o Verificador de Driver habilitará automaticamente tanto Forçar Solicitações de E/S Pendentes (0x200) como a Verificação de E/S.
Você também pode ativar e desativar Solicitações de E/S Pendentes de Força sem reinicializar o computador, adicionando o parâmetro /volatile ao comando. Por exemplo:
verifier /volatile /flags 0x210 /adddriver MyDriver.sysEssa configuração entra em vigor imediatamente, mas é perdida quando você desliga ou reinicia o computador. Para obter detalhes, consulte Usando Configuração Volátil.
Usando o Gestor do Verificador de Drivers
- Inicie o Driver Verifier Manager. Digite Verifier numa janela da Linha de Comandos.
- Selecione Criar configurações personalizadas (para desenvolvedores de código) e clique em Avançar.
- Selecione configurações individuais de uma lista completa.
- Selecione Verificação de E/S e force solicitações de E/S pendentes.
Se selecionar apenas Forçar solicitações de E/S pendentes, o Driver Verifier Manager lembrará que a verificação de E/S é necessária e oferecerá ativá-la para si.
Visualizando os resultados
Para exibir os resultados do teste Force Pending I/O Requests, use a extensão do depurador !verifier com um valor de sinalizador de 0x40.
Para obter informações sobre !verifier, consulte o tópico !verifier na documentação Debugging Tools for Windows .
Se a máquina de teste falhar como resultado do teste Force Pending I/O Requests, você poderá usar o comando !verifier 40 para encontrar a causa. Em um rastreamento de pilha atual, localize o endereço do IRP que foi usado recentemente pelo seu driver. Por exemplo, se utilizares o comando kP, que exibe o quadro de pilha para uma thread, poderás encontrar o endereço IRP entre os parâmetros de função do rastreio de pilha atual. Em seguida, execute !verifier 40 e procure o endereço do IRP. Os rastreamentos de pilha de força pendente mais recentes aparecem na parte superior da tela.
Por exemplo, o seguinte stack trace de Pci.sys mostra a sua resposta a Forçar Pedidos de I/O Pendentes. O teste não revela quaisquer erros na lógica Pci.sys.
kd> !verifier 40
# Size of the log is 0x40
========================================================
IRP: 8f84ef00 - forced pending from stack trace:
817b21e4 nt!IovpLocalCompletionRoutine+0xb2
81422478 nt!IopfCompleteRequest+0x15c
817b2838 nt!IovCompleteRequest+0x9c
84d747df acpi!ACPIBusIrpDeviceUsageNotification+0xf5
84d2d36c acpi!ACPIDispatchIrp+0xe8
817b258f nt!IovCallDriver+0x19d
8142218e nt!IofCallDriver+0x1c
817c6a9d nt!ViFilterDispatchPnp+0xe9
817b258f nt!IovCallDriver+0x19d
8142218e nt!IofCallDriver+0x1c
84fed489 pci!PciCallDownIrpStack+0xbf
84fde1cb pci!PciDispatchPnpPower+0xdf
817b258f nt!IovCallDriver+0x19d
8142218e nt!IofCallDriver+0x1c
817c6a9d nt!ViFilterDispatchPnp+0xe9
817b258f nt!IovCallDriver+0x19d
8142218e nt!IofCallDriver+0x1c
84ff2ff5 pci!PciSendPnpIrp+0xbd
84fec820 pci!PciDevice_DeviceUsageNotification+0x6e
84fde1f8 pci!PciDispatchPnpPower+0x10c
817b258f nt!IovCallDriver+0x19d
8142218e nt!IofCallDriver+0x1c
84d76ce2 acpi!ACPIFilterIrpDeviceUsageNotification+0x96
84d2d36c acpi!ACPIDispatchIrp+0xe8
817b258f nt!IovCallDriver+0x19d
8142218e nt!IofCallDriver+0x1c
84f7f16c PCIIDEX!PortWdmForwardIrpSynchronous+0x8e
84f7b2b3 PCIIDEX!GenPnpFdoUsageNotification+0xcb
84f7d301 PCIIDEX!PciIdeDispatchPnp+0x45
817b258f nt!IovCallDriver+0x19d
8142218e nt!IofCallDriver+0x1c
O traço da pilha mostra que Acpi.sys estava a tentar concluir o IRP 8f84ef00. Driver Verifier forçou uma conclusão diferida, então Acpi.sys retornou STATUS_PENDING para pci!PciCallDownIrpStack. Se esta chamada tivesse causado uma falha, o proprietário do driver precisaria rever o código-fonte para pci! PciCallDownIrpStack e revisá-lo para lidar com o STATUS_PENDING corretamente.