共用方式為


ZwCreateFile 函式 (wdm.h)

ZwCreateFile 例程會建立新的檔案或開啟現有的檔案。

語法

NTSYSAPI NTSTATUS ZwCreateFile(
  [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              CreateDisposition,
  [in]           ULONG              CreateOptions,
  [in, optional] PVOID              EaBuffer,
  [in]           ULONG              EaLength
);

參數

[out] FileHandle

HANDLE 變數的指標,可接收檔案的句柄。

[in] DesiredAccess

指定 ACCESS_MASK 值,決定物件的要求存取權。 除了針對所有類型的物件所定義的訪問許可權之外,呼叫者還可以指定下列任何訪問許可權,這些許可權是檔案特有的。

ACCESS_MASK旗標 允許呼叫端執行此動作
FILE_READ_DATA 從檔案讀取數據。
FILE_READ_ATTRIBUTES 讀取檔案的屬性。 (如需詳細資訊,請參閱 FileAttributes 參數的描述。)
FILE_READ_EA 讀取檔案的擴充屬性 (EAS) 。 此旗標與裝置和中繼驅動程序無關。
FILE_WRITE_DATA 將數據寫入檔案。
FILE_WRITE_ATTRIBUTES 寫入檔案的屬性。 (如需詳細資訊,請參閱 FileAttributes 參數的描述。)
FILE_WRITE_EA 變更檔案的擴充屬性 (EAS) 。 此旗標與裝置和中繼驅動程序無關。
FILE_APPEND_DATA 將數據附加至檔案。
FILE_EXECUTE 使用系統分頁 I/O 將資料從檔案讀取到記憶體中。 此旗標與裝置和中繼驅動程序無關。

當您建立或開啟目錄時,請勿指定FILE_READ_DATA、FILE_WRITE_DATA、FILE_APPEND_DATA或FILE_EXECUTE。

呼叫端只能指定檔案的一般訪問許可權,GENERIC_XXX,而不是目錄。 一般訪問許可權對應至特定訪問許可權,如下表所示。

一般訪問許可權 一組特定的訪問許可權
GENERIC_READ STANDARD_RIGHTS_READ、FILE_READ_DATA、FILE_READ_ATTRIBUTES、FILE_READ_EA和 SYNCHRONIZE。
GENERIC_WRITE STANDARD_RIGHTS_WRITE、FILE_WRITE_DATA、FILE_WRITE_ATTRIBUTES、FILE_WRITE_EA、FILE_APPEND_DATA和 SYNCHRONIZE。
GENERIC_EXECUTE STANDARD_RIGHTS_EXECUTE、FILE_EXECUTE、FILE_READ_ATTRIBUTES和 SYNCHRONIZE。 此值與裝置和中繼驅動程序無關。
GENERIC_ALL FILE_ALL_ACCESS。

例如,如果您指定檔案物件的GENERIC_READ,例程會將此值對應至特定訪問許可權的FILE_GENERIC_READ位掩碼。 在上表中,針對 GENERIC_READ 列出的特定訪問許可權會對應至包含在FILE_GENERIC_READ位掩碼中的存取旗標。

如果檔案實際上是目錄,呼叫端也可以指定下列一般訪問許可權。

DesiredAccess 旗標 允許呼叫端執行此動作
FILE_LIST_DIRECTORY 列出目錄中的檔案。
FILE_TRAVERSE 周遊目錄,換句話說,將目錄包含在檔案的路徑中。

如需訪問許可權的詳細資訊,請參閱 ACCESS_MASK

[in] ObjectAttributes

指定物件名稱和其他屬性 之OBJECT_ATTRIBUTES 結構的指標。 使用 InitializeObjectAttributes 初始化這個結構。 如果呼叫端未在系統線程內容中執行,它必須在呼叫 InitializeObjectAttributes 時設定OBJ_KERNEL_HANDLE屬性。

[out] IoStatusBlock

接收最終完成狀態的 IO_STATUS_BLOCK 結構的指標,以及所要求作業的其他資訊。 特別是, Information 成員會收到下列其中一個值:

  • FILE_CREATED

  • FILE_OPENED

  • FILE_OVERWRITTEN

  • FILE_SUPERSEDED

  • FILE_EXISTS

  • FILE_DOES_NOT_EXIST

[in, optional] AllocationSize

包含所建立或覆寫檔案之初始配置大小的LARGE_INTEGER指標,以位元組為單位。 如果 AllocationSizeNULL,則未指定配置大小。 如果未建立或覆寫任何檔案, 則會忽略 AllocationSize

[in] FileAttributes

指定一或多個FILE_ATTRIBUTE_XXX 旗標,代表建立或覆寫檔案時要設定的檔案屬性。 呼叫端通常會指定FILE_ATTRIBUTE_NORMAL,這會設定預設屬性。 如需有效FILE_ATTRIBUTE_XXX 旗標的清單,請參閱 CreateFile 例程。 如果未建立或覆寫任何檔案, 則會忽略 FileAttributes

[in] ShareAccess

共用存取的類型,指定為零或下列旗標的任何組合。

ShareAccess 旗標 允許其他線程執行此動作
FILE_SHARE_READ 讀取檔案
FILE_SHARE_WRITE 寫入檔案
FILE_SHARE_DELETE 刪除檔案

裝置和中繼驅動程式通常會將 ShareAccess 設定為零,這可讓呼叫端獨佔存取開啟的檔案。

[in] CreateDisposition

指定檔案不存在或不存在時所要執行的動作。 CreateDisposition 可以是下表中的其中一個值。

CreateDisposition 如果檔案存在,則採取動作 如果檔案不存在,則採取動作
FILE_SUPERSEDE 取代檔案。 建立檔案。
FILE_CREATE 傳回錯誤。 建立檔案。
FILE_OPEN 開啟該檔案。 傳回錯誤。
FILE_OPEN_IF 開啟該檔案。 建立檔案。
FILE_OVERWRITE 開啟檔案,並加以覆寫。 傳回錯誤。
FILE_OVERWRITE_IF 開啟檔案,並加以覆寫。 建立檔案。

[in] CreateOptions

指定驅動程式建立或開啟檔案時要套用的選項。 使用下表中的一或多個旗標。

CreateOptions 旗標 意義
FILE_DIRECTORY_FILE 檔案是目錄。 相容的 CreateOptions 旗標是FILE_SYNCHRONOUS_IO_ALERT、FILE_SYNCHRONOUS_IO_NONALERT、FILE_WRITE_THROUGH、FILE_OPEN_FOR_BACKUP_INTENT和FILE_OPEN_BY_FILE_ID。 CreateDisposition 參數必須設定為FILE_CREATE、FILE_OPEN或FILE_OPEN_IF。
FILE_NON_DIRECTORY_FILE 檔案不是目錄。 要開啟的檔案物件可以代表數據檔;邏輯、虛擬或實體裝置;或磁碟區。
FILE_WRITE_THROUGH 將數據寫入檔案的系統服務、檔案系統驅動程式和驅動程式必須實際將數據傳輸到檔案,才能將任何要求的寫入作業視為完成。
FILE_SEQUENTIAL_ONLY 對檔案的所有存取都是循序的。
FILE_RANDOM_ACCESS 檔案的存取權可以是隨機的,因此檔系統驅動程式或系統應該不會執行循序的預先讀取作業。
FILE_NO_INTERMEDIATE_BUFFERING 檔案無法在驅動程式的內部緩衝區中快取或緩衝處理。 此旗標與 DesiredAccess 參數的 FILE_APPEND_DATA 旗標不相容。
FILE_SYNCHRONOUS_IO_ALERT 檔案上的所有作業都會同步執行。 代表來電者的任何等候,都受限於警示的提前終止。 此旗標也會讓 I/O 系統維護檔案位置指標。 如果設定此旗標,則 SYNCHRONIZE 旗標必須在 DesiredAccess 參數中設定。
FILE_SYNCHRONOUS_IO_NONALERT 檔案上的所有作業都會同步執行。 在同步處理 I/O 佇列和完成的系統中等候,不會受限於警示。 此旗標也會讓 I/O 系統維護檔案位置內容。 如果設定此旗標,則 SYNCHRONIZE 旗標必須在 DesiredAccess 參數中設定。
FILE_CREATE_TREE_CONNECTION Create 此檔案的樹狀結構連線,以便透過網路開啟。 裝置和中繼驅動程式不會使用此旗標。
FILE_COMPLETE_IF_OPLOCKED 如果目標檔案不小心鎖定 (oplock) ,而不是封鎖呼叫端的線程,請立即以替代成功碼STATUS_OPLOCK_BREAK_IN_PROGRESS完成此作業。 如果檔案為 oplocked,則另一個呼叫端已經可以存取該檔案。 裝置和中繼驅動程式不會使用此旗標。 如需 oplock 的相關信息,請參閱 Opportunistic Locks
FILE_NO_EA_KNOWLEDGE 如果已開啟之現有檔案的擴充屬性 (EAS) 表示呼叫端必須瞭解 EA 才能正確解譯檔案, ZwCreateFile 應該會傳回錯誤。 此旗標與裝置和中繼驅動程序無關。
FILE_OPEN_REPARSE_POINT 使用重新分析點開啟檔案,並略過檔案的一般重新分析點處理。 如需詳細資訊,請參閱接下來的<備註>一節。 如需重新分析點的相關信息,請參閱 重新分析點
FILE_DELETE_ON_CLOSE 當最後一個檔案的句柄傳遞至 ZwClose 時,系統會刪除檔案。 如果設定此旗標,必須在 DesiredAccess 參數中設定 DELETE 旗標。
FILE_OPEN_BY_FILE_ID ObjectAttributes 參數指定的檔名包含二進位 8 位元組或 16 位元組檔案參考編號或檔案的物件標識碼,視文件系統而定,如下所示。 或者,裝置名稱後面接著反斜杠字元可能會繼續這些二進位值。 例如,裝置名稱的格式如下:

??\C:\FileID
\device\HardDiskVolume1\ObjectID

其中 FileID 是 8 個字節,而 ObjectID 是 16 個字節。

在NTFS上,這可以是8位元組或16位元組的參考編號或對象標識碼。 16 位元組的參考編號與以零填補的8位元組數位相同。

在 ReFS 上,這可以是 8 位元組或 16 位元組的參考編號。 16 位元組的數位與8位元組的數字無關。 不支援物件識別碼。

FAT、ExFAT、UDFS 和 CDFS 檔案系統不支援此旗標。

這個數位是由 指派給特定文件系統,而且是特定的。

因為檔名字段會部分包含二進位 Blob,所以假設這是有效的 Unicode 字串,更重要的是可能不是 Null 終止的字串。
FILE_OPEN_FOR_BACKUP_INTENT 正在開啟檔案以供備份意圖使用。 因此,系統應該檢查特定訪問許可權,並將適當的存取權授與呼叫者,再針對檔案的安全性描述元檢查 DesiredAccess 參數。 裝置和中繼驅動程式不會使用此旗標。
FILE_RESERVE_OPFILTER 此旗標可讓應用程式要求篩選條件不透明度鎖定 (oplock) ,以防止其他應用程式收到共用違規。 如果已經有開啟的句柄,則建立要求將會失敗,並STATUS_OPLOCK_NOT_GRANTED。 如需詳細資訊,請參閱接下來的<備註>一節。 如需 oplock 的相關信息,請參閱 Opportunistic Locks
FILE_OPEN_REQUIRING_OPLOCK 檔案正在開啟,而檔案上 (oplock) 的商機鎖定會要求為單一不可部分完成的作業。 文件系統在執行建立作業之前會先檢查 oplock,如果結果會中斷現有的 oplock,則會讓建立失敗並傳回STATUS_CANNOT_BREAK_OPLOCK代碼。

windows 7、Windows Server 2008 R2 和更新版本的 Windows 操作系統中提供FILE_OPEN_REQUIRING_OPLOCK旗標。
FILE_SESSION_AWARE 開啟檔案或裝置的用戶端會感知會話,並視需要驗證每個會話存取權。

FILE_SESSION_AWARE旗標可從 Windows 8 開始提供。

[in, optional] EaBuffer

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

[in] EaLength

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

傳回值

ZwCreateFile 會在成功時傳回STATUS_SUCCESS,或在失敗時傳回適當的 NTSTATUS 錯誤碼。 在後者的情況下,呼叫端可以藉由檢查 IoStatusBlock 參數來判斷失敗的原因。

ZwCreateFile 可能會傳回STATUS_FILE_LOCK_CONFLICT做為傳回值,或在 IoStatusBlock 參數所指向之IO_STATUS_BLOCK結構的 Status 成員中。 只有在NTFS記錄檔已滿,且 ZwCreateFile 嘗試處理這種情況時,才會發生錯誤。

備註

ZwCreateFile 提供呼叫端可用來操作檔案數據的句柄,或檔案物件的狀態和屬性。 如需詳細資訊,請參閱 在驅動程式中使用檔案

FileHandle 所指向的句柄不再使用之後,驅動程式必須呼叫 ZwClose 以關閉它。

如果呼叫端未在系統線程內容中執行,則必須確保它建立的任何句柄都是私用句柄。 否則,進程可以在其內容中執行驅動程式的句柄來存取。 如需詳細資訊,請參閱 物件句柄

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

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

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

DesiredAccess 參數中設定特定旗標會導致下列效果:

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

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

  • 設定檔案的FILE_WRITE_DATA旗標,也可讓呼叫端寫入檔案結尾之外。 同樣地,檔案會視需要自動擴充。

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

ShareAccess 參數會判斷個別線程是否可以同時存取相同的檔案。 前提是這兩個呼叫端都有適當的訪問許可權,檔案可以成功開啟和共用。 如果 ZwCreateFile 的原始呼叫端未指定FILE_SHARE_READ、FILE_SHARE_WRITE或FILE_SHARE_DELETE,則沒有其他呼叫端可以開啟檔案,也就是說,原始呼叫端會被授與獨佔存取權。

若要成功開啟共用檔案, DesiredAccess 旗標必須與先前尚未透過 發行之所有開啟作業的 DesiredAccessShareAccess 旗標相容。 也就是說,指定給 ZwCreateFileDesiredAccess 不得與其他檔案開啟者不允許的存取衝突。

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

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

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

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

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

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

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

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

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

  • 緩衝區必須符合基礎裝置的對齊需求。 若要取得這項資訊,請呼叫 ZwCreateFile 以取得代表實體裝置之檔案物件的句柄,並將該句柄傳遞至 ZwQueryInformationFile。 如需系統FILE_XXX_ALIGNMENT值的清單,請參閱 DEVICE_OBJECT

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

FILE_SYNCHRONOUS_IO_ALERT和FILE_SYNCHRONOUS_IO_NONALERT CreateOptions 旗標,其名稱建議互斥,指定檔案上的所有 I/O 作業都是同步的,只要它們透過傳回 的 FileHandle 所參考的檔案物件發生即可。 這類檔案上的所有 I/O 都會使用傳回的句柄,跨所有線程串行化。 如果已設定這其中一個 CreateOptions 旗標,則也必須設定 SYNCHRONIZE DesiredAccess 旗標,以強制 I/O 管理員使用檔案物件做為同步處理物件。 在這些情況下,I/O 管理員會追蹤目前的檔案位置位移,您可以傳遞至 ZwReadFileZwWriteFile。 呼叫 ZwQueryInformationFileZwSetInformationFile 以取得或設定此位置。

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

CreateOptions FILE_OPEN_REQUIRING_OPLOCK 旗標可排除開啟檔案並要求 Oplock 之間的時間,這可能會允許第三方開啟檔案並取得共享違規。 應用程式可以使用 ZwCreateFile 上的 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、Batch 或 Filter oplock,以防止其他應用程式收到共享違規。 不過,FILE_RESERVE_OPFILTER只適用於篩選 oplock。 若要使用它,您必須完成下列步驟:

  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 僅針對篩選 oplock 進行這項操作。 步驟 3 中開啟的句柄可以有包含最多FILE_READ_ATTRIBUTES的 DesiredAccess |FILE_WRITE_ATTRIBUTES |FILE_READ_DATA |FILE_READ_EA |FILE_EXECUTE |SYNCHRONIZE |READ_CONTROL,但仍不會中斷篩選 oplock。 不過,任何大於 FILE_READ_ATTRIBUTES 的 DesiredAccess |FILE_WRITE_ATTRIBUTES |SYNCHRONIZE 會中斷層級 1 或 Batch oplock,並使FILE_RESERVE_OPFILTER旗標不適用於這些 oplock 類型。

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

ZwCreateFile 的呼叫端必須在 IRQL = PASSIVE_LEVEL且啟用特殊核心 APC 時執行

如果在使用者模式中呼叫此函式,您應該使用名稱 「NtCreateFile」 而不是 「ZwCreateFile」。

針對來自內核模式驅動程式的呼叫,Windows 原生系統服務例程的 NtXxxZwXxx 版本會以處理和解譯輸入參數的方式,以不同的方式運作。 如需 例程 NtXxxZwXxx 版本之間關聯性的詳細資訊,請參閱 使用原生系統服務例程的 Nt 和 Zw 版本

規格需求

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

另請參閱

ACCESS_MASK

DEVICE_OBJECT

IO_STATUS_BLOCK

InitializeObjectAttributes

使用 Nt 和 Zw 版本的原生系統服務例程

ZwClose

ZwOpenFile

ZwQueryInformationFile

ZwReadFile

ZwSetInformationFile

ZwWriteFile

 商機鎖定

重新剖析點