由於檢視媒體廣播的應用程式有多個實例可以在系統上同時執行,因此您應該撰寫 BDA 迷你驅動程式以容納篩選的多個實例。 每個篩選實例都可以包含不同的資訊。 例如,微調器篩選條件的一個實例可以包含微調至通道 5 的要求,而另一個實例可以包含微調至通道 8 的要求。 當控件從某個實例轉換到另一個實例時,BDA 迷你驅動程式必須指示基礎微調裝置變更資源設定的方式。 BDA 迷你驅動程式會處理 KSMETHODSETID_BdaChangeSync 方法集的方法請求,以協調其中一個迷你驅動程式的篩選器實例上的屬性請求清單。
KSMETHODSETID_BdaChangeSync方法集的主要目的是提供觸發點,讓篩選的基礎迷你驅動程式可以從minidriver的裝置物件取得和釋放資源。 minidriver 必須協調這些觸發點與篩選器在進入和退出停止狀態時的轉換。 例如,如果濾波器處於停止狀態,微型驅動程式應將新資源指派給濾波器,但在網路供應商指定進行 BDA 拓撲變更時,並不需要取得這些資源。 當過濾器從停止狀態轉換出來時,minidriver 然後應該嘗試從基礎裝置取得這些資源。
另一方面,如果篩選器已作用中,迷你驅動程序應該會在網路提供者指定認可 BDA 拓撲變更時,嘗試從基礎裝置取得新的資源。 篩選器的實例在任何時間只能有一個處於運行中狀態,同時占用相同的資源。 當過濾器轉換為停止狀態時,必須釋放其所有資源,包括配置給任何接腳的資源,以便這些資源可供另一個過濾器圖形轉換至執行狀態時使用。
一般而言,BDA 迷你驅動程式的篩檢程式物件會攔截並為 KSMETHODSETID_BdaChangeSync 方法集的方法提供方法。 例如,小型驅動程式提供啟動、檢查和認可濾波器變更的方法,以及取得濾波器變更狀態的方法。 此外,下列 minidriver 提供的方法應該呼叫對應的 BDA 支援連結庫函式,以同步處理先前向 BDA 支援連結庫註冊的 minidriver 結構變更:
Start-changes 方法會呼叫 BdaStartChanges 函式。
Check-changes 方法會呼叫 BdaCheckChanges 函式。
認可變更方法會呼叫 BdaCommitChanges 函式。
Get-changed-state 方法會呼叫 BdaGetChangeState 函式。
下列代碼段示範如何使用內部方法攔截KSMETHODSETID_BdaChangeSync方法集的方法要求:
//
// BDA Change Sync Method Set
//
// Defines the dispatch routines for the filter level
// Change Sync methods
//
DEFINE_KSMETHOD_TABLE(BdaChangeSyncMethods)
{
DEFINE_KSMETHOD_ITEM_BDA_START_CHANGES(
CFilter::StartChanges,
NULL
),
DEFINE_KSMETHOD_ITEM_BDA_CHECK_CHANGES(
CFilter::CheckChanges,
NULL
),
DEFINE_KSMETHOD_ITEM_BDA_COMMIT_CHANGES(
CFilter::CommitChanges,
NULL
),
DEFINE_KSMETHOD_ITEM_BDA_GET_CHANGE_STATE(
CFilter::GetChangeState,
NULL
)
};
下列代碼段示範在 Minidriver 呼叫 BdaStartChanges 支援函式以起始新 BDA 拓撲變更設定之後,BDA 迷你驅動程式中的內部啟動變更方法如何重設暫止的資源變更:
//
// StartChanges ()
//
// Puts the filter into change state. All changes to BDA topology
// and properties changed after this will be in effect only after
// CommitChanges.
//
NTSTATUS
CFilter::
StartChanges(
IN PIRP pIrp,
IN PKSMETHOD pKSMethod,
OPTIONAL PVOID pvIgnored
)
{
NTSTATUS Status = STATUS_SUCCESS;
CFilter * pFilter;
ASSERT( pIrp);
ASSERT( pKSMethod);
// Obtain a "this" pointer for the method.
//
// Because this function is called directly from the property
// dispatch table, must get pointer to the underlying object.
//
pFilter = FilterFromIRP( pIrp);
ASSERT( pFilter);
if (!pFilter)
{
Status = STATUS_INVALID_PARAMETER;
goto errExit;
}
// Reset any pending BDA topology changes.
//
Status = BdaStartChanges( pIrp);
if (!NT_SUCCESS( Status))
{
goto errExit;
}
// Reset any pending resource changes.
//
pFilter->m_NewTunerResource = pFilter->m_CurTunerResource;
pFilter->m_BdaChangeState = BDA_CHANGES_COMPLETE;
errExit:
return Status;
}