Framework 檔案物件

當應用程式或驅動程式嘗試存取裝置時,通常是藉由建立或開啟檔案,作業系統會將檔案建立要求傳送至驅動程式堆疊。 當應用程式或驅動程式使用完裝置時,系統會傳送檔案清除,並將要求關閉至驅動程式堆疊。 這三個 要求的要求類型 分別是 WdfRequestTypeCreateWdfRequestTypeCleanupWdfRequestTypeClose

一般而言,除非您的驅動程式呼叫 WdfDeviceInitSetExclusive,否則驅動程式在收到檔案建立、清除和關閉要求時,必須執行檔案特定的或其他存取特定作業,因為多個檔案可以同時開啟,或多個應用程式可以同時存取裝置。 因此,驅動程式必須追蹤與每個檔案或應用程式相關聯的 I/O 要求。

架構會定義 架構檔案物件,代表應用程式或驅動程式存取裝置的方法,例如檔案、目錄、磁片區、郵件位置、具名管道或整個裝置。 檔案名可以與檔案物件相關聯,但檔案名的意義是驅動程式特定的。 如需檔案名的詳細資訊,請參閱 控制裝置命名空間存取

如果您的驅動程式必須處理檔案作業,它必須從其EvtDriverDeviceAdd回呼函式內呼叫WdfDeviceInitSetFileObjectConfigWdfDeviceInitSetFileObjectConfig方法會接收WDF_FILEOBJECT_CONFIG結構做為輸入。 驅動程式會使用此結構來註冊其 EvtDeviceFileCreateEvtFileCleanupEvtFileClose 回呼函式,並選擇性地指出架構是否應該在每次驅動程式收到檔案建立要求時建立架構檔案物件。

處理檔案作業的大部分驅動程式會將檔案特定資訊儲存在架構檔案物件 的內容空間中。 如果您的驅動程式會處理檔案作業,但不需要將資訊儲存在檔案物件的內容空間中,架構就不需要為驅動程式建立架構檔案物件。

建立或開啟檔案

當架構收到函式驅動程式的檔案建立要求時,它會:

  1. 除非驅動程式先前指出不需要使用架構檔案物件,否則會建立代表檔案的架構檔案物件。

  2. 如果驅動程式已註冊回呼函式,則呼叫驅動程式的 EvtDeviceFileCreate 回呼函式。

EvtDeviceFileCreate回呼函式通常會取得檔案的相關資訊,例如其名稱和檔案物件旗標。 驅動程式通常會將這項資訊儲存在架構檔案物件的內容空間中。

驅動程式可以呼叫WdfDeviceConfigureRequestDispatching來設定 I/O 佇列,以接收WdfRequestTypeCreate要求類型) 的所有檔案建立要求 (,而不是提供EvtDeviceFileCreate回呼函式。 驅動程式後續會在佇列的 EvtIoDefault 要求處理常式中接收檔案建立要求。 (如果佇列WDF_IO_QUEUE_CONFIG結構的DefaultQueue成員設定為TRUE.) ,I/O 佇列便無法接收檔案建立要求

如果您的驅動程式未提供 EvtDeviceFileCreate 回呼函式,而且未設定 I/O 佇列來處理 WdfRequestTypeCreate-typed I/O 要求,架構:

  • 如果您的驅動程式是函式驅動程式,請完成驅動程式的所有檔案建立要求,其狀態值為 STATUS_SUCCESS。

  • 如果您的驅動程式是篩選驅動程式,請將所有檔案建立要求轉送到下一個較低的驅動程式。

(若要查看如何變更此行為,請參閱WDF_FILEOBJECT_CONFIG structure.) 的AutoForwardCleanupClose成員

注意 如果您的函式驅動程式未提供應用程式可用來存取驅動程式 裝置的任何裝置介面 ,驅動程式必須提供 EvtDeviceFileCreate 回呼函式,此函式會以狀態值完成所有檔案建立要求,NT_SUCCESS (狀態) 等於 FALSE。 否則,惡意應用程式可能會嘗試使用裝置實體裝置物件的名稱 (PDO) 來存取裝置。 (所有 PDO 都有 name.)

如果驅動程式將建立要求 轉送 至 I/O 目標,除非驅動程式從 I/O 目標收到失敗狀態值,否則驅動程式不得以失敗狀態值 完成 要求。 否則,下層驅動程式將不會收到建立要求失敗的通知,而且可能會嘗試像開啟檔案一樣運作。

如果驅動程式將建立要求轉送至 I/O 目標,如果架構已建立建立要求的架構檔案物件,驅動程式就無法設定 WDF_REQUEST_SEND_OPTION_SEND_AND_FORGET 旗標。 因此,除非驅動程式也設定 WdfFileObjectNotRequired 旗標,否則驅動程式無法設定建立要求的WDF_REQUEST_SEND_OPTION_SEND_AND_FORGET旗標,因為驅動程式將無法在堆疊較低時清除 WDFFILEOBJECT。 相反地,驅動程式可以使用任何其他傳送選項,例如,使用完成常式以非同步方式傳送,或以同步方式傳送。 在這兩種情況下,驅動程式必須在重新取得控制權時呼叫 WdfRequestComplete

請注意,如果驅動程式完成具有錯誤狀態的建立要求,架構會刪除架構檔案物件,但不會呼叫驅動程式的 EvtFileCleanupEvtFileClose 回 呼函式。 因此,如果驅動程式在檔案物件的內容空間之外配置額外的物件特定記憶體,則必須提供刪除已配置記憶體的 EvtCleanupCallbackEvtDestroyCallback 回 呼函式。

針對 Windows Vista 和更新版本,可以 取消檔案建立要求。 舊版 Windows 作業系統不支援取消檔案建立要求。

系統會針對來自使用者應用程式的每個建立要求, (WDM) 檔案物件建立 Windows 驅動程式模型。 如果驅動程式傳送建立要求,它可能不會為要求建立 WDM 檔案物件。 一般而言,如果 WDM 檔案物件不存在,架構就不會建立架構檔案物件。 不過,如果您的驅動程式已呼叫WdfDeviceInitSetExclusive,而且驅動程式已在WDF_FILEOBJECT_CONFIG結構的FileObjectClass成員中設定WdfFileObjectWdfCannotUseFsCoNtexts,則架構會建立架構檔案物件,即使 WDM 檔案物件不存在也一樣。

取得檔案資訊

驅動程式的 EvtDeviceFileCreate 回呼函式可以呼叫下列一或多個物件方法,以取得應用程式或驅動程式存取裝置的相關資訊:

WdfFileObjectGetFileName
傳回包含在架構檔案物件中的檔案名。

WdfFileObjectGetFlags
傳回包含在架構檔案物件中的旗標。

WdfFileObjectWdmGetFileObject
傳回與架構檔案物件相關聯的 WDM 檔案物件。

WdfRequestGetParameters
擷取與架構要求物件相關聯的參數。 如果要求類型WdfRequestTypeCreateWDF_REQUEST_PARAMETERS結構的Parameters.Create成員會包含檔案建立要求的相關資訊。

驅動程式通常會將檔案資訊儲存在架構檔案物件的內容空間中。 當您的驅動程式從其中一個 I/O 佇列取得 I/O 要求時,驅動程式可以呼叫 WdfRequestGetFileObject ,以取得與要求相關聯的架構檔案物件的控制碼。 驅動程式接著可以擷取儲存在架構檔案物件內容空間中的檔案資訊。

您的驅動程式可以藉由呼叫 WdfIoQueueRetrieveRequestByFileObject來搜尋與特定檔案相關聯的要求 I/O 佇列。

如果您的驅動程式具有 WDM DEVICE_OBJECT 結構的指標,驅動程式可以呼叫 WdfDeviceGetFileObject ,以取得與 WDM 裝置物件相關聯的架構檔案物件的控制碼。

關閉檔案

當應用程式或其他驅動程式關閉檔案時,架構會收到清除要求,以及驅動程式的關閉要求。 架構:

  1. 如果驅動程式已註冊這些回呼函式,請呼叫驅動程式的 EvtFileCleanupEvtFileClose 回呼函式。

  2. 刪除代表檔案的架構檔案物件。

驅動程式的 EvtFileCleanupEvtFileClose 回呼函式會收到架構檔案物件的控制碼。 驅動程式可以呼叫 WdfFileObjectGetDevice 來判斷哪個架構裝置物件與架構檔案物件相關聯。