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;
}
/* ..................... */