共用方式為


驅動程式套件隔離

驅動程式套件隔離是 Windows 驅動程式的需求,可讓驅動程式套件對外部變更更有彈性、更容易更新,以及更容易安裝。

注意

雖然 Windows 驅動程式需要驅動程式套件隔離,但 Windows 桌面驅動程式仍可透過改善的復原能力和可服務性來受益於此驅動程式。

下表顯示一些舊版驅動程式套件實務範例,這些做法已不再允許左欄中的 Windows 驅動程式,以及右側數據行中 Windows 驅動程式的必要行為。

非隔離驅動程式 隔離驅動程式
INF 會將檔案複製到 %windir%\System32 或 %windir%\System32\drivers 驅動程式檔案是從 驅動程式存放區執行
使用硬式編碼路徑與裝置堆疊/驅動程序互動 使用系統提供的函式或裝置介面與裝置堆疊/驅動程序互動
全域登錄位置的硬式編碼路徑 針對登錄和檔案狀態的相對位置使用 HKR 和系統提供的函式
運行時間檔案寫入任何位置 檔案會相對於作業系統提供的位置寫入

如需判斷驅動程式套件是否符合驅動程式套件隔離需求的說明,請參閱 驗證 Windows 驅動程式。 如需如何更新 INF 以符合驅動程式套件隔離需求的範例,請參閱 移植 INF 以遵循驅動程式套件隔離

從驅動程式存放區執行

所有隔離的驅動程式套件都會將其驅動程式套件檔案保留在驅動程式存放區中。 這表示他們在 INF 中指定 DIRID 13 ,以指定安裝時驅動程式套件檔案的位置。 如需如何在驅動程式套件中使用此功能的詳細資訊,請參閱 從驅動程式存放區執行。

讀取和寫入狀態

注意

如果您的元件使用裝置或裝置介面 屬性 來儲存狀態,請繼續使用該方法和適當的OS API來儲存和存取狀態。 下列登錄和檔案狀態指引適用於 元件需要儲存的其他 狀態。

若要存取各種登錄和檔案狀態,應該藉由呼叫函式來提供狀態位置的呼叫端來完成,然後狀態會相對於該位置讀取/寫入。 請勿使用硬式編碼的絕對登錄路徑和檔案路徑。

本節包含下列子區段:

登錄狀態

本節包含下列子區段:

PnP 裝置登錄狀態

隔離的驅動程式套件和使用者模式元件通常會使用兩個位置的其中一個,將裝置狀態儲存在登錄中。 這些是 裝置的硬體金鑰(裝置金鑰 )和 裝置的軟體金鑰 (驅動程式金鑰)。 硬體 密鑰 通常適用於與個別裝置實例如何與硬體互動的相關設定。 例如,若要啟用硬體功能,或將硬體放入特定模式。 軟體 金鑰 通常適用於與個別裝置實例如何與系統和其他軟體互動的相關設定。 例如,若要設定資料檔的位置、與架構互動,或存取裝置的應用程式設定。 若要擷取這些登錄位置的句柄,請使用下列其中一個選項:

[ExampleDDInstall.HW]
AddReg = Example_DDInstall.AddReg

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

裝置介面登錄狀態

若要讀取和寫入裝置介面登錄狀態,請使用下列其中一個選項:

服務登錄狀態

服務狀態應分類為3個類別之一

不可變的服務登錄狀態

固定服務狀態是安裝服務的驅動程式套件所提供的狀態。 這些由 INF 為驅動程式和 Win32 服務設定的登錄值,必須儲存在服務的 「參數」子機碼下,方法是在 AddReg 區段中提供 HKR 行,然後在 INF 的服務安裝區段中參考該區段。 例如:

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

[Example_Service_Inst]
DisplayName    = %ExampleService.SvcDesc%
ServiceType    = 1
StartType      = 3
ErrorControl   = 1
ServiceBinary  = %13%\ExampleService.sys
AddReg=Example_Service_Inst.AddReg

[Example_Service_Inst.AddReg]
HKR, Parameters, ExampleValue, 0x00010001, 1

若要在執行時間從服務存取此狀態的位置,請使用下列其中一個函式:

INF 在服務的 「Parameters」 子機碼中提供的這些登錄值,應該只在運行時間讀取,而不會修改。 應該將它們視為唯讀。

如果 INF 所提供的登錄值是可在運行時間覆寫的預設設定,則覆寫值應該寫入 服務的內部服務登錄狀態共用服務登錄狀態 。 擷取設定時,可以先在可變動狀態中尋找設定。 如果不存在,則可以在不可變的狀態中尋找設定。 RtlQueryRegistryValueWithFallback 可用來協助查詢設定,例如具有覆寫和預設值的查詢設定。

內部服務登錄狀態

內部服務狀態是在運行時間寫入且只由服務本身所擁有和管理的狀態,而且只能供該服務存取。 若要存取內部服務狀態的位置,請使用服務的其中一個函式:

如果服務想要允許其他元件修改這些設定,服務必須公開另一個元件可以呼叫的介面,告知服務如何改變這些設定。 例如,Win32 服務可能會公開 COM 或 RPC 介面,而驅動程式服務可以透過裝置介面公開 IOCTL 介面。

共用服務登錄狀態

共用服務狀態是在運行時間寫入的狀態,如果元件具有足夠的許可權,則可以與其他使用者模式元件共用。 若要存取此共享服務狀態的位置,請使用下列其中一個函式:

檔案狀態

本節包含下列子區段:

裝置檔案狀態

如果與裝置相關的檔案必須在運行時間寫入,這些檔案應該與透過OS API提供的句柄或檔案路徑相對儲存。 該裝置特有的組態檔是此處要儲存的檔類型的其中一個範例。 若要存取此狀態的位置,請使用服務中的其中一個函式:

服務檔案狀態

服務檔案狀態可分類為3個類別之一

不可變的服務檔案狀態

不可變的服務檔案狀態是屬於驅動程式套件的檔案。 如需存取這些檔案的詳細資訊,請參閱 從驅動程式存放區執行。

內部服務檔案狀態

內部服務檔案狀態是在運行時間寫入,且只由服務本身擁有和管理的狀態,而且只能供該服務存取。 若要存取內部服務狀態的位置,請使用服務的其中一個函式:

如果服務想要允許其他元件修改這些設定,服務必須公開另一個元件可以呼叫的介面,告知服務如何改變這些設定。 例如,Win32 服務可能會公開 COM 或 RPC 介面,而驅動程式服務可以透過裝置介面公開 IOCTL 介面。

共用服務檔案狀態

共用服務檔案狀態是在運行時間寫入的狀態,如果元件具有足夠的許可權,則可以與其他使用者模式元件共用。 若要存取此共享服務狀態的位置,請使用下列其中一個函式:

  • IoGetDriverDirectory (WDM, KMDF) ,並將 DirectoryType 參數設定為 DriverDirectorySharedData

  • GetSharedServiceDirectory (Win32 Services) ,並將 DirectoryType 參數設定為 ServiceSharedDirectoryPersistentState

DriverData 和 ProgramData

可以與其他元件共用但不符合 共用服務檔案狀態 類別的檔案,可以寫入 DriverDataProgramData 位置。

這些位置提供元件位置,以寫入要由其他元件取用的暫存狀態或狀態,並可能從系統收集並複製,以便由另一個系統處理。 例如,自定義記錄檔或損毀傾印符合此描述。

避免在 或 ProgramData 目錄的DriverData根目錄中寫入檔案。 相反地,請使用您的公司名稱建立子目錄,然後在該目錄中寫入檔案和進一步子目錄。

例如,針對 Contoso 的公司名稱,內核模式驅動程式可以將自定義記錄寫入 , \DriverData\Contoso\Logs 而使用者模式應用程式可以從 收集或分析記錄檔 %DriverData%\Contoso\Logs

DriverData

DriverData 目錄可在 Windows 10 版本 1803 和更新版本中使用,而且可供系統管理員和 UMDF 驅動程式存取。

內核模式驅動程式會使用稱為\DriverData的系統提供的符號連結來存取DriverData目錄。

使用者模式程式會使用環境變數 %DriverData%來存取DriverData目錄。

ProgramData

使用者 %ProgramData% 模式環境變數可用於儲存數據時要使用的使用者模式元件。

暫存檔案

臨時檔通常用於中繼作業。 這些可以寫入 或 %TMP% 環境變數下的%TEMP%子路徑。 由於這些位置是透過環境變數存取,因此這項功能僅限於使用者模式元件。 在關閉這些暫存盤的句柄之後,這些暫存盤的存留期或持續性沒有任何保證。 操作系統或使用者可以隨時移除它們,而且可能無法在重新啟動期間保存。

避免在 或 %TMP% 目錄的%TEMP%根目錄中寫入檔案。 相反地,請使用您的公司名稱建立子目錄,然後在該目錄中寫入檔案和進一步子目錄。

屬性狀態

裝置和裝置介面都支援透過 PnP 屬性模型儲存狀態。 屬性模型允許針對裝置或裝置介面儲存結構化屬性數據。 這適用於較小的數據,可合理地納入屬性模型所支援的屬性類型。

若要存取裝置屬性,可以使用這些 API:

若要存取裝置介面屬性,可以使用這些 API:

使用裝置介面

如果驅動程式想要允許其他元件讀取或修改驅動程式的內部狀態,驅動程式應該公開另一個元件可以呼叫的介面,告知驅動程式要傳回哪些設定,或如何修改特定設定。 例如,驅動程式服務可以透過裝置介面公開IOCTL介面。

一般而言,擁有狀態的驅動程式會在自定義裝置介面類別中公開裝置介面。 當驅動程式準備好讓其他元件能夠存取狀態時,它會啟用 介面。 若要在啟用裝置介面時收到通知,使用者模式元件可以註冊 裝置介面抵達通知 ,而核心模式元件可以使用 IoRegisterPlugPlayNotification。 若要讓這些元件存取狀態,啟用介面的驅動程序必須為其自定義裝置介面類別定義合約。 此合約通常是兩種類型之一:

  • I/O 合約可以與該裝置介面類別相關聯,該類別提供存取狀態的機制。 其他元件會使用已啟用的裝置介面來傳送符合合約的 I/O 要求。

  • 透過 查詢介面傳回的直接呼叫介面 。 其他驅動程式可能會傳送 IRP_MN_QUERY_INTERFACE ,以從驅動程式擷取要呼叫的函式指標。

或者,如果擁有狀態的驅動程式允許直接存取狀態,其他驅動程式可以使用系統提供的函式來存取狀態,以程序設計方式存取裝置介面狀態。 如需詳細資訊,請參閱 裝置介面登錄狀態

這些介面或狀態(視所使用的共用方法而定)必須正確設定版本,以便擁有狀態的驅動程式可以獨立於存取該狀態的其他元件進行服務。 驅動程式廠商無法依賴與驅動程式同時服務的其他元件,並保持相同的版本。

因為控制介面的裝置和驅動程式會來回走,驅動程式和應用程式應該避免在元件啟動時呼叫 IoGetDeviceInterfaces ,以取得已啟用介面的清單。 相反地,最佳做法是註冊裝置介面抵達或移除的通知,然後呼叫適當的函式以取得計算機上現有已啟用介面的清單。

如需裝置介面的詳細資訊,請參閱:

狀態管理 API 作業系統支援的快速參考

大部分的驅動程式套件都需要支援一系列操作系統版本。 如需如何在驅動程式套件中達成此目的的詳細資訊,請參閱 支援多個操作系統版本 。 下表提供針對各種狀態管理 API 新增作業系統支援時的快速參考。

WDM 驅動程式

作業系統 已新增支援
Windows 2000 IoOpenDeviceRegistryKey
IoOpenDeviceInterfaceRegistryKey
Windows Vista IoGetDevicePropertyData
IoSetDevicePropertyData
Windows 8 IoGetDeviceInterfacePropertyData
IoSetDeviceInterfacePropertyData
Windows 8.1 IoQueryFullDriverPath
Windows 10 1803 DriverRegKeyParameters 和 DriverRegKeyPersistentState 之 RegKeyTypeIoOpenDriverRegistryKey
IoGetDeviceDirectory
DriverDirectoryImage 和 DriverDirectoryData 之 DirectoryTypeIoGetDriverDirectory
Windows 10 1809 RtlQueryRegistryValueWithFallback
Windows 11 21H2 DriverRegKeySharedPersistentState 之 RegKeyTypeIoOpenDriverRegistryKey
DriverDirectorySharedData 的 DirectoryTypeIoGetDriverDirectory

KMDF 驅動程式

KMDF 版本 已新增支援
1.0 WdfDeviceOpenRegistryKey
WdfFdoInitOpenRegistryKey
WdfDriverOpenParametersRegistryKey
WdfDeviceQueryProperty
WdfDeviceAllocAndQueryProperty
WdfFdoInitQueryProperty
WdfFdoInitAllocAndQueryProperty
1.13 WdfDeviceQueryPropertyEx
WdfDeviceAllocAndQueryPropertyEx
WdfDeviceAssignProperty
WdfFdoInitQueryPropertyEx
WdfFdoInitAllocAndQueryPropertyEx
1.25 WdfDriverOpenPersistentStateRegistryKey (Windows 10 1803)

UMDF 驅動程式

UMDF 版本 已新增支援
2.0 WdfDeviceOpenRegistryKey
WdfFdoInitOpenRegistryKey
WdfDriverOpenParametersRegistryKey
WdfDeviceQueryProperty
WdfDeviceAllocAndQueryProperty
WdfDeviceQueryPropertyEx
WdfDeviceAllocAndQueryPropertyEx
WdfDeviceAssignProperty
WdfFdoInitQueryProperty
WdfFdoInitAllocAndQueryProperty
WdfFdoInitQueryPropertyEx
WdfFdoInitAllocAndQueryPropertyEx
WdfDeviceQueryInterfaceProperty (Windows 8.1)
WdfDeviceAllocAndQueryInterfaceProperty (Windows 8.1)
WdfDeviceAssignInterfaceProperty (Windows 8.1)
2.25 WdfDeviceRetrieveDeviceDirectoryString
WdfDriverOpenPersistentStateRegistryKey (Windows 10 1803)
2.27 WdfDriverRetrieveDriverDataDirectoryString

使用者模式程序代碼

作業系統 已新增支援
Windows 2000 CM_Open_DevNode_Key
Windows Vista CM_Open_Device_Interface_Key
CM_Get_DevNode_Property
CM_Set_DevNode_Property
CM_Get_Device_Interface_Property
CM_Set_Device_Interface_Property
Windows 10 2004 GetServiceRegistryStateKey
GetServiceDirectory
Windows 11 21H2 GetSharedServiceRegistryStateKey
GetSharedServiceDirectory