Partilhar via


Usando __sdv_save_adapter_context para rastrear campos de contexto do adaptador

Quando o NDIS chama a função de retorno de chamada MiniportInitializeEx de um driver de miniport para inicializar um adaptador de miniporto, o driver cria sua própria estrutura de dados interna para representar o adaptador de miniporto. O driver usa essa estrutura, conhecida como o contexto do adaptador de miniporto, para manter informações de estado específicas do dispositivo de que o driver precisa para gerenciar o adaptador de miniporta. O driver passa um identificador para essa estrutura para o NDIS.

Quando o NDIS chama uma das funções MiniportXxx do driver de miniport que se relaciona a um adaptador de miniporto, o NDIS passa o contexto do adaptador de miniporto para identificar o adaptador de miniporto correto para o driver. O contexto do adaptador de miniporta pertence e é mantido pelo driver de miniporta e é opaco para o NDIS e para drivers de protocolo.

Como o contexto do adaptador de miniporta mantém o estado do driver de miniporto entre chamadas NDIS, o Verificador de Driver Estático (SDV) deve ser capaz de identificar o ponteiro para essa estrutura. Para habilitar o SDV para acompanhar o estado do driver de miniporta, você deve salvar o identificador no contexto do adaptador de miniporta usando a função __sdv_save_adapter_context .

A função __sdv_save_adapter_context tem a seguinte sintaxe:

__sdv_save_adapter_context( &adapter_context ) 

Em que adapter_context é o identificador para o contexto do adaptador de miniporta definido pelo driver de miniporta. Essa função deve ser chamada apenas uma vez no contexto de um driver de miniporta.

A função __sdv_save_adapter_context é usada apenas pelas ferramentas de análise estática. Essa função é ignorada pelo compilador.

O exemplo de código a seguir mostra quando chamar __sdv_save_adapter_context e como o SDV acompanhará as informações no contexto do adaptador de miniporta.

O exemplo de código a seguir mostra uma versão simplificada da estrutura de exemplo de contexto do adaptador de miniport, MP_Adapter.

typedef struct _MP_ADAPTER
{
    NDIS_HANDLE             AdapterHandle;

    BOOLEAN                 InterruptRegistered;
    NDIS_HANDLE             InterruptHandle;

    /* ..................... */

} MP_ADAPTER, *PMP_ADAPTER;

Durante a execução de MiniportInitializeEx, a memória da estrutura MP_ADAPER é alocada. Imediatamente após a alocação de memória, __sdv_save_adapter_context é chamado.

Você deve chamar a função __sdv_save_adapter_context assim que tiver um ponteiro válido para a estrutura de contexto do adaptador de miniport.

NDIS_STATUS 
MPInitialize(
    IN  NDIS_HANDLE                        MiniportAdapterHandle,
    IN  NDIS_HANDLE                        MiniportDriverContext,
    IN  PNDIS_MINIPORT_INIT_PARAMETERS     MiniportInitParameters
    )
{
    NDIS_STATUS     Status = NDIS_STATUS_SUCCESS;
    PMP_ADAPTER     pAdapter = NULL;
 
    /* ..................... */
 
    do
    {
   // allocate the memory for the AdapterContext
        pAdapter = NdisAllocateMemoryWithTagPriority(
            MiniportAdapterHandle,
            sizeof(MP_ADAPTER),
            NIC_TAG,
            LowPoolPriority
            );

   // save the adapter context, even before we check whether it is NULL or not 
 __sdv_save_adapter_context(&pAdapter);

        if (pAdapter == NULL)
        {
            Status = NDIS_STATUS_RESOURCES;
            break;
        }
 
        NdisZeroMemory(pAdapter, sizeof(MP_ADAPTER));
 
        pAdapter->AdapterHandle = MiniportAdapterHandle;
        pAdapter->PauseState = NicPaused;

   /* ..................... */

O exemplo de código a seguir mostra como o SDV rastreia valores no contexto do adaptador de miniport. Neste exemplo, o driver registra uma interrupção chamando a função fornecida por miniport, MpRegisterInterrupt. Se a chamada for bem-sucedida, o driver salvará os resultados no campo contexto do adaptador de miniporta (pAdapter), InterruptRegistered.

//
// Register the interrupt
   //
        Status = MpRegisterInterrupt(pAdapter);
        if (Status != NDIS_STATUS_SUCCESS)
        {
            break;
        }
 
   // save the value of the result into the AdapterContext
        pAdapter->InterruptRegistered = TRUE;

Quando o driver de miniporto precisa ser interrompido, o NDIS chama a função MiniportHaltEx do driver passando o identificador para o contexto do adaptador de miniporto. Como o SDV também tem esse identificador, da chamada anterior para __sdv_save_adapter_context, o SDV pode acompanhar o valor do campo InterruptRegistered.

VOID MPHalt(
    IN  NDIS_HANDLE             MiniportAdapterContext,
    IN  NDIS_HALT_ACTION        HaltAction
    )
{
    PMP_ADAPTER     pAdapter = (PMP_ADAPTER) MiniportAdapterContext;
 
    /* ..................... */

    if (pAdapter->InterruptRegistered)
    {
        NdisMDeregisterInterruptEx(pAdapter->InterruptHandle);
        pAdapter->InterruptRegistered = FALSE;
    }

/* ..................... */