zoukankan      html  css  js  c++  java
  • 文件操作

    1.文件的创建
    
    对文件的创建或者打开都是通过内核函数ZwCreateFile实现的。和Windows API类似,这个内核函数返回一个文件句柄,文件的所有操作都是依靠这个句柄进行操作的。在文件操作完毕后,要关闭这个文件句柄。
    
    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
        );
    
     
    
    FileHandle:返回打开文件的句柄
    
    DesiredAccess: 一般指定为GENERIC_READ 或者 GENERIC_WRITE
    
    ObjectAttributes:是OBJECT_ATTRIBUTES结构的地址,该结构包含要打开的文件名。
    
    IoStatusBlock:指向一个IO_STATUS_BLOCK结构体,该结构接收ZwCreateFile操作的结果状态。
    
    AllocationSize:是一个指针,指向一个64位整数,该数指定文件初始分配时的大小、该参数仅关系到创建或重写文件操作。如果忽略它,那么文件长度将从0开始,并随着写入而增长。
    
    FileAttributes:指定新创建文件的属性,一般为0或FILE_ATTRIBUTE_NORMAL
    
    ShareAccess:指定文件的共享方式,0或者FILE_SHARE_READ
    
    CreateDisposition:指定当文件存在或不存在时,该如何处理
    
    CreateOptions:FILE_SYNCHRONOUS_IO_NONALERT,指定控制打开操作和句柄使用的附加标志位。
    
    EaBuffer:一个指针,指向可选的扩展属性区
    
    EaLength:扩展属性区的长度
    
     
    
    要创建的文件的文件名是通过第三个参数传入的。这个参数是一个OBJECT_ATTRIBUTES得结构。DDK提供了对OBJECT_ATTRIBUTES初始化的宏:
    
    VOID 
      InitializeObjectAttributes(
        OUT POBJECT_ATTRIBUTES  InitializedAttributes,
        IN PUNICODE_STRING  ObjectName,//文件名
        IN ULONG  Attributes,//一般为OBJ_CASE_INSENSITIVE,对大小写敏感
        IN HANDLE  RootDirectory,//一般为NULL
        IN PSECURITY_DESCRIPTOR  SecurityDescriptor //一般为NULL
        );
    
     
    
    示例代码:
    
    
    [cpp] view plaincopy在CODE上查看代码片派生到我的代码片
    VOID TetsCreateFile()  
    {  
        UNICODE_STRING string;  
        RtlInitUnicodeString(&string, L"\??\C:\1.log");  
      
        OBJECT_ATTRIBUTES objattr;  
        InitializeObjectAttributes(&objattr, &string, OBJ_CASE_INSENSITIVE, NULL, NULL);  
       
        HANDLE hFile;  
        IO_STATUS_BLOCK iostatus;  
      
        NTSTATUS status = ZwCreateFile(&hFile, GENERIC_READ | GENERIC_WRITE, &objattr, &iostatus,  
      
                  NULL, FILE_ATTRIBUTE_NORMAL, 0, FILE_OPEN_IF, FILE_SYNCHRONOUS_IO_NONALERT, NULL, 0);  
        if (!NT_SUCCESS(status))  
        {  
           KdPrint(("文件创建失败!
    "));  
        }  
        else  
        {  
           KdPrint(("文件创建成功!
    "));  
        }  
        //文件操作  
      
        //......  
      
        //关闭文件句柄  
        ZwClose(hFile);  
    }  
    除了可以用ZwCreateFile函数打开文件,DDK还为我们提供了一个ZwOpenFile函数用来打开文件,以简化文件的打开操作。
    
    NTSTATUS
      ZwOpenFile(
        OUT PHANDLE  FileHandle,
        IN ACCESS_MASK  DesiredAccess, //打开权限,一般为GENERIC_ALL
        IN POBJECT_ATTRIBUTES  ObjectAttributes,
        OUT PIO_STATUS_BLOCK  IoStatusBlock,
        IN ULONG  ShareAccess,
        IN ULONG  OpenOptions//打开选项,一般为FILE_SYNCHRONOUS_IO_NONALERT
        );
    
    2.获取或修改文件属性
    
    获取和修改文件属性,包括获取文件大小,获取或修改文件指针位置,获取或修改文件名,获取或修改文件属性(只读属性,隐藏属性),获取或修改文件创建,修改日期。
    
    NTSTATUS 
      ZwSetInformationFile(
        IN HANDLE  FileHandle,
        OUT PIO_STATUS_BLOCK  IoStatusBlock,
        IN PVOID  FileInformation,
        IN ULONG  Length,
        IN FILE_INFORMATION_CLASS  FileInformationClass
        );
    
    NTSTATUS 
      ZwQueryInformationFile(
        IN HANDLE  FileHandle,
        OUT PIO_STATUS_BLOCK  IoStatusBlock,
        OUT PVOID  FileInformation,
        IN ULONG  Length,
        IN FILE_INFORMATION_CLASS  FileInformationClass
        );
    
    FileInformation:依据FileInformationClass不同而不同。
    
    Length:FileInformation数据的长度
    
    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;
    
    (3)   当FileInformationClass 是FileNameInformation 时,输入和输出数据是FILE_NAME_INFORMATION结构体,描述文件名信息。
    
    typedef struct _FILE_NAME_INFORMATION {
      ULONG  FileNameLength; //文件名长度
      WCHAR  FileName[1]; //文件名
    } 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;
    
    示例代码:
    
    
    [cpp] view plaincopy在CODE上查看代码片派生到我的代码片
    VOID TetsFile()  
    {  
        UNICODE_STRING string;  
        RtlInitUnicodeString(&string, L"\??\C:\1.log");  
       
        OBJECT_ATTRIBUTES objattr;  
        InitializeObjectAttributes(&objattr, &string, OBJ_CASE_INSENSITIVE, NULL, NULL);  
       
        HANDLE hFile;  
        IO_STATUS_BLOCK iostatus;  
       
        //打开文件  
        NTSTATUS status = ZwCreateFile(&hFile, GENERIC_READ, &objattr, &iostatus, NULL,   
        FILE_ATTRIBUTE_NORMAL, 0, FILE_OPEN, FILE_SYNCHRONOUS_IO_NONALERT, NULL, 0);  
         
        if (!NT_SUCCESS(status))  
        {  
           KdPrint(("文件打开失败!
    "));  
        }  
        else  
        {  
           KdPrint(("文件打开成功!
    "));  
       
           FILE_BASIC_INFORMATION fbi;  
             
        //查询文件基本信息  
           status = ZwQueryInformationFile(hFile, &iostatus, &fbi, sizeof(FILE_BASIC_INFORMATION), FileBasicInformation);  
       
        if (NT_SUCCESS(status))  
        {  
           KdPrint(("查询文件属性成功!
    "));  
        }  
      
        //设置文件只读属性   
        fbi.FileAttributes |= FILE_ATTRIBUTE_READONLY;  
        status = ZwSetInformationFile(hFile, &iostatus, &fbi, sizeof(FILE_BASIC_INFORMATION),FileBasicInformation);  
      
        if (NT_SUCCESS(status))  
        {  
           KdPrint(("设置文件只读属性成功!
    "));  
        }  
        //关闭文件句柄  
        ZwClose(hFile);  
        }    
    }  
    
    
    3.文件的写操作
    
    NTSTATUS 
      ZwWriteFile(
        IN HANDLE  FileHandle,
        IN HANDLE  Event  OPTIONAL, //一般设为NULL
        IN PIO_APC_ROUTINE  ApcRoutine  OPTIONAL, //一般设为NULL
        IN PVOID  ApcContext  OPTIONAL, //一般设为NULL
        OUT PIO_STATUS_BLOCK  IoStatusBlock, //记录实际写的字节数
        IN PVOID  Buffer, //从这个缓冲区中开始往文件里写
        IN ULONG  Length, //准备写多少字节
        IN PLARGE_INTEGER  ByteOffset  OPTIONAL, //从文件的多少偏移开始写
        IN PULONG  Key  OPTIONAL //一般设为NULL
        );
    
    IoStatusBlock:IoStatusBlock.Information记录实际写了多少字节。
    
    示例代码:
    
    [cpp] view plaincopy在CODE上查看代码片派生到我的代码片
    #define BUFFER_SIZE 1024  
    #pragma INITCODE  
    VOID TetsFile()  
    {  
             UNICODE_STRING string;  
             RtlInitUnicodeString(&string, L"\??\C:\1.log");  
       
             OBJECT_ATTRIBUTES objattr;  
             InitializeObjectAttributes(&objattr, &string, OBJ_CASE_INSENSITIVE, NULL, NULL);  
       
             HANDLE hFile;  
             IO_STATUS_BLOCK iostatus;  
       
             //打开文件  
             NTSTATUS status = ZwCreateFile(&hFile, GENERIC_WRITE, &objattr, &iostatus, NULL,   
         FILE_ATTRIBUTE_NORMAL, FILE_SHARE_WRITE, FILE_OPEN_IF, FILE_SYNCHRONOUS_IO_NONALERT, NULL, 0);  
              
             //分配Buffer空间  
             PUCHAR pBuffer = (PUCHAR)ExAllocatePool(PagedPool, BUFFER_SIZE);  
             RtlFillMemory(pBuffer, BUFFER_SIZE, 'A');  
             //写文件  
             status = ZwWriteFile(hFile, NULL, NULL, NULL, &iostatus, pBuffer, BUFFER_SIZE, NULL, NULL);  
              
             LARGE_INTEGER  ByteOffset;  
             ByteOffset.QuadPart = 1024i64; //设置文件指针偏移  
             RtlFillMemory(pBuffer, BUFFER_SIZE, 'B');  
       
             status = ZwWriteFile(hFile, NULL, NULL, NULL, &iostatus, pBuffer, BUFFER_SIZE, &ByteOffset, NULL);  
             //关闭文件句柄  
             ZwClose(hFile);  
             //释放内存  
             ExFreePool(pBuffer);  
    }  
     
    
    4.文件的读操作
    
    NTSTATUS 
      ZwReadFile(
        IN HANDLE  FileHandle,
        IN HANDLE  Event  OPTIONAL,
        IN PIO_APC_ROUTINE  ApcRoutine  OPTIONAL,
        IN PVOID  ApcContext  OPTIONAL,
        OUT PIO_STATUS_BLOCK  IoStatusBlock,
        OUT PVOID  Buffer,
        IN ULONG  Length,
        IN PLARGE_INTEGER  ByteOffset  OPTIONAL,
        IN PULONG  Key  OPTIONAL
        );
    
    如果需要读取整个文件,那么得知道文件的大小,我们可以用ZwQueryInformationFile来实现。
    
    示例代码:
    
    [cpp] view plaincopy在CODE上查看代码片派生到我的代码片
    #pragma INITCODE  
    VOID TetsFile()  
    {  
             UNICODE_STRING string;  
             RtlInitUnicodeString(&string, L"\??\C:\1.log");  
       
             OBJECT_ATTRIBUTES objattr;  
             InitializeObjectAttributes(&objattr, &string, OBJ_CASE_INSENSITIVE, NULL, NULL);  
       
             HANDLE hFile;  
             IO_STATUS_BLOCK iostatus;  
       
             //打开文件  
             NTSTATUS status = ZwCreateFile(&hFile, GENERIC_READ, &objattr, &iostatus, NULL,   
         FILE_ATTRIBUTE_NORMAL, FILE_SHARE_READ, FILE_OPEN, FILE_SYNCHRONOUS_IO_NONALERT, NULL, 0);  
       
             //获得文件的大小  
             FILE_STANDARD_INFORMATION fsi;  
             status = ZwQueryInformationFile(hFile, &iostatus, &fsi, sizeof(FILE_STANDARD_INFORMATION), FileStandardInformation);  
       
             //分配Buffer空间  
             PUCHAR pBuffer = (PUCHAR)ExAllocatePool(PagedPool, (LONG)fsi.EndOfFile.QuadPart);  
              
             //读文件  
             status = ZwReadFile(hFile, NULL, NULL, NULL, &iostatus, pBuffer, (LONG)fsi.EndOfFile.QuadPart, NULL, NULL);  
             KdPrint(("Read %d bytes
    ", iostatus.Information));  
       
             //关闭文件句柄  
             ZwClose(hFile);  
             //释放内存  
             ExFreePool(pBuffer);  
    }  
  • 相关阅读:
    pat00-自测5. Shuffling Machine (20)
    Spiral Matrix
    Search in Rotated Sorted Array II
    Search in Rotated Sorted Array
    Best Time to Buy and Sell Stock II
    4Sum
    3Sum Closest
    3Sum
    MySQL存储过程、函数和游标
    Word Ladder
  • 原文地址:https://www.cnblogs.com/IMyLife/p/4826198.html
Copyright © 2011-2022 走看看