Catatan
Akses ke halaman ini memerlukan otorisasi. Anda dapat mencoba masuk atau mengubah direktori.
Akses ke halaman ini memerlukan otorisasi. Anda dapat mencoba mengubah direktori.
Artikel ini menjelaskan cara menulis driver Universal Windows kecil menggunakan Kernel-Mode Driver Framework (KMDF) lalu menyebarkan dan menginstal driver Anda di komputer terpisah.
Prasyarat
Ikuti langkah-langkah untuk menginstal Windows Driver Kit (WDK). Alat Penelusuran Kesalahan untuk Windows disertakan saat Anda menginstal WDK.
Instal Visual Studio 2022. Saat Anda menginstal Visual Studio 2022, pilih Pengembangan desktop dengan beban kerja C++, lalu di bawah Komponen Individual tambahkan:
- MSVC v143 - VS 2022 C++ ARM64/ARM64EC Spectre-mitigated libs (Terbaru)
- MSVC v143 - VS 2022 C++ x64/x86 pustaka yang sudah dimitigasi Spectre (Terbaru)
- C++ ATL untuk alat build v143 terbaru dengan Spectre Mitigations (ARM64/ARM64EC)
- C++ ATL untuk perangkat pembangunan v143 terbaru dengan mitigasi Spectre (x86 & x64)
- C++ MFC untuk perangkat pembangunan terbaru v143 dengan mitigasi Spectre (ARM64/ARM64EC)
- C++ MFC untuk alat build v143 terbaru yang menyertakan Mitigasi Spectre (x86 & x64)
- Windows Driver Kit
Membuat dan mengembangkan driver
Buka Microsoft Visual Studio. Pada menu File, pilih Baru > Proyek.
Dalam kotak dialog Buat proyek baru, pilih C++ di menu dropdown kiri, pilih Windows di menu dropdown tengah, dan pilih Driver di menu dropdown kanan.
Pilih Kernel Mode Driver, Kosong (KMDF) dari daftar jenis proyek. Pilih Berikutnya.
Petunjuk
Jika Anda tidak dapat menemukan templat proyek driver di Visual Studio, ekstensi WDK Visual Studio tidak diinstal dengan benar. Untuk mengatasi masalah ini, luncurkan Penginstal Visual Studio, pilih Ubah, tambahkan Windows Driver Kits di tab Komponen Individual, dan pilih Ubah.
Dalam kotak dialog Mengonfigurasi proyek baru Anda, masukkan "KmdfHelloWorld" di bidang Nama proyek.
Nota
Saat membuat driver KMDF atau UMDF baru, Anda harus memilih nama driver yang memiliki 32 karakter atau kurang. Batas panjang ini didefinisikan dalam wdfglobals.h.
Di bidang Lokasi, masukkan direktori tempat Anda ingin membuat proyek baru.
Periksa solusi dan proyek ditempatkan di direktori yang sama dan pilih Buat.
Visual Studio membuat satu proyek dan solusi. Anda dapat melihatnya di jendela Penjelajah Solusi. (Jika jendela Penjelajah Solusi tidak terlihat, pilih Penjelajah Solusi dari menu Tampilan.) Solusinya memiliki proyek driver bernama KmdfHelloWorld.
Di jendela Penjelajah Solusi, pilih kanan solusi 'KmdfHelloWorld' (1 dari 1 proyek) dan pilih Configuration Manager. Pilih konfigurasi dan platform untuk proyek driver. Misalnya, pilih Debug dan x64.
Di jendela Penjelajah Solusi, pilih kanan proyek KmdfHelloWorld, pilih Tambahkan, lalu pilih Item Baru.
Dalam kotak dialog Tambahkan Item Baru, masukkan "Driver.c".
Nota
Ekstensi nama file .c, bukan .cpp.
Pilih Tambahkan. File Driver.c ditambahkan di bawah File Sumber, seperti yang ditunjukkan di sini.
Menulis kode driver pertama Anda
Sekarang setelah Anda membuat proyek Hello World kosong dan menambahkan file sumber Driver.c, Anda menulis kode paling mendasar yang diperlukan agar driver berjalan dengan menerapkan dua fungsi panggilan balik peristiwa dasar.
Di Driver.c, mulailah dengan menyertakan header ini:
#include <ntddk.h> #include <wdf.h>Petunjuk
Jika Anda tidak dapat menambahkan
Ntddk.h, buka Konfigurasi -> C/C++ -> Umum -> Direktori Sertakan Tambahan dan tambahkanC:\Program Files (x86)\Windows Kits\10\Include\<build#>\km, ganti<build#>dengan direktori yang sesuai dalam penginstalan WDK Anda.Ntddk.h berisi definisi kernel Windows inti untuk semua driver, sementara Wdf.h berisi definisi untuk driver berdasarkan Windows Driver Framework (WDF).
Selanjutnya, berikan deklarasi untuk dua panggilan balik:
DRIVER_INITIALIZE DriverEntry; EVT_WDF_DRIVER_DEVICE_ADD KmdfHelloWorldEvtDeviceAdd;Gunakan kode berikut untuk menulis DriverEntryAnda :
NTSTATUS DriverEntry( _In_ PDRIVER_OBJECT DriverObject, _In_ PUNICODE_STRING RegistryPath ) { // NTSTATUS variable to record success or failure NTSTATUS status = STATUS_SUCCESS; // Allocate the driver configuration object WDF_DRIVER_CONFIG config; // Print "Hello World" for DriverEntry KdPrintEx(( DPFLTR_IHVDRIVER_ID, DPFLTR_INFO_LEVEL, "KmdfHelloWorld: DriverEntry\n" )); // Initialize the driver configuration object to register the // entry point for the EvtDeviceAdd callback, KmdfHelloWorldEvtDeviceAdd WDF_DRIVER_CONFIG_INIT(&config, KmdfHelloWorldEvtDeviceAdd ); // Finally, create the driver object status = WdfDriverCreate(DriverObject, RegistryPath, WDF_NO_OBJECT_ATTRIBUTES, &config, WDF_NO_HANDLE ); return status; }DriverEntry adalah titik masuk untuk semua driver, seperti halnya
Main()untuk banyak program di mode pengguna. Tugas DriverEntry adalah memulai struktur dan sumber daya yang berlaku untuk seluruh driver. Dalam contoh ini, Anda mencetak "Hello World" untuk DriverEntry, mengonfigurasi objek driver untuk mendaftarkan titik masuk callback EvtDeviceAdd, kemudian membuat objek driver dan mengembalikan.Objek driver bertindak sebagai objek induk untuk semua objek kerangka kerja lain yang mungkin Anda buat di driver Anda, yang mencakup objek perangkat, antrean I/O, timer, spinlock, dan banyak lagi. Untuk informasi selengkapnya tentang objek kerangka kerja, lihat Pengenalan Objek Kerangka Kerja.
Petunjuk
Untuk DriverEntry, kami sangat menyarankan untuk menyimpan nama sebagai "DriverEntry" untuk membantu analisis kode dan penelusuran kesalahan.
Selanjutnya, gunakan kode berikut untuk menulis KmdfHelloWorldEvtDeviceAdd:
NTSTATUS KmdfHelloWorldEvtDeviceAdd( _In_ WDFDRIVER Driver, _Inout_ PWDFDEVICE_INIT DeviceInit ) { // We're not using the driver object, // so we need to mark it as unreferenced UNREFERENCED_PARAMETER(Driver); NTSTATUS status; // Allocate the device object WDFDEVICE hDevice; // Print "Hello World" KdPrintEx(( DPFLTR_IHVDRIVER_ID, DPFLTR_INFO_LEVEL, "KmdfHelloWorld: KmdfHelloWorldEvtDeviceAdd\n" )); // Create the device object status = WdfDeviceCreate(&DeviceInit, WDF_NO_OBJECT_ATTRIBUTES, &hDevice ); return status; }EvtDeviceAdd dipanggil oleh sistem ketika mendeteksi bahwa perangkat Anda tiba. Tugasnya adalah menginisialisasi struktur dan sumber daya untuk perangkat tersebut. Dalam contoh ini, Anda mencetak pesan "Halo Dunia" untuk EvtDeviceAdd, membuat objek perangkat, dan mengembalikan. Dalam driver lain yang Anda tulis, Anda dapat membuat antrean I/O untuk perangkat keras Anda, menyiapkan konteks perangkat , ruang penyimpanan untuk informasi khusus perangkat, atau melakukan tugas lain yang diperlukan untuk menyiapkan perangkat Anda.
Petunjuk
Untuk penambahan panggilan balik perangkat, perhatikan cara Anda menamainya dengan nama driver Anda sebagai awalan (KmdfHelloWorldEvtDeviceAdd). Umumnya, sebaiknya beri nama fungsi driver Anda dengan cara ini untuk membedakannya dari fungsi driver lain. DriverEntry adalah satu-satunya yang harus Anda beri nama persis seperti itu.
Driver.c lengkap Anda sekarang terlihat seperti ini:
#include <ntddk.h> #include <wdf.h> DRIVER_INITIALIZE DriverEntry; EVT_WDF_DRIVER_DEVICE_ADD KmdfHelloWorldEvtDeviceAdd; NTSTATUS DriverEntry( _In_ PDRIVER_OBJECT DriverObject, _In_ PUNICODE_STRING RegistryPath ) { // NTSTATUS variable to record success or failure NTSTATUS status = STATUS_SUCCESS; // Allocate the driver configuration object WDF_DRIVER_CONFIG config; // Print "Hello World" for DriverEntry KdPrintEx(( DPFLTR_IHVDRIVER_ID, DPFLTR_INFO_LEVEL, "KmdfHelloWorld: DriverEntry\n" )); // Initialize the driver configuration object to register the // entry point for the EvtDeviceAdd callback, KmdfHelloWorldEvtDeviceAdd WDF_DRIVER_CONFIG_INIT(&config, KmdfHelloWorldEvtDeviceAdd ); // Finally, create the driver object status = WdfDriverCreate(DriverObject, RegistryPath, WDF_NO_OBJECT_ATTRIBUTES, &config, WDF_NO_HANDLE ); return status; } NTSTATUS KmdfHelloWorldEvtDeviceAdd( _In_ WDFDRIVER Driver, _Inout_ PWDFDEVICE_INIT DeviceInit ) { // We're not using the driver object, // so we need to mark it as unreferenced UNREFERENCED_PARAMETER(Driver); NTSTATUS status; // Allocate the device object WDFDEVICE hDevice; // Print "Hello World" KdPrintEx(( DPFLTR_IHVDRIVER_ID, DPFLTR_INFO_LEVEL, "KmdfHelloWorld: KmdfHelloWorldEvtDeviceAdd\n" )); // Create the device object status = WdfDeviceCreate(&DeviceInit, WDF_NO_OBJECT_ATTRIBUTES, &hDevice ); return status; }Simpan Driver.c.
Contoh ini menggambarkan konsep mendasar driver: mereka adalah "kumpulan panggilan balik" yang, setelah diinisialisasi, berdiam diri dan menunggu sistem memanggilnya ketika sistem membutuhkannya. Panggilan sistem bisa menjadi peristiwa kedatangan perangkat baru, permintaan I/O dari aplikasi mode pengguna, peristiwa pematian daya sistem, permintaan dari driver lain, atau peristiwa penghapusan mendadak saat pengguna mencabut perangkat secara tak terduga. Untungnya, untuk mengucapkan "Halo Dunia", Anda hanya perlu memikirkan pembuatan driver dan perangkat.
Selanjutnya, Anda mengembangkan driver Anda.
Membangun penggerak
Di jendela Penjelajah Solusi, pilih kanan solusi 'KmdfHelloWorld' (1 dari 1 proyek) dan pilih Configuration Manager. Pilih konfigurasi dan platform untuk proyek driver. Untuk latihan ini, pilih Debug dan x64.
Di jendela Penjelajah Solusi, pilih kanan KmdfHelloWorld dan pilih properti . Di Pelacakan Wpp > Semua Opsi, atur Jalankan pelacakan Wpp ke Tidak. Pilih Terapkan lalu OK.
Untuk membangun driver Anda, pilih Build Solution dari menu Build. Visual Studio memperlihatkan kemajuan build di jendela Output. (Jika jendela Output tidak terlihat, pilih Output dari menu Tampilan.) Saat Anda memverifikasi bahwa solusi berhasil dibuat, Anda dapat menutup Visual Studio.
Untuk melihat driver bawaan, di File Explorer, buka folder KmdfHelloWorld Anda, lalu ke x64\Debug\KmdfHelloWorld. Folder ini mencakup:
- KmdfHelloWorld.sys -- berkas penggerak mode kernel
- KmdfHelloWorld.inf -- file informasi yang digunakan Windows saat Anda menginstal driver
- KmdfHelloWorld.cat -- file katalog yang digunakan alat penginstal untuk memverifikasi tanda tangan pengujian driver
Petunjuk
Jika Anda melihat DriverVer set to a date in the future saat membangun driver, ubah pengaturan proyek driver Anda sehingga Inf2Cat mengatur /uselocaltime. Untuk melakukannya, gunakan Configuration Properties->Inf2Cat->General->Gunakan Local Time. Sekarang Stampinf dan Inf2Cat menggunakan waktu lokal.
Menyebarkan pengandar
Biasanya ketika Anda menguji dan men-debug driver, debugger dan driver berjalan pada komputer terpisah. Komputer yang menjalankan debugger disebut komputer host , dan komputer yang menjalankan driver disebut komputer target . Komputer target juga disebut komputer uji .
Sejauh ini Anda menggunakan Visual Studio untuk membangun driver di komputer host. Sekarang Anda perlu mengonfigurasi komputer target.
Ikuti instruksi di Menyediakan komputer untuk penyebaran dan pengujian driver (WDK 10).
Petunjuk
Saat Anda mengikuti langkah-langkah untuk memprovisikan komputer target secara otomatis menggunakan kabel jaringan, perhatikan port dan kunci. Anda akan menggunakannya nanti di langkah debugging. Dalam contoh ini, Anda menggunakan 50000 sebagai port dan 1.2.3.4 sebagai kunci.
Dalam skenario debugging driver yang sebenarnya, sebaiknya gunakan kunci yang dihasilkan oleh KDNET. Untuk informasi selengkapnya tentang cara menggunakan KDNET untuk menghasilkan kunci acak, lihat topik Driver Debug - Step by Step Lab (Mode Kernel Sysvad).
Di komputer host, buka solusi Anda di Visual Studio. Anda dapat mengklik dua kali file solusi, KmdfHelloWorld.sln, di folder KmdfHelloWorld Anda.
Di jendela Penjelajah Solusi, klik kanan proyek KmdfHelloWorld, dan pilih properti .
Pergi ke >.
Untuk Nama Perangkat Target, pilih nama komputer yang Anda konfigurasi untuk pengujian dan debugging. Dalam latihan ini, kita menggunakan komputer bernama MyTestComputer.
Untuk memastikan bahwa Anda menguji versi terbaru driver, periksa Hapus versi driver sebelumnya sebelum penyebaran.
Pilih Pembaruan Driver ID Perangkat Keras , dan masukkan ID perangkat keras untuk driver Anda. Untuk latihan ini, ID perangkat keras adalah Root\KmdfHelloWorld. Pilih OK.
Nota
Dalam latihan ini, ID perangkat keras tidak mengidentifikasi perangkat keras yang sebenarnya. Ini mengidentifikasi perangkat imajiner yang ditempatkan di pohon perangkat sebagai anak dari simpul akar. Untuk perangkat keras sebenarnya, jangan pilih Pembaruan Driver ID Perangkat Keras; sebagai alternatif, pilih Instal dan Verifikasi. Anda melihat ID perangkat keras dalam file informasi driver (INF) Anda. Di jendela Penjelajah Solusi, buka KmdfHelloWorld > Driver Files, dan klik dua kali KmdfHelloWorld.inf. ID perangkat keras terletak di bawah [Standard.NT$ARCH$].
[Standard.NT$ARCH$] %KmdfHelloWorld.DeviceDesc%=KmdfHelloWorld_Device, Root\KmdfHelloWorldPada menu Build, pilih Deploy Solution. Visual Studio secara otomatis menyalin file yang diperlukan untuk menginstal dan menjalankan driver ke komputer target. Penyebaran mungkin memakan waktu satu atau dua menit.
Ketika Anda menyebarkan driver, file driver disalin ke folder %Systemdrive%\drivertest\drivers pada komputer pengujian. Jika terjadi kesalahan selama penyebaran, Anda dapat memeriksa untuk melihat apakah file disalin ke komputer pengujian. Verifikasi bahwa file .inf, .cat, sertifikasi pengujian, dan .sys, dan file lain yang diperlukan, ada di folder %systemdrive%\drivertest\drivers.
Untuk informasi selengkapnya tentang menyebarkan driver, lihat Menyebarkan Driver ke Komputer Uji.
Pasang driver
Setelah driver Hello World Anda disebarkan ke komputer target, sekarang Anda menginstal driver tersebut. Ketika sebelumnya Anda memprovisikan komputer target dengan Visual Studio menggunakan opsi otomatis, Visual Studio menyiapkan komputer target untuk menjalankan driver yang ditandatangani untuk pengujian sebagai bagian dari proses provisi. Sekarang Anda hanya perlu menginstal driver menggunakan alat DevCon.
Di komputer host, navigasikan ke folder Alat di penginstalan WDK Anda dan temukan alat DevCon. Misalnya, lihat di folder berikut:
C:\Program Files (x86)\Windows Kits\10\Tools\<version number>\x64\devcon.exe
Salin alat DevCon ke komputer jarak jauh Anda.
Pada komputer target, instal driver dengan menavigasi ke folder yang berisi file driver, lalu jalankan alat DevCon.
Berikut adalah sintaks umum untuk alat devcon yang akan Anda gunakan untuk menginstal driver:
devcon install <pasang file INF><ID perangkat keras>
File INF yang diperlukan untuk menginstal driver ini adalah KmdfHelloWorld.inf. File INF berisi ID perangkat keras untuk menginstal biner driver, KmdfHelloWorld.sys. Ingat bahwa ID perangkat keras, yang terdapat di file INF, adalah Root\KmdfHelloWorld.
Buka jendela Prompt Perintah sebagai Administrator. Navigasi ke folder Anda yang berisi file .sys driver bawaan dan masukkan perintah ini:
devcon install kmdfhelloworld.inf root\kmdfhelloworld
Jika Anda mendapatkan pesan kesalahan tentang devcon tidak dikenali, coba tambahkan jalur ke alat devcon. Misalnya, jika Anda menyalinnya ke folder di komputer target yang disebut C:\Tools, maka coba gunakan perintah berikut:
c:\tools\devcon install kmdfhelloworld.inf root\kmdfhelloworld
Kotak dialog muncul menunjukkan bahwa driver pengujian adalah driver yang belum ditandatangani. Pilih Tetap instal driver ini untuk melanjutkan.
Melakukan debug pada driver
Sekarang setelah Anda menginstal driver KmdfHelloWorld pada komputer target, Anda menghubungkan debugger secara jarak jauh dari komputer host.
Di komputer host, buka jendela Prompt Perintah sebagai Administrator. Ubah ke direktori WinDbg.exe. Anda menggunakan x64version WinDbg.exe dari Windows Driver Kit (WDK) yang diinstal sebagai bagian dari penginstalan kit Windows. Berikut adalah jalur default ke WinDbg.exe:
C:\Program Files (x86)\Windows Kits\10\Debuggers\x64
Luncurkan WinDbg untuk menyambungkan ke sesi debug kernel pada komputer target dengan menggunakan perintah berikut. Nilai untuk port dan kunci harus sama dengan yang Anda gunakan untuk menyediakan komputer target. Anda menggunakan 50000 untuk port dan 1.2.3.4 untuk kunci, nilai yang Anda gunakan pada langkah penerapan. Bendera k menunjukkan bahwa ini adalah sesi debug kernel.
WinDbg -k net:port=50000,key=1.2.3.4
Pada menu Debug, pilih Break. Debugger pada komputer host menerobos ke komputer target. Di jendela Perintah Debugger, Anda dapat melihat prompt perintah debugging kernel: kd>.
Pada titik ini, Anda dapat bereksperimen dengan debugger dengan memasukkan perintah di prompt> kd. Misalnya, Anda dapat mencoba perintah ini:
Untuk membiarkan komputer target berjalan lagi, pilih Go dari menu Debug atau tekan "g," lalu tekan "enter."
Untuk menghentikan sesi debugging, pilih Detach Debugger dari menu Debug.
Penting
Pastikan Anda menggunakan perintah "go" untuk membiarkan komputer target berjalan lagi sebelum keluar dari debugger, atau komputer target akan tetap tidak responsif terhadap input mouse dan keyboard Anda karena masih berbicara dengan debugger.
Untuk panduan langkah demi langkah terperinci dari proses debugging driver, lihat Debug Universal Driver - Step by Step Lab (Echo Kernel-Mode).
Untuk informasi selengkapnya tentang penelusuran kesalahan jarak jauh, lihat Penelusuran Kesalahan Jarak Jauh Menggunakan WinDbg.