共用方式為


使用__sdv_save_adapter_context追蹤轉接器上下文欄位

當 NDIS 呼叫迷你埠驅動程式的 MiniportInitializeEx 回呼函式來初始化迷你埠配接器時,驅動程式會建立自己的內部數據結構來代表迷你埠配接器。 驅動程式會使用此結構,稱為 迷你埠配接器內容,維護驅動程式為了管理迷你埠配接器所需的裝置特定狀態資訊。 驅動程式會將句柄傳遞至此結構體給 NDIS。

當 NDIS 呼叫與迷你埠配接器相關的其中一個迷你埠驅動程式 MiniportXxx 函式時,NDIS 會將迷你埠配接器內容傳遞給驅動程式,以識別正確的迷你埠適配卡。 迷你埠配接器內容是由迷你埠驅動程式所擁有和維護,對 NDIS 和通訊協定驅動程式來說是無法理解的。

由於迷你埠配接器內容會維護 NDIS 呼叫之間的迷你埠驅動程式狀態,靜態驅動程序驗證器 (SDV) 必須能夠識別這個結構的指標。 若要讓 SDV 追蹤迷你埠驅動程式的狀態,您必須使用 __sdv_save_adapter_context 函式,將句柄儲存至迷你埠配接器內容。

__sdv_save_adapter_context函式具有下列語法:

__sdv_save_adapter_context( &adapter_context ) 

其中 adapter_context 是迷你埠驅動程式所定義的迷你埠配接器上下文的控制代碼。 此函式應該只在迷你埠驅動程序的內容中呼叫一次。

__sdv_save_adapter_context函式只能由靜態分析工具使用。 編譯程式會忽略此函式。

下列程式代碼範例示範何時呼叫 __sdv_save_adapter_context,以及 SDV 如何追蹤 迷你埠配接器內容中的資訊。

下列程式代碼範例示範小型埠配接器內容範例結構的簡化版本,MP_Adapter。

typedef struct _MP_ADAPTER
{
    NDIS_HANDLE             AdapterHandle;

    BOOLEAN                 InterruptRegistered;
    NDIS_HANDLE             InterruptHandle;

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

} MP_ADAPTER, *PMP_ADAPTER;

在執行 MiniportInitializeEx 期間,會配置MP_ADAPER結構的記憶體。 緊接在記憶體配置之後, 就會呼叫__sdv_save_adapter_context

當您有迷你埠配接器內容結構的有效指標時,必須立即呼叫 __sdv_save_adapter_context 函式。

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;

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

下列程式代碼範例示範 SDV 如何追蹤迷你埠配接器內容中的值。 在此範例中,驅動程式會呼叫 Miniport 提供的函式 MpRegisterInterrupt 來註冊中斷。 如果呼叫成功,驅動程式會將結果儲存至迷你埠配接器內容 (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;

當需要停止迷你埠驅動程式時,NDIS 會透過傳遞句柄給迷你埠配接器上下文,以調用驅動程式的 MiniportHaltEx 函式。 由於 SDV 也具有此句柄,因而從先前對__sdv_save_adapter_context的呼叫中,SDV 可以追蹤 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;
    }

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