Mengubah Properti Filter BDA

Karena beberapa instans aplikasi yang melihat siaran media dapat berjalan secara bersamaan pada sistem, Anda harus menulis minidriver BDA untuk mengakomodasi beberapa instans filter. Setiap instans filter dapat berisi informasi yang berbeda. Misalnya, satu instans filter penyetel dapat berisi permintaan untuk menyetel ke saluran 5, sementara instans lain dapat berisi permintaan untuk menyetel ke saluran 8. Saat transisi kontrol dari satu instans ke instans lainnya, minidriver BDA harus menginstruksikan perangkat penyetelan yang mendasar untuk mengubah cara sumber daya dikonfigurasi. Minidriver BDA memproses permintaan metode dari metode KSMETHODSETID_BdaChangeSync yang diatur untuk mengoordinasikan daftar permintaan properti pada satu instans filter minidriver.

Tujuan utama dari set metode KSMETHODSETID_BdaChangeSync adalah untuk menyediakan titik pemicu di mana minidriver yang mendasar untuk filter dapat memperoleh dan melepaskan sumber daya dari objek perangkat minidriver. Minidriver harus mengoordinasikan titik pemicu ini dengan transisi filter ke dan dari status berhenti. Misalnya, jika filter dalam status berhenti, minidriver harus menetapkan sumber daya baru ke filter tetapi tidak memperoleh sumber daya tersebut setiap kali penyedia jaringan menentukan untuk melakukan perubahan topologi BDA. Ketika filter kemudian beralih keluar dari status berhentinya, minidriver kemudian harus mencoba memperoleh sumber daya tersebut dari perangkat yang mendasar.

Di sisi lain, jika filter sudah aktif, minidriver harus mencoba memperoleh sumber daya baru dari perangkat yang mendasar setiap kali penyedia jaringan menentukan untuk melakukan perubahan topologi BDA. Hanya satu instans filter yang dapat aktif--dalam status berjalan dan menyimpan sumber daya yang sama--pada waktu tertentu. Ketika filter beralih ke status berhenti, filter harus melepaskan semua sumber dayanya, termasuk sumber daya yang dialokasikan untuk salah satu pin-nya, sehingga sumber daya tersedia untuk grafik filter lain yang beralih ke status berjalan.

Biasanya, objek filter BDA minidriver mencegat dan memasok metode untuk metode set metode KSMETHODSETID_BdaChangeSync. Misalnya, minidriver menyediakan metode untuk memulai, memeriksa, dan menerapkan perubahan filter dan untuk mendapatkan status perubahan filter. Selain itu, metode yang disediakan minidriver berikut harus memanggil fungsi pustaka dukungan BDA yang sesuai untuk menyinkronkan perubahan pada struktur yang sebelumnya didaftarkan minidriver ke pustaka dukungan BDA:

Cuplikan kode berikut menunjukkan cara mencegat permintaan metode dari set metode KSMETHODSETID_BdaChangeSync menggunakan metode internal:

//
//  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
        )
};

Cuplikan kode berikut menunjukkan bagaimana metode start-changes internal dalam minidriver BDA mengatur ulang perubahan sumber daya yang tertunda setelah minidriver memanggil fungsi dukungan BdaStartChanges untuk memulai pengaturan perubahan topologi BDA baru:

//
// 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;
}