Freigeben über


Verwenden von __sdv_save_adapter_context zum Nachverfolgen von Adapterkontextfeldern

Wenn NDIS die Rückruffunktion MiniportInitializeEx eines Miniporttreibers aufruft, um einen Miniportadapter zu initialisieren, erstellt der Treiber eine eigene interne Datenstruktur, um den Miniportadapter darzustellen. Der Treiber verwendet diese Struktur, die als Miniportadapterkontext bezeichnet wird, um gerätespezifische Zustandsinformationen beizubehalten, die der Treiber zum Verwalten des Miniportadapters benötigt. Der Treiber übergibt ein Handle an diese Struktur an NDIS.

Wenn NDIS eine der MiniportXxx-Funktionen des Miniporttreibers aufruft, die sich auf einen Miniportadapter bezieht, übergibt NDIS den Kontext des Miniportadapters, um den richtigen Miniportadapter an den Treiber zu identifizieren. Der Miniportadapterkontext gehört und wird vom Miniporttreiber verwaltet und ist für NDIS und Protokolltreiber undurchsichtig.

Da der Miniportadapterkontext den Zustand des Miniporttreibers zwischen NDIS-Aufrufen beibehält, muss der Static Driver Verifier (SDV) in der Lage sein, den Zeiger auf diese Struktur zu identifizieren. Damit SDV den Status des Miniporttreibers nachverfolgen kann, müssen Sie das Handle mithilfe der funktion __sdv_save_adapter_context im Kontext des Miniportadapters speichern.

Die __sdv_save_adapter_context-Funktion weist die folgende Syntax auf:

__sdv_save_adapter_context( &adapter_context ) 

Wobei adapter_context das Handle für den Miniportadapterkontext ist, der vom Miniporttreiber definiert wird. Diese Funktion sollte nur einmal im Kontext eines Miniporttreibers aufgerufen werden.

Die __sdv_save_adapter_context-Funktion wird nur von den statischen Analysetools verwendet. Diese Funktion wird vom Compiler ignoriert.

Das folgende Codebeispiel zeigt, wann __sdv_save_adapter_context aufgerufen werden soll und wie SDV die Informationen im Miniportadapterkontext nachverfolgt.

Das folgende Codebeispiel zeigt eine vereinfachte Version der Beispielstruktur des Miniportadapterkontexts, MP_Adapter.

typedef struct _MP_ADAPTER
{
    NDIS_HANDLE             AdapterHandle;

    BOOLEAN                 InterruptRegistered;
    NDIS_HANDLE             InterruptHandle;

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

} MP_ADAPTER, *PMP_ADAPTER;

Während der Ausführung von MiniportInitializeEx wird der Arbeitsspeicher für die MP_ADAPER Struktur zugewiesen. Unmittelbar nach der Speicherzuordnung wird __sdv_save_adapter_context aufgerufen.

Sie müssen die __sdv_save_adapter_context-Funktion aufrufen, sobald Sie über einen gültigen Zeiger auf die Kontextstruktur des Miniportadapters verfügen.

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;

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

Das folgende Codebeispiel zeigt, wie SDV Werte im Miniportadapterkontext nachverfolgt. In diesem Beispiel registriert der Treiber einen Interrupt, indem er die miniport-bereitgestellte Funktion MpRegisterInterrupt aufruft. Wenn der Aufruf erfolgreich ist, speichert der Treiber die Ergebnisse im Feld InterruptRegistered (Miniport Adapter Context, pAdapter).

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

Wenn der Miniporttreiber angehalten werden muss, ruft NDIS die MiniportHaltEx-Funktion des Treibers auf, indem das Handle an den Miniportadapterkontext übergeben wird. Da SDV auch über dieses Handle verfügt, kann SDV vom vorherigen Aufruf an __sdv_save_adapter_context den Wert des InterruptRegistered-Felds nachverfolgen.

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;
    }

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