前言 :
在驅動程式開發中, 經常會對檔案進行操作, 與 Win32 API 不同, DDK 提供另一套對檔案的操作函式.
檔案新建 :
對檔案的新建或者打開都是透過內核函式 ZwCreateFile 實作的. 和 Windows API 類似, 這個內核函式返回一個檔案控制程式碼. 檔的所有操作都是依靠這個控制碼進行操作的. 在檔案操作完畢後, 需要關閉這個控制碼 :
參數說明 :
這個函式需要填寫 CreateDisposition 參數. 如果想打開檔, CreateDisposition 參數設置成 FILE_OPEN, 如果想新建檔案, CreateDisposition 參數設置成 FILE_OVERWRITE_IF. 此時無論檔案是否存在, 都會新建新檔案.
檔案名稱的指定是透過設定第三個參數 ObjectAttributes. 這個參數是一個 OBJECT_ATTRIBUTES 結構, DDK 提供對該結構初始化的巨集 InitializeObjectAttributes :
參數說明 :
另外檔名必須是符號連結或者是設備名. 符號連結拿磁碟代號 "C:" 來說, 就應該用 "\??\C:" 代替, 也就是說 "C:\1.log" 要寫成 "\??\C:\1.log". 其中 "\??\C:" 是符號連結, 內核會將它轉換成設備名 "\Device\HarddiskVolume1", 下面代碼演式如何在驅動程式中新建檔和打開檔 :
需要注意的是當檔案被成功打開後, 一定要記得關閉控制碼, 關閉控制碼使用 ZwClose 內核函式.
檔案的打開 :
除了使用 ZwCreateFile 函式可以打開檔案, DDK 還提供了一個內核函式 ZwOpenFile. 該函式的參數比 ZwCreateFile 的參數簡化, 方便程式設計師打開檔案, 宣告如下 :
參數說明 :
下面程式碼演示了如何使用 ZwOpenFile 打開檔案 :
獲取或修改檔案屬性 :
獲取和修改檔案屬性, 包括檔案大小, 獲取與修改檔案指標位址, 獲取與修改檔案名, 獲取與修改檔案屬性 (唯讀屬性, 隱藏屬性)等. DDK 提供了內核函式 ZwSetInformtionFile 和ZwQueryInformationFile 函式來進行獲取與修改檔案屬性. 其宣告如下 :
這兩個函式的參數基本相同, 其中 FileInformationClass 指定修改或者查詢的類別.
(1) 當 FileInformationClass 是 FileStandardInformation 時, 輸入與輸出的資料是 FILE_STANDARD_INFORMATION 結構體, 描述檔的基本資訊如下 :
(2) 當FileInformationClass 是 FileBasicInformation 時, 輸入與輸出的資料是 FILE_BASIC_INFORMATION 結構體, 描述檔資訊如下 :
其中時間參數是一個 LARGE_INTEGER 的整數, 該整數代表從 1901 年經過多少個 100ns. FileAttributes 描述檔屬性, 而 FILE_ATTRIBUTE_NORMAL 指一般檔, FILE_ATTRIBUTE_DIRECTORY 指目錄, FILE_ATTRIBUTE_READONLY 指該檔唯讀, FILE_ATTRIBUTE_HIDDEN 指該檔維隱含檔, FILE_ATTRIBUTE_SYSTEM 代表系統檔.
(3) 當 FileInformationClass 是 FileNameInformation 時, 輸入與輸出的資料是 FILE_NAME_INFORMATION 結構體, 資訊如下 :
(4) 當 FileInformationClass 是 FilePositionInformation 時, 輸入和輸出的資料是 FILE_POSITION_INFORMATION 結構體, 資訊如下 :
下面程式碼演示如何使用 ZwQueryInformationFile 函式查詢, 些改檔案屬性 :
檔案的寫操作 :
DDK 提供了檔案寫入操作的內核函式 ZwWriteFile, 其宣告如下 :
參數說明 :
下面程式碼演示了如何對檔案進行寫操作 :
檔案的讀操作 :
DDK 提供了檔案操作的內核函式 ZwReadFile, 其函式宣告如下 :
下面程式碼演示如何在驅動程式中讀取檔案 :
補充說明 :
* MSDN : CreateFile Function
* 如何從核心模式裝置驅動程式中開啟檔案,以及如何從讀取或寫入至檔案 :
在驅動程式開發中, 經常會對檔案進行操作, 與 Win32 API 不同, DDK 提供另一套對檔案的操作函式.
檔案新建 :
對檔案的新建或者打開都是透過內核函式 ZwCreateFile 實作的. 和 Windows API 類似, 這個內核函式返回一個檔案控制程式碼. 檔的所有操作都是依靠這個控制碼進行操作的. 在檔案操作完畢後, 需要關閉這個控制碼 :
- Syntax :
- 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 : 返回打開的控制碼.
* DesiredAccess : 對打開檔案操作的描述, 讀, 寫或是其他. 一般指定為 GENERIC_READ 或 GENERIC_WRITE.
* ObjectAttributes : 是 OBJECT_ATTRIBUTES 結構位址, 該結構包含要打開的檔案名.
* IoStatusBlock : 指向一個 IO_STATUS_BLOCK 結構, 該結構接收 ZwCreateFile 操作的結果狀態.
* AllocationSize : 是一個指標, 指向一個 64 位元整數, 該數指定檔初始分配的大小. 該參數僅關係到新建或重寫檔案操作, 如果忽略它, 那麼檔案長度從0 開始並隨寫入增大.
* FileAttributes : 0 或 FILE_ATTRIBUTE_NORMAL, 指定新建檔案的屬性.
* ShareAccess : FILE_SHARE_READ 或 0, 指定檔案的共用方式. 如果僅為讀資料而打開檔, 則可以與其他執行緒同時讀取該檔. 如果為寫資料而打開檔, 可能不希望其他執行緒訪問該檔.
* CreateDisposition : FILE_OPEN 或 FILE_OVERWRITE_IF. 表明當指定檔案不存在或存在應該如何處理.
* CreateOptions : FILE_SYNCHRONOUS_IO_NONALERT, 指定控制打開操作和控制碼使用的附加旗標位元.
* EaBuffer : 一個指標, 指向可選的擴充屬性區.
* EaLength : 擴充屬性區的長度
這個函式需要填寫 CreateDisposition 參數. 如果想打開檔, CreateDisposition 參數設置成 FILE_OPEN, 如果想新建檔案, CreateDisposition 參數設置成 FILE_OVERWRITE_IF. 此時無論檔案是否存在, 都會新建新檔案.
檔案名稱的指定是透過設定第三個參數 ObjectAttributes. 這個參數是一個 OBJECT_ATTRIBUTES 結構, DDK 提供對該結構初始化的巨集 InitializeObjectAttributes :
- Syntax :
- VOID InitializeObjectAttributes(
- [out] POBJECT_ATTRIBUTES InitializedAttributes,
- [in] PUNICODE_STRING ObjectName,
- [in] ULONG Attributes,
- [in] HANDLE RootDirectory,
- [in, optional] PSECURITY_DESCRIPTOR SecurityDescriptor
- );
參數說明 :
* InitializeAttributes : 返回的 OBJECT_ATTRIBUTES 結構.
* ObjectName : 物件名稱, 用 UNICODE_STRING 描述, 這裡設置的是檔案名.
* Attributes : 一般設為 OBJ_CASE_INSENSITIVE, 對大小寫敏感.
* RootDirectory : 一般設為 NULL
* SecurityDescriptor : 一般設為 NULL
另外檔名必須是符號連結或者是設備名. 符號連結拿磁碟代號 "C:" 來說, 就應該用 "\??\C:" 代替, 也就是說 "C:\1.log" 要寫成 "\??\C:\1.log". 其中 "\??\C:" 是符號連結, 內核會將它轉換成設備名 "\Device\HarddiskVolume1", 下面代碼演式如何在驅動程式中新建檔和打開檔 :
- 範例代碼 : (1) 新建檔案
- #pragma INITCODE
- VOID CreateFileTest()
- {
- OBJECT_ATTRIBUTES objectAttributes;
- IO_STATUS_BLOCK iostatus;
- HANDLE hfile;
- UNICODE_STRING logFileUnicodeString;
- //初始化UNICODE_STRING字串
- RtlInitUnicodeString( &logFileUnicodeString,
- L"\\??\\C:\\1.log");
- //或者寫成 "\\Device\\HarddiskVolume1\\1.LOG"
- //初始化objectAttributes
- InitializeObjectAttributes(&objectAttributes,
- &logFileUnicodeString,
- OBJ_CASE_INSENSITIVE,
- NULL,
- NULL );
- //新建檔案
- NTSTATUS ntStatus = ZwCreateFile( &hfile,
- GENERIC_WRITE,
- &objectAttributes,
- &iostatus,
- NULL,
- FILE_ATTRIBUTE_NORMAL,
- FILE_SHARE_READ,
- FILE_OPEN_IF,
- FILE_SYNCHRONOUS_IO_NONALERT,
- NULL,
- 0 );
- if ( NT_SUCCESS(ntStatus))
- {
- KdPrint(("Create file succussfully!\n"));
- }else
- {
- KdPrint(("Create file unsuccessfully!\n"));
- }
- //檔案操作
- //.......
- //關閉檔案控制代碼
- ZwClose(hfile);
- }
- 範例代碼 : (2) 打開檔案
- #pragma INITCODE
- VOID OpenFileTest1()
- {
- OBJECT_ATTRIBUTES objectAttributes;
- IO_STATUS_BLOCK iostatus;
- HANDLE hfile;
- UNICODE_STRING logFileUnicodeString;
- //初始化UNICODE_STRING字串
- RtlInitUnicodeString( &logFileUnicodeString,
- L"\\??\\C:\\1.log");
- //或者寫成 "\\Device\\HarddiskVolume1\\1.LOG"
- //初始化objectAttributes
- InitializeObjectAttributes(&objectAttributes,
- &logFileUnicodeString,
- OBJ_CASE_INSENSITIVE,//對大小寫敏感
- NULL,
- NULL );
- //新建檔案
- NTSTATUS ntStatus = ZwCreateFile( &hfile,
- GENERIC_READ,
- &objectAttributes,
- &iostatus,
- NULL,
- FILE_ATTRIBUTE_NORMAL,
- FILE_SHARE_WRITE,
- FILE_OPEN,//對檔案開啟,如果不存在則返回錯誤
- FILE_SYNCHRONOUS_IO_NONALERT,
- NULL,
- 0 );
- if ( NT_SUCCESS(ntStatus))
- {
- KdPrint(("Open file succussfully!\n"));
- }else
- {
- KdPrint(("Open file unsuccessfully!\n"));
- }
- //檔案操作
- //.......
- //關閉檔案控制代碼
- ZwClose(hfile);
- }
需要注意的是當檔案被成功打開後, 一定要記得關閉控制碼, 關閉控制碼使用 ZwClose 內核函式.
檔案的打開 :
除了使用 ZwCreateFile 函式可以打開檔案, DDK 還提供了一個內核函式 ZwOpenFile. 該函式的參數比 ZwCreateFile 的參數簡化, 方便程式設計師打開檔案, 宣告如下 :
- Syntax :
- NTSTATUS ZwOpenFile(
- __out PHANDLE FileHandle,
- __in ACCESS_MASK DesiredAccess,
- __in POBJECT_ATTRIBUTES ObjectAttributes,
- __out PIO_STATUS_BLOCK IoStatusBlock,
- __in ULONG ShareAccess,
- __in ULONG OpenOptions
- );
參數說明 :
* FileHandle : 返回打開檔案控制程式碼.
* DesiredAccess : 打開的權限, 一般為 GENERIC_ALL
* ObjectAttributes : OBJECT_ATTRIBUTES 結構.
* IoStatusBlock : 指向一個結構體的指標, 該結構體指明打開檔案狀態.
* ShareAccess : 共用的權限. 可以是 FILE_SHARE_READ 或者 FILE_SHARE_WRITE
* OpenOptions : 一般為 FILE_SYNCHRONOUS_IO_NONALERT
下面程式碼演示了如何使用 ZwOpenFile 打開檔案 :
- 範例代碼 : 使用函式 ZwOpenFile 打開檔案
- #pragma INITCODE
- VOID OpenFileTest2()
- {
- OBJECT_ATTRIBUTES objectAttributes;
- IO_STATUS_BLOCK iostatus;
- HANDLE hfile;
- UNICODE_STRING logFileUnicodeString;
- //初始化UNICODE_STRING字串
- RtlInitUnicodeString( &logFileUnicodeString,
- L"\\??\\C:\\1.log");
- //或者寫成 "\\Device\\HarddiskVolume1\\1.LOG"
- //初始化objectAttributes
- InitializeObjectAttributes(&objectAttributes,
- &logFileUnicodeString,
- OBJ_CASE_INSENSITIVE,
- NULL,
- NULL );
- //新建檔案
- NTSTATUS ntStatus = ZwOpenFile( &hfile,
- GENERIC_ALL,
- &objectAttributes,
- &iostatus,
- FILE_SHARE_READ|FILE_SHARE_WRITE,
- FILE_SYNCHRONOUS_IO_NONALERT);
- if ( NT_SUCCESS(ntStatus))
- {
- KdPrint(("Create file succussfully!\n"));
- }else
- {
- KdPrint(("Create file unsuccessfully!\n"));
- }
- //檔操作
- //.......
- //關閉檔案控制代碼
- ZwClose(hfile);
- }
獲取或修改檔案屬性 :
獲取和修改檔案屬性, 包括檔案大小, 獲取與修改檔案指標位址, 獲取與修改檔案名, 獲取與修改檔案屬性 (唯讀屬性, 隱藏屬性)等. DDK 提供了內核函式 ZwSetInformtionFile 和ZwQueryInformationFile 函式來進行獲取與修改檔案屬性. 其宣告如下 :
- ZwQueryInformationFile Syntax :
- NTSTATUS ZwQueryInformationFile(
- __in HANDLE FileHandle,
- __out PIO_STATUS_BLOCK IoStatusBlock,
- __out PVOID FileInformation,
- __in ULONG Length,
- __in FILE_INFORMATION_CLASS FileInformationClass
- );
- ZwSetInformationFile Syntax :
- NTSTATUS ZwSetInformationFile(
- __in HANDLE FileHandle,
- __out PIO_STATUS_BLOCK IoStatusBlock,
- __in PVOID FileInformation,
- __in ULONG Length,
- __in FILE_INFORMATION_CLASS FileInformationClass
- );
這兩個函式的參數基本相同, 其中 FileInformationClass 指定修改或者查詢的類別.
(1) 當 FileInformationClass 是 FileStandardInformation 時, 輸入與輸出的資料是 FILE_STANDARD_INFORMATION 結構體, 描述檔的基本資訊如下 :
- Syntax :
- typedef struct _FILE_STANDARD_INFORMATION {
- LARGE_INTEGER AllocationSize; // 檔的分配大小 ( The sector or cluster size of the underlying physical device.)
- LARGE_INTEGER EndOfFile; //距離檔案結尾還有多少位元組
- ULONG NumberOfLinks; // 有多少個連結檔
- BOOLEAN DeletePending; // 是否準備刪除
- BOOLEAN Directory; // 是否為目錄
- } FILE_STANDARD_INFORMATION, *PFILE_STANDARD_INFORMATION;
(2) 當FileInformationClass 是 FileBasicInformation 時, 輸入與輸出的資料是 FILE_BASIC_INFORMATION 結構體, 描述檔資訊如下 :
- Syntax :
- typedef struct _FILE_BASIC_INFORMATION {
- LARGE_INTEGER CreationTime; // 檔新建時間
- LARGE_INTEGER LastAccessTime; // 最後存取時間
- LARGE_INTEGER LastWriteTime; // 最後寫時間
- LARGE_INTEGER ChangeTime; // 最後修改時間
- ULONG FileAttributes; // 檔案屬性
- } FILE_BASIC_INFORMATION, *PFILE_BASIC_INFORMATION;
其中時間參數是一個 LARGE_INTEGER 的整數, 該整數代表從 1901 年經過多少個 100ns. FileAttributes 描述檔屬性, 而 FILE_ATTRIBUTE_NORMAL 指一般檔, FILE_ATTRIBUTE_DIRECTORY 指目錄, FILE_ATTRIBUTE_READONLY 指該檔唯讀, FILE_ATTRIBUTE_HIDDEN 指該檔維隱含檔, FILE_ATTRIBUTE_SYSTEM 代表系統檔.
(3) 當 FileInformationClass 是 FileNameInformation 時, 輸入與輸出的資料是 FILE_NAME_INFORMATION 結構體, 資訊如下 :
- Syntax :
- typedef struct _FILE_NAME_INFORMATION {
- ULONG FileNameLength; // 檔案名長度
- WCHAR FileName[1]; // 檔案名
- } FILE_NAME_INFORMATION, *PFILE_NAME_INFORMATION;
(4) 當 FileInformationClass 是 FilePositionInformation 時, 輸入和輸出的資料是 FILE_POSITION_INFORMATION 結構體, 資訊如下 :
- Syntax :
- typedef struct _FILE_POSITION_INFORMATION {
- LARGE_INTEGER CurrentByteOffset; // 代表當前檔案指標位址
- } FILE_POSITION_INFORMATION, *PFILE_POSITION_INFORMATION;
下面程式碼演示如何使用 ZwQueryInformationFile 函式查詢, 些改檔案屬性 :
- 範例代碼 : 下面程式碼演示如何使用 ZwQueryInformationFile 函式
- #pragma INITCODE
- VOID FileAttributeTest()
- {
- OBJECT_ATTRIBUTES objectAttributes;
- IO_STATUS_BLOCK iostatus;
- HANDLE hfile;
- UNICODE_STRING logFileUnicodeString;
- //初始化UNICODE_STRING字串
- RtlInitUnicodeString( &logFileUnicodeString,
- L"\\??\\C:\\1.log");
- //或者寫成 "\\Device\\HarddiskVolume1\\1.LOG"
- //初始化objectAttributes
- InitializeObjectAttributes(&objectAttributes,
- &logFileUnicodeString,
- OBJ_CASE_INSENSITIVE,//對大小寫敏感
- NULL,
- NULL );
- //新建檔案
- NTSTATUS ntStatus = ZwCreateFile( &hfile,
- GENERIC_READ,
- &objectAttributes,
- &iostatus,
- NULL,
- FILE_ATTRIBUTE_NORMAL,
- 0,
- FILE_OPEN,//對檔案開啟,如果不存在則返回錯誤
- FILE_SYNCHRONOUS_IO_NONALERT,
- NULL,
- 0 );
- if (NT_SUCCESS(ntStatus))
- {
- KdPrint(("open file successfully.\n"));
- }
- FILE_STANDARD_INFORMATION fsi;
- //讀取檔案長度
- ntStatus = ZwQueryInformationFile(hfile,
- &iostatus,
- &fsi,
- sizeof(FILE_STANDARD_INFORMATION),
- FileStandardInformation);
- if (NT_SUCCESS(ntStatus))
- {
- KdPrint(("file length:%u\n",fsi.EndOfFile.QuadPart));
- }
- //修改當前檔案指標
- FILE_POSITION_INFORMATION fpi;
- fpi.CurrentByteOffset.QuadPart = 100i64;
- ntStatus = ZwSetInformationFile(hfile,
- &iostatus,
- &fpi,
- sizeof(FILE_POSITION_INFORMATION),
- FilePositionInformation);
- if (NT_SUCCESS(ntStatus))
- {
- KdPrint(("update the file pointer successfully.\n"));
- }
- //關閉檔案控制代碼
- ZwClose(hfile);
- }
檔案的寫操作 :
DDK 提供了檔案寫入操作的內核函式 ZwWriteFile, 其宣告如下 :
- Syntax :
- NTSTATUS ZwWriteFile(
- __in HANDLE FileHandle,
- __in_opt HANDLE Event,
- __in_opt PIO_APC_ROUTINE ApcRoutine,
- __in_opt PVOID ApcContext,
- __out PIO_STATUS_BLOCK IoStatusBlock,
- __in PVOID Buffer,
- __in ULONG Length,
- __in_opt PLARGE_INTEGER ByteOffset,
- __in_opt PULONG Key
- );
參數說明 :
* FileHandle : 檔案打開的控制碼.
* Event : 一般為 NULL.
* ApcRoutine : 一般為 NULL.
* ApcContext : 一般為 NULL.
* IoStatusBlock : 記錄寫操作的狀態. 其中 IoStatusBlock.Information 記錄了實際寫了多少位元組.
* Buffer : 從這個緩衝區開始往檔案寫.
* Length : 準備寫多少位元組.
* ByteOffset : 從檔的多少偏移位址開始寫.
* Key : 一般為 NULL.
下面程式碼演示了如何對檔案進行寫操作 :
- 範例代碼 : 檔案寫操作
- #pragma INITCODE
- VOID WriteFileTest()
- {
- OBJECT_ATTRIBUTES objectAttributes;
- IO_STATUS_BLOCK iostatus;
- HANDLE hfile;
- UNICODE_STRING logFileUnicodeString;
- //初始化UNICODE_STRING字串
- RtlInitUnicodeString( &logFileUnicodeString,
- L"\\??\\C:\\1.log");
- //或者寫成 "\\Device\\HarddiskVolume1\\1.LOG"
- //初始化objectAttributes
- InitializeObjectAttributes(&objectAttributes,
- &logFileUnicodeString,
- OBJ_CASE_INSENSITIVE,//對大小寫敏感
- NULL,
- NULL );
- //新建檔案
- NTSTATUS ntStatus = ZwCreateFile( &hfile,
- GENERIC_WRITE,
- &objectAttributes,
- &iostatus,
- NULL,
- FILE_ATTRIBUTE_NORMAL,
- FILE_SHARE_WRITE,
- FILE_OPEN_IF,//即使存在該檔案,也新建
- FILE_SYNCHRONOUS_IO_NONALERT,
- NULL,
- 0 );
- #define BUFFER_SIZE 1024
- PUCHAR pBuffer = (PUCHAR)ExAllocatePool(PagedPool,BUFFER_SIZE);
- //建構要填充的資料
- RtlFillMemory(pBuffer,BUFFER_SIZE,0xAA);
- KdPrint(("The program will write %d bytes\n",BUFFER_SIZE));
- //寫入檔案
- ZwWriteFile(hfile,NULL,NULL,NULL,&iostatus,pBuffer,BUFFER_SIZE,NULL,NULL);
- KdPrint(("The program really wrote %d bytes\n",iostatus.Information));
- //建構要填充的資料
- RtlFillMemory(pBuffer,BUFFER_SIZE,0xBB);
- KdPrint(("The program will append %d bytes\n",BUFFER_SIZE));
- //追加資料
- LARGE_INTEGER number;
- number.QuadPart = 1024i64;//設置檔案指標
- //對檔案進行附加寫
- ZwWriteFile(hfile,NULL,NULL,NULL,&iostatus,pBuffer,BUFFER_SIZE,&number,NULL);
- KdPrint(("The program really appended %d bytes\n",iostatus.Information));
- //關閉檔案控制代碼
- ZwClose(hfile);
- ExFreePool(pBuffer);
- }
檔案的讀操作 :
DDK 提供了檔案操作的內核函式 ZwReadFile, 其函式宣告如下 :
- Syntax :
- NTSTATUS ZwReadFile(
- __in HANDLE FileHandle, // Handle to the file object.
- __in_opt HANDLE Event, // Device and intermediate drivers should set this parameter to NULL
- __in_opt PIO_APC_ROUTINE ApcRoutine, // Device and intermediate drivers should set this pointer to NULL.
- __in_opt PVOID ApcContext, // Device and intermediate drivers should set this pointer to NULL.
- __out PIO_STATUS_BLOCK IoStatusBlock, // 記錄了實際讀了多少位元組的狀態.
- __out PVOID Buffer, // Pointer to a caller-allocated buffer that receives the data read from the file.
- __in ULONG Length, // The size, in bytes, of the buffer pointed to by Buffer.
- __in_opt PLARGE_INTEGER ByteOffset, // 從檔的多少偏移位址開始讀.
- __in_opt PULONG Key // Device and intermediate drivers should set this pointer to NULL.
- );
下面程式碼演示如何在驅動程式中讀取檔案 :
- 範例代碼 : 檔案讀操作
- #pragma INITCODE
- VOID ReadFileTest()
- {
- OBJECT_ATTRIBUTES objectAttributes;
- IO_STATUS_BLOCK iostatus;
- HANDLE hfile;
- UNICODE_STRING logFileUnicodeString;
- //初始化UNICODE_STRING字串
- RtlInitUnicodeString( &logFileUnicodeString,
- L"\\??\\C:\\1.log");
- //或者寫成 "\\Device\\HarddiskVolume1\\1.LOG"
- //初始化objectAttributes
- InitializeObjectAttributes(&objectAttributes,
- &logFileUnicodeString,
- OBJ_CASE_INSENSITIVE,//對大小寫敏感
- NULL,
- NULL );
- //新建檔案
- NTSTATUS ntStatus = ZwCreateFile( &hfile,
- GENERIC_READ,
- &objectAttributes,
- &iostatus,
- NULL,
- FILE_ATTRIBUTE_NORMAL,
- FILE_SHARE_READ,
- FILE_OPEN,//即使存在該檔案,也新建
- FILE_SYNCHRONOUS_IO_NONALERT,
- NULL,
- 0 );
- if (!NT_SUCCESS(ntStatus))
- {
- KdPrint(("The file is not exist!\n"));
- return;
- }
- FILE_STANDARD_INFORMATION fsi;
- //讀取檔案長度
- ntStatus = ZwQueryInformationFile(hfile,
- &iostatus,
- &fsi,
- sizeof(FILE_STANDARD_INFORMATION),
- FileStandardInformation);
- KdPrint(("The program want to read %d bytes\n",fsi.EndOfFile.QuadPart));
- //為讀取的檔案分配緩衝區
- PUCHAR pBuffer = (PUCHAR)ExAllocatePool(PagedPool,
- (LONG)fsi.EndOfFile.QuadPart);
- //讀取檔案
- ZwReadFile(hfile,NULL,
- NULL,NULL,
- &iostatus,
- pBuffer,
- (LONG)fsi.EndOfFile.QuadPart,
- NULL,NULL);
- KdPrint(("The program really read %d bytes\n",iostatus.Information));
- //關閉檔案控制代碼
- ZwClose(hfile);
- //釋放緩衝區
- ExFreePool(pBuffer);
- }
補充說明 :
* MSDN : CreateFile Function
Creates or opens a file or I/O device. The most commonly used I/O devices are as follows: file, file stream, directory, physical disk, volume, console buffer, tape drive, communications resource, mailslot, and pipe. The function returns a handle that can be used to access the file or device for various types of I/O depending on the file or device and the flags and attributes specified.
* 如何從核心模式裝置驅動程式中開啟檔案,以及如何從讀取或寫入至檔案 :
本文將告訴您如何從核心模式裝置驅動程式開啟磁碟檔案,以及如何讀取或寫入檔案
This message was edited 13 times. Last update was at 23/12/2010 11:37:39
沒有留言:
張貼留言