Eszközinterfészek (WDF) használata

A eszközfelület egy szimbolikus link a plug and play (PnP) eszközhöz, amelyet egy alkalmazás használhat az eszköz eléréséhez. A felhasználói módú alkalmazások átadhatják a felület szimbolikus hivatkozásnevét egy API-elemnek, például a Microsoft Win32 CreateFile függvénynek. Az eszközfelület szimbolikus hivatkozásnevének lekéréséhez a felhasználói módú alkalmazás meghívhatja a Configuration Manager-függvényeket vagy a SetupApi-függvényeket. További információ: Telepített eszközillesztők számbavétele.

Minden eszköz interfész egy eszköz interfész osztályhoz tartozik. Előfordulhat például, hogy egy CD-ROM eszköz illesztőprogram-verme olyan felületet biztosít, amely a GUID_DEVINTERFACE_CDROM osztályhoz tartozik. Az CD-ROM eszköz egyik illesztőprogramja regisztrálná a GUID_DEVINTERFACE_CDROM osztály egy példányát, hogy tájékoztassa a rendszert és az alkalmazásokat arról, hogy elérhető egy CD-ROM eszköz. Az eszközillesztő-osztályokról további információt az Eszközillesztőosztályok áttekintése című témakörben talál.

Eszközfelület regisztrálása

Az eszközillesztő-osztály egy példányának regisztrálásához a keretrendszer-alapú illesztőprogram meghívhatja a WdfDeviceCreateDeviceInterface-t az eszköz indítása előtt vagy után. Ha az illesztő a felület több példányát is támogatja, minden példányhoz hozzárendelhet egy egyedi hivatkozási sztringet.

Miután az illesztőprogram regisztrált egy eszközfelületet, az illesztőprogram meghívhatja a WdfDeviceRetrieveDeviceInterfaceString függvényt, hogy megszerezze a rendszer által az eszközfelülethez rendelt szimbolikus hivatkozásnevet.

Az illesztőprogramok eszközinterfészek regisztrálásának egyéb módjairól további információt az Eszközillesztő-osztály regisztrálása című témakörben talál.

Eszközillesztő engedélyezése és letiltása

Az eszköz indítása előtt létrehozott interfészeket (például EvtDriverDeviceAdd, EvtChildListCreateDevice vagy EvtDevicePrepareHardware) a keretrendszer automatikusan engedélyezi, amikor az eszköz pnP-számbavételen megy keresztül és elindul. Ha meg szeretné akadályozni, hogy az interfész automatikusan engedélyezve legyen a PnP indítása során, hívja meg a WdfDeviceSetDeviceInterfaceStateEx függvényt ugyanabból a visszahívási függvényből (állítsa az EnableInterface paramétert FALSE értékre) az adott interfészhez a PnP indítása előtt.

Az eszköz elindítása után létrehozott felületek nem lesznek automatikusan engedélyezve. Az illesztőnek meg kell hívnia a WdfDeviceSetDeviceInterfaceState vagy WdfDeviceSetDeviceInterfaceStateEx parancsot az ilyen felületek engedélyezéséhez.

Minden illesztő automatikusan le lesz tiltva, amikor az eszköz PnP-eltávolításon megy keresztül. Vegye figyelembe, hogy az eszköz energiaállapotának módosítása vagy a PnP-erőforrás-újraegyensúlyozás nem változtatja meg a felület állapotát.

Egy illesztőprogram szükség esetén letilthatja és újra engedélyezheti az eszköz felületét. Ha például egy illesztőprogram azt állapítja meg, hogy az eszköz nem válaszol, az illesztőprogram meghívhatja a WdfDeviceSetDeviceInterfaceState vagy a WdfDeviceSetDeviceInterfaceStateEx parancsot , hogy letiltsa az eszköz interfészeit, és megtiltsa az alkalmazások számára, hogy új leírókat szerezzenek be a felületre. (A felület meglévő fogópontjait nem érinti.) Ha az eszköz később elérhetővé válik, az illesztőprogram újra meghívhatja a WdfDeviceSetDeviceInterfaceState-t vagy a WdfDeviceSetDeviceInterfaceStateEx-et , hogy újratelepítse az interfészeket.

Eszközfelület elérésére irányuló kérések fogadása

Amikor egy alkalmazás vagy kernel módú összetevő hozzáférést kér egy illesztőprogram eszközfelületéhez, a keretrendszer meghívja az illesztőprogram EvtDeviceFileCreate visszahívási függvényét. Az illesztőprogram meghívhatja a WdfFileObjectGetFileName függvényt, hogy megkapja annak az eszköznek vagy fájlnak a nevét, amelyhez az alkalmazás vagy a kernel módú összetevő hozzáfér. Ha az illesztőprogram referenciasztringet adott meg az eszközillesztő regisztrálásakor, az operációs rendszer tartalmazza a WdfFileObjectGetFileName által visszaadott fájl vagy eszköznév hivatkozási sztringjét.

Egy másik illesztőprogram eszközfelületének elérése

Ez a szakasz bemutatja, hogyan regisztrál egy Kernel-Mode Illesztőprogram-keretrendszer (KMDF) vagy egy User-Mode Illesztőprogram-keretrendszer (UMDF) 2- es verziójának illesztőprogramja egy másik illesztőprogram által biztosított eszközillesztő érkezéséről vagy eltávolításáról szóló értesítésre, majd létrehoz egy távoli I/O-célt az eszközfelület által képviselt eszközzel való kommunikációhoz.

A UMDF 1-es verziójú illesztőprogramjaival kapcsolatos további információkért lásd: Eszközillesztők alkalmazása UMDF-illesztőprogramokban.

Az eszközillesztő-események értesítésére való regisztrációhoz egy KMDF-illesztőprogram meghívja az IoRegisterPlugPlayNotification parancsot, míg egy UMDF 2-illesztőprogram CM_Register_Notification. Mindkét esetben az illesztőprogram meghívja a megfelelő rutint az EvtDriverDeviceAdd visszahívási függvényéből.

Az alábbi példakód bemutatja, hogyan regisztrál egy helyi UMDF 2-illesztő az értesítésekre, majd megnyitja a távoli I/O-célt.

  1. A távoli vezérlő az EvtDriverDeviceAdd függvényből a WdfDeviceCreateDeviceInterface meghívásával regisztrál egy eszközfelületre.

        UNICODE_STRING ref;
        RtlInitUnicodeString(&ref, MY_HID_FILTER_REFERENCE_STRING);
        status = WdfDeviceCreateDeviceInterface(
                     hDevice,
                     (LPGUID) &GUID_DEVINTERFACE_MY_HIDFILTER_DRIVER,
                     &ref // ReferenceString
                 );
    
        if (!NT_SUCCESS (status)) {
            MyKdPrint( ("WdfDeviceCreateDeviceInterface failed 0x%x\n", status));
            return status;
        }
    
    
  2. A helyi illesztőprogram meghívja a CM_Register_Notification-t a EvtDriverDeviceAdd-ből, hogy értesítésre regisztráljon, amikor elérhetővé válik egy eszköz felület. Adjon meg egy mutatót egy értesítési visszahívási rutinhoz, amelyet a keretrendszer hív meg, amikor elérhetőek az eszközillesztők.

    DWORD cmRet;
        CM_NOTIFY_FILTER cmFilter;
    
        ZeroMemory(&cmFilter, sizeof(cmFilter));
        cmFilter.cbSize = sizeof(cmFilter);
        cmFilter.FilterType = CM_NOTIFY_FILTER_TYPE_DEVICEINTERFACE;
        cmFilter.u.DeviceInterface.ClassGuid = GUID_DEVINTERFACE_MY_HIDFILTER_DRIVER;
    
        cmRet = CM_Register_Notification(
                    &cmFilter,                     // PCM_NOTIFY_FILTER pFilter,
                    (PVOID) hDevice,               // PVOID pContext,
                    MyCmInterfaceNotification,    // PCM_NOTIFY_CALLBACK pCallback,
                    &fdoData->CmNotificationHandle // PHCMNOTIFICATION pNotifyContext
                    );
        if (cmRet != CR_SUCCESS) {
            MyKdPrint( ("CM_Register_Notification failed, error %d\n", cmRet));
            status = STATUS_UNSUCCESSFUL;
            return status;
        }   
    
  3. A rendszer minden alkalommal meghívja a helyi illesztőprogram értesítési visszahívási rutinját, amikor a megadott eszközfelület megérkezik vagy el lesz távolítva. A visszahívási rutin megvizsgálhatja az EventData paramétert annak megállapításához, hogy melyik eszközillesztő érkezett. Ezután előfordulhat, hogy egy munkaelem várólistára kerül az eszköz felületének megnyitásához.

    DWORD 
    MyCmInterfaceNotification(
        _In_ HCMNOTIFICATION       hNotify,
        _In_opt_ PVOID             Context,
        _In_ CM_NOTIFY_ACTION      Action,
        _In_reads_bytes_(EventDataSize) PCM_NOTIFY_EVENT_DATA EventData,
        _In_ DWORD                 EventDataSize
        )
    {
        PFDO_DATA fdoData;
        UNICODE_STRING name;
        WDFDEVICE device;
        NTSTATUS status;
        WDFWORKITEM workitem;
    
        UNREFERENCED_PARAMETER(hNotify);
        UNREFERENCED_PARAMETER(EventDataSize);
    
        device = (WDFDEVICE) Context;
        fdoData = ToasterFdoGetData(device);
    
        switch(Action) {
        case CM_NOTIFY_ACTION_DEVICEINTERFACEARRIVAL: 
            MyKdPrint( ("MyCmInterfaceNotification: Arrival of %S\n",
                EventData->u.DeviceInterface.SymbolicLink));
    
            //
            // Enqueue a work item to open target
            //
    
            break;
        case CM_NOTIFY_ACTION_DEVICEINTERFACEREMOVAL: 
            MyKdPrint( ("MyCmInterfaceNotification: removal of %S\n",
                EventData->u.DeviceInterface.SymbolicLink));
            break;
        default:
            MyKdPrint( ("MyCmInterfaceNotification: Arrival unknown action\n"));
            break;
        }
    
        return 0;
    }
    
  4. A munkaelem visszahívási függvényéből a helyi illesztőprogram meghívja a WdfIoTargetCreate parancsot a távoli cél létrehozásához, a WdfIoTargetOpen pedig egy távoli I/O-cél megnyitásához.

    A WdfIoTargetOpen hívásakor az illesztőprogram opcionálisan regisztrál egy EvtIoTargetQueryRemove visszahívási függvényt az eltávolítási értesítés fogadásához, valamint az eltávolítás elutasításának lehetőségét. Ha az illesztőprogram nem adja meg az EvtIoTargetQueryRemove szolgáltatást, a keretrendszer bezárja az I/O-célt az eszköz eltávolításakor.

    Ritkán az UMDF 2 illesztőprogramja másodszor is meghívhat CM_Register_Notification , hogy regisztráljon az eszköz eltávolításáról szóló értesítésre. Ha például az illesztőprogram meghívja a CreateFile-t , hogy lekérjen egy HANDLE-t az eszköz felületére, regisztrálnia kell az eszköz eltávolításáról szóló értesítésre, hogy megfelelően reagálhasson a lekérdezés-eltávolítási kísérletekre. A legtöbb esetben az UMDF 2 illesztőprogram csak egyszer hív CM_Register_Notification , és az eszköz eltávolításához a WDF-támogatásra támaszkodik.

    VOID 
    EvtWorkItem(
        _In_ WDFWORKITEM WorkItem
    )
    {
        // 
        // create and open remote target
        //
    
        return;
    }
    

Regisztráció az eszköz felületének érkezéséről és eltávolításáról szóló értesítéshez