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