Изменение свойств фильтра BDA
Так как несколько экземпляров приложения, которое просматривает трансляции мультимедиа, могут работать одновременно в системе, следует написать мини-диск BDA для размещения нескольких экземпляров фильтра. Каждый экземпляр фильтра может содержать разные сведения. Например, один экземпляр фильтра тюнера может содержать запрос на настройку канала 5, а другой — запрос на настройку канала 8. При переходе элемента управления из одного экземпляра в другой мини-диск BDA должен указать базовому устройству настройки изменить способ настройки ресурсов. Мини-диск BDA обрабатывает запросы методов из набора методов KSMETHODSETID_BdaChangeSync для координации списка запросов свойств в одном экземпляре фильтра мини-драйвера.
Основная цель набора методов KSMETHODSETID_BdaChangeSync заключается в предоставлении точек триггера, в которых базовый мини-диск для фильтра может получать и освобождать ресурсы из объекта устройства мини-накопителя. Мини-диск должен координировать эти точки триггера с переходом фильтра в остановленное состояние и из нее. Например, если фильтр находится в остановленном состоянии, мини-driver должен назначать новые ресурсы фильтру, но не получать эти ресурсы всякий раз, когда поставщик сети указывает для фиксации изменений топологии BDA. При последующем переходе фильтра из остановленного состояния мини-диск должен попытаться получить эти ресурсы с базового устройства.
С другой стороны, если фильтр уже активен, мини-driver должен пытаться получить новые ресурсы с базового устройства, когда поставщик сети указывает для фиксации изменений топологии BDA. В любой момент времени может быть активен только один экземпляр фильтра в состоянии выполнения и в котором содержатся одни и те же ресурсы. При переходе фильтра в остановленное состояние он должен освободить все свои ресурсы, включая ресурсы, выделенные для любого из его контактов, чтобы ресурсы были доступны другому графу фильтров, который переходит в запущенное состояние.
Как правило, объект фильтра мини-драйвера BDA перехватывает и предоставляет методы для методов набора KSMETHODSETID_BdaChangeSync методов. Например, мини-диск предоставляет методы для запуска, проверки и фиксации изменений фильтра, а также для получения состояния изменения фильтра. Кроме того, следующие методы, предоставляемые мини-накопителем, должны вызывать соответствующие функции библиотеки поддержки BDA для синхронизации изменений в структурах, которые мини-диск ранее зарегистрировал в библиотеке поддержки 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
)
};
В следующем фрагменте кода показано, как внутренний метод start-changes в мини-накопителе BDA сбрасывает ожидающие изменения ресурсов после вызова мини-драйвера функции поддержки 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;
}