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指標,以位元組為單位。 如果 AllocationSize 為 NULL,則未指定配置大小。 如果未建立或覆寫任何檔案, 則會忽略 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 建立或開啟的檔名:
作為完整路徑名稱,提供於輸入 ObjectAttributes 的 ObjectName 成員中。
路徑名稱,相對於輸入 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 旗標必須與先前尚未透過 發行之所有開啟作業的 DesiredAccess 和 ShareAccess 旗標相容。 也就是說,指定給 ZwCreateFile 的 DesiredAccess 不得與其他檔案開啟者不允許的存取衝突。
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 值會指定要建立或開啟的檔案是目錄。 建立目錄檔案時,文件系統會在磁碟上建立適當的結構,以代表該特定文件系統的磁碟上結構的空白目錄。 如果指定此選項且要開啟的指定檔案不是目錄檔案,或呼叫端指定不一致的 CreateOptions 或 CreateDisposition 值, 則 ZwCreateFile 的呼叫將會失敗。
FILE_NO_INTERMEDIATE_BUFFERING CreateOptions 旗標可防止文件系統代表呼叫端執行任何中繼緩衝。 指定此旗標會對其他 ZwXxx 檔案 例程的呼叫端參數設定下列限制:
任何傳遞至 ZwReadFile 或 ZwWriteFile 的選擇性 ByteOffset 都必須是扇區大小的倍數。
傳遞至 ZwReadFile 或 ZwWriteFile 的 Length 必須是扇區大小的整數。 請注意,如果傳輸期間到達檔尾,將讀取作業指定至緩衝區的長度與扇區大小完全相同,可能會導致傳送到該緩衝區的顯著位元組數目較少。
緩衝區必須符合基礎裝置的對齊需求。 若要取得這項資訊,請呼叫 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 管理員會追蹤目前的檔案位置位移,您可以傳遞至 ZwReadFile 和 ZwWriteFile。 呼叫 ZwQueryInformationFile 或 ZwSetInformationFile 以取得或設定此位置。
如果未指定 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。 若要使用它,您必須完成下列步驟:
使用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失敗。
如果建立要求成功,請要求 oplock。
開啟檔案的另一個句柄以執行 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 原生系統服務例程的 NtXxx 和 ZwXxx 版本會以處理和解譯輸入參數的方式,以不同的方式運作。 如需 例程 NtXxx 和 ZwXxx 版本之間關聯性的詳細資訊,請參閱 使用原生系統服務例程的 Nt 和 Zw 版本。
規格需求
需求 | 值 |
---|---|
目標平台 | Universal |
標頭 | wdm.h (包括 Wdm.h、Ntddk.h、Ntifs.h) |
程式庫 | NtosKrnl.lib |
Dll | NtosKrnl.exe |
IRQL | PASSIVE_LEVEL (请参阅一节) |
DDI 合規性規則 | HwStorPortProhibitedDIS (storport) 、 PowerIrpDDis (wdm) |