前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >Windows 内核实现复制文件

Windows 内核实现复制文件

作者头像
我与梦想有个约会
发布2023-10-21 14:09:25
1720
发布2023-10-21 14:09:25
举报
文章被收录于专栏:jiajia_deng

Windows 内核编程并没有提供像 Ring3 层的 CopyFile 这样的 API,看了看书中的例子自己写了一份 MyCopyFile,以后用来备用。

代码语言:javascript
复制
#include <ntddk.h>

#ifndef MEM_TAG
#define MEM_TAG 'MyTt'
#endif

NTSTATUS MyOpenFile(
    HANDLE* handle, 
    IO_STATUS_BLOCK* io_status, 
    CONST PUNICODE_STRING file_path)
{
    NTSTATUS status;
    OBJECT_ATTRIBUTES object_attributes;

    InitializeObjectAttributes(
        &object_attributes,
        file_path,
        OBJ_CASE_INSENSITIVE  OBJ_KERNEL_HANDLE,
        NULL, NULL);

    status = ZwCreateFile(
        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);

    return status;
}

NTSTATUS MyCopyFile(PUNICODE_STRING target_path, PUNICODE_STRING source_path)
{
    NTSTATUS status;
    // 创建源文件和目标文件句柄
    HANDLE target = NULL;
    HANDLE source = NULL;

    // buffer
    PVOID buffer = NULL;
    // offset
    LARGE_INTEGER offset = { 0 };
    // io_status
    IO_STATUS_BLOCK io_status = { 0 };

#if DBG
    _asm int 3
#endif

    do 
    {
        // 分别打开文件得到文件句柄
        MyOpenFile(&source, &io_status, source_path);
        MyOpenFile(&target, &io_status, target_path);

        // 分配一个缓冲区用来存储每次读取的内容
        buffer = (PWCHAR)ExAllocatePoolWithTag(NonPagedPool, 4096, MEM_TAG);

        // ZwReadFile 和 ZwWriteFile 所需的两个参数
        IO_STATUS_BLOCK IoStatus = { 0 };
        ULONG length = 4 * 1024;

        while (1)
        {
            // 读取
            status = ZwReadFile(source, NULL, NULL, NULL,
                &IoStatus, buffer, length, &offset, NULL);
            if (!NT_SUCCESS(status))
            {
                if (status == STATUS_END_OF_FILE)
                {
                    status = STATUS_SUCCESS;
                }
                break;
            }

            // 获取实际读到的大小
            length = IoStatus.Information;

            // 根据读取到的实际大小写入到另外一个文件中
            status = ZwWriteFile(target, NULL, NULL, NULL,
                &IoStatus, buffer, length, &offset, NULL);
            if (!NT_SUCCESS(status))
                break;

            // offset 后移
            offset.QuadPart += IoStatus.Information;
        }

    } while (0);

    if (target != NULL)
        ZwClose(target);
    if (source != NULL)
        ZwClose(source);
    if (buffer != NULL)
        ExFreePool(buffer);

    return STATUS_SUCCESS;
}

NTSTATUS DriverEntry(PDRIVER_OBJECT DriverObject, PUNICODE_STRING RegistryPath)
{
    UNICODE_STRING src = RTL_CONSTANT_STRING(L"\\??\\C:\\1.txt");
    UNICODE_STRING dst = RTL_CONSTANT_STRING(L"\\??\\C:\\2.txt");
    MyCopyFile(&dst, &src);
    return STATUS_UNSUCCESSFUL;
}
本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
原始发表:2016-03-30,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
相关产品与服务
对象存储
对象存储(Cloud Object Storage,COS)是由腾讯云推出的无目录层次结构、无数据格式限制,可容纳海量数据且支持 HTTP/HTTPS 协议访问的分布式存储服务。腾讯云 COS 的存储桶空间无容量上限,无需分区管理,适用于 CDN 数据分发、数据万象处理或大数据计算与分析的数据湖等多种场景。
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档