Bagikan melalui


Menggunakan Antarmuka Perangkat (WDF)

Antarmuka perangkat adalah tautan simbolis ke perangkat Plug and Play (PnP) yang dapat digunakan aplikasi untuk mengakses perangkat. Aplikasi mode pengguna dapat meneruskan nama tautan simbolis antarmuka ke elemen API, seperti fungsi Microsoft Win32 CreateFile . Untuk mendapatkan nama tautan simbolis antarmuka perangkat, aplikasi mode pengguna dapat memanggil fungsi manajer konfigurasi atau fungsi SetupApi. Untuk informasi selengkapnya, lihat Menghitung antarmuka perangkat yang terinstal.

Setiap antarmuka perangkat termasuk dalam kelas antarmuka perangkat. Misalnya, tumpukan driver untuk perangkat CD-ROM mungkin menyediakan antarmuka milik kelas GUID_DEVINTERFACE_CDROM. Salah satu driver perangkat CD-ROM akan mendaftarkan instans kelas GUID_DEVINTERFACE_CDROM untuk memberi tahu sistem dan aplikasi bahwa perangkat CD-ROM tersedia. Untuk informasi selengkapnya tentang kelas antarmuka perangkat, lihat Gambaran Umum Kelas Antarmuka Perangkat.

Mendaftarkan Antarmuka Perangkat

Untuk mendaftarkan instans kelas antarmuka perangkat, driver berbasis kerangka kerja dapat memanggil WdfDeviceCreateDeviceInterface baik sebelum atau sesudah perangkat dimulai. Jika driver mendukung beberapa instans antarmuka, driver dapat menetapkan string referensi unik untuk setiap instans.

Setelah driver mendaftarkan antarmuka perangkat, driver dapat memanggil WdfDeviceRetrieveDeviceInterfaceString untuk mendapatkan nama tautan simbolis yang telah ditetapkan sistem ke antarmuka perangkat.

Untuk informasi tentang cara lain agar driver dapat mendaftarkan antarmuka perangkat, lihat Mendaftarkan Kelas Antarmuka Perangkat.

Mengaktifkan dan Menonaktifkan Antarmuka Perangkat

Antarmuka yang dibuat sebelum perangkat dimulai (misalnya dari EvtDriverDeviceAdd, EvtChildListCreateDevice, atau EvtDevicePrepareHardware) secara otomatis diaktifkan oleh kerangka kerja ketika perangkat melewati enumerasi PnP dan dimulai. Untuk mencegah antarmuka diaktifkan secara otomatis selama mulai PnP, panggil WdfDeviceSetDeviceInterfaceStateEx dari fungsi panggilan balik yang sama (atur parameter EnableInterface ke FALSE) untuk antarmuka tersebut sebelum PnP dimulai.

Antarmuka yang dibuat setelah perangkat dimulai tidak akan diaktifkan secara otomatis. Driver harus memanggil WdfDeviceSetDeviceInterfaceState atau WdfDeviceSetDeviceInterfaceStateEx untuk mengaktifkan antarmuka tersebut.

Semua antarmuka secara otomatis dinonaktifkan ketika perangkat mengalami penghapusan PnP. Perhatikan bahwa setiap perubahan status daya perangkat atau penyeimbangan ulang sumber daya PnP tidak mengubah status antarmuka.

Driver dapat menonaktifkan dan mengaktifkan kembali antarmuka perangkat jika perlu. Misalnya, jika driver menentukan bahwa perangkatnya telah berhenti merespons, driver dapat memanggil WdfDeviceSetDeviceInterfaceState atau WdfDeviceSetDeviceInterfaceStateEx untuk menonaktifkan antarmuka perangkat dan melarang aplikasi mendapatkan handel baru ke antarmuka. (Handel yang ada ke antarmuka tidak terpengaruh.) Jika perangkat nantinya tersedia, driver dapat memanggil WdfDeviceSetDeviceInterfaceState atau WdfDeviceSetDeviceInterfaceStateEx lagi untuk mengaktifkan kembali antarmuka.

Menerima Permintaan untuk Mengakses Antarmuka Perangkat

Ketika komponen aplikasi atau mode kernel meminta akses ke antarmuka perangkat driver, kerangka kerja memanggil fungsi panggilan balik EvtDeviceFileCreate driver. Driver dapat memanggil WdfFileObjectGetFileName untuk mendapatkan nama perangkat atau file yang diakses komponen aplikasi atau mode kernel. Jika driver menentukan string referensi saat mendaftarkan antarmuka perangkat, sistem operasi menyertakan string referensi dalam file atau nama perangkat yang dikembalikan WdfFileObjectGetFileName .

Mengakses Antarmuka Perangkat Pengandar Lain

Bagian ini menunjukkan bagaimana driver Kernel-Mode Driver Framework (KMDF) atau driver User-Mode Driver Framework (UMDF) versi 2 mendaftar untuk pemberitahuan kedatangan atau penghapusan antarmuka perangkat yang disediakan oleh driver lain, lalu membuat target I/O jarak jauh untuk berkomunikasi dengan perangkat yang diwakili oleh antarmuka perangkat.

Untuk informasi tentang cara melakukan ini di driver UMDF versi 1, lihat Menggunakan Antarmuka Perangkat di Driver UMDF.

Untuk mendaftar pemberitahuan peristiwa antarmuka perangkat, driver KMDF memanggil IoRegisterPlugPlayNotification, sementara driver UMDF 2 memanggil CM_Register_Notification. Dalam kedua kasus, driver memanggil rutinitas yang sesuai dari fungsi panggilan balik EvtDriverDeviceAdd-nya .

Contoh kode berikut menunjukkan bagaimana driver UMDF 2 lokal mendaftar untuk pemberitahuan lalu membuka target I/O jarak jauh.

  1. Driver jarak jauh mendaftar untuk antarmuka perangkat dengan memanggil WdfDeviceCreateDeviceInterface dari EvtDriverDeviceAdd.

        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. Driver lokal memanggil CM_Register_Notification dari EvtDriverDeviceAdd untuk mendaftar pemberitahuan saat antarmuka perangkat tersedia. Berikan penunjuk ke rutinitas panggilan balik pemberitahuan yang dipanggil kerangka kerja saat antarmuka perangkat tersedia.

    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. Sistem memanggil rutinitas panggilan balik pemberitahuan driver lokal setiap kali antarmuka perangkat yang ditentukan tiba atau dihapus. Rutinitas panggilan balik dapat memeriksa parameter EventData untuk menentukan antarmuka perangkat mana yang telah tiba. Kemudian mungkin mengantrekan item kerja untuk membuka antarmuka perangkat.

    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. Dari fungsi panggilan balik item kerja, driver lokal memanggil WdfIoTargetCreate untuk membuat target jarak jauh, dan WdfIoTargetOpen untuk membuka target I/O jarak jauh.

    Saat memanggil WdfIoTargetOpen, driver secara opsional mendaftarkan fungsi panggilan balik EvtIoTargetQueryRemove untuk menerima pemberitahuan penghapusan, bersama dengan kesempatan untuk menolak penghapusan. Jika driver tidak menyediakan EvtIoTargetQueryRemove, kerangka kerja menutup target I/O saat perangkat dihapus.

    Dalam kasus yang jarang terjadi, driver UMDF 2 dapat memanggil CM_Register_Notification untuk kedua kalinya, untuk mendaftar pemberitahuan penghapusan perangkat. Misalnya, jika driver memanggil CreateFile untuk mendapatkan HANDLE ke antarmuka perangkat, driver harus mendaftar untuk pemberitahuan penghapusan perangkat sehingga dapat merespons upaya penghapusan kueri dengan benar. Dalam kebanyakan kasus, driver UMDF 2 memanggil CM_Register_Notification hanya sekali, dan bergantung pada dukungan WDF untuk penghapusan perangkat.

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

Mendaftar untuk Pemberitahuan Kedatangan Antarmuka Perangkat dan Penghapusan Perangkat