Not
Bu sayfaya erişim yetkilendirme gerektiriyor. Oturum açmayı veya dizinleri değiştirmeyi deneyebilirsiniz.
Bu sayfaya erişim yetkilendirme gerektiriyor. Dizinleri değiştirmeyi deneyebilirsiniz.
Bu makalede, Kernel-Mode Driver Framework (KMDF) kullanarak küçük bir Evrensel Windows sürücüsü yazma ve ardından sürücünüzü ayrı bir bilgisayara dağıtma ve yükleme işlemleri açıklanmaktadır.
Önkoşullar
Windows Driver Kit (WDK)yüklemek için adımları izleyin. WDK'yi yüklediğinizde Windows için Hata Ayıklama Araçları eklenir.
Visual Studio 2022yükleyin. Visual Studio 2022'yi yüklediğinizde, C++ ile Masaüstü geliştirme iş yükünü seçin, ardından Tek Tek Bileşenler altında şunları ekleyin:
- MSVC v143 - VS 2022 C++ ARM64/ARM64EC Spectre etkisini azaltıcı kütüphaneler (Güncel)
- MSVC v143 - VS 2022 C++ x64/x86 Spectre önlemleri alınmış kütüphaneler (En son sürüm)
- Spectre Azaltma Önlemleri (ARM64/ARM64EC) ile C++ ATL için en son v143 derleme araçları
- Son sürüm v143 derleme araçları için Spectre Azaltmaları içeren C++ ATL (x86 & x64)
- Spectre Azaltmaları (ARM64/ARM64EC) ile en son v143 derleme araçları için C++ MFC
- Spectre Azaltmaları ile en yeni v143 yapı araçları için C++ MFC (x86 & x64)
- Windows Sürücü Seti
Sürücü yarat ve geliştir
Microsoft Visual Studio'yu açın. Dosya menüsünde Yeni Proje >seçin.
Yeni proje oluştur iletişim kutusunda, soldaki açılan listeden C++ seçin, ortadaki açılan listeden Windows 'i seçin ve sağ açılan listeden Sürücü 'yi seçin.
Proje türleri listesinden Çekirdek Modu Sürücüsü, Boş (KMDF) seçin. Sonrakiseçin.
Bahşiş
Visual Studio'da sürücü projesi şablonlarını bulamazsanız, WDK Visual Studio uzantısı düzgün yüklenmedi. Bu sorunu çözmek için Visual Studio Installerbaşlatın, Değiştirseçeneğini seçin, Bireysel Bileşen sekmesinde Windows Sürücü Setleri'ni ekleyin ve Değiştirseçeneğini seçin.
Yeni Proje Yapılandır iletişim kutusunda, Proje Adı alanına "KmdfHelloWorld" yazın.
Not (Açıklama)
Yeni bir KMDF veya UMDF sürücüsü oluşturduğunuzda, 32 karakter veya daha az karakter içeren bir sürücü adı seçmeniz gerekir. Bu uzunluk sınırı wdfglobals.h içinde tanımlanır.
Konum alanına yeni projeyi oluşturmak istediğiniz dizini girin.
Çözümü ve projeyi aynı dizin yerleştir'i işaretleyin ve Oluşturöğesini seçin.
Visual Studio bir proje ve bir çözüm oluşturur. Bunları Çözüm Gezgini penceresinde görebilirsiniz. (Çözüm Gezgini penceresi görünmüyorsa, Görünüm menüsünden Çözüm Gezgini seçin.) Çözümün KmdfHelloWorld adlı bir sürücü projesi vardır.
Çözüm Gezgini penceresinde, 'KmdfHelloWorld' çözümüne (1 proje içinden 1) sağ tıklayın ve Configuration Manager'ı seçin. Sürücü projesi için bir yapılandırma ve platform seçin. Örneğin, Hata Ayıklama ve x64seçin.
Çözüm Gezgini penceresinde, KmdfHelloWorld projesine sağ tıklayın, Ekle'yi seçin ve ardından Yeni Öğeyiseçin.
Yeni Öğe Ekle iletişim kutusuna "Driver.c" yazın.
Not (Açıklama)
Dosya adı uzantısı .c.cppdeğil.
Ekle'ı seçin. Driver.c dosyası, burada gösterildiği gibi Kaynak Dosyalaraltına eklenir.
İlk sürücü kodunuzu yazma
Boş Hello World projenizi oluşturduğunuza ve Driver.c kaynak dosyasını eklediğinize göre, iki temel olay geri çağırma işlevi uygulayarak sürücünün çalışması için gereken en temel kodu yazarsınız.
Driver.c'de şu üst bilgileri ekleyerek başlayın:
#include <ntddk.h> #include <wdf.h>
Bahşiş
Ntddk.h
ekleyemiyorsanız, WDK yüklemenizdeki uygun dizinle >'yi değiştirerek >'yi açın ve >ekleyin.Ntddk.h tüm sürücüler için çekirdek Windows çekirdek tanımlarını içerirken Wdf.h, Windows Driver Framework(WDF) tabanlı sürücüler için tanımlar içerir.
Ardından, iki callback fonksiyonu için tanımlar sağlayın.
DRIVER_INITIALIZE DriverEntry; EVT_WDF_DRIVER_DEVICE_ADD KmdfHelloWorldEvtDeviceAdd;
DriverEntryyazmak için aşağıdaki kodu kullanın:
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,
Main()
birçok kullanıcı modu uygulaması için olduğu gibi tüm sürücülerin giriş noktasıdır. DriverEntry görevi, sürücü genelindeki yapıları ve kaynakları başlatmaktır. Bu örnekte, DriverEntryiçin "Hello World" yazdırdıysanız, sürücü nesnesini EvtDeviceAdd geri çağırmanın giriş noktasını kaydedecek şekilde yapılandırdıktan sonra sürücü nesnesini oluşturup döndürdünüz.Sürücü nesnesi, sürücünüzde oluşturabileceğiniz cihaz nesneleri, G/Ç kuyrukları, zamanlayıcılar, spinlock'lar ve daha fazlasını içeren diğer tüm çerçeve nesneleri için üst nesne olarak görev yapar. Çerçeve nesneleri hakkında daha fazla bilgi için bkz. Framework Nesnelerine Giriş.
Bahşiş
DriverEntryiçin, kod analizi ve hata ayıklama konusunda yardımcı olması için adın "DriverEntry" olarak tutulmasını kesinlikle öneririz.
Ardından, KmdfHelloWorldEvtDeviceAddyazmak için aşağıdaki kodu kullanın:
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, cihazınızın geldiğini algıladığında sistem tarafından çağrılır. Onun görevi, bu cihaz için yapı ve kaynakları başlatmaktır. Bu örnekte, EvtDeviceAddiçin bir "Merhaba Dünya" iletisi yazdırıp cihaz nesnesini oluşturdunuz ve döndürdün. Yazdığınız diğer sürücülerde donanımınız için G/Ç kuyrukları oluşturabilir, cihaza özgü bilgiler için bir cihaz bağlamı depolama alanı ayarlayabilir veya cihazınızı hazırlamak için gereken diğer görevleri gerçekleştirebilirsiniz.
Bahşiş
Cihaz ekleme geri çağrısı için, sürücünüzün adını ön ek olarak kullandığınız şekle dikkat edin (KmdfHelloWorldEvtDeviceAdd). Genel olarak, sürücünüzün işlevlerini diğer sürücülerin işlevlerinden ayırt etmek için bu şekilde adlandırmanızı öneririz. DriverEntry tam olarak böyle adlandırılması gereken tek isimdir.
Driver.c dosyasının tamamı şu şekilde görünür:
#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; }
Driver.c dosyasını kaydedin.
Bu örnekte temel bir sürücü kavramı gösterilmektedir: bunlar, başlatıldıktan sonra sistemin bir şeye ihtiyaç duyduğunda bunları çağırmasını bekleyen bir "geri çağırma koleksiyonu"dur. Sistem çağrısı yeni bir cihaz varış olayı, kullanıcı modu uygulamasından gelen G/Ç isteği, sistem güç kapatma olayı, başka bir sürücüden gelen istek veya bir kullanıcı cihazı beklenmedik bir şekilde çıkardığında sürpriz bir kaldırma olayı olabilir. Neyse ki "Merhaba Dünya" demek için yalnızca sürücü ve cihaz oluşturma konusunda endişelenmeniz gerekiyordu.
Ardından sürücünüzü oluşturuyorsunuz.
Sürücüyü oluştur
Çözüm Gezgini penceresinde, 'KmdfHelloWorld' çözümüne (1 proje içinden 1) sağ tıklayın ve Configuration Manager'ı seçin. Sürücü projesi için bir yapılandırma ve platform seçin. Bu alıştırma için Hata Ayıklama ve x64seçeneklerini seçin.
Çözüm Gezgini penceresinde, KmdfHelloWorld sağ tıklayın ve Özellikler'i seçin. Wpp İzleme > Tüm Seçenekleriçinde, Wpp izlemeyi çalıştırma seçiminiYok olarak ayarlayın. Uygula'yı seçin, ardından ve Tamam'ı, sonratıklayın.
Sürücünüzü oluşturmak için, Derleme menüsünden Çözümü Derle seçin. Visual Studio, Çıktı penceresinde derleme ilerleme durumunu gösterir. (Çıktı penceresi görünmüyorsa, Görünüm menüsünden Çıkış seçin.) Çözümün başarıyla derlendiğini doğruladığınızda Visual Studio'yu kapatabilirsiniz.
Yerleşik sürücüyü görmek için Dosya Gezgini'nde KmdfHelloWorld klasörünüze gidin ve ardından x64\Debug\KmdfHelloWorld . Klasör şunları içerir:
- KmdfHelloWorld.sys -- çekirdek modu sürücü dosyası
- KmdfHelloWorld.inf -- Windows'un sürücüyü yüklediğinizde kullandığı bir bilgi dosyası
- KmdfHelloWorld.cat -- yükleyicinin sürücünün test imzasını doğrulamak için kullandığı bir katalog dosyası
Bahşiş
Sürücünüzü oluştururken DriverVer set to a date in the future
görürseniz, Inf2Cat'in /uselocaltime
ayarlaması için sürücü projesi ayarlarınızı değiştirin. Bunu yapmak için Yapılandırma Özellikleri->Inf2Cat->Genel->Yerel Saatkullanın. Şimdi hem Stampinf hem de Inf2Cat yerel saati kullanıyor.
Sürücüyü yükle
Genellikle bir sürücüyü test edip hata ayıkladığınızda, hata ayıklayıcı ve sürücü ayrı bilgisayarlarda çalışır. Hata ayıklayıcısını çalıştıran bilgisayara ana bilgisayar adı verilir ve sürücüyü çalıştıran bilgisayara hedef bilgisayar adı verilir. Hedef bilgisayar, test bilgisayarıolarak da adlandırılır.
Şimdiye kadar konak bilgisayarda bir sürücü oluşturmak için Visual Studio'yu kullandınız. Şimdi bir hedef bilgisayar yapılandırmanız gerekir.
Sürücü dağıtımı ve testi için bilgisayar sağlama (WDK 10)yönergelerini izleyin.
Bahşiş
Hedef bilgisayarı bir ağ kablosu kullanarak otomatik olarak sağlama adımlarını izlediğinizde bağlantı noktasını ve anahtarı not edin. Bunları daha sonra hata ayıklama adımında kullanacaksınız. Bu örnekte bağlantı noktası olarak 50000 ve anahtar olarak 1.2.3.4 kullanırsınız.
Gerçek sürücü hata ayıklama senaryolarında, KDNET tarafından oluşturulan bir anahtar kullanmanızı öneririz. Rastgele bir anahtar oluşturmak için KDNET'i kullanma hakkında daha fazla bilgi için Hata Ayıklama Sürücüleri - Adım Adım Laboratuvar (Sysvad Çekirdek Modu) konusundaki makaleye bakın.
Ana bilgisayarda çözümünüzü Visual Studio'da açın. KmdfHelloWorld klasörünüzde KmdfHelloWorld.sln çözüm dosyasına çift tıklayabilirsiniz.
Çözüm Gezgini penceresinde, KmdfHelloWorld projesine sağ tıklayın ve Özellikleröğesini seçin.
Sürücü Yükleme > Dağıtım bölümüne git.
Hedef Cihaz Adıiçin, test ve hata ayıklama için yapılandırdığınız bilgisayarın adını seçin. Bu alıştırmada MyTestComputer adlı bir bilgisayar kullanacağız.
Sürücünün en son sürümünü test ettiğinizden emin olmak için, dağıtımdan önce önceki sürücü sürümlerini kaldırkontrol edin.
Donanım Kimliği Sürücü Güncelleştirmeöğesini seçin ve sürücünüzün donanım kimliğini girin. Bu alıştırmada donanım kimliği Root\KmdfHelloWorld şeklindedir. Tamamseçin.
Not (Açıklama)
Bu alıştırmada donanım kimliği gerçek bir donanım parçasını tanımlamaz. Kök düğümün çocuğu olarak cihaz ağacında bir yer verilen hayali bir cihazı tanımlar. Gerçek donanım için Donanım Kimliği Sürücü Güncelleştirmesiseçmeyin; bunun yerine Yükle veDoğrula'yı seçin. Sürücünüzün bilgi (INF) dosyasında donanım kimliğini görürsünüz. Çözüm Gezgini penceresinde KmdfHelloWorld > Sürücü Dosyaları'ne gidin ve KmdfHelloWorld.inf'e çift tıklayın. Donanım kimliği [Standard.NT$ARCH$] altında bulunur.
[Standard.NT$ARCH$] %KmdfHelloWorld.DeviceDesc%=KmdfHelloWorld_Device, Root\KmdfHelloWorld
Derleme menüsünde Çözümü Dağıtseçin. Visual Studio, sürücüyü yüklemek ve çalıştırmak için gereken dosyaları otomatik olarak hedef bilgisayara kopyalar. Dağıtım bir veya iki dakika sürebilir.
Bir sürücü dağıttığınızda, sürücü dosyaları test bilgisayarındaki %Systemdrive%\drivertest\drivers klasörüne kopyalanır. Dağıtım sırasında bir sorun olursa, dosyaların test bilgisayarına kopyalanmış olup olmadığını kontrol edebilirsiniz. .inf, .cat, test sertifikası ve .sys dosyalarının ve diğer tüm gerekli dosyaların %systemdrive%\drivertest\drivers klasöründe bulunduğunu doğrulayın.
Sürücüleri dağıtma hakkında daha fazla bilgi için bkz. Test Bilgisayarına Sürücü Dağıtma.
Sürücüyü yükleme
Hello World sürücünüz hedef bilgisayara dağıtıldığında, şimdi sürücüyü yüklersiniz. Daha önce otomatik seçeneğini kullanarak hedef bilgisayarı Visual Studio ile sağladığınızda, Visual Studio sağlama işleminin bir parçası olarak test imzalı sürücüleri çalıştırmak için hedef bilgisayarı ayarlar. Şimdi DevCon aracını kullanarak sürücüyü yüklemeniz yeterlidir.
Konak bilgisayarda, WDK yüklemenizde Araçlar klasörüne gidin ve DevCon aracını bulun. Örneğin, aşağıdaki klasöre bakın:
C:\Program Files (x86)\Windows Kits\10\Tools\x64\devcon.exe
DevCon aracını uzak bilgisayarınıza kopyalayın.
Hedef bilgisayarda, sürücü dosyalarını içeren klasöre gidip DevCon aracını çalıştırarak sürücüyü yükleyin.
Sürücüyü yüklemek için kullanacağınız devcon aracının genel söz dizimi aşağıdadır:
devcon kur <INF dosyası><donanım kimliği>
Bu sürücüyü yüklemek için gereken INF dosyası KmdfHelloWorld.inf dosyasıdır. INF dosyası, sürücü ikili dosyasını yüklemek için donanım kimliğini KmdfHelloWorld.sysiçerir. INF dosyasında bulunan donanım kimliğinin Root\KmdfHelloWorld olduğunu hatırlayın.
Yönetici olarak bir Komut İstemi penceresi açın. Yerleşik sürücü .sys dosyasını içeren klasörünüze gidin ve şu komutu girin:
devcon install kmdfhelloworld.inf root\kmdfhelloworld
devcon tanınmadığı hakkında bir hata iletisi alırsanız, devcon aracına dosya yolunu eklemeyi deneyin. Örneğin, hedef bilgisayardaki C:\Toolsadlı bir klasöre kopyaladıysanız aşağıdaki komutu kullanmayı deneyin:
c:\tools\devcon install kmdfhelloworld.inf root\kmdfhelloworld
Test sürücüsünün imzasız bir sürücü olduğunu belirten bir iletişim kutusu görüntülenir. Devam etmek için bu sürücüyü yine de yükle seçin.
Sürücüde hata ayıklama
KmdfHelloWorld sürücünüzü hedef bilgisayara yüklediğinize göre, ana bilgisayardan uzaktan bir hata ayıklayıcı eklersiniz.
Ana bilgisayarda, Yönetici olarak bir Komut İstemi penceresi açın. WinDbg.exe dizinine geçin. Windows seti yüklemesinin bir parçası olarak yüklenen Windows Sürücü Seti'nden (WDK) WinDbg.exe x64version'ını kullanırsınız. WinDbg.exeiçin varsayılan yol aşağıdadır:
C:\Program Files (x86)\Windows Kits\10\Debuggers\x64
Aşağıdaki komutu kullanarak hedef bilgisayarda bir çekirdek hata ayıklama oturumuna bağlanmak için WinDbg'yi başlatın. Bağlantı noktası ve anahtar değeri, hedef bilgisayarı sağlamak için kullandığınız değerle aynı olmalıdır. Dağıtım adımında kullandığınız değerlere göre, bağlantı noktası için 50000 ve anahtar için 1.2.3.4 kullanırsınız. k bayrağı bunun bir çekirdek hata ayıklama oturumu olduğunu gösterir.
WinDbg -k net:port=50000,key=1.2.3.4
Hata Ayıklama menüsünde Kesmeseçin. Ana bilgisayardaki hata ayıklayıcı, hedef bilgisayara müdahale eder. Hata Ayıklayıcısı Komut penceresinde, çekirdek hata ayıklama komut istemini görebilirsiniz: kd>.
Bu noktada, kd> istemine komutlar girerek hata ayıklayıcıyla denemeler yapabilirsiniz. Örneğin, şu komutları deneyebilirsiniz:
Hedef bilgisayarın yeniden çalışmasına izin vermek için, Git seçeneğini Hata Ayıkla menüsünden seçin veya "g" tuşuna basın, sonra "enter" tuşuna basın.
Hata ayıklama oturumunu durdurmak için, Hata Ayıklama menüsünden Hata Ayıklayıcıyı Ayır'ı seçin.
Önemli
Hata ayıklayıcıdan çıkmadan önce hedef bilgisayarın yeniden çalışmasına izin vermek için "git" komutunu kullandığınızdan emin olun; aksi takdirde hedef bilgisayar, hata ayıklayıcıyla konuşmaya devam ettiğinden fare ve klavye girişinize yanıt vermemeye devam eder.
Sürücü hata ayıklama işleminin ayrıntılı adım adım izlenecek yolu için bkz. Evrensel Sürücülerde Hata Ayıklama - Adım Adım Laboratuvar (Echo Kernel-Mode).
Uzaktan hata ayıklama hakkında daha fazla bilgi için windbg kullanarak uzaktan hata ayıklama başlığına bkz.
İlgili makaleler
Windows için Hata Ayıklama Araçları
Evrensel Sürücülerde Hata Ayıklama - Adım Adım Laboratuvarı (Echo Çekirdek Modu)