找回密码
 立即注册
搜索
热搜: 活动 交友 discuz
查看: 146|回复: 0

【驱动笔记3】在驱动中读写文件

[复制链接]

210

主题

371

回帖

0

积分

管理员

积分
0
发表于 2013-10-16 12:07:45 | 显示全部楼层 |阅读模式
对文件的读写操作一直是我们需要熟练掌握的内容,在ring3我们可以使用CreateFile、ReadFile、WriteFile等API,在ring0同样很相似,不过函数变成了ZwCreateFile、ZwReadFile、ZwWriteFile等函数。
    在“【驱动笔记1】第一个驱动程序”一文中我们曾经用到过ZwCreateFile,并且成功使用它创建了一个新文件,但那个文件里面什么内容也没有。本节我们就对那个程序进行扩充,实现一个MyCopyFile函数,通过文件的读写来复制文件。
    下面的代码来自楚狂人的《Windows驱动编程基础教程》,我把它前面省略的文件打开和缓冲区分配过程都补充完整了,下面是该函数的完整代码。
BOOLEAN
MyCopyFile(
           IN PUNICODE_STRING    ustrDestFile,
           IN PUNICODE_STRING    ustrSrcFile
            )
{
    HANDLE    hSrcFile, hDestFile;
    PVOID    buffer = NULL;
    ULONG    length = 0;
    LARGE_INTEGER    offset = {0};
    IO_STATUS_BLOCK Io_Status_Block = {0};
    OBJECT_ATTRIBUTES obj_attrib;
    NTSTATUS status;
    BOOLEAN  bRet = FALSE;

    do
    {
        // 打开源文件
        InitializeObjectAttributes(    &obj_attrib,
            ustrSrcFile,
            OBJ_CASE_INSENSITIVE | OBJ_KERNEL_HANDLE,
            NULL,
            NULL);
        status = ZwCreateFile(    &hSrcFile,
            GENERIC_READ,
            &obj_attrib,
            &Io_Status_Block,
            NULL,
            FILE_ATTRIBUTE_NORMAL,
            FILE_SHARE_READ,
            FILE_OPEN,
            FILE_NON_DIRECTORY_FILE | FILE_SYNCHRONOUS_IO_NONALERT,
            NULL,
            0 );
        if (!NT_SUCCESS(status))
        {
            bRet = FALSE;
            goto END;
        }

        // 打开目标文件
        InitializeObjectAttributes(    &obj_attrib,
                                ustrDestFile,
                                OBJ_CASE_INSENSITIVE | OBJ_KERNEL_HANDLE,
                                NULL,
                                NULL);
        status = ZwCreateFile(    &hDestFile,
            GENERIC_WRITE,
            &obj_attrib,
            &Io_Status_Block,
            NULL,
            FILE_ATTRIBUTE_NORMAL,
            FILE_SHARE_READ,
            FILE_OPEN_IF,
            FILE_NON_DIRECTORY_FILE | FILE_SYNCHRONOUS_IO_NONALERT,
            NULL,
            0 );
        if (!NT_SUCCESS(status))
        {
            bRet = FALSE;
            goto END;
        }

        // 为buffer分配4KB空间
        buffer = ExAllocatePool(NonPagedPool, 1024 * 4);
        if (buffer == NULL)
        {
            bRet = FALSE;
            goto END;
        }

        // 复制文件
        while (1)
        {
            length = 4 * 1024;
            // 读取源文件
            status = ZwReadFile(hSrcFile,
                            NULL,
                            NULL,
                            NULL,
                            &Io_Status_Block,
                            buffer,
                            length,
                            &offset,
                            NULL);
            if (!NT_SUCCESS(status))
            {
                // 如果状态为STATUS_END_OF_FILE,说明文件已经读取到末尾
                if (status == STATUS_END_OF_FILE)
                {
                    bRet = TRUE;
                    goto END;
                }
            }

            // 获得实际读取的长度
            length = Io_Status_Block.Information;

            // 写入到目标文件
            status = ZwWriteFile(    hDestFile,
                                NULL,
                                NULL,
                                NULL,
                                &Io_Status_Block,
                                buffer,
                                length,
                                &offset,
                                NULL);
            if (!NT_SUCCESS(status))
            {
                bRet = FALSE;
                goto END;
            }
            
            // 移动文件指针
            offset.QuadPart += length;
        }

    } while (0);
END:
    if (hSrcFile)
    {
        ZwClose(hSrcFile);
    }
    if (hDestFile)
    {
        ZwClose(hDestFile);
    }
    if (buffer = NULL)
    {
        ExFreePool(buffer);
    }

    return bRet;
}

    在DriverEntry中调用该函数的测试代码如下所示:
    // 测试函数
    RtlInitUnicodeString(&ustrSrcFile, L"
\\??\\C:\\windows\\notepad.exe");
    RtlInitUnicodeString(&ustrDestFile, L"
\\??\\C:\\notepad.exe");

    if(MyCopyFile(&ustrDestFile, &ustrSrcFile))
    {
         KdPrint(("[ReadFileTest] CopyFile Success!"));
    }
    else
    {  
         KdPrint(("[ReadFileTest] CopyFile Error!"));
    }
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

果子博客
扫码关注微信公众号

Archiver|手机版|小黑屋|风叶林

GMT+8, 2026-2-1 03:24 , Processed in 0.066787 second(s), 19 queries .

Powered by 风叶林

© 2001-2026 Discuz! Team.

快速回复 返回顶部 返回列表