Windows核心驅動中操作檔案

來源:互聯網
上載者:User

一. 在驅動中使用檔案

在Windows執行體中,通過檔案對象來代表檔案,該檔案對象是一種由對象管理器管理的執行體對象。例如:目錄也是由檔案對象代表的。

核心組件通過對象名來引用檔案,即在檔案的全路徑前面加\DosDevices。(在Windows 2000及後續作業系統中,\??等同於\DosDevices)。例如,檔案C:\WINDOWS\example.txt的對象名為\DosDevices\C:\WINDOWS\example.txt。你需要用對象名來開啟檔案以擷取控制代碼。

對象名在下面會講述。

使用檔案步驟:

  1. 開啟檔案返迴文件控制代碼。

  2. 調用合適的ZwXxxFile 函數以完成對檔案的操作。

  3. 調用ZwClose函數關閉開啟的檔案控制代碼。

當開啟一個指向檔案的檔案控制代碼時,Windows執行體就建立了一個檔案對象來代表該檔案,同時返回一個代表該對象的檔案控制代碼。因此,對於單個檔案來說,會存在多個檔案對象的情況。同樣,由於使用者模式的應用程式可能會複製檔案控制代碼,因此,對於同一個檔案對象,也會存在多個檔案控制代碼。只有當所有指向一個檔案對象的檔案控制代碼都關閉後,Windows執行體才會刪除該檔案對象。

二. 對象名

核心模式的對象可以是具名的或者是無名的。對象名是一個Unicode字串,不管是使用者模式還是核心模式,都可以額用它來引用對象。例如,\KernelObjects\LowMemoryCondition是一個指示在系統中總的可用記憶體偏低的標準事件對象名稱。

使用者模式和核心模式都利用對象名來開啟指向對象的控制代碼。所有的後續操作都需要用該開啟的控制代碼來完成。

如果對象是無名的,使用者模式的組件無法開啟指向該對象的控制代碼。核心模式則不同,它可以通過指標或控制代碼來引用無名對象。

具名對象被組織成層狀結構。每個對象的命名同其父物件有關係。每個組件的對象名以反斜線開頭。例如,\KernelObjects對象是\KernelObjects\LowMemoryCondition對象的父物件。

    只有某些類型的對象才擁有子物件。下面列出其中的一部分:

1. 目錄對象。對象管理器利用目錄對象管理對象,例如,\KernelObjects是一個目錄對象,它用來維護標準事件對象。目錄對象不與真實的磁碟目錄相對應。這裡,目錄的意思不是普通我們講的檔案夾目錄的意思。

2. 磁碟驅動裝置對象。這與磁碟檔案(含常規目錄)相對應。

3. 代表目錄的檔案對象。對應指定目錄下的所有檔案,此處的目錄同常規理解的目錄相同。

4. WDM驅動裝置對象,具有自己的命名空間,可以用在驅動定義的方式中。

    檔案具有對象名,其命名與\DosDevices有關。例如,檔案C:\Directory\File的對象名為\DosDevices\C:\Directory\File

下表描述了一組典型的對象名

對象名

描述

\DosDevices

對象目錄

\DosDevices\C:

代表C盤的裝置對象

\DosDevices\C:\Directory

代表名為C:\Director的檔案對象

\DosDevices\C:\Directory\File

代表名為C:\Directo\Filer的檔案對象

驅動可以在指定的對象目錄中建立具名對象

三. 開啟指向檔案的控制代碼

按如下步驟來開啟指向檔案的控制代碼:

1. 定義各一個OBJECT_ATTRIBUTES結構體變數,然後調用InitializeObjectAttributes函數初始化該變數。關鍵是設定改變數的ObjectName欄位為檔案對象名。

2. 調用IoCreateFile,
ZwCreateFile
, 或者 ZwOpenFile,傳遞上面定義的結構體變數,成功就會返回執行該檔案的控制代碼。

註:驅動一般用ZwCreateFileZwOpenFileIoCreateFile很少使用

    當調用ZwCreateFileZwOpenFileIoCreateFile時,Windows執行體建立一個代表該檔案的新的檔案對象,並返回一個指向該對象的控制代碼。檔案對象一直存在,知道你關閉了所有指向它的檔案控制代碼。

四. 使用檔案控制代碼操作檔案

    下表列出了驅動中常用的利用檔案控制代碼操作檔案的函數

操作

函數

讀檔案

ZwReadFile

寫檔案

ZwWriteFile

讀檔案屬性

ZwQueryInformationFile

設定檔案屬性

ZwSetInformationFile

 

五. 驅動中使用檔案程式碼範例

 

/** @file *Copyright(C):     Information Technology Co Ltd., All rights reserved.*@n*@n 檔案:            MyKFile.h*@n 功能:            處理核心檔案的操作*@n 作者:            aurain(zhangqiushui@gmail.com) 2009-12-31*/#ifndef __MYKFILE_H__#define __MYKFILE_H__#include "debug.h"/*** 建立或開啟檔案* @param lpFileHandle 返回開啟的檔案控制代碼指標* @param usFileName 需要開啟的檔案路徑,使用物件路徑,如\\??\\c:\test.txt* @param dwDesiredAccess 申請許可權,可以用|(或)組合以下操作寫檔案內容-FILE_WRITE_DATA,設定檔案屬性-FILE_WRITE_ATTRIBUTES,通用寫-GENERIC_WRITE讀檔案內容-FILE_READ_DATA,設定檔案屬性-FILE_READE_ATTRIBUTES,通用寫-GENERIC_READ刪除檔案-DELETE全部許可權-GENERIC_ALL同步開啟檔案-SYNCHRONIZE* @param dwShareAccess 共用方式(是指本代碼開啟這個檔案時,允許別的代碼同時開啟這個檔案所具有的許可權可以用|(或)組合以下操作共用讀-FILE_SHARE_READ共用寫-FILE_SHARE_WRITE共用刪除-FILE_SHARE_DELETE* @param dwCreateDisposition 建立或開啟檔案的目的建立檔案-FILE_CREATE開啟檔案-FILE_OPEN開啟或建立-FILE_OPEN_IF覆蓋-FILE_OVERWRITE建立或覆蓋-FILE_OVERWRITE_IF建立或取代-FILE_SUPERSEDE* @param dwCreateOptions 開啟檔案時選項設定一般用FILE_NOT_DIRECTORY_FILE | FILE_SYNCHRONOUS_IO_NONALERT* @return 讀取成功: STATUS_SUCCESS;讀取失敗:NTSTATUS error code*/__inlineNTSTATUS MyCreateFile(OUT PHANDLE lpFileHandle,                      IN PUNICODE_STRING usFileName,                      IN ULONG dwDesiredAccess,                      IN ULONG dwShareAccess,                      IN ULONG dwCreateDisposition,                      IN ULONG dwCreateOptions){    NTSTATUS ntStatus = STATUS_UNSUCCESSFUL;    OBJECT_ATTRIBUTES oaName;    IO_STATUS_BLOCK iosBlock;    if (lpFileHandle != NULL && usFileName != NULL && usFileName->Buffer != NULL)    {        if (PASSIVE_LEVEL != KeGetCurrentIrql())         {            return ntStatus;        }        InitializeObjectAttributes(&oaName,            usFileName,            OBJ_CASE_INSENSITIVE | OBJ_KERNEL_HANDLE,            NULL,            NULL);        ntStatus = ZwCreateFile(lpFileHandle,            dwDesiredAccess,            &oaName,            &iosBlock,            NULL,            FILE_ATTRIBUTE_NORMAL,            dwShareAccess,            dwCreateDisposition,            dwCreateOptions,            NULL,            0);        if (!NT_SUCCESS(ntStatus))        {                DEBUG_ERROR(("[MyCreateFile]ZwCreateFile(%ws)failed with error:%08x\r\n", usFileName->Buffer, ntStatus));                return ntStatus;        }    }    return ntStatus;}/*** 關閉開啟的檔案控制代碼* @param hFile 檔案控制代碼* @return 讀取成功: STATUS_SUCCESS;讀取失敗:NTSTATUS error code*/__inlineNTSTATUS MyCloseFile(IN HANDLE hFile){    return ZwClose(hFile);}/*** 讀取檔案內容* @param hFile 檔案控制代碼* @param pBuffer 緩衝區* @param ulBufferSize 緩衝區大小* @param pulBytesRead 實際讀取的大小* @return 讀取成功: STATUS_SUCCESS;讀取失敗:NTSTATUS error code*/__inlineNTSTATUS MyReadFile(IN HANDLE hFile,                    IN PVOID pBuffer,                    IN ULONG ulBufferSize,                    OUT PULONG pulBytesRead){    IO_STATUS_BLOCK    iosBlock;    NTSTATUS        ntStatus = STATUS_UNSUCCESSFUL;    if (hFile == NULL || pBuffer == NULL)    {        return ntStatus;    }    if( PASSIVE_LEVEL < KeGetCurrentIrql())    {            DEBUG_ERROR(("All kernel file operating functions must running on PASSIVE_LEVEL\r\n"));        return ntStatus;    }    *pulBytesRead = 0;    ntStatus = ZwReadFile(hFile,        NULL,        NULL,        NULL,        &iosBlock,        pBuffer,        ulBufferSize,        NULL,        NULL);    if (NT_SUCCESS(ntStatus))    {        //擷取實際讀取到的大小        *pulBytesRead = (ULONG)iosBlock.Information;    }    else    {        DEBUG_ERROR(("[MyReadFile]ZwReadFile failed with:%08x\r\n", ntStatus));    }    return ntStatus;}/*** 向檔案寫入內容* @param hFile 檔案控制代碼* @param pBuffer 緩衝區* @param ulBufferSize 緩衝區大小* @param pulBytesWrite 實際寫入的大小* @return 讀取成功: STATUS_SUCCESS;讀取失敗:NTSTATUS error code*/__inlineNTSTATUS MyWriteFile(IN HANDLE hFile,                     IN PVOID pBuffer,                     IN ULONG ulBufferSize,                     OUT PULONG pulBytesWrite){    IO_STATUS_BLOCK    iosBlock;    NTSTATUS        ntStatus = STATUS_UNSUCCESSFUL;        if (hFile == NULL || pBuffer == NULL)    {        return ntStatus;    }    // All kernel file operating functions must running on PASSIVE_LEVEL    if (PASSIVE_LEVEL !=  KeGetCurrentIrql())     {        return ntStatus;    }    *pulBytesWrite = 0;    ntStatus = ZwWriteFile(hFile,        NULL,        NULL,        NULL,        &iosBlock,        pBuffer,        ulBufferSize,        NULL,        NULL);    if (NT_SUCCESS(ntStatus))    {        *pulBytesWrite = (ULONG)iosBlock.Information;    }    else    {        DEBUG_ERROR(("[MyWriteFile]ZwWriteFile failed with:%08x\r\n", ntStatus));    }    return ntStatus;}#endif

引用地址:http://www.cppblog.com/aurain/archive/2009/12/31/104563.html

相關文章

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.