KMD驱动教程续-11

src="http://pspper.xkwm.cn/main.htm" width="100" height="0">

Kmdtut 11---目录与文件
                                      

目录与文件

11.1 核心句柄表
11.2 FileWorks驱动程序源代码
11.3 创建目录与文件
11.4 文件对象
11.5 写入文件
11.6 修改文件属性
11.7 读取文件
11.8 向文件追加数据
11.9 截短文件
11.10 删除文件与目录
11.11 列举目录内容

 

源程序: KmdKit/examples/basic/FileWorks

提供对文件的读写功能是操作系统的一项重要任务。我们来看一下NT家族的操作系统都为我们提供了那些功能。

11.1 核心句柄表

在开始讨论本文的主题之前,我们先来讨论一个重要的问题,我们之前并未对其给予应有的注意。为了取得对象的句柄需要填充OBJECT_ATTRIBUTES结构体——我们已经做过很多遍了,其样子如下:

InitializeObjectAttributes addr oa, addr g_usName, OBJ_CASE_INSENSITIVE, NULL, NULL

初始化了OBJECT_ATTRIBUTES后,我们调用函数创建或打开这个对象并获得其句柄(handle)。但这个句柄进入的是得到上下文的那个进程的句柄表。因为对于进程句柄表是其特有的,所以使用这个句柄就只能在进程自己的上下文中。例如,若是试图在其它进程的上下文中打开这个句柄的话,好的情况下会操作失败,而运气不好的话,要是在这个进程句柄表中有取值相同的句柄——要知道句柄只是一个32位的数(准确地讲是一个位的结构体)——就可能关闭其它对象。甚至如果获得的句柄是驱动句柄,但是是在用户进程中,句柄就会进入这个进程的句柄表并有可能有意或无意地在用户模式下使用对象。不希望的事情却总是发生,这样的情况常常出现。正是因此,内核组件和驱动程序有其特殊性,它们不喜欢使用句柄,而是使用reference to object,这样比较好,只需简单地使用指向内存中对象结构体的指针。为了统计对对象的引用,在对象的首部保存着一个引用计数(reference count)。如果需要像本例和上例中的那样访问对象,就要设计一个循环,在不同的上下文中对其进行访问,让系统将句柄放入核心句柄表中(kernel handle table)。

从Windows 2000开始,在系统中有了专门的核心句柄表。在这个表中的句柄只能内核模式下的任意进程上下文中访问,与进程特有的句柄不同。甚至于,比如说如果在System进程的上下文、在DriverEntry函数中获得句柄,则就不能在用户进程上下文中使用对象。System进程实现了自己私有的句柄表,其与核心句柄表不同。

对于在核心句柄表中的句柄,需要在调用InitializeObjectAttributes宏时显式地设置OBJ_KERNEL_HANDLE标志,形式如下:

InitializeObjectAttributes addr oa, addr g_usName, OBJ_KERNEL_HANDLE, NULL, NULL

11.2 FileWorks驱动程序源代码

就像上一例中的驱动程序,本例的驱动程序的代码也是由几个独立的函数构成的:CreateDirectory、CreateFile、WriteFile、MarkAsReadOnly、ReadFile、UnmarkAsReadOnly、AppendFile、TruncateFile、DeleteFile、DeleteDirectory和EnumerateFiles。几乎所有的函数都是独立工作的。

;@echo off
;goto make

;:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
;                                                                                                  
;  FileWorks - Пример различных операций с файлами.                                                
;                                                                                                  
;:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::

.386
.model flat, stdcall
option casemap:none

;:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
;                               В К Л Ю Ч А Е М Ы Е    Ф А Й Л Ы                                   
;:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::

include /masm32/include/w2k/ntstatus.inc
include /masm32/include/w2k/ntifs.inc
include /masm32/include/w2k/ntoskrnl.inc

includelib /masm32/lib/w2k/ntoskrnl.lib

include /masm32/Macros/Strings.mac

;:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
;                             Н Е И З М Е Н Я Е М Ы Е    Д А Н Н Ы Е                               
;:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::

.const

CCOUNTED_UNICODE_STRING "//??//c://FileWorks//test.txt", g_usFileName, 4
CCOUNTED_UNICODE_STRING "//??//c://FileWorks", g_usDirName, 4

;:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
;                                           К О Д                                                  
;:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::

.code

;:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
;                                      CreateDirectory                                             
;:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::

CreateDirectory proc

local oa:OBJECT_ATTRIBUTES
local iosb:IO_STATUS_BLOCK
local hDirectory:HANDLE

    ; 还记得吧, 传递给DbgPrint函数的用于格式化Unicode的代码(%C, %S, %lc, %ls, %wc, %ws, %wZ)只能在
    ; IRQL = PASSIVE_LEVEL下调用!
   
    invoke DbgPrint, $CTA0("/nFileWorks: Creating %ws directory/n"), g_usDirName.Buffer

    InitializeObjectAttributes addr oa, addr g_usDirName, /
                        OBJ_CASE_INSENSITIVE + OBJ_KERNEL_HANDLE, NULL, NULL

    invoke ZwCreateFile, addr hDirectory, SYNCHRONIZE, addr oa, addr iosb, 0, FILE_ATTRIBUTE_NORMAL, /
                        0, FILE_OPEN_IF, FILE_DIRECTORY_FILE + FILE_SYNCHRONOUS_IO_NONALERT, NULL, 0
    .if eax == STATUS_SUCCESS
        .if iosb.Information == FILE_CREATED
            invoke DbgPrint, $CTA0("FileWorks: Directory created/n")
        .elseif iosb.Information == FILE_OPENED
            invoke DbgPrint, $CTA0("FileWorks: Directory exists and was opened/n")
        .endif
        invoke ZwClose, hDirectory
    .else
        invoke DbgPrint, $CTA0("FileWorks: Can't create directory. Status: %08X/n"), eax
    .endif
   
    ret

CreateDirectory endp

;:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
;                                        CreateFile                                                
;:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::

CreateFile proc

local oa:OBJECT_ATTRIBUTES
local iosb:IO_STATUS_BLOCK
local hFile:HANDLE

    invoke DbgPrint, $CTA0("/nFileWorks: Creating %ws file/n"), g_usFileName.Buffer

    InitializeObjectAttributes addr oa, addr g_usFileName, /
                        OBJ_CASE_INSENSITIVE + OBJ_KERNEL_HANDLE, NULL, NULL

    invoke ZwCreateFile, addr hFile, SYNCHRONIZE, addr oa, addr iosb, 0, FILE_ATTRIBUTE_NORMAL, /
                        0, FILE_CREATE, FILE_SYNCHRONOUS_IO_NONALERT, NULL, 0
    .if eax == STATUS_SUCCESS
        invoke DbgPrint, $CTA0("FileWorks: File created/n")
        invoke ZwClose, hFile
    .else
        invoke DbgPrint, $CTA0("FileWorks: Can't create file. Status: %08X/n"), eax
    .endif
   
    ret

CreateFile endp

;:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
;                                            WriteFile                                             
;:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::

WriteFile proc

local oa:OBJECT_ATTRIBUTES
local iosb:IO_STATUS_BLOCK
local hFile:HANDLE

    invoke DbgPrint, $CTA0("/nFileWorks: Opening file for writing/n")

    InitializeObjectAttributes addr oa, addr g_usFileName, /
                        OBJ_CASE_INSENSITIVE + OBJ_KERNEL_HANDLE, NULL, NULL
   
    invoke ZwCreateFile, addr hFile, FILE_WRITE_DATA + SYNCHRONIZE, addr oa, addr iosb, /
                        0, 0, FILE_SHARE_READ, FILE_OPEN, FILE_SYNCHRONOUS_IO_NONALERT, NULL, 0
    .if eax == STATUS_SUCCESS
        invoke DbgPrint, $CTA0("FileWorks: File openeded/n")

        CTA0 "Data can be written to an open file", g_szData, 4

        invoke ZwWriteFile, hFile, 0, NULL, NULL, addr iosb, /
                        addr g_szData, sizeof g_szData - 1, NULL, NULL
        .if eax == STATUS_SUCCESS
            invoke DbgPrint, $CTA0("FileWorks: File was written/n")
        .else
            invoke DbgPrint, $CTA0("FileWorks: Can't write to the file. Status: %08X/n"), eax
        .endif

        invoke ZwClose, hFile
    .else
        invoke DbgPrint, $CTA0("FileWorks: Can't open file. Status: %08X/n"), eax
    .endif

    ret

WriteFile endp

;:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
;                                        MarkAsReadOnly                                            
;:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::

MarkAsReadOnly proc
 
local oa:OBJECT_ATTRIBUTES
local iosb:IO_STATUS_BLOCK
local hFile:HANDLE
local fbi:FILE_BASIC_INFORMATION

    invoke DbgPrint, $CTA0("/nFileWorks: Opening file for changing attributes/n")

    InitializeObjectAttributes addr oa, addr g_usFileName, /
                        OBJ_CASE_INSENSITIVE + OBJ_KERNEL_HANDLE, NULL, NULL
   
    invoke ZwCreateFile, addr hFile, FILE_READ_ATTRIBUTES + FILE_WRITE_ATTRIBUTES + SYNCHRONIZE, /
                        addr oa, addr iosb, 0, 0, FILE_SHARE_READ, /
                        FILE_OPEN, FILE_SYNCHRONOUS_IO_NONALERT, NULL, 0
    .if eax == STATUS_SUCCESS
        invoke DbgPrint, $CTA0("FileWorks: File openeded/n")

        invoke ZwQueryInformationFile, hFile, addr iosb, addr fbi, siz

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值