裝置延伸模組

對於大部分的中繼和最低層級驅動程式,裝置延伸模組是與裝置物件相關聯的最重要資料結構。 其內部結構是驅動程式定義的,而且通常用來:

  • 維護裝置狀態資訊。

  • 為驅動程式所使用的任何核心定義物件或其他系統資源提供儲存體,例如微調鎖定。

  • 保存驅動程式必須具有駐留和系統空間才能執行其 I/O 作業的任何資料。

因為大部分匯流排、函式和篩選驅動程式 (最低層級和中繼驅動程式,) 任意執行緒內容中執行, (執行緒發生目前) ,裝置擴充功能是每個驅動程式的主要位置,可維護驅動程式所需的裝置狀態和其他所有裝置特定資料。 例如,任何實作 CustomTimerDpcCustomDpc 常式的驅動程式,通常會為裝置擴充功能中必要的核心定義計時器和/或 DPC 物件提供儲存體。

具有 ISR 的每個驅動程式都必須為一組核心定義的中斷物件提供指標的儲存體,而且大部分的設備磁碟機都會將此指標儲存在裝置延伸模組中。 每個驅動程式會在建立裝置物件時決定裝置擴充功能的大小,而每個驅動程式都會定義其本身裝置擴充功能的內容和結構。

I/O 管理員的IoCreateDevice 和 IoCreateDeviceSecure常式會從非分頁式記憶體集區配置裝置物件的記憶體和擴充功能。

接收 IRP 的每個標準驅動程式常式也會接收代表所要求 I/O 作業之目標裝置之裝置物件的指標。 這些驅動程式常式可以透過這個指標存取對應的裝置延伸模組。 通常 ,DeviceObject 指標也是最低層級驅動程式 ISR 的輸入參數。

下圖顯示最低層級驅動程式裝置物件的裝置延伸模組的一組代表性驅動程式定義資料。 較高層級的驅動程式不會為 IoConnectInterrupt 傳回的中斷物件指標提供儲存體,並傳遞至 KeSynchronizeExecutionIoDisconnectInterrupt。 不過,如果驅動程式有 CustomTimerDpc 常式,則較高層級的驅動程式會為下圖所示的計時器和 DPC 物件提供儲存體。 較高層級的驅動程式也可能提供執行微調鎖定和相互鎖定工作佇列的儲存體。

此圖說明最低層級驅動程式的範例裝置擴充功能。

除了提供中斷物件指標的儲存空間之外,如果其 ISR 處理不同向量上兩或多個裝置的中斷,或有一個以上的 ISR,則最低層級設備磁碟機必須提供中斷微調鎖定的儲存體。 如需註冊 ISR 的詳細資訊,請參閱 註冊 ISR

一般而言,驅動程式會將其裝置物件的指標儲存在其裝置延伸模組中,如下圖所示。 驅動程式也可能保留擴充功能中裝置的資源清單複本。

較高層級的驅動程式通常會在其裝置擴充功能中儲存下一個較低驅動程式裝置物件的指標。 較高層級的驅動程式必須在 IRP 中設定下一個較低驅動程式的 I/O 堆疊位置之後,將下一個較低驅動程式的裝置物件指標傳遞至 IoCallDriver,如 處理 IRP中所述。

另請注意,為較低層級驅動程式配置 IRP 的任何較高層級驅動程式,都必須指定新 IRP 應該擁有多少堆疊位置。 特別是,如果較高層級的驅動程式呼叫 IoMakeAssociatedIrpIoAllocateIrpIoInitializeIrp,則必須存取下一個較低層級驅動程式的目標裝置物件來讀取其 StackSize 值,以便提供正確的 StackSize 作為這些支援常式的引數。

雖然較高層級的驅動程式可以透過 IoAttachDeviceToDeviceStack所傳回的指標,從下一個較低層級驅動程式的裝置物件讀取資料,但這類驅動程式必須遵循下列實作指導方針:

  • 絕不會嘗試將資料寫入較低驅動程式的裝置物件。

    此指導方針的唯一例外是檔案系統,這些檔案系統會在較低層級卸載式媒體驅動程式裝置物件的 標中設定和清除DO_VERIFY_VOLUME。

  • 基於下列原因,請勿嘗試存取較低驅動程式的裝置擴充功能:

    • 無法安全地同步存取兩個驅動程式之間的單一裝置擴充功能。

    • 一組實作這類後門程式通訊配置的驅動程式無法個別升級,而且在它們之間無法插入中繼驅動程式,而不需要變更現有的驅動程式來源,也無法從一個 Windows 平臺重新編譯並移動至下一個 Windows 平臺。

為了保留其與較低層級驅動程式的互通性,從一個 Windows 平臺或版本到下一個版本,較高層級驅動程式必須重複使用指定的 IRP,或必須建立新的 IRP,而且必須使用 IoCallDriver 將要求傳達給較低層級的驅動程式。