Compartir a través de


Uso de __sdv_save_adapter_context para realizar un seguimiento de los campos de contexto del adaptador

Cuando NDIS llama a la función de devolución de llamada MiniportInitializeEx de un controlador de miniporte para inicializar un adaptador de minipuerto, el controlador crea su propia estructura de datos interna para representar el adaptador de miniport. El controlador usa esta estructura, conocida como contexto del adaptador de minipuerto, para mantener información de estado específica del dispositivo que el controlador necesita para administrar el adaptador de minipuerto. El controlador pasa un identificador a esta estructura a NDIS.

Cuando NDIS llama a una de las funciones MiniportXxx del controlador de minipuerto relacionadas con un adaptador de miniporte, NDIS pasa el contexto del adaptador de minipuerto para identificar el adaptador de miniporte correcto al controlador. El contexto del adaptador de minipuerto es propiedad del controlador de minipuerto y es opaco para NDIS y para los controladores de protocolo.

Dado que el contexto del adaptador de minipuerto mantiene el estado del controlador de minipuerto entre llamadas NDIS, el comprobador de controladores estáticos (SDV) debe ser capaz de identificar el puntero a esta estructura. Para habilitar SDV para realizar un seguimiento del estado del controlador de minipuerto, debe guardar el identificador en el contexto del adaptador de miniporte mediante la función __sdv_save_adapter_context .

La función __sdv_save_adapter_context tiene la siguiente sintaxis:

__sdv_save_adapter_context( &adapter_context ) 

Donde adapter_context es el identificador del contexto del adaptador de miniporte definido por el controlador de minipuerto. Esta función debe llamarse solo una vez en el contexto de un controlador de minipuerto.

Las herramientas de análisis estáticos solo usan la función __sdv_save_adapter_context . El compilador omite esta función.

En el ejemplo de código siguiente se muestra cuándo llamar a __sdv_save_adapter_context y cómo SDV realizará un seguimiento de la información en el contexto del adaptador de minipuerto.

En el ejemplo de código siguiente se muestra una versión simplificada de la estructura de ejemplo de contexto del adaptador de miniporte, MP_Adapter.

typedef struct _MP_ADAPTER
{
    NDIS_HANDLE             AdapterHandle;

    BOOLEAN                 InterruptRegistered;
    NDIS_HANDLE             InterruptHandle;

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

} MP_ADAPTER, *PMP_ADAPTER;

Durante la ejecución de MiniportInitializeEx, se asigna la memoria de la estructura MP_ADAPER. Inmediatamente después de la asignación de memoria, se llama a __sdv_save_adapter_context .

Debe llamar a la función __sdv_save_adapter_context tan pronto como tenga un puntero válido a la estructura de contexto del adaptador de miniporte.

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;

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

En el ejemplo de código siguiente se muestra cómo SDV realiza un seguimiento de los valores en el contexto del adaptador de minipuerto. En este ejemplo, el controlador registra una interrupción mediante una llamada a la función proporcionada por miniporte, MpRegisterInterrupt. Si la llamada se realiza correctamente, el controlador guarda los resultados en el campo del contexto del adaptador de miniport (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;

Cuando se tiene que detener el controlador de minipuerto, NDIS llama a la función MiniportHaltEx del controlador pasando el controlador al contexto del adaptador de minipuerto. Dado que SDV también tiene este identificador, desde la llamada anterior a __sdv_save_adapter_context, SDV puede realizar un seguimiento del valor del 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;
    }

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