驅動開發之 ZwCreateFile函式

2021-06-22 11:12:35 字數 4338 閱讀 6427

函式原型:

ntstatus zwcreatefile(

_out_ phandle filehandle,

_in_ access_mask desiredaccess,

_in_ pobject_attributes objectattributes,

_out_ pio_status_block iostatusblock,

_in_opt_ plarge_integer allocationsize,

_in_ ulong fileattributes,

_in_ ulong shareaccess,

_in_ ulong createdisposition,

_in_ ulong createoptions,

_in_opt_ pvoid eabuffer,

_in_ ulong ealength

);

引數:

filehandle:

是乙個控制代碼的指標。如果這個函式呼叫返回成成功(status_success),那就麼開啟的檔案控制代碼就返回在這個位址內。

desiredaccess:申請的許可權。

如果開啟寫檔案內容,請使用file_write_data。

如果需要讀檔案內容,請使用file_read_data。

如果需要刪除檔案或者把檔案改名,請使用delete。

如果想設定檔案屬性,請使用file_write_attributes。

反之,讀檔案屬性則使用file_read_attributes。

這些條件可以用|(位或)來組合。有兩個巨集分別組合了常用的讀許可權和常用的寫許可權。分別為generic_read和generic_write。此外還有乙個巨集代表全部許可權,是generic_all。此外,如果想同步的開啟檔案,**上synchronize。同步開啟檔案詳見後面對createoptions的說明。

objectattribute:

物件描述。

typedef struct _object_attributes   object_attributes, *pobject_attributes;
iostatusblock也是乙個結構。這個結構在核心開發中經常使用。它往往用於表示乙個操作的結果。這個結構在文件中是公開的,如下:

typedef struct _io_status_block ;

ulong_ptr information;

} io_status_block, *pio_status_block;

實際程式設計中很少用到pointer。一般的說,返回的結果在status中。成功則為status_success。否則則是乙個錯誤碼。進一步的資訊在information中。不同的情況下返回的information的資訊意義不同。針對zwcreatefile呼叫的情況,information的返回值有以下幾種可能:

file_created:檔案被成功的新建了。

file_opened:    檔案被開啟了。

file_overwritten:檔案被覆蓋了。

file_superseded:    檔案被替代了。

file_exists:檔案已存在。(因而開啟失敗了)。

file_does_not_exist:檔案不存在。(因而開啟失敗了)。

這些返回值和開啟檔案的意圖有關(有時希望開啟已存在的檔案,有時則希望建立新的檔案等等。這些意圖在本小節稍後的內容中詳細說明。

allocationsize:

這個引數很少使用,請設定為null。    

fileattributes:

這個引數控制新建立的檔案的屬性。一般的說,設定為file_attribute_normal即可。在實際程式設計中,筆者沒有嘗試過其他的值。

shareaccess:

這是乙個非常容易被人誤解的引數。實際上,這是在本**開啟這個檔案的時候,允許別的**同時開啟這個檔案所持有的許可權。所以稱為共享訪問。一共有三種共享標記可以設定:file_share_read、file_share_write、file_share_delete。這三個標記可以用|(位或)來組合。

舉例如下:如果本次開啟只使用了file_share_read,那麼這個檔案在本次開啟之後,關閉之前,別人再次開啟試圖以讀許可權開啟,則被允許,可以成功開啟。如果別人再次開啟試圖以寫許可權開啟,則一定失敗。返回共享衝突。

同時,如果本次開啟只只用了file_share_read,而之前這個檔案已經被另一次開啟用寫許可權開啟著。那麼本次開啟一定失敗,返回共享衝突。其中的邏輯關係貌似比較複雜,讀者應耐心理解。

createdisposition:

在慣常的程式設計中,筆者使用file_non_directory_file| file_synchronous_io_nonalert。此時檔案被同步的開啟。而且開啟的是檔案(而不是目錄。建立目錄請用file_ directory_file)。所謂同步的開啟的意義在於,以後每次操作檔案的時候,比如寫入檔案,呼叫zwwritefile,在zwwritefile返回時,檔案寫操作已經得到了完成。而不會有返回status_pending(未決)的情況。在非同步檔案的情況下,返回未決是常見的。此時檔案請求沒有完成,使用者需要等待事件來等待請求的完成。當然,好處是使用者可以先去做別的事情。

要同步開啟,前面的desiredaccess必須含有synchronize。

eabuffer:

裝置驅動中必須設為null。

ealength:

必須設為0.

此外還有一些其他的情況。比如不通過緩衝操作檔案。希望每次讀寫檔案都是直接往磁碟上操作的。此時createoptions中應該帶標記file_no_intermediate_buffering。帶了這個標記後,請注意操作檔案每次讀寫都必須以磁碟扇區大小(最常見的是512位元組)對齊。否則會返回錯誤。

返回值:

成功返回

status_success,失敗返回值檢視iostatusblock.status.

例子:

// 要返回的檔案控制代碼

handle file_handle = null;

// 返回值

ntstatus status;

// 首先初始化含有檔案路徑的object_attributes

object_attributes object_attributes;

unicode_string ufile_name ;

rtlinitunicodestring(&ufile_name,l"\\??\\c:\\a.txt");//初始化檔名

initializeobjectattributes(

&object_attributes,

&ufile_name,

obj_case_insensitive|obj_kernel_handle,

null,

null);

// 以open_if方式開啟檔案。

status = zwcreatefile(

&file_handle,

generic_read | generic_write,

&object_attributes,

&io_status,

null,

file_attribute_normal,

file_share_read,

file_open_if,

file_non_directory_file |

file_random_access |

file_synchronous_io_nonalert,

null,

0);if (!nt_success(status))

值得注意的是路徑的寫法。並不是像應用層一樣直接寫「c:\a.dat」。而是寫成了「\\??\\c:\\a.dat」。這是因為zwcreatefile使用的是物件路徑。「c:」是乙個符號鏈結物件。符號鏈結物件一般都在「\\??\\」路徑下。

這種檔案控制代碼的關閉非常簡單。呼叫zwclose即可。核心控制代碼的關閉不需要和開啟在同一程序中。示例如下:

zwclose(file_handle);

Linux驅動開發之DRM驅動

qq群 852283276 b站 主頁 drm 驅動程式開發 開篇 drm 驅動程式開發 vkms 最簡單的drm應用程式 single buffer drm 驅動是如何建立 fb device 的 linux中的drm 介紹 linux graphic dri 顯示子系統 介紹1 xilinx d...

驅動開發之模組

模組 可以在執行時插入到核心中的 叫做模組 模組和應用程式的區別 應用程式 模組 1.執行空間 使用者空間 核心空間 2.入口函式 main 載入函式 3.庫 usr lib 核心原始碼庫 4.資源釋放 可以釋放 必須釋放 5.段錯誤的危害 危害小 危害大 模組三要素 模組許可證宣告 必須 modu...

linux裝置驅動之PCIE驅動開發

pcie pci express 是intel提出的新一代的匯流排介面,目前普及的pcie 3.0的傳輸速率為8gt s,下一代pcie 4.0將翻番為16gt s,因為傳輸速率快廣泛應用於資料中心 雲計算 人工智慧 機器學習 視覺計算 顯示卡 儲存和網路等領域。pcie插槽是可以向下相容的,比如p...