zoukankan      html  css  js  c++  java
  • Windows内核编程之:文件操作

    一:文件的创建
    /*
    *********************************************************************** * 函数名称:ZwCreateFile * 功能描述:文件的创建 * 参数列表: FileHandle:返回打开文件的句柄 DesiredAccess:对打开文件操作的描述,读,写或是其他。一般指定为GENERIC_READ 或 GENERIC_WRITE ObjectAttributes:是OBJECT_ATTRIBUTES结构的地址,该结构包含要打开的文件名 IoStatusBlock:指向一个IO_STATUS_BLOCK结构,该结构接收ZwCreateFile操作的结果状态 AllocationSize:是一个指针,指向一个64位整数,该数指定文件初始分配时的大小 该参数仅关系到创建或重写文件操作,如果忽略它,那么文件长度从0开始 病随着写入而增长 FileAttributes:0或FILE_ATTRIBUTE_NORMAL,指定新创建文件的属性 ShareAccess:FILE_SHARE_READ或0,指定文件的共享方式。 如果为写数据而打开文件,可能不希望其他线程访问该文件 CreateDisposition:FILE_OPEN或FILE_OVERWRITE_IF,表明当指定文件存在或不存在时应如何处理 CreateOptions:FILE_SYNCHARONOUS_IO_NONALERT,指定控制打开操作和句柄使用的附加标志位 EaBuffer:一个指针,指向可选的扩展属性区 EaLength:扩展属性区的长度 * 返回 值: NTSTATUS *************************************************************************/ NTSTATUS ZwCreateFile( OUT PHANDLE FileHandle, IN ACCESS_MASK DesiredAccess, IN POBJECT_ATTRIBUTES ObjectAttributes, OUT PIO_STATUS_BLOCK IoStatusBlock, IN PLARGE_INTEGER AllocationSize OPTIONAL, IN ULONG FileAttributes, IN ULONG ShareAccess, IN ULONG CreateDisposition, IN ULONG CreateOptions, IN PVOID EaBuffer OPTIONAL, IN ULONG EaLength); /* *备注: * 1、CreateDisposition参数。 * 如果想打开文件,CreateDisposition参数设置成FILE_OPEN. * 如果想创建文件,CreateDisposition参数设置成FILE_OVERWRITE_IF * 此时,无论文件是否存在,都会创建新文件 * 2、文件名是通过第三个参数ObjectAttributes * 这个参数是一个OBJECT_ATTRIBUTES结构体 * 通过InitializeObjectAttributes初始化 */
    /************************************************************************
    * 函数名称:InitializeObjectAttributes
    * 功能描述:初始化OBJECT_ATTRIBUTES结构体
    * 参数列表:
            InitializedAttributes:返回的OBJECT_ATTRIBUTES结构体
            ObjectName:对象名称,用UNICODE_STRING描述,这里设置的是文件名
            Attributes:一般设置为OBJ_CASE_INSENSITIVE,对大小写敏感
            RootDirectory:一般设置为NULL
            SecurityDescriptor:一般设置为NULL
    * 返回 值:相等的字节数
            不一致返回零        
    *************************************************************************/
    VOID InitializeObjectAttributes(
        OUT POBJECT_ATTRIBUTES InitializedAttributes,
        IN PUNICODE_STRING ObjectName,
        IN ULONG Attributes,
        IN HANDLE RootDirectory,
        IN PSECURITY_DESCRIPTOR SecurityDescriptor);
    
    /*
    *备注:
    * 1、文件名[必须]是符号链接或者是设备名
    * 2、例如:盘符 "c:",就是一个符号链接
    *        这里应该用 "\??\c:" 代替 
    *        "c:\1.log" 要写成 "\??\c:\1.log"
    * 3、其中 "\??\c:" 是符号链接,内核会将它转换成设备名 "\Device\HarddiskColume1"
    */

    (1)创建文件

    OBJECT_ATTRIBUTES objectAttributes;
    IO_STATUS_BLOCK iostatus;
    HANDLE hfile;
    UNICODE_STRING logFileUnicodeString;
    
    //初始化UNICODE_STRING字符串
    RtlInitUnicodeString(&logFileUnicodeString, L"\\??\\C:\\1.log");
    //或者改写成  "\\Device\\HarddiskVolume1\\1.log"
    
    //初始化objectAttributes
    InitializeObjectAttributes(&objectAttributes,
        &logFileUnicodeString,
        OBJ_CASE_INSENSITIVE,
        NULL,
        NULL);
    
    //创建文件
    NTSTATUS ntStatus = ZwCreateFile(&hfile, //打开文件的句柄
        GENERIC_WRITE, //读,写
        &objectAttributes, //OBJECT_ATTRIBUTES结构的地址 包含文件名
        &iostatus,  //接收ZwCreateFile操作的结果状态
        NULL, //初始分配时的大小
        FILE_ATTRIBUTE_NORMAL, //新创建文件的属性
        FILE_SHARE_READ, //共享方式
        FILE_OPEN_IF, //当指定文件存在或不存在时应如何处理
        FILE_SYNCHRONOUS_IO_NONALERT, //指定控制打开操作和句柄使用的附加标志位
        NULL, //指向可选的扩展属性区
        0); //扩展属性区的长度
    
    if( NT_SUCCESS(ntStatus) )
    {
        KdPrint(("Create file successfully!\n"));
    }
    else
    {
        KdPrint(("Create file unsuccessfully!\n"));
    }
    
    //文件操作
    //......
    
    //关闭文件句柄
    ZwClose(hfile);

    (2)打开文件

    OBJECT_ATTRIBUTES objectAttributes;
    IO_STATUS_BLOCK iostatus;
    HANDLE hfile;
    UNICODE_STRING logFileUnicodeString;
    
    //初始化UNICODE_STRING字符串
    RtlInitUnicodeString(&logFileUnicodeString, L"\\??\\C:\\1.log");
    //或者改写成  "\\Device\\HarddiskVolume1\\1.log"
    
    //初始化objectAttributes
    InitializeObjectAttributes(&objectAttributes,
        &logFileUnicodeString,
        OBJ_CASE_INSENSITIVE, //对大小写敏感
        NULL,
        NULL);
    
    //创建文件
    NTSTATUS ntStatus = ZwCreateFile(&hfile, //打开文件的句柄
        GENERIC_READ, //
        &objectAttributes, //OBJECT_ATTRIBUTES结构的地址 包含文件名
        &iostatus,  //接收ZwCreateFile操作的结果状态
        NULL, //初始分配时的大小
        FILE_ATTRIBUTE_NORMAL, //新创建文件的属性
        FILE_SHARE_READ, //共享方式
        FILE_OPEN, //打开文件,如果不存在,则返回错误
        FILE_SYNCHRONOUS_IO_NONALERT, //指定控制打开操作和句柄使用的附加标志位
        NULL, //指向可选的扩展属性区
        0); //扩展属性区的长度
    
    if( NT_SUCCESS(ntStatus) )
    {
        KdPrint(("Open file successfully!\n"));
    }
    else
    {
        KdPrint(("Open file unsuccessfully!\n"));
    }
    
    //文件操作
    //......
    
    //关闭文件句柄
    ZwClose(hfile);

    二:文件的打开

    /************************************************************************
    * 函数名称:ZwOpenFile
    * 功能描述:打开文件
    * 参数列表:
            FileHandle:返回打开的文件句柄
            DesiredAccess:打开的权限,一般设为GENERIC_ALL
            ObjectAttributes:objectAttributes结构
            IoStatusBlock:指向一个结构体的指针。该结构体指明打开文件的状态
            ShareAccess:共享的权限。可以是FILE_SHARE_READ或者FILE_SHARE_WRITE
            OpenOptions:打开选项,一般设为FILE_SYNCHRONOUS_IO_NONALERT
    * 返回 值:指明文件是否被成功打开
    *************************************************************************/
    NTSTATUS ZwOpenFile(
        OUT PHANDLE FileHandle,
        IN ACCESS_MASK DesiredAccess,
        IN POBJECT_ATTRIBUTES ObjectAttributes,
        OUT PIO_STATUS_BLOCK IoStatusBlock,
        IN ULONG ShareAccess,
        IN ULONG OpenOptions);

    如何使用ZwOpenFile打开文件

    OBJECT_ATTRIBUTES objectAttributes;
    IO_STATUS_BLOCK iostatus;
    HANDLE hfile;
    UNICODE_STRING logFileUnicodeString;
    
    //初始化UNICODE_STRING字符串
    RtlInitUnicodeString(&logFileUnicodeString, L"\\??\\C:\\1.log");
    //或者写成 \\Device\\HarddiskVolume1\\1.log
    
    //初始化objectAttributes
    InitializeObjectAttributes(
        &objectAttributes,
        &logFileUnicodeString,
        OBJ_CASE_INSENSITIVE,
        NULL,
        NULL);
    
    //创建文件
    NTSTATUS ntStatus = ZwOpenFile(&hfile,
                                   GENERIC_ALL,
                                   &objectAttributes,
                                   &iostatus,
                                   FILE_SHARE_READ || FILE_SHARE_WRITE,
                                   FILE_SYNCHRONOUS_IO_NONALERT);
    if( NT_SUCCESS(ntStatus) )
    {
        KdPrint(("Create FILE successfully!\n"));
    }
    else
    {
        KdPrint(("Create FILE unsuccessfully!\n"));
    }
    
    //文件操作
    //..........
    
    //关闭文件句柄
    ZwClose(hfile);

    三:获取或修改文件属性

    /************************************************************************
    * 函数名称:ZwSetInformationFile
    * 功能描述:设置文件属性
    * 参数列表:
            FileHandle:文件句柄
            IoStatusBlock:返回设置的状态
            FileInformation:依据FileInformationClass不同而不同。作为输入信息
            Length:FileInformation数据的长度
            FileInformationClass:描述修改属性的类型
    * 返回 值:设置属性是否成功
    *************************************************************************/
    NTSTATUS ZwSetInformationFile(
                IN HANDLE FileHandle,
                OUT PIO_STATUS_BLOCK IoStatusBlock,
                IN PVOID FileInformation,
                IN ULONG Length,
                IN FILE_INFORMATION_CLASS FileInformationClass);
    /************************************************************************
    * 函数名称:ZwQueryInformationFile
    * 功能描述:获取文件属性
    * 参数列表:
            FileHandle:文件句柄
            IoStatusBlock:返回设置的状态
            FileInformation:依据FileInformationClass不同而不同。作为输出信息
            Length:FileInformation数据的长度
            FileInformationClass:描述修改属性的类型
    * 返回 值:设置属性查询
    *************************************************************************/
    NTSTATUS ZwQueryInformationFile(
                IN HANDLE FileHandle,
                OUT PIO_STATUS_BLOCK IoStatusBlock,
                OUT PVOID FileInformation,
                IN ULONG Length,
                IN FILE_INFORMATION_CLASS FileInformationClass);

    (1)当FileInformationClass是FileStandardInformation时,
    输入和输出的数据时FILE_STANDARD_INFORMATION结构体,描述文件的基本信息

    typedef struct FILE_STANDARD_INFORMATION(
            LARGE_INTEGER AllocationSize;//为文件分配的大小[注意:不是文件大小,而是占用蔟所需要的大小]
            LARGE_INTEGER EndOfFile; //距离文件结尾还有多少字节
            ULONG NumberOfLinks; //有多少个链接文件
            BOOLEAN DeletePending; //是否准备删除
            BOOLEAN Directory; //是否为目录
            )FILE_STANDARD_INFORMATION, *PFILE_STANDARD_INFORMATION;

    (2)当FileInformationClass是FileBasicInformation时,
    输入和输出的数据时FILE_BASIC_INFORMATION结构体,描述文件的基本信息

        typedef struct FILE_BASIC_INFORMATION(
            LARGE_INTEGER CreationTime, //文件创建时间
            LARGE_INTEGER LastAccessTime, //最后访问时间
            LARGE_INTEGER LastWriteTime, //最后写时间
            LARGE_INTEGER ChangeTime, //修改修改时间
            ULONG FileAttributes;    //文件属性 
            )FILE_BASIC_INFORMATION, *PFILE_BASIC_INFORMATION;
    //其中,时间参数是从一个LARGE_INTEGER的整数,该整数代表从1601年经过多少个100ns(纳秒)
    //FileAttributes描述文件属性。
        //FILE_ATTRIBUTE_NORMAL描述一般文件
        //FILE_ATTRIBUTE_DIRECTORY描述是目录
        //FILE_ATTRIBUTE_READONLY描述是只读
        //FILE_ATTRIBUTE_SYSTEM代表系统文件

    (3)当FileInformationClass是FileNameInformation时,
    输入和输出的数据时FILE_NAME_INFORMATION结构体,描述文件的基本信息

        typedef struct _FILE_NAME_INFORMATION(
                ULONG FileNameLength; //文件名长度
                WCHAR Filename; //文件名
            )FILE_NAME_INFORMATION, *PFILE_NAME_INFORMATION;
    //注意:文件名的字符串是宽字符集字符串

    (4)当FileInformationClass是FilePositionInformation时,
    输入和输出的数据时FILE_POSITION_INFORMATION结构体,描述文件的基本信息

        typedef struct FILE_POSITION_INFORMATION(
                LARGE_INTEGER CurrentByteOffset; //代表当前文件指针位置
            )FILE_POSITION_INFORMATION, *PFILE_POSITION_INFORMATION;

    使用ZwQueryInformationFile函数查询、修改文件属性

    OBJECT_ATTRIBUTES objectAttributes;
    IO_STATUS_BLOCK iostatus;
    HANDLE hfile;
    UNICODE_STRING logFileUnicodeString;
    
    //初始化UNICODE_STRING字符串
    RtlInitUnicodeString(&logFileUnicodeString,
                         L"\\??\\C:\\1.log");
    //或者写成 "\\Device\\HarddisVolume1\\1.log"
    
    //初始化objectAttributes
    InitializeObjectAttributes(&objectAttributes,
                               &logFileUnicodeString,
                               OBJ_CASE_INSENSITIVE, //对大小写敏感
                               NULL,
                               NULL);
    
    //创建文件
    NTSTATUS  ntStatus = ZwCreateFile(&hfile,
                                      GENERIC_READ,
                                      &objectAttributes,
                                      &iostatus,
                                      NULL,
                                      FILE_ATTRIBUTE_NORMAL,
                                      0,
                                      FILE_OPEN, //打开文件,如果不存在则返回错误
                                      FILE_SYNCHRONOUS_IO_NONALERT,
                                      NULL,
                                      0);
    if( NT_SUCCESS(ntStatus) )
    {
        KdPrint(("Open FILE successFully!\n"));
    }
    else
    {
        KdPrint(("Open FILE unsuccessFully!\n"));
    }
    
    FILE_STANDARD_INFORMATION fsi;
    //读取文件长度
    ntStatus = ZwQueryInformationFile(hfile,
                                      &iostatus,
                                      &fsi,
                                      sizeof(FILE_STANDARD_INFORMATION).
                                      FileStandardInformation);
    
    if( NT_SUCCESS(ntStatus) )
    {
        KdPrint(("FILE length:%u\n", fsi.EndOfFile.QuadPart));
    }
    
    //修改当前文件指针
    FILE_POSITION_INFORMATION fpi;
    fpi.CurrentByteOffset.QuadPart = 100i64;
    ntStatus = ZwSetInformationFile(hfile,
                                    &iostatus,
                                    &fpi,
                                    sizeof(FILE_POSITION_INFORMATION),
                                    FilePositionInformation);
    if( NT_SUCCESS(ntStatus) )
    {
        KdPrint(("update the FILE pointer successfully.\n"));
    }
    
    //关闭文件句柄
    ZwClose(hfile);

    四:文件的写操作

    /************************************************************************
    * 函数名称:ZwWriteFile
    * 功能描述:文件的写操作
    * 参数列表:
            FileHandle:文件打开的句柄
            Event:很少用到,一般设为NULL
            ApcRoutine:很少用到,一般设为NULL
            ApcContext:很少用到,一般设为NULL
            IoStatusBlock:记录些操作的状态。其中,IoStatusBlock.Infomation记录实际写了多少字节
            Buffer:从这个缓冲区开始往文件里写
            Length:准备写多少字节
            Byteoffset:从文件的多少便宜地址开始写
            Key:很少用到,一般设为NULL
    * 返回 值:
    *************************************************************************/
    NTSTATUS ZwWriteFile(
        IN HANDLE FileHandle,
        IN HANDLE Event OPTIONAL,
        IN PIO_APC_ROUTINE ApcRoutine OPTIONAL,
        IN PVOID ApcContext OPTIONAL,
        OUT PIO_STATUS_BLOCK IoStatusBlock,
        IN PVOID Buffer,
        IN ULONG Length,
        IN PLARGE_INTEGER Byteoffset OPTIONAL,
        IN PULONG Key OPTIONAL);

    演示如何对文件进行写操作

    OBJECT_ATTRIBUTES objectAttributes;
    IO_STATUS_BLOCK iostatus;
    HANDLE hfile;
    UNICODE_STRING logFileUnicodeString;
    
    //初始化UNICODE_STRING字符串
    RtlInitUnicodeString(&logFileUnicodeString,
        L"\\??\\C:\\1.log");
    //或者写成 "\\Device\\HarddiskVolume1\\1.LOG"
    
    //初始化objectAttributes
    InitializeObjectAttributes(&objectAttributes,
        &logFileUnicodeString,
        OBJ_CASE_INSENSITIVE,//对大小写敏感
        NULL,
        NULL);
    
    //创建文件
    NTSTATUS ntStatus = ZwCreateFile(&hfile,
        GENERIC_WRITE,
        &objectAttributes,
        &iostatus,
        NULL,
        FILE_ATTRIBUTE_NORMAL,
        FILE_SHARE_WRITE,
        FILE_OPEN_IF, //即使存在该文件, 也创建
        FILE_SYNCHRONOUS_IO_NONALERT,
        NULL,
        0);
    if( NT_SUCCESS(ntStatus) )
    {
        KdPrint(("Create file successfully!\n"));
    }
    else
    {
        KdPrint(("Create file unsuccessfully!\n"));
    }
    
    #define BUFFER_SIZE 1024
    
    PUCHAR pBuffer = (PUCHAR)ExAllocatePool(PagedPool, BUFFER_SIZE);
    //构造要填充的数据
    RtlFillMemory(pBuffer, BUFFER_SIZE, 0xAA);
    
    KdPrint(("Thr program will write %d bytes\n", BUFFER_SIZE));
    
    //写文件
    NTSTATUS ntStatus = ZwWriteFile(hfile,
        NULL,
        NULL,
        NULL,
        &iostatus,
        pBuffer,
        BUFFER_SIZE,
        NULL,
        NULL);
    
    if( NT_SUCCESS(ntStatus) )
    {
        KdPrint(("Write file successfully!\n"));
    }
    else
    {
        KdPrint(("Write file unsuccessfully!\n"));
    }
    
    //构造要填充的数据
    RtlFillMemory(pBuffer, BUFFER_SIZE, 0xBB);
    KdPrint(("The program will append %d bytes\n", BUFFER_SIZE));
    
    //追加数据
    LARGE_INTEGER number;
    number.QuadPart = 1024i64; //设置文件指针
    //对文件进行附加写
    NTSTATUS ntStatus = ZwWriteFile(hfile,
        NULL,
        NULL,
        NULL,
        &iostatus,
        pBuffer,
        BUFFER_SIZE,
        &number,
        NULL);
    
    if( NT_SUCCESS(ntStatus) )
    {
        KdPrint(("Write file successfully!\n"));
    }
    else
    {
        KdPrint(("Write file unsuccessfully!\n"));
    }
    
    KdPrint(("The program really appended %d bytes\n", iostatus.Information));
    
    //关闭文件句柄
    ZwClose(hfile);
    
    ExFreePool(pBuffer);

    五:文件的读操作

    /************************************************************************
    * 函数名称:ZwReadFile
    * 功能描述:文件的读操作
    * 参数列表:
            FileHandle:文件打开的句柄
            Event:很少用到,一般设为NULL
            ApcRoutine:很少用到,一般设为NULL
            ApcContext:很少用到,一般设为NULL
            IoStatusBlock:记录些操作的状态。其中,IoStatusBlock.Infomation记录实际写了多少字节
            Buffer:从这个缓冲区开始开始从文件里读
            Length:准备读多少字节
            Byteoffset:从文件的多少偏移地址开始读
            Key:很少用到,一般设为NULL
    * 返回 值:
    *************************************************************************/
    NTSTATUS ZwReadFile(
        IN HANDLE FileHandle,
        IN HANDLE Event OPTIONAL,
        IN PIO_APC_ROUTINE ApcRoutine OPTIONAL,
        IN PVOID ApcContext OPTIONAL,
        OUT PIO_STATUS_BLOCK IoStatusBlock,
        IN PVOID Buffer,
        IN ULONG Length,
        IN PLARGE_INTEGER Byteoffset OPTIONAL,
        IN PULONG Key OPTIONAL);

    演示如何对文件进行读操作

    OBJECT_ATTRIBUTES objectAttributes;
    IO_STATUS_BLOCK iostatus;
    HANDLE hfile;
    UNICODE_STRING logFileUnicodeString;
    
    //初始化UNICODE_STRING字符串
    RtlInitUnicodeString(&logFileUnicodeString,
        L"\\??\\C:\\1.log");
    //或者写成 "\\Device\\HarddiskVolume1\\1.LOG"
    
    //初始化objectAttributes
    InitializeObjectAttributes(&objectAttributes,
        &logFileUnicodeString,
        OBJ_CASE_INSENSITIVE,//对大小写敏感
        NULL,
        NULL);
    
    //创建文件
    NTSTATUS ntStatus = ZwCreateFile(&hfile,
        GENERIC_WRITE,
        &objectAttributes,
        &iostatus,
        NULL,
        FILE_ATTRIBUTE_NORMAL,
        FILE_SHARE_WRITE,
        FILE_OPEN,
        FILE_SYNCHRONOUS_IO_NONALERT,
        NULL,
        0);
    if( !NT_SUCCESS(ntStatus) )
    {
        KdPrint(("The file is nor exist!\n"));
        return;
    }
    
    FILE_STANDARD_INFORMATION fsi;
    
    //读取文件长度
    ntStatus = ZwQueryInformationFile(hfile,
        &iostatus,
        &fsi,
        sizeof(FILE_STANDARD_INFORMATION),
        FileStandardInformation);
    
    KdPrint(("Thr program want to read %d bytes\n", fsi.EndOfFile.QuadPart));
    
    //为读取的文件分配缓冲区
    PUCHAR pBuffer = (PUCHAR)ExAllocatePool(PagedPool, (LONG)fsi.EndOfFile.QuadPart);
    
    //读文件
    NTSTATUS ntStatus = ZwReadFile(hfile,
        NULL,
        NULL,
        NULL,
        &iostatus,
        pBuffer,
        BUFFER_SIZE,
        (LONG)fsi.EndOfFile.QuadPart,
        NULL);
    
    if( NT_SUCCESS(ntStatus) )
    {
        KdPrint(("Read file successfully!\n"));
    }
    else
    {
        KdPrint(("Read file unsuccessfully!\n"));
    }
    
    KdPrint(("The program really read %d bytes\n", iostatus.Information));
    
    //关闭文件句柄
    ZwClose(hfile);
    
    //释放缓冲区
    ExFreePool(pBuffer);
  • 相关阅读:
    JSTL XML标签库 使用
    JSTL SQL标签库 使用
    JSTL I18N 格式标签库
    基于struts2的ajaxfileupload异步上传插件的使用
    Spring 使用注解方式进行事务管理
    vi编辑器的使用方式
    js基础知识介绍
    选择语句
    数组
    0411作业
  • 原文地址:https://www.cnblogs.com/qintangtao/p/3067240.html
Copyright © 2011-2022 走看看