變更 BDA 篩選屬性
因為檢視媒體廣播的應用程式有多個實例可以同時在系統上執行,所以您應該撰寫 BDA 迷你驅動程式,以容納篩選的多個實例。 每個篩選實例都可以包含不同的資訊。 例如,微調器篩選準則的一個實例可以包含微調至通道 5 的要求,而另一個實例可以包含微調至通道 8 的要求。 當控制項從一個實例轉換成另一個實例時,BDA 迷你驅動程式必須指示基礎微調裝置變更資源設定的方式。 BDA minidriver 會處理 KSMETHODSETID_BdaChangeSync 方法設定的方法要求,以協調迷你驅動程式篩選實例上的屬性要求清單。
KSMETHODSETID_BdaChangeSync方法集的主要用途是提供觸發點,讓篩選的基礎迷你驅動程式可以從 minidriver 的裝置物件取得和釋放資源。 minidriver 必須協調這些觸發點,並搭配篩選準則的轉換和停止狀態。 例如,如果篩選處於已停止狀態,迷你驅動程式應該將新的資源指派給篩選,但每當網路提供者指定認可 BDA 拓撲變更時,不應該取得這些資源。 當篩選後續從其停止狀態轉換出時,迷你驅動程式應該接著嘗試從基礎裝置取得這些資源。
另一方面,如果篩選已作用中,迷你驅動程式應該每當網路提供者指定認可 BDA 拓撲變更時,嘗試從基礎裝置取得新的資源。 篩選準則只有一個實例可以處於作用中狀態,並在任何指定時間保留相同的資源。 當篩選轉換為已停止狀態時,它應該釋放其所有資源,包括配置給任何針腳的資源,讓資源可供另一個轉換至執行狀態的篩選圖形使用。
一般而言,BDA 迷你驅動程式的篩選物件會攔截並提供方法給KSMETHODSETID_BdaChangeSync方法集的方法。 例如,minidriver 提供啟動、檢查和認可篩選變更的方法,以及取得篩選準則的變更狀態。 此外,下列 minidriver 提供的方法應該呼叫對應的 BDA 支援程式庫函式,以同步處理 Minidriver 先前向 BDA 支援程式庫註冊之結構上的變更:
Start-changes 方法會呼叫 BdaStartChanges 函式。
Check-changes 方法會呼叫 BdaCheckChanges 函式。
Commit-changes 方法會呼叫 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
)
};
下列程式碼片段顯示 BDA minidriver 中的內部啟動變更方法如何在 minidriver 呼叫 BdaStartChanges 支援函式之後重設擱置的資源變更,以起始新 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;
}