使用__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;
}
/* ..................... */