Udostępnij przez


Śledzenie pól kontekstowych adaptera za pomocą funkcji __sdv_save_adapter_context

Gdy NDIS wywołuje funkcję zwrotną sterownika MiniportInitializeEx w celu zainicjowania adaptera miniportu, sterownik tworzy własną wewnętrzną strukturę danych do reprezentowania tego adaptera miniportu. Sterownik używa tej struktury, znanej jako kontekst karty miniportu, do obsługi informacji o stanie specyficznym dla urządzenia, których potrzebuje sterownik w celu zarządzania kartą miniportu. Sterownik przekazuje uchwyt do tej struktury do NDIS.

Gdy NDIS wywołuje jedną z funkcji sterownika MiniportXxx, która odnosi się do karty miniportu, NDIS przekazuje kontekst karty miniportu, aby zidentyfikować poprawną kartę miniportu. Kontekst adaptera miniportu jest własnością sterownika miniportu i jest niedostępny dla NDIS i sterowników protokołów.

Ponieważ kontekst adaptera miniportu utrzymuje stan sterownika miniportu między wywołaniami NDIS, Static Driver Verifier (SDV) musi być w stanie rozpoznać wskaźnik do tej struktury. Aby umożliwić SDV śledzenie stanu sterownika miniportu, należy zapisać uchwyt do kontekstu adaptera miniportu przy użyciu funkcji __sdv_save_adapter_context.

Funkcja __sdv_save_adapter_context ma następującą składnię:

__sdv_save_adapter_context( &adapter_context ) 

Gdzie adapter_context jest uchwytem do kontekstu karty miniport, który jest zdefiniowany przez sterownik miniportu. Ta funkcja powinna być wywoływana tylko raz w kontekście sterownika miniportu.

Funkcja __sdv_save_adapter_context jest używana tylko przez narzędzia do analizy statycznej. Ta funkcja jest ignorowana przez kompilator.

Poniższy przykład kodu pokazuje, kiedy wywołać __sdv_save_adapter_context i jak SDV będzie śledzić informacje w kontekście karty miniportu.

Poniższy przykład kodu przedstawia uproszczoną wersję przykładowej struktury kontekstu miniportu adaptera MP_Adapter.

typedef struct _MP_ADAPTER
{
    NDIS_HANDLE             AdapterHandle;

    BOOLEAN                 InterruptRegistered;
    NDIS_HANDLE             InterruptHandle;

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

} MP_ADAPTER, *PMP_ADAPTER;

Podczas wykonywania funkcji MiniportInitializeEx jest przydzielana pamięć dla struktury MP_ADAPER. Natychmiast po alokacji pamięci wywoływana jest __sdv_save_adapter_context .

Należy wywołać funkcję __sdv_save_adapter_context gdy tylko masz prawidłowy wskaźnik do struktury kontekstu adaptera 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;

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

Poniższy przykład kodu pokazuje, jak SDV śledzi wartości w kontekście adaptera miniportu. W tym przykładzie sterownik rejestruje przerwanie przez wywołanie funkcji udostępnionej przez miniport, MpRegisterInterrupt. Jeśli wywołanie zakończy się pomyślnie, sterownik zapisze wyniki w polu kontekstu adaptera miniportu (pAdapter), nazwanym 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;

Gdy sterownik miniportu musi zostać zatrzymany, NDIS wywołuje funkcję MiniportHaltEx, przekazując uchwyt do kontekstu adaptera miniportu. Ponieważ sdV ma również to dojście, z wcześniejszego wywołania do __sdv_save_adapter_context, SDV może śledzić wartość pola 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;
    }

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