當應用程式或驅動程式嘗試存取裝置時,通常是藉由建立或開啟檔案,作系統會將檔案建立要求傳送至驅動程式堆疊。 當應用程式或驅動程式使用裝置完成時,系統會將檔案清除和關閉要求傳送至驅動程式堆疊。 這三個要求的 要求類型 分別 WdfRequestTypeCreate、WdfRequestTypeCleanup和 WdfRequestTypeClose。
一般而言,除非您的驅動程式已呼叫 WdfDeviceInitSetExclusive,否則驅動程式在收到檔案建立、清除和關閉要求時,必須執行檔案特定或其他存取特定作業,因為多個檔案可以同時開啟,或多個應用程式可以同時存取裝置。 因此,驅動程式必須追蹤與每個檔案或應用程式相關聯的 I/O 要求。
架構會定義 架構檔案物件,代表應用程式或驅動程式存取裝置的方法,例如檔案、目錄、磁碟區、郵件位置、命名管道或整個裝置。 檔名可以與檔案對象相關聯,但檔名的意義是驅動程式特定的。 如需檔案名的詳細資訊,請參閱 控制裝置命名空間存取。
如果您的驅動程式必須處理檔案作業,它必須從其 EvtDriverDeviceAdd 回呼函式內呼叫 WdfDeviceInitSetFileObjectConfig。 WdfDeviceInitSetFileObjectConfig 方法會接收 WDF_FILEOBJECT_CONFIG 結構做為輸入。 驅動程式會使用此結構來註冊其 EvtDeviceFileCreate、EvtFileCleanup,以及 EvtFileClose 回呼函式,並選擇性地指出架構是否應該在每次驅動程式收到檔案建立要求時建立架構檔案物件。
處理檔案作業的大部分驅動程式會將檔案特定資訊儲存在架構檔案物件的 內容空間中,。 如果您的驅動程式處理檔案作業,但不需要將資訊儲存在檔案對象的內容空間中,架構就不需要建立驅動程式的架構檔案物件。
建立或開啟檔案
當架構收到函式驅動程序的檔案建立要求時,它會:
建立代表檔案的架構檔案物件,除非驅動程式先前指出它不需要使用架構檔案物件。
如果驅動程式已註冊回呼函式,請呼叫驅動程式的 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 結構的 AutoForwardCleanupClose 成員。
注意:如果您的函式驅動程式未提供任何 裝置介面 供應用程式存取驅動程式的裝置,則驅動程式必須提供 EvtDeviceFileCreate 回呼函式,以用一個 NT_SUCCESS(狀態) 等於 FALSE的狀態值來完成所有檔案建立要求。 否則,惡意應用程式可能會嘗試使用裝置實體裝置物件 (PDO) 的名稱來存取裝置。 (所有 PDO 都有 名稱。
如果驅動程式 將建立要求轉送至 I/O 目標,除非從 I/O 目標收到失敗狀態值,否則驅動程式不得隨後以失敗狀態值 完成 該要求。 否則,較低驅動程式將不會收到建立要求失敗的通知,而且可能會嘗試像開啟檔案一樣運作。
如果驅動程式將建立要求轉送至 I/O 目標,如果架構已建立建立要求的架構檔案對象,驅動程式就無法設定 WDF_REQUEST_SEND_OPTION_SEND_AND_FORGET 旗標。 因此,驅動程式無法為建立要求設定 WDF_REQUEST_SEND_OPTION_SEND_AND_FORGET 旗標,除非它也設定 WdfFileObjectNotRequired 旗標,因為當堆疊中的較低層驅動程式使建立要求失敗時,驅動程式將無法清除 WDFFILEOBJECT。 相反地,驅動程式可以使用任何其他傳送選項,例如,使用完成例程以異步方式傳送或同步傳送。 在這兩種情況下,驅動程式必須在重新取得控制權時呼叫 WdfRequestComplete。
請注意,如果驅動程式完成具有錯誤狀態的建立要求,架構會刪除架構檔案物件,但不會呼叫驅動程式的 EvtFileCleanup 或 EvtFileClose 回呼函式。 因此,如果驅動程式在檔案對象的內容空間之外配置額外的物件特定記憶體,則必須提供 EvtCleanupCallback 或 EvtDestroyCallback 回呼函式,以刪除已配置的記憶體。
針對 Windows Vista 和更新版本,檔案建立要求可以在 取消。 舊版 Windows作系統不支援取消檔案建立要求。
系統會針對來自使用者應用程式的每個建立要求,一律建立 Windows 驅動程式模型 (WDM) 檔案物件。 如果驅動程式傳送建立要求,它可能不會建立要求的 WDM 檔案物件。 一般而言,如果 WDM 檔案物件不存在,架構就不會建立架構檔案物件。 不過,如果您的驅動程式已呼叫 WdfDeviceInitSetExclusive,並且在 WDF_FILEOBJECT_CONFIG 結構的 FileObjectClass 成員中設定 WdfFileObjectWdfCannotUseFsContexts,則即使 WDM 檔案物件不存在,架構仍會建立一個架構檔案物件。
取得檔案資訊
驅動程式的 EvtDeviceFileCreate 回呼函式可以呼叫下列一或多個物件方法,以取得應用程式或驅動程式存取裝置的相關信息:
WdfFileObjectGetFileName
傳回包含在架構檔案物件中的檔名。
WdfFileObjectGetFlags
傳回包含在架構檔案物件內的旗標。
WdfFileObjectWdmGetFileObject
傳回與架構檔案對象相關聯的 WDM 檔案物件。
WdfRequestGetParameters
擷取與架構要求對象相關聯的參數。 如果 請求類型 是 WdfRequestTypeCreate,則 WDF_REQUEST_PARAMETERS 結構中的 Parameters.Create 成員包含有關建立檔案請求的資訊。
驅動程式通常會將檔案資訊儲存在架構檔案對象的內容空間中。 當您的驅動程式在其 I/O 佇列中取得 I/O 要求時,驅動程式可以呼叫 WdfRequestGetFileObject,以取得與要求相關聯的架構檔案物件的句柄。 然後,驅動程式可以擷取儲存在架構檔案對象內容空間中的檔案資訊。
您的驅動程式可以藉由呼叫 WdfIoQueueRetrieveRequestByFileObject來搜尋與特定檔案相關聯的要求 I/O 佇列。
如果您的驅動程式具有 WDM DEVICE_OBJECT 結構的指標,驅動程式可以呼叫 WdfDeviceGetFileObject,以取得與 WDM 裝置對象相關聯的架構檔案物件的句柄。
關閉檔案
當應用程式或其他驅動程式關閉檔案時,框架會收到對您的驅動程式的清理請求和關閉請求。 架構:
如果驅動程式已註冊這些回呼函式,請呼叫驅動程式的 EvtFileCleanup 和 EvtFileClose 回呼函式。
刪除代表檔案的架構檔案物件。
驅動程式的 EvtFileCleanup 和 EvtFileClose 回呼函式會收到框架文件物件的控制代碼。 驅動程式可以呼叫 WdfFileObjectGetDevice,以判斷哪個架構裝置物件與架構檔案對象相關聯。