Usando a função _analysis_assume para suprimir falsos defeitos

Você pode fornecer ao Verificador de Driver Estático (SDV) informações adicionais sobre o código-fonte do driver para que, durante a verificação, você possa suprimir os relatórios de falsos defeitos. Os falsos defeitos ocorrem quando o SDV relata uma violação de regra aparente, mas em uma situação em que o driver está agindo corretamente.

Para fornecer ao SDV essas informações adicionais, use a função __analysis_assume . A função tem a seguinte sintaxe:

__analysis_assume( expression ) 

Onde a expressão pode ser qualquer expressão que seja considerada como true.

Quando você usa essa função, o SDV pressupõe que a condição representada pela expressão é verdadeira no ponto em que a função __analysis_assume é exibida. A função __analysis_assume é usada apenas pelas ferramentas de análise estática. A função é ignorada pelo compilador.

Se você usar __analysis_assume, é extremamente importante que você tenha certeza da validade da suposição que está fazendo. Se sua suposição for falsa, agora ou no futuro, você pode estar suprimindo um verdadeiro defeito. Recomendamos que você sempre adicione um comentário ao seu código que explique por que você está usando a função __analysis_assume . Se você não puder escrever um motivo para a suposição, não suprima o defeito.

Você deve adicionar a função __analysis_assume conforme necessário, sempre que encontrar falsos defeitos que você possa suprimir com segurança.

Exemplos

No exemplo de código a seguir, a regra KMDF RequestCompletedLocal relata um defeito. Esse é um falso defeito porque o SDV não pode interpretar corretamente a instrução switch e, consequentemente, não entra no branch em que a solicitação é concluída.

Nesta instrução switch , há seis casos possíveis. O driver definiu seis códigos IOCTL, portanto, o driver definitivamente pegará um dos branches. Se um dos branches for obtido, a solicitação será concluída com êxito.

VOID
PortIOEvtIoDeviceControl(
      __in WDFQUEUE     Queue,
      __in WDFREQUEST   Request,
      __in size_t       OutputBufferLength,
  __in size_t       InputBufferLength,
  __in ULONG        IoControlCode
     )
 
     PDEVICE_CONTEXT devContext = NULL;
     WDFDEVICE device;

     PAGED_CODE();
 
     device = WdfIoQueueGetDevice(Queue);
 
     devContext = PortIOGetDeviceContext(device);
 
     switch(IoControlCode)
         case IOCTL_GPD_READ_PORT_UCHAR:
         case IOCTL_GPD_READ_PORT_USHORT:
         case IOCTL_GPD_READ_PORT_ULONG:
             PortIOIoctlReadPort(devContext,
                                 Request,
                                 OutputBufferLength,
                                 InputBufferLength,
                                 IoControlCode);
             break;

 
         case IOCTL_GPD_WRITE_PORT_UCHAR:
         case IOCTL_GPD_WRITE_PORT_USHORT:
         case IOCTL_GPD_WRITE_PORT_ULONG:    
             PortIOIoctlWritePort(devContext,
                                  Request,
                                  OutputBufferLength,
                                  InputBufferLength,
                                  IoControlCode);
             break;
 
     }
 
}

Para suprimir com segurança o falso defeito, use a função __analysis_assume para especificar que o IoControlCode é garantido como um dos IOCTLs definidos pelo driver.

VOID
PortIOEvtIoDeviceControl(
      __in WDFQUEUE     Queue,
      __in WDFREQUEST   Request,
      __in size_t       OutputBufferLength,
      __in size_t       InputBufferLength,
      __in ULONG        IoControlCode
     )
 
     PDEVICE_CONTEXT devContext = NULL;
     WDFDEVICE device;

     PAGED_CODE();
 
     device = WdfIoQueueGetDevice(Queue);
 
     devContext = PortIOGetDeviceContext(device);

/* Use __analysis_assume to suppress a false defect for the SDV RequestCompletedLocal rule. 
There are only 6 possible IOCTLs for IoControlCode; each case is covered in the switch statement.
*/

 __analysis_assume( IoControlCode == IOCTL_GPD_READ_PORT_UCHAR || \
                       IoControlCode == IOCTL_GPD_READ_PORT_USHORT|| \
                       IoControlCode == IOCTL_GPD_READ_PORT_ULONG || \
                       IoControlCode == IOCTL_GPD_WRITE_PORT_UCHAR|| \
                       IoControlCode == IOCTL_GPD_WRITE_PORT_USHORT|| \
                       IoControlCode == IOCTL_GPD_WRITE_PORT_ULONG);

     switch(IoControlCode)
         case IOCTL_GPD_READ_PORT_UCHAR:
         case IOCTL_GPD_READ_PORT_USHORT:
         case IOCTL_GPD_READ_PORT_ULONG:
             PortIOIoctlReadPort(devContext,
                                 Request,
                                 OutputBufferLength,
                                 InputBufferLength,
                                 IoControlCode);
             break;

 
         case IOCTL_GPD_WRITE_PORT_UCHAR:
         case IOCTL_GPD_WRITE_PORT_USHORT:
         case IOCTL_GPD_WRITE_PORT_ULONG:    
             PortIOIoctlWritePort(devContext,
                                  Request,
                                  OutputBufferLength,
                                  InputBufferLength,
                                  IoControlCode);
             break;
 
     }
 
}

Para obter outro exemplo de como você pode usar __analysis_assume, consulte o código de exemplo usado em Usando __sdv_save_request e __sdv_retrieve_request para Chamadas de Procedimento Adiado. O exemplo mostra como usar __sdv_save_request e __sdv_retrieve_request para DPCs (workitems, Timers e assim por diante). A função __analysis_assume é usada para suprimir falsos defeitos que podem resultar de outra forma.