win下驱动文件操作相关函数封装

创建文件

//创建文件
HANDLE KernelCreateFile(
    IN PUNICODE_STRING pstrFile, // 文件路径符号链接
    IN BOOLEAN         bIsDir)   // 是否为文件夹
{
    HANDLE          hFile = NULL;
    NTSTATUS        Status = STATUS_UNSUCCESSFUL;
    IO_STATUS_BLOCK StatusBlock = { 0 };
    ULONG           ulShareAccess =
        FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE;
    ULONG           ulCreateOpt =
        FILE_SYNCHRONOUS_IO_NONALERT;
    // 1. 初始化OBJECT_ATTRIBUTES的内容
    OBJECT_ATTRIBUTES objAttrib = { 0 };
    ULONG             ulAttributes =
        OBJ_CASE_INSENSITIVE | OBJ_KERNEL_HANDLE;
    InitializeObjectAttributes(
        &objAttrib,    // 返回初始化完毕的结构体
        pstrFile,      // 文件对象名称
        ulAttributes,  // 对象属性
        NULL, NULL);   // 一般为NULL
                       // 2. 创建文件对象
    ulCreateOpt |= bIsDir ?
        FILE_DIRECTORY_FILE : FILE_NON_DIRECTORY_FILE;
    Status = ZwCreateFile(
        &hFile,                // 返回文件句柄
        GENERIC_ALL,           // 文件操作描述
        &objAttrib,            // OBJECT_ATTRIBUTES
        &StatusBlock,          // 接受函数的操作结果
        0,                     // 初始文件大小
        FILE_ATTRIBUTE_NORMAL, // 新建文件的属性
        ulShareAccess,         // 文件共享方式
        FILE_OPEN_IF,          // 文件存在则打开不存在则创建
        ulCreateOpt,           // 打开操作的附加标志位
        NULL,                  // 扩展属性区
        0);                   // 扩展属性区长度
    if (!NT_SUCCESS(Status))
        return (HANDLE)-1;
    return hFile;
}

获取文件大小


//获取文件大小
ULONG64 KernelGetFileSize(IN HANDLE hfile)
{
    // 查询文件状态
    IO_STATUS_BLOCK           StatusBlock = { 0 };
    FILE_STANDARD_INFORMATION fsi = { 0 };
    NTSTATUS Status = STATUS_UNSUCCESSFUL;
    Status = ZwQueryInformationFile(
        hfile,        // 文件句柄
        &StatusBlock, // 接受函数的操作结果
        &fsi,         // 根据最后一个参数的类型输出相关信息
        sizeof(FILE_STANDARD_INFORMATION),
        FileStandardInformation);
    if (!NT_SUCCESS(Status))
        return 0;
    return fsi.EndOfFile.QuadPart;
}

读取文件

ULONG64 KernelReadFile(
    IN  HANDLE         hfile,    // 文件句柄
    IN  PLARGE_INTEGER Offset,   // 从哪里开始读取
    IN  ULONG          ulLength, // 读取多少字节
    OUT PVOID          pBuffer)  // 保存数据的缓存
{
    // 1. 读取文件
    IO_STATUS_BLOCK StatusBlock = { 0 };
    NTSTATUS        Status = STATUS_UNSUCCESSFUL;
    Status = ZwReadFile(
        hfile,        // 文件句柄
        NULL,         // 信号状态(一般为NULL)
        NULL, NULL,   // 保留
        &StatusBlock, // 接受函数的操作结果
        pBuffer,      // 保存读取数据的缓存
        ulLength,     // 想要读取的长度
        Offset,       // 读取的起始偏移
        NULL);        // 一般为NULL
    if (!NT_SUCCESS(Status))  return 0;
    // 2. 返回实际读取的长度
    return StatusBlock.Information;
}

写入文件

//写文件
ULONG64 KernelWriteFile(
    IN HANDLE         hfile,    // 文件句柄
    IN PLARGE_INTEGER Offset,   // 从哪里开始写入
    IN ULONG          ulLength, // 写入多少字节
    IN PVOID          pBuffer)  // 欲写入的数据
{
    // 1. 写入文件
    IO_STATUS_BLOCK StatusBlock = { 0 };
    NTSTATUS        Status = STATUS_UNSUCCESSFUL;
    Status = ZwWriteFile(
        hfile,        // 文件句柄
        NULL,         // 信号状态(一般为NULL)
        NULL, NULL,   // 保留
        &StatusBlock, // 接受函数的操作结果
        pBuffer,      // 欲写入的数据
        ulLength,     // 想要写入的长度
        Offset,       // 写入的起始偏移
        NULL);        // 一般为NULL
    if (!NT_SUCCESS(Status))  return 0;
    // 2. 返回实际写入的长度
    // 2. 返回实际写入的长度
    return StatusBlock.Information;
}

删除文件

/删除文件
NTSTATUS KernelDeleteFile(IN PUNICODE_STRING pstrFile)
{
    // 1. 初始化OBJECT_ATTRIBUTES的内容
    OBJECT_ATTRIBUTES objAttrib = { 0 };
    ULONG             ulAttributes =
        OBJ_CASE_INSENSITIVE | OBJ_KERNEL_HANDLE;
    InitializeObjectAttributes(
        &objAttrib,    // 返回初始化完毕的结构体
        pstrFile,      // 文件对象名称
        ulAttributes,  // 对象属性
        NULL,          // 根目录(一般为NULL)
        NULL);         // 安全属性(一般为NULL)
                       // 2. 删除指定文件/文件夹
    return ZwDeleteFile(&objAttrib);
}

拷贝文件

//拷贝文件
VOID ZwMyCopyFile(
    PUNICODE_STRING  SouPath,//源地址
    PUNICODE_STRING DenPath  //目的地址
)
{

    //1 打开源地址文件
    HANDLE hSorHandle = KernelCreateFile(SouPath, FALSE);
    //2 获取大小
    ULONG64 FileSize = KernelGetFileSize(hSorHandle);
    //3 申请空间,读取数据
    PVOID buf = ExAllocatePool(NonPagedPool, (SIZE_T)FileSize);
    RtlZeroMemory(buf, (SIZE_T)FileSize);
    LARGE_INTEGER Offset = {0,0};
    KernelReadFile(hSorHandle, &Offset, (SIZE_T)FileSize, buf);
    //4 打开目的地址文件
    HANDLE hDenHandle = KernelCreateFile(DenPath, FALSE);
    //5 写入数据
    KernelWriteFile(hDenHandle, &Offset, (SIZE_T)FileSize, buf);
    //6 关闭句柄
    ZwClose(hSorHandle);
    ZwClose(hDenHandle);
}

文件遍历

#define _countof(arr) sizeof(arr)/sizeof(arr[0])
BOOLEAN KernelFindFirstFile(
    IN  HANDLE                     hFile, // 文件句柄
    IN  ULONG                      ulLen, // 信息长度
    OUT PFILE_BOTH_DIR_INFORMATION  pDir, // 文件信息
    IN  ULONG                      uFirstlLen, // 信息长度
    OUT PFILE_BOTH_DIR_INFORMATION pFirstDir // 第一个文件信息
) {
    NTSTATUS                   Status = STATUS_UNSUCCESSFUL;
    IO_STATUS_BLOCK            StatusBlock = { 0 };
    // 1. 获取第一个文件信息,看是否成功
    Status = ZwQueryDirectoryFile(
        hFile, NULL, NULL, NULL,// 文件句柄
        &StatusBlock, // 接受函数的操作结果
        pFirstDir,         // 文件信息
        uFirstlLen,        // “文件信息“的数据长度
        FileBothDirectoryInformation, // 查询模式
        TRUE,              // 是否返回一条起始信息
        NULL,              // 文件句柄指向的文件(一般为NULL)
        FALSE);            // 是否从目录开始的第一项扫描
                           // 2. 若成功,则获取文件列表
    if (NT_SUCCESS(Status) == FALSE) {
        return FALSE;
    }
    Status = ZwQueryDirectoryFile(
        hFile, NULL, NULL, NULL,// 文件句柄
        &StatusBlock, // 接受函数的操作结果
        pDir,         // 文件信息
        ulLen,        // “文件信息“的数据长度
        FileBothDirectoryInformation, // 查询模式
        FALSE,        // 是否返回一条起始信息
        NULL,         // 文件句柄指向的文件(一般为NULL)
        FALSE);       // 是否从目录开始的第一项扫描
    return NT_SUCCESS(Status);
}

BOOLEAN KernelFindNextFile(
    IN  PFILE_BOTH_DIR_INFORMATION pDirList,//
    OUT PFILE_BOTH_DIR_INFORMATION pDirInfo,
    IN OUT LONG * Loc) {
    // 如果有下一项,则移动指针指向下一项
    PFILE_BOTH_DIR_INFORMATION pDir = (PFILE_BOTH_DIR_INFORMATION)((PCHAR)pDirList + *Loc);
    LONG StructLenth = 0;
    if (pDir->FileName[0] != 0)
    {
        StructLenth = sizeof(FILE_BOTH_DIR_INFORMATION);
        memcpy(pDirInfo, pDir, StructLenth + pDir->FileNameLength);
        *Loc = *Loc + pDir->NextEntryOffset;
        if (pDir->NextEntryOffset == 0) {
            *Loc = *Loc + StructLenth + pDir->FileNameLength;
        }
        return TRUE;
    }
    return FALSE;
}
NTSTATUS EnmuFile()
{
    UNICODE_STRING ustrFolder = { 0 };
    WCHAR          szSymbol[0x512] = L"\\??\\";
    UNICODE_STRING ustrPath =
        RTL_CONSTANT_STRING(L"C:\\");
    HANDLE         hFile = NULL;
    SIZE_T         nFileInfoSize =
        sizeof(FILE_BOTH_DIR_INFORMATION) + 270 * sizeof(WCHAR);
    SIZE_T         nSize = nFileInfoSize * 0x256; //假设最多有0x256个文件
    char           strFileName[0x256] = { 0 };
    PFILE_BOTH_DIR_INFORMATION pFileTemp = NULL;
    PFILE_BOTH_DIR_INFORMATION pFileList = NULL;
    pFileList = (PFILE_BOTH_DIR_INFORMATION)ExAllocatePool(PagedPool, nSize);
    pFileTemp = (PFILE_BOTH_DIR_INFORMATION)ExAllocatePool(PagedPool,
        nFileInfoSize);
    // 1. 将路径组装为连接符号名,并打开文件
    wcscat_s(szSymbol, _countof(szSymbol), ustrPath.Buffer);
    RtlInitUnicodeString(&ustrFolder, szSymbol);
    hFile = KernelCreateFile(&ustrFolder, TRUE);
    if (KernelFindFirstFile(hFile, nSize, pFileList, nFileInfoSize, pFileTemp))
    {
        LONG Loc = 0;
        do
        {
            RtlZeroMemory(strFileName, 0x256);
            RtlCopyMemory(strFileName,
                pFileTemp->FileName,
                pFileTemp->FileNameLength);
            if (strcmp(strFileName, "..") == 0
                || strcmp(strFileName, ".") == 0)
                continue;
            if (pFileTemp->FileAttributes
                & FILE_ATTRIBUTE_DIRECTORY)
                DbgPrint("[目录]%S\n", strFileName);
            else
                DbgPrint("[文件]%S\n", strFileName);
            memset(pFileTemp, 0, nFileInfoSize);
        } while (KernelFindNextFile(pFileList, pFileTemp, &Loc));
    }
    return STATUS_SUCCESS;
}

原文地址:http://blog.51cto.com/haidragon/2131404

时间: 2024-11-06 17:03:34

win下驱动文件操作相关函数封装的相关文章

Linux(C/C++)下的文件操作open、fopen与freopen

Linux(C/C++)下的文件操作open.fopen与freopen open是linux下的底层系统调用函数,fopen与freopen c/c++下的标准I/O库函数,带输入/输出缓冲. linxu下的fopen是open的封装函数,fopen终于还是要调用底层的系统调用open. 所以在linux下假设须要对设备进行明白的控制.那最好使用底层系统调用(open), open相应的文件操作有:close, read, write,ioctl 等. fopen 相应的文件操作有:fclos

熟练掌握doc命令下的文件操作

这里以介绍操作php脚本为例 熟练掌握doc命令下的文件操作

Linux文件操作相关函数

一.整体大纲 st_mode整体介绍: st_mode详细介绍: 二. Linux文件操作相关函数 1. stat 作用:获得文件信息,也可以获取文件大小. 头文件 #include <sys/types.h> #include <sys/stat.h> #include <unistd.h> 函数原型 int stat(const char *path, struct stat *buf); int fstat(int fd, struct stat *buf); i

C# WPF Application 下的文件操作

好气哦,电脑好烂,每天花大把的时间在等电脑反应上. 没有钱买新电脑,连组台式机的钱都没有.好气哦. 啊啊啊啊文件操作是什么鬼???C++下我都懵了,C#下好多东西要学!!!我不会!我不会!我不会!!!啊啊啊啊啊啊!!! 怎么办啊?用windows API写我要怎么样移植到Linux下? WINDOWS API的文件操作 一.常用函数 CreateFile 创建.打开文件 ReadFile 读取文件内容 WriteFile 写入文件内容 SetFilePointer 移动文件指针 SetEndOf

win下svn常用操作笔记

svn基本命令 checkout 检出 把服务器代码下载到本地一份update 更新 把服务器上的最新代码更新到本地commit 提交 把本地代码提交到服务器上 win下svn的客户端工具TortoiseSVN 一.创建一个仓库 1.在E盘新建一个空目录test2.进入这个目录,右键选择TortoiseSVN->Create repository here(在此创建版本库) 二.我们在检出该仓库 1.右键选择Svn Checkout(SVN检出)2.输入file:///E:/test(如果是远程

内核模式下的文件操作

1.文件的创建 对文件的创建或者打开都是通过内核函数ZwCreateFile实现的.和Windows API类似,这个内核函数返回一个文件句柄,文件的所有操作都是依靠这个句柄进行操作的.在文件操作完毕后,要关闭这个文件句柄. NTSTATUS     ZwCreateFile(     OUT PHANDLE  FileHandle,     IN ACCESS_MASK  DesiredAccess,     IN POBJECT_ATTRIBUTES  ObjectAttributes,  

linux下对文件操作报错----------Unable to *** ***: Read-only file system

在linux中对文件操作时报错:Unable to chmod ***: Read-only file system 用如下指令能解决该问题: 输入su root 进入超级用户 输入 mount -o remount rw / 然后可输入 mount 查看

ubuntu下zip文件操作

转自 https://blog.csdn.net/hpu11/article/details/71524013 1.zip $ zip -r myfile.zip ./* 将当前目录下的所有文件和文件夹全部压缩成myfile.zip文件,-r表示递归压缩子目录下所有文件. 2.unzip $ unzip -o -d /home/sunny myfile.zip 把myfile.zip文件解压到 /home/sunny/ -o:不提示的情况下覆盖文件: -d:-d /home/sunny 指明将文

CMD下常用文件操作指令

1.输入盘符 如C: 然后回车,相当于进了C盘(c盘一般进的是桌面目录) 2.输入 cd 目录名 然后回车(目录名是c盘中的一级目录名,也可为c盘中的目录路径).如cd mm即是进入了mm文件夹 (若要打开某个文件则不需要cd) 3.如果你想返回到上层目录,那么直接输入cd..就行了,可以返回到上层目录.开发过程中最常用的命令也就这些. 4.dir命令查看目录下的文件列表,查看该目录下的所有文件:dir /a * 5.attrib命令,更改文件属性,去除该目录下所有文件(夹)的隐藏属性:attr