IoCreateFile 函式 (wdm.h)

IoCreateFile 例程會建立新的檔案或目錄,或開啟現有的檔案、裝置、目錄或磁碟區,讓呼叫端擁有檔案物件的句柄。

語法

NTSTATUS IoCreateFile(
  [out]          PHANDLE            FileHandle,
  [in]           ACCESS_MASK        DesiredAccess,
  [in]           POBJECT_ATTRIBUTES ObjectAttributes,
  [out]          PIO_STATUS_BLOCK   IoStatusBlock,
  [in, optional] PLARGE_INTEGER     AllocationSize,
  [in]           ULONG              FileAttributes,
  [in]           ULONG              ShareAccess,
  [in]           ULONG              Disposition,
  [in]           ULONG              CreateOptions,
  [in, optional] PVOID              EaBuffer,
  [in]           ULONG              EaLength,
  [in]           CREATE_FILE_TYPE   CreateFileType,
  [in, optional] PVOID              InternalParameters,
  [in]           ULONG              Options
);

參數

[out] FileHandle

如果呼叫成功,則會接收檔句柄的變數指標。 一旦不再使用句柄,驅動程式就必須關閉 ZwClose 的句柄。

[in] DesiredAccess

旗標的位掩碼,指定呼叫端所需的檔案或目錄存取類型。 如需此參數的詳細資訊和旗標值清單,請參閱IoCreateFileExDesiredAccess 參數。

[in] ObjectAttributes

已使用 InitializeObjectAttributes 初始化之不透明OBJECT_ATTRIBUTES結構的指標。 如需詳細資訊和每個結構成員的描述,請參閱IoCreateFileExObjectAttributes 參數。

[out] IoStatusBlock

接收最終完成狀態和所要求作業相關信息 之IO_STATUS_BLOCK 結構的指標。 請參閱IoCreateFileExIoStatusBlock參數。

[in, optional] AllocationSize

選擇性地指定檔案的初始配置大小,以位元組為單位。 除非正在建立、覆寫或取代檔案,否則非零值沒有任何作用。

[in] FileAttributes

只有在檔案建立、取代或在某些情況下覆寫時,才會套用明確指定的屬性。 根據預設,此值為 FILE_ATTRIBUTE_NORMAL,可由 Wdm.h 中定義的一或多個 FILE_ATTRIBUTE_XXX 旗標的 ORed 組合覆寫。 如需可與 IoCreateFile搭配使用的旗標清單,請參閱 CreateFile

[in] ShareAccess

指定呼叫端所需的檔案共用存取類型、零或一個,或旗標的組合。 如需詳細資訊和旗標清單,請參閱IoCreateFileExShareAccess參數。

[in] Disposition

指定值,根據檔案是否已經存在,決定要採取的動作。 如需可能的值清單,請參閱IoCreateFileExDisposition 參數。

[in] CreateOptions

指定要在建立或開啟檔案時套用的選項。 此參數是IoCreateFileEx的 CreateOptions 參數所列出的旗標相容組合。

[in, optional] EaBuffer

對於裝置和中繼驅動程式,此參數必須是 NULL 指標。

[in] EaLength

針對裝置和中繼驅動程式,此參數必須為零。

[in] CreateFileType

驅動程式必須將此參數設定為 CreateFileTypeNone

[in, optional] InternalParameters

驅動程式必須將此參數設定為 NULL

[in] Options

指定要在建立要求期間使用的選項。 如需可能的選項清單,請參閱IoCreateFileExOptions參數。

傳回值

IoCreateFile 會傳回STATUS_SUCCESS或適當的錯誤狀態。 NTSTATUS 值。 如需可能的傳回碼清單,請參閱IoCreateFileEx的傳回一節。

備註

IoCreateFileEx 例程類似於IoCreateFile例程,但提供比IoCreateFile例程更大的功能,包括存取額外的建立參數 (ECP) 、裝置物件和交易資訊。

後續呼叫即可使用 IoCreateFile 取得的句柄,以操作檔案內的數據或檔案物件的狀態或屬性。

有兩種替代方式可指定要使用 IoCreateFile 建立或開啟的檔名:

  1. 作為完整路徑名稱,在輸入 ObjectAttributesObjectName 成員中提供

  2. 路徑名稱,相對於輸入 ObjectAttributes之 RootDirectory 成員中句柄所代表的目錄檔案

某些 DesiredAccess 旗標和旗標組合具有下列效果:

  • 若要讓呼叫端等候傳回的 FileHandle 同步處理 I/O 完成,必須設定 SYNCHRONIZE 旗標。 否則,屬於裝置或中繼驅動程式的呼叫端必須使用事件物件同步處理I/O完成。

  • 如果只設定FILE_APPEND_DATA和SYNCHRONIZE旗標,則呼叫端只能寫入檔案結尾,而且會忽略寫入檔案的任何位移資訊。 不過,此類型的寫入作業將視需要自動擴充檔案。

  • 設定檔案的FILE_WRITE_DATA旗標也可允許寫入超過檔案結尾的寫入。 此檔案也會針對這種類型的寫入自動擴充。

  • 如果只設定FILE_EXECUTE和 SYNCHRONIZE 旗標,則呼叫端無法使用傳回的 FileHandle 直接讀取或寫入檔案中的任何數據:也就是說,檔案上的所有作業都會透過系統呼叫器進行,以回應指令和資料存取。 裝置和中繼驅動程序不應該在 DesiredAccess 中設定FILE_EXECUTE旗標。

ShareAccess 參數會判斷個別線程是否可以同時存取相同的檔案。 如果這兩個檔案開啟者具有以指定方式存取檔案的許可權,則可以成功開啟和共用檔案。 如果 IoCreateFile 的原始呼叫端未指定FILE_SHARE_READ、FILE_SHARE_WRITE或FILE_SHARE_DELETE,則無法對檔案執行其他開啟作業:也就是說,原始呼叫端會獲得檔案的獨佔存取權。

為了讓共用檔案成功開啟,要求之 DesiredAccess 至檔案必須與先前所有尚未與 ZwClose 發行的 DesiredAccessShareAccess 規格相容。 也就是說,指定給指定檔案之 IoCreateFileDesiredAccess 不得與其他檔案開啟者不允許的存取發生衝突。

處置值FILE_SUPERSEDE要求呼叫端具有現有檔案物件的 DELETE 存取權。 如果是的話,在現有檔案上成功呼叫 IoCreateFile 並FILE_SUPERSEDE會有效地刪除該檔案,然後重新建立該檔案。 這表示,如果檔案已經由另一個線程開啟,它會指定 shareAccess參數並設定FILE_SHARE_DELETE旗標,以開啟檔案。 請注意,這種類型的處置與覆寫檔案的POSIX樣式一致。

處置值FILE_OVERWRITE_IF和FILE_SUPERSEDE類似。 如果使用現有的檔案和其中一個 Disposition 值呼叫 IoCreateFile,則會取代檔案。

覆寫檔案的語意相當於取代作業,但下列情況除外:

  • 呼叫端必須具有檔案的寫入許可權,而不是刪除存取權。 這表示,如果檔案已經由另一個線程開啟,則會開啟檔案,並在輸入 ShareAccess中設定FILE_SHARE_WRITE旗標。

  • 指定的檔案屬性在邏輯上為 ORed,且檔案上已有這些屬性。 這表示,如果檔案已由另一個線程開啟, IoCreateFile 的後續呼叫端就無法停用現有的 FileAttributes 旗標,但可以啟用相同檔案的其他旗標。

CreateOptions FILE_DIRECTORY_FILE 值會指定要建立或開啟的檔案是目錄檔案。 建立目錄檔案時,文件系統會在磁碟上建立適當的結構,以代表該特定文件系統的磁碟上結構的空白目錄。 如果指定此選項且要開啟的指定檔案不是目錄檔案,或者呼叫端指定了不一致的 CreateOptionsDisposition 值, 則 IoCreateFile 的呼叫將會失敗。

CreateOptions FILE_NO_INTERMEDIATE_BUFFERING 旗標可防止文件系統代表呼叫端執行任何中繼緩衝。 指定此值會對 ZwXxx 檔案 例程的呼叫端參數設定特定限制,包括下列各項:

  • 任何傳遞至 ZwReadFileZwWriteFile 的選擇性 ByteOffset 都必須是扇區大小的整數。

  • 傳遞至 ZwReadFileZwWriteFileLength 必須是扇區大小的整數。 請注意,如果傳輸期間到達檔尾,將讀取作業指定至緩衝區的長度與扇區大小完全相同,可能會導致傳送到該緩衝區的顯著位元組數目較少。

  • 緩衝區必須符合基礎裝置的對齊需求。 您可以呼叫 IoCreateFile 以取得代表實體裝置之檔案物件的句柄,然後使用該句柄呼叫 ZwQueryInformationFile 來取得這項資訊。 如需系統FILE_XXX_ALIGNMENT值的清單,請參閱 DEVICE_OBJECT

  • 呼叫 ZwSetInformationFile 並將 FileInformationClass 參數設定為 FilePositionInformation 必須指定扇區大小的整數位移。

CreateOptions FILE_SYNCHRONOUS_IO_ALERT和FILE_SYNCHRONOUS_IO_NONALERT,其名稱建議互斥,請指定檔案上的所有 I/O 作業只要透過傳回的 FileHandle 所參考的檔案物件進行,就會同步。 這類檔案上的所有 I/O 都會使用傳回的句柄,跨所有線程串行化。 使用上述任一 CreateOptions 時,必須設定 DesiredAccess SYNCHRONIZE 旗標,讓 I/O 管理員將使用檔案對象作為同步處理物件。 其中一個 CreateOptions 設定後,I/O 管理員會維護檔案物件的「檔案位置內容」,也就是內部、目前的檔案位置位移。 此位移可用於呼叫 ZwReadFileZwWriteFile。 您也可以使用 ZwQueryInformationFileZwSetInformationFile 來查詢或設定其位置。

如果未指定 CreateOptions FILE_OPEN_REPARSE_POINT 旗標, 且 IoCreateFile 會嘗試開啟具有重新分析點的檔案,則會發生檔案的一般重新分析點處理。 另一方面,如果指定FILE_OPEN_REPARSE_POINT旗標,則不會發生一般重新分析處理, 而且 IoCreateFile 會嘗試直接開啟重新分析點檔案。 不論是哪一種情況,如果開啟作業成功, IoCreateFile 會傳回STATUS_SUCCESS;否則,例程會傳回NTSTATUS錯誤碼。 IoCreateFile 永遠不會傳回STATUS_REPARSE。

CreateOptions FILE_OPEN_REQUIRING_OPLOCK 旗標可排除開啟檔案和要求 oplock 之間的時間,這可能會讓第三方開啟檔案並取得共享違規。 應用程式可以使用 IoCreateFile 上的 FILE_OPEN_REQUIRING_OPLOCK旗標,然後要求任何oplock。 這可確保 oplock 擁有者會收到任何後續開啟要求而造成共用違規的通知。

在 Windows 7 中,如果應用程式使用 FILE_OPEN_REQUIRING_OPLOCK 旗標時檔案上存在其他句柄,則建立作業將會失敗並STATUS_OPLOCK_NOT_GRANTED。 從 Windows 8 開始,此限制已不存在。

如果此建立作業會中斷檔案上已經存在的 oplock,則設定 FILE_OPEN_REQUIRING_OPLOCK 旗標會導致建立作業失敗並STATUS_CANNOT_BREAK_OPLOCK。 此建立作業不會中斷現有的 oplock。

使用此FILE_OPEN_REQUIRING_OPLOCK旗標的應用程式必須在此呼叫成功之後要求 oplock,否則所有後續嘗試開啟檔案都會遭到封鎖,而不需要一般 oplock 處理的好處。 同樣地,如果此呼叫成功,但後續的 oplock 要求失敗,則使用此旗標的應用程式必須在偵測到 oplock 要求失敗之後關閉其句柄。

Windows 7、Windows Server 2008 R2 和更新版本的 Windows 中提供FILE_OPEN_REQUIRING_OPLOCK旗標。 在 Windows 7 中實作此旗標的 Microsoft 文件系統為 NTFS、FAT 和 exFAT。

CreateOptions 旗標FILE_RESERVE_OPFILTER可讓應用程式要求層級 1、批次或篩選 oplock,以防止其他應用程式收到共享違規。 不過,FILE_RESERVE_OPFILTER僅適用於篩選作業鎖定。 若要使用它,您必須遵循下列步驟:

  1. 使用FILE_RESERVE_OPFILTER的 CreateOptions 、完全FILE_READ_ATTRIBUTES的 DesiredAccess 和完全FILE_SHARE_READ的 ShareAccess 發出建立要求 |FILE_SHARE_WRITE |FILE_SHARE_DELETE。

    • 如果已經有開啟的句柄,則建立要求會失敗並STATUS_OPLOCK_NOT_GRANTED,而下一個要求的 oplock 也會失敗。

    • 如果您以更多存取權或較少的共享開啟,也會造成STATUS_OPLOCK_NOT_GRANTED失敗。

  2. 如果建立要求成功,請要求 oplock。

  3. 開啟檔案的另一個句柄以執行 I/O。

步驟 3 僅針對篩選作業鎖定進行這項操作。 在步驟 3 中開啟的句柄可以有一個 DesiredAccess ,其中包含最多FILE_READ_ATTRIBUTES |FILE_WRITE_ATTRIBUTES |FILE_READ_DATA |FILE_READ_EA |FILE_EXECUTE |SYNCHRONIZE |READ_CONTROL,但仍不會中斷篩選作業。 不過,任何 DesiredAccess 大於 FILE_READ_ATTRIBUTES |FILE_WRITE_ATTRIBUTES |SYNCHRONIZE 會中斷層級 1 或批次 oplock,並讓FILE_RESERVE_OPFILTER旗標不適用於這些 oplock 類型。

如果驅動程式代表使用者模式應用程式所起始的作業發出核心模式建立要求, 選項 IO_NO_PARAMETER_CHECKING旗標會很有用。 由於要求會在使用者模式內容中發生,因此 I/O 管理員預設會探查提供的參數值,如果參數是核心模式位址,可能會導致存取違規。 此旗標可讓呼叫端覆寫此預設行為,並避免存取違規。

針對源自使用者模式的建立要求,如果驅動程式在IoCreateFileOptions參數中同時設定IO_NO_PARAMETER_CHECKING和IO_FORCE_ACCESS_CHECK,則它也應該在 ObjectAttributes 參數中設定OBJ_FORCE_ACCESS_CHECK。 如需此旗標的資訊,請參閱 OBJECT_ATTRIBUTES的屬性成員。

NTFS 是唯一實作FILE_RESERVE_OPFILTER的 Microsoft 文件系統。

在系統進程以外的進程內容中執行的驅動程式例程,必須為IoCreateFileObjectAttributes 參數設定 OBJ_KERNEL_HANDLE 屬性。 這會將 IoCreateFile 傳回的句柄使用限制為只在核心模式中執行的進程。 否則,進程可以在其中執行驅動程序的內容中存取句柄。 驅動程式可以呼叫 InitializeObjectAttributes 來設定OBJ_KERNEL_HANDLE屬性,如下所示。

InitializeObjectAttributes(&ObjectAttributes, NULL, OBJ_KERNEL_HANDLE, NULL, NULL);

規格需求

需求
目標平台 Universal
標頭 wdm.h (包括 Wdm.h、Ntddk.h、Ntifs.h)
程式庫 NtosKrnl.lib
Dll NtosKrnl.exe
IRQL PASSIVE_LEVEL
DDI 合規性規則 HwStorPortProhibitedDDIs (storport) IrqlIoPassive4 (wdm) PowerIrpDDis (wdm)

另請參閱

ACCESS_MASK

InitializeObjectAttributes

IO_STATUS_BLOCK

IoCreateFileEx (DesiredAccess 参數)

OBJECT_ATTRIBUTES

ZwClose

ZwCreateFile

ZwQueryInformationFile

ZwReadFile

ZwSetInformationFile

ZwWriteFile