Poznámka:
Přístup k této stránce vyžaduje autorizaci. Můžete se zkusit přihlásit nebo změnit adresáře.
Přístup k této stránce vyžaduje autorizaci. Můžete zkusit změnit adresáře.
Ovladače můžou definovat rozhraní specifická pro zařízení, ke kterým mají přístup ostatní ovladače. Tato rozhraní definovaná ovladači se můžou skládat ze sady volatelných rutin, sady datových struktur nebo obojího. Ovladač obvykle poskytuje ukazatele na tyto rutiny a struktury v struktuře rozhraní definované ovladačem, které ovladač zpřístupní ostatním ovladačům.
Například sběrnicový ovladač může poskytnout jednu nebo více rutin, které mohou ovladače vyšší úrovně volat, aby získaly informace o podřízeném zařízení, pokud tyto informace nejsou dostupné v seznamu prostředků podřízeného zařízení.
Příklad sady rozhraní definovaných ovladačem, které jsou zdokumentované v WDK, viz USB Rutiny. Viz také verzi toustovače na bázi frameworku.
Vytvoření rozhraní
Každé rozhraní definované řidičem je specifikováno:
Identifikátor GUID
Číslo verze
Struktura rozhraní definovaná ovladačem
Referenční a dereferenční rutiny
Pokud chcete vytvořit rozhraní a zpřístupnit ho jiným ovladačům, můžou ovladače založené na rozhraní použít následující kroky:
Definujte strukturu rozhraní.
Prvním členem této strukturou definované ovladačem musí být hlavičková struktura INTERFACE. Další členy mohou zahrnovat data rozhraní a ukazatele na další struktury nebo rutiny, které může volat jiný ovladač.
Ovladač musí obsahovat WDF_QUERY_INTERFACE_CONFIG strukturu, která popisuje vámi definované rozhraní.
Poznámka:
Při použití WDF_QUERY_INTERFACE_CONFIGWDF nepodporuje více verzí jednoho rozhraní, které používají stejný identifikátor GUID rozhraní.
V důsledku toho doporučujeme při zavádění nové verze existujícího rozhraní vytvořit nový GUID (globálně jedinečný identifikátor), místo aby byla revidována pole Velikost nebo Verze ve struktuře INTERFACE.
Pokud váš ovladač znovu používá stejný identifikátor GUID rozhraní se změněnými poli Velikost nebo Verze, ovladač by neměl poskytovat WDF_QUERY_INTERFACE_CONFIG, ale místo toho by měl poskytnout zpětnou volací rutinu EvtDeviceWdmIrpPreprocess pro IRP_MN_QUERY_INTERFACE.
Volání WdfDeviceAddQueryInterface .
Metoda WdfDeviceAddQueryInterface provede následující:
- Ukládá informace o rozhraní, například identifikátor GUID, číslo verze a velikost struktury, aby architektura rozpoznala požadavek jiného ovladače na rozhraní.
- Zaregistruje volitelnou EvtDeviceProcessQueryInterfaceRequest funkci zpětného volání událostí, kterou rozhraní volá, když jiný ovladač požádá o rozhraní.
Každá instance rozhraní definovaného ovladačem je přiřazena ke konkrétnímu zařízení, takže ovladače obvykle volají WdfDeviceAddQueryInterface z EvtDriverDeviceAdd nebo EvtChildListCreateDevice zpětné volací funkce.
Přístup k rozhraní
Pokud ovladač definoval rozhraní, může jiný ovladač založený na rozhraní požádat o přístup k rozhraní voláním WdfFdoQueryForInterface a předáním identifikátoru GUID, čísla verze, ukazatele na strukturu a velikosti struktury. Rámec vytvoří požadavek na vstup/výstup a odešle ho na začátek zásobníku ovladačů.
Ovladač obvykle volá WdfFdoQueryForInterface ve EvtDriverDeviceAdd funkci zpětného volání. Pokud ovladač musí uvolnit rozhraní, když není zařízení v provozním stavu, může volat WdfFdoQueryForInterface v rámci EvtDevicePrepareHardware funkce zpětného volání a volat dereference rutinu rozhraní v rámci EvtDeviceReleaseHardware funkce zpětného volání.
Pokud ovladač A požádá ovladač B o rozhraní, které ovladač B definoval, architektura zpracovává požadavek na ovladač B. Architektura ověřuje, že identifikátor GUID a verze představují podporované rozhraní a že velikost struktury, kterou ovladač A zadal, je dostatečně velká pro uložení rozhraní.
Když ovladač zavolá WdfFdoQueryForInterface, vstupně-výstupní požadavek, který framework vytvoří, se přesune až na dno zásobníku ovladačů. Pokud se jednoduchý zásobník ovladačů skládá ze tří ovladačů – A, B a C – a pokud ovladač A žádá o rozhraní, může rozhraní podporovat ovladač B i ovladač C. Například ovladač B může před předáním požadavku na ovladač C vyplnit strukturu rozhraní ovladače A. Ovladač C může poskytnout EvtDeviceProcessQueryInterfaceRequest funkci zpětného volání, která zkoumá obsah struktury rozhraní a případně je upravuje.
Pokud ovladač A potřebuje získat přístup k rozhraní ovladače B a ovladač B je vzdálený vstupně-výstupní cíl (tj. ovladač, který je v jiném zásobníku ovladačů), ovladač A musí volat WdfIoTargetQueryForInterface místo WdfFdoQueryForInterface.
Použití komunikace One-Way nebo Two-Way
Můžete definovat rozhraní, které poskytuje jednosměrnou komunikaci nebo jednocestnou komunikaci. Chcete-li určit obousměrnou komunikaci, ovladač nastaví ImportInterface jako člena struktury WDF_QUERY_INTERFACE_CONFIG na hodnotu TRUE.
Pokud rozhraní poskytuje jednosměrnou komunikaci a pokud ovladač A požádá o rozhraní ovladače B, data rozhraní proudí pouze z ovladače B na ovladač A. Když rozhraní obdrží požadavek A ovladače na rozhraní, které podporuje jednosměrnou komunikaci, architektura zkopíruje hodnoty rozhraní definované ovladačem do struktury rozhraní ovladače A. Pak volá funkci zpětného volání EvtDeviceProcessQueryInterfaceRequest ovladače B, pokud existuje, aby mohla prozkoumat a případně upravit hodnoty rozhraní.
Pokud rozhraní poskytuje obousměrnou komunikaci, struktura rozhraní obsahuje některé členy, které ovladač A vyplní před odesláním požadavku na ovladač B. Ovladač B může přečíst hodnoty parametrů, které ovladač A poskytl, a na základě těchto hodnot určit, které informace mají ovladačI A poskytnout. Když architektura obdrží požadavek A ovladače pro rozhraní, které podporuje obousměrnou komunikaci, volá rozhraní ovladač B EvtDeviceProcessQueryInterfaceRequest funkce zpětného volání, aby mohl zkoumat přijaté hodnoty a poskytovat výstupní hodnoty. Pro obousměrnou komunikaci je vyžadována funkce zpětného volání, protože architektura nekopíruje žádné hodnoty rozhraní do struktury rozhraní ovladače A.
Údržba referenčního počtu
Každé rozhraní musí obsahovat referenční funkci a funkci dereference, která zvýší a sníží počet odkazů pro rozhraní. Ovladač, který definuje rozhraní, určuje adresy těchto funkcí v INTERFACE struktuře.
Když ovladač A požádá ovladač B o rozhraní, architektura volá referenční funkci rozhraní před zpřístupněním rozhraní pro ovladač A. Když ovladač A dokončí použití rozhraní, musí volat funkci dereference rozhraní.
Referenční funkce a funkce dereference pro většinu rozhraní mohou být no-op funkce, které nedělají nic. Rámec poskytuje funkce pro počet odkazů no-op, WdfDeviceInterfaceReferenceNoOp a WdfDeviceInterfaceDereferenceNoOp, které může většina ovladačů používat.
Jediná situace, kdy ovladače musí sledovat referenční počet rozhraní a poskytovat skutečné funkce pro referenci a dereferenci, nastává, když ovladač A požaduje rozhraní z externího I/O cíle (tj. ovladač, který je v jiném ovladačovém zásobníku). V tomto případě musí ovladač B (v jiném zásobníku) implementovat referenční počet, aby jeho zařízení nemohlo být odebráno, zatímco ovladač A používá rozhraní ovladače B.
Pokud navrhujete ovladač B, který definuje rozhraní, musíte se rozhodnout, jestli bude rozhraní ovladače přístupné z jiného zásobníku ovladačů. (Ovladač B nemůže určit, zda je požadavek na jeho rozhraní z místního zásobníku ovladačů nebo ze vzdáleného zásobníku.) Pokud ovladač bude podporovat požadavky rozhraní ze vzdáleného zásobníku, musí ovladač implementovat referenční počet.
Pokud navrhujete ovladač A, který přistupuje k rozhraní na vzdáleném V/V cíli, musí ovladač poskytnout EvtIoTargetQueryRemove funkci zpětného volání, která uvolní rozhraní, když se zařízení ovladače B chystá odebrat, EvtIoTargetRemoveComplete funkci zpětného volání, která uvolní rozhraní při nečekaném odstranění zařízení ovladače B, a EvtIoTargetRemoveCanceled funkci zpětného volání, která znovu získá rozhraní, pokud došlo k zrušení pokusu o odebrání zařízení.