Bagikan melalui


Jalankan Dari Penyimpanan Driver

INF yang menggunakan 'run from Driver Store' berarti bahwa INF menggunakan DIRID 13 untuk menentukan lokasi untuk file paket driver saat diinstal.

Untuk file 'jalankan dari Penyimpanan Driver' yang dimuat oleh INF, subdir yang tercantum dalam entri SourceDisksFiles untuk file di INF harus cocok dengan subdir yang tercantum dalam entri DestinationDirs untuk file di INF.

Selain itu, direktif CopyFiles tidak dapat digunakan untuk mengganti nama file yang dijalankan dari Penyimpanan Driver. Pembatasan ini diperlukan agar penginstalan INF pada perangkat tidak mengakibatkan pembuatan file baru di direktori Penyimpanan Driver.

Karena entri SourceDisksFiles tidak dapat memiliki beberapa entri dengan nama file yang sama dan CopyFiles tidak dapat digunakan untuk mengganti nama file, setiap file 'run from Driver Store' yang direferensikan INF harus memiliki nama file yang unik.

Paket driver memiliki dukungan umum untuk 'run from Driver Store' yang dimulai dengan Windows 10 1709. Namun, tumpukan perangkat tertentu dapat menempatkan pembatasan ekstra pada file yang perlu Anda berikan yang dicolokkan ke tumpukan tersebut. Beberapa contohnya adalah tumpukan perangkat ini yang tidak mendukung 'jalankan dari Penyimpanan Driver' hingga Windows 10 1803:

Jika menyediakan biner yang dicolokkan ke tumpukan perangkat tertentu, silakan lihat dokumentasi untuk tumpukan perangkat tertentu yang Anda colokkan untuk memeriksa apakah mendukung penyediaan jalur file lengkap ke biner dan jika ada batasan pada jalur file lengkap tersebut. Jika mendukung penyediaan jalur file lengkap ke biner tanpa batasan pada jalur tersebut, maka harus mendukung file yang 'dijalankan dari Penyimpanan Driver'.

Menemukan dan memuat file secara dinamis dari Penyimpanan Driver

Terkadang ada kebutuhan komponen untuk memuat file yang merupakan bagian dari paket driver yang menggunakan 'run from Driver Store'. Jalur ke file paket driver ini tidak boleh dikodekan secara permanen karena dapat berbeda antara versi paket driver yang berbeda, versi OS yang berbeda, edisi OS yang berbeda, dll. Ketika kebutuhan seperti itu untuk memuat file paket driver muncul, file paket driver ini harus ditemukan dan dimuat secara dinamis menggunakan beberapa paradigma yang dijelaskan di bawah ini.

Menemukan dan memuat file dalam paket driver yang sama

Ketika file dalam paket driver perlu memuat file lain dari paket driver yang sama, salah satu opsi potensial untuk menemukan file tersebut secara dinamis adalah menentukan direktori tempat file ini dijalankan dan memuat file lain yang relatif terhadap direktori tersebut.

Driver WDM atau KMDF yang berjalan dari Driver Store pada Windows 10 versi 1803 dan yang lebih baru yang perlu mengakses file lain dari paket drivernya harus memanggil IoGetDriverDirectory dengan DriverDirectoryImage sebagai jenis direktori untuk mendapatkan jalur direktori tempat driver dimuat. Atau untuk driver yang perlu mendukung versi OS sebelum Windows 10 versi 1803, gunakan IoQueryFullDriverPath untuk menemukan jalur driver, mendapatkan jalur direktori tempat driver dimuat, dan mencari file yang relatif terhadap jalur tersebut. Jika driver mode kernel adalah driver KMDF, driver dapat menggunakan WdfDriverWdmGetDriverObject untuk mengambil objek driver WDM untuk diteruskan ke IoQueryFullDriverPath.

Biner mode pengguna dapat menggunakan GetModuleHandleExW dan GetModuleFileNameW untuk menentukan dari mana biner dimuat. Misalnya, biner driver UMDF dapat melakukan sesuatu seperti berikut:

bRet = GetModuleHandleExW(GET_MODULE_HANDLE_EX_FLAG_FROM_ADDRESS,
                         (PCWSTR)&DriverEntry,
                         &handleModule);
if (bRet) {
    charsWritten = GetModuleFileNameW(handleModule,
                                      path,
                                      pathLength);
    …

Menemukan dan memuat file dalam paket driver apa pun

Dalam beberapa skenario, paket driver mungkin berisi file yang dimaksudkan untuk dimuat oleh biner dalam paket driver lain atau oleh komponen mode pengguna. Metode ini juga dapat digunakan untuk file dari paket driver yang sama jika ini lebih disukai daripada metode yang dijelaskan di atas untuk memuat file dari paket driver yang sama.

Berikut adalah beberapa contoh skenario yang mungkin melibatkan pemuatan file dari paket driver:

  • DLL mode pengguna dalam paket driver menyediakan antarmuka untuk berkomunikasi dengan driver dalam paket driver.

  • Paket driver ekstensi berisi file konfigurasi yang dimuat oleh driver dalam paket driver dasar.

Dalam situasi ini, paket driver harus mengatur beberapa status pada perangkat atau antarmuka perangkat yang menunjukkan jalur file yang diharapkan untuk dimuat.

Paket driver biasanya akan menggunakan HKR AddReg untuk mengatur status ini. Untuk contoh ini, harus diasumsikan bahwa untuk ExampleFile.dll, paket driver memiliki entri SourceDisksFiles tanpa subdir. Ini menghasilkan file berada di akar direktori paket driver. Juga harus diasumsikan bahwa DestinationDirs untuk direktif CopyFiles menentukan dirid 13.

Berikut adalah contoh INF untuk mengatur ini sebagai status perangkat:

[ExampleDDInstall.HW]
AddReg = Example_DDInstall.AddReg

[Example_DDInstall.AddReg]
HKR,,ExampleValue,,%13%\ExampleFile.dll

Contoh INF untuk mengatur ini sebagai status antarmuka perangkat adalah:

[ExampleDDInstall.Interfaces]
AddInterface = {<fill in an interface class GUID for an interface exposed by the device>},,Example_Add_Interface_Section

[Example_Add_Interface_Section]
AddReg = Example_Add_Interface_Section.AddReg

[Example_Add_Interface_Section.AddReg]
HKR,,ExampleValue,,%13%\ExampleFile.dll

Contoh sebelumnya menggunakan nilai bendera kosong, yang menghasilkan nilai registri REG_SZ. Ini menghasilkan %13% diubah menjadi jalur file mode pengguna yang sepenuhnya memenuhi syarat. Dalam banyak kasus, lebih disukai untuk memiliki jalur relatif terhadap variabel lingkungan. Jika nilai bendera 0x20000 digunakan, nilai registri berjenis REG_EXPAND_SZ dan %13% dikonversi ke jalur dengan variabel lingkungan yang sesuai untuk mengabstraksi lokasi jalur. Saat mengambil nilai registri ini, panggil ExpandEnvironmentStrings untuk menyelesaikan variabel lingkungan di jalur.

Jika nilai perlu dibaca oleh komponen mode kernel, nilainya harus menjadi nilai REG_SZ. Ketika komponen mode kernel membaca nilai tersebut, komponen tersebut harus diawali \??\ sebelum meneruskannya ke API seperti ZwOpenFile.

Untuk mengakses pengaturan ini ketika merupakan bagian dari status perangkat, pertama-tama aplikasi harus menemukan identitas perangkat. Kode mode pengguna dapat menggunakan CM_Get_Device_ID_List_Size dan CM_Get_Device_ID_List untuk mendapatkan daftar perangkat, difilter seperlunya. Daftar perangkat tersebut mungkin berisi beberapa perangkat, jadi cari perangkat yang sesuai sebelum membaca status dari perangkat. Misalnya, panggil CM_Get_DevNode_Property untuk mengambil properti pada perangkat saat mencari perangkat yang cocok dengan kriteria tertentu.

Setelah perangkat yang benar ditemukan, panggil CM_Open_DevNode_Key untuk mendapatkan handel ke lokasi registri tempat status perangkat disimpan.

Kode mode kernel harus mengambil PDO (objek perangkat fisik) ke perangkat dengan status dan memanggil IopenDeviceRegistryKey. Salah satu cara yang mungkin bagi kode mode kernel untuk mengambil PDO perangkat adalah dengan menemukan antarmuka yang diaktifkan yang diekspos oleh perangkat dan menggunakan IoGetDeviceObjectPointer untuk mengambil objek perangkat.

Untuk mengakses pengaturan ini saat status antarmuka perangkat, Kode mode pengguna dapat memanggil CM_Get_Device_Interface_List_Size dan CM_Get_Device_Interface_List.

Selain itu CM_Register_Notification dapat digunakan untuk diberi tahu tentang kedatangan dan penghapusan antarmuka perangkat sehingga kode akan diberi tahu ketika antarmuka diaktifkan dan kemudian dapat mengambil status. Mungkin ada beberapa antarmuka perangkat di kelas antarmuka perangkat yang digunakan dalam API di atas. Periksa antarmuka tersebut untuk menentukan antarmuka mana yang benar untuk dibaca oleh pengaturan.

Setelah antarmuka perangkat yang benar ditemukan, panggil CM_Open_Device_Interface_Key.

Kode mode kernel dapat mengambil nama tautan simbolis untuk antarmuka perangkat untuk mendapatkan status. Untuk melakukannya, panggil IoRegisterPlugPlayNotification untuk mendaftar pemberitahuan antarmuka perangkat pada kelas antarmuka perangkat yang sesuai. Atau, panggil IoGetDeviceInterfaces untuk mendapatkan daftar antarmuka perangkat saat ini pada sistem. Mungkin ada beberapa antarmuka perangkat di kelas antarmuka perangkat yang digunakan dalam API di atas. Periksa antarmuka tersebut untuk menentukan antarmuka mana yang benar yang harus memiliki pengaturan yang akan dibaca.

Setelah nama tautan simbolis yang sesuai ditemukan, panggil IoOpenDeviceInterfaceRegistryKey untuk mengambil handel ke lokasi registri tempat status antarmuka perangkat disimpan.

Catatan

Gunakan bendera CM_GETIDLIST_FILTER_PRESENT dengan bendera CM_Get_Device_ID_List_Size dan CM_Get_Device_ID_List atau bendera CM_GET_DEVICE_INTERFACE_LIST_PRESENT dengan CM_Get_Device_Interface_List_Size dan CM_Get_Device_Interface_List. Ini memastikan bahwa perangkat keras yang terkait dengan status yang berisi jalur file ada dan siap untuk komunikasi.

Menghapus paket driver

Secara default, paket driver tidak dapat dihapus dari sistem jika masih diinstal pada perangkat apa pun. Namun, beberapa opsi untuk menghapus paket driver dari sistem memungkinkannya untuk dicoba untuk 'dipaksa' dihapus. Ini mencoba menghapus paket driver meskipun paket driver tersebut masih diinstal pada beberapa perangkat pada sistem. Penghapusan paksa tidak diperbolehkan untuk paket driver yang memiliki file apa pun yang 'dijalankan dari Penyimpanan Driver'. Ketika paket driver dihapus dari sistem, isi Penyimpanan Driver-nya akan dihapus. Jika ada perangkat yang masih diinstal dengan paket driver tersebut, file 'jalankan dari Penyimpanan Driver' dalam paket driver tersebut sekarang akan hilang dan file yang hilang tersebut dapat menyebabkan perangkat tersebut tidak berfungsi. Untuk mencegah menempatkan perangkat ke status buruk seperti itu, paket driver yang berisi file 'jalankan dari Penyimpanan Driver' tidak dapat dihapus paksa. Mereka hanya dapat dihapus setelah tidak lagi diinstal di perangkat apa pun. Untuk membantu penghapusan paket driver tersebut, DiUninstallDriver atau pnputil /delete-driver <oem#.inf> /uninstall dapat digunakan. Metode penghapusan ini pertama-tama akan memperbarui perangkat apa pun yang menggunakan paket driver yang dihapus untuk tidak lagi diinstal dengan paket driver tersebut sebelum mencoba menghapus paket driver.

Pengembangan paket driver

Menguji biner privat

Saat mengembangkan paket driver, jika ada kebutuhan untuk mengganti file yang dapat dieksekusi tertentu dari paket driver dengan versi privat alih-alih membangun kembali sepenuhnya dan mengganti paket driver pada sistem, maka disarankan agar debugger kernel digunakan bersama dengan perintah .kdfiles. Karena jalur lengkap ke file di Penyimpanan Driver tidak boleh dikodekan secara permanen, disarankan agar dalam pemetaan .kdfiles, nama file OldDriver hanyalah nama langsung file tanpa informasi jalur sebelumnya. Untuk memfasilitasi ini (dan skenario lainnya), nama file dalam paket driver harus seunik mungkin sehingga tidak cocok dengan nama file dari paket driver yang tidak terkait pada sistem.

Memindahkan INF untuk menggunakan jalankan dari Penyimpanan Driver

Jika Anda memiliki paket driver yang sudah ada dengan INF yang tidak menggunakan jalankan dari Driver Store dan memindahkannya untuk menggunakan jalankan dari Driver Store, contoh berikut menunjukkan beberapa penggunaan file umum dalam INF dan pola saat memperbarui file tersebut untuk dijalankan dari DriverStore.

Referensi cepat untuk pembaruan direktori tujuan

Tabel berikut ini menyediakan referensi cepat untuk menemukan panduan yang sesuai berdasarkan direktori tujuan SAAT INI DIRID yang ditentukan INF paket driver untuk file.

DIRID Subdirektori Detail
13 File sudah menggunakan 'jalankan dari Penyimpanan Driver'. Tidak diperlukan pekerjaan lebih lanjut.
1 DIRID 1 tidak boleh digunakan. Tidak ada jaminan bahwa direktori sumber akan tersedia ketika referensi ke file perlu diselesaikan. Sebaliknya, jika komponen dalam paket driver bergantung pada file tertentu, sertakan file tersebut dalam paket driver dan jalankan dari Penyimpanan Driver.
10 Firmware Untuk informasi tentang cara menggunakan DIRID 13 dengan paket driver pembaruan firmware untuk membuatnya menggunakan 'run from Driver Store', lihat Menulis paket driver pembaruan untuk.
10 Lihat File lainnya.
11 Lihat File lainnya.
12 UMDF Lihat biner driver UMDF.
12 Sebagian besar file dengan tujuan DIRID 12 mewakili biner layanan driver. Lihat Biner layanan.
16422, 16426, 16427, 16428 Sebagian besar file dengan tujuan DARI DIRID ini mewakili penginstalan aplikasi. Sebagai gantinya, sediakan aplikasi Platform Windows Universal (UWP) dan instal menggunakan direktif AddSoftware dari bagian DDInstall.Software dari PAKET driver INF. Untuk detailnya, lihat Memasangkan driver dengan aplikasi Platform Windows Universal (UWP).

Biner layanan

Jika INF Anda menambahkan layanan dan biner tidak dijalankan dari Driver Store, maka INF Anda mungkin terlihat seperti:

[DestinationDirs]
 ; Copy the file to %windir%\system32\drivers
 Example_CopyFiles = 12

[ExampleDDInstall]
CopyFiles = Example_CopyFiles

[Example_CopyFiles]
ExampleBinary.sys

[ExampleDDInstall.Services]
AddService = ExampleService,0x2,Example_Service_Inst

[Example_Service_Inst]
DisplayName   = %SvcDesc%
ServiceType   = %SERVICE_KERNEL_DRIVER%
StartType     = %SERVICE_DEMAND_START%
ErrorControl  = %SERVICE_ERROR_NORMAL%
; Point at the file in %windir%\system32\drivers
ServiceBinary = %12%\ExampleBinary.sys

Untuk memindahkan file ini agar dijalankan dari Penyimpanan Driver, Anda perlu memperbarui entri DestinationDirs tempat file akan disalin dan memperbarui arahan ServiceBinary yang merujuk lokasi file ini.

[DestinationDirs]
; Update the destination to DIRID 13
Example_CopyFiles = 13

[ExampleDDInstall]
CopyFiles = Example_CopyFiles

[Example_CopyFiles]
ExampleBinary.sys

[ExampleDDInstall.Services]
AddService = ExampleService,0x2,Example_Service_Inst

[Example_Service_Inst]
DisplayName   = %SvcDesc%
ServiceType   = %SERVICE_KERNEL_DRIVER%
StartType     = %SERVICE_DEMAND_START%
ErrorControl  = %SERVICE_ERROR_NORMAL%
; Point at the run from Driver Store file using DIRID 13
ServiceBinary = %13%\ExampleBinary.sys

Biner driver UMDF

Jika INF Anda menambahkan driver UMDF dan biner tidak dijalankan dari Driver Store, maka INF Anda mungkin terlihat seperti:

[DestinationDirs]
; Copy the file to %windir%\system32\drivers\UMDF
Example_CopyFiles = 12, UMDF

[ExampleDDInstall]
CopyFiles = Example_CopyFiles

[Example_CopyFiles]
ExampleUmdfDriver.dll

[ExampleDDInstall.Wdf]
UmdfService = ExampleUmdfDriver,Example_UMDF_Inst
...

[Example_UMDF_Inst]
; Point at the file in %windir%\system32\drivers\UMDF
ServiceBinary = %12%\UMDF\ExampleUmdfDriver.dll
...

Untuk memindahkan file ini agar dijalankan dari Penyimpanan Driver, Anda perlu memperbarui entri DestinationDirs tempat file akan disalin dan memperbarui arahan ServiceBinary yang merujuk lokasi file ini.

[DestinationDirs]
; Update the destination to DIRID 13
Example_CopyFiles = 13

[ExampleDDInstall]
CopyFiles = Example_CopyFiles

[Example_CopyFiles]
ExampleUmdfDriver.dll

[ExampleDDInstall.Wdf]
UmdfService = ExampleUmdfDriver,Example_UMDF_Inst
...

[Example_UMDF_Inst]
; Point at the run from Driver Store file using DIRID 13
ServiceBinary = %13%\ExampleUmdfDriver.dll
...

File lain

Jika INF Anda menambahkan file yang mungkin dimuat oleh komponen lain dan tidak dijalankan dari Penyimpanan Driver, maka INF Anda mungkin terlihat seperti berikut ini. Dalam contoh ini, hanya nama file yang ditulis ke status registri perangkat. Komponen yang membaca nilai registri ini untuk menentukan file apa yang akan dimuat tergantung pada file yang ada di dalamnya %windir%\system32 atau bergantung pada urutan pencarian LoadLibrary yang dapat menemukan file.

[DestinationDirs]
; Copy the file to %windir%\system32
Example_CopyFiles = 11

[ExampleDDInstall]
CopyFiles=Example_CopyFiles
AddReg=Example_AddReg

[Example_CopyFiles]
ExampleFile.dll

[Example_AddReg]
HKR,,FileLocation,,"ExampleFile.dll"

Untuk memindahkan file ini agar dijalankan dari Penyimpanan Driver, Anda perlu memperbarui entri DestinationDirs tempat file akan disalin dan memperbarui lokasi yang disimpan dalam status perangkat. Ini mengharuskan komponen yang membaca nilai registri tersebut untuk dapat menangani nilai registri tersebut menjadi jalur lengkap ke file alih-alih file yang relatif terhadap %windir%\system32.

[DestinationDirs]
Example_CopyFiles = 13 ; update the destination to DIRID 13

[ExampleDDInstall]
CopyFiles=Example_CopyFiles
AddReg=Example_AddReg

[Example_CopyFiles]
ExampleFile.dll

[Example_AddReg]
; Point at the run from Driver Store file using DIRID 13
HKR,,FileLocation,,"%13%\ExampleFile.dll"