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
        );

     

    示例代码:

    1. VOID);  
    2.  hFile;  
    3.     IO_STATUS_BLOCK iostatus;  
    4.  (!NT_SUCCESS(status))  
    5.     {  
    6. ));  
    7.     }  
    8.   
    9.     {  
    10. ));  
    11.     }  
    12.   
    13.   
    14.   
    15.   
    16.   
    17.     ZwClose(hFile);  
    18. }  
    19. 除了可以用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;

      示例代码:

      1. VOID);  
      2.  hFile;  
      3.     IO_STATUS_BLOCK iostatus;  
      4.   
      5.  (!NT_SUCCESS(status))  
      6. ));  
      7.   
      8. ));  
      9.   
      10. (FILE_BASIC_INFORMATION), FileBasicInformation);  
      11.    
      12.  (NT_SUCCESS(status))  
      13.     {  
      14. ));  
      15.     }  
      16.   
      17. (FILE_BASIC_INFORMATION),FileBasicInformation);  
      18.  (NT_SUCCESS(status))  
      19. ));  
      20.   
      21. }  
      22. 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
            );

        IoStatusBlockIoStatusBlock.Information记录实际写了多少字节。

        示例代码:

        1. #define BUFFER_SIZE 1024#pragma INITCODEVOID);  
        2.  hFile;  
        3.          IO_STATUS_BLOCK iostatus;  
        4.   
        5.   
        6.  pBuffer = ()ExAllocatePool(PagedPool, BUFFER_SIZE);  
        7.          RtlFillMemory(pBuffer, BUFFER_SIZE, );  
        8.   
        9.          status = ZwWriteFile(hFile, NULL, NULL, NULL, &iostatus, pBuffer, BUFFER_SIZE, NULL, NULL);  
        10.   
        11.          RtlFillMemory(pBuffer, BUFFER_SIZE, );  
        12.   
        13.          ZwClose(hFile);  
        14.   
        15.          ExFreePool(pBuffer);  
        16. }  
        17. 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来实现。

          示例代码:

          1. #pragma INITCODEVOID);  
          2.    
          3.  hFile;  
          4.   
          5.          NTSTATUS status = ZwCreateFile(&hFile, GENERIC_READ, &objattr, &iostatus, NULL,   
          6.   
          7.          FILE_STANDARD_INFORMATION fsi;  
          8. (FILE_STANDARD_INFORMATION), FileStandardInformation);  
          9.    
          10.   
          11.           pBuffer = ()ExAllocatePool(PagedPool, ()fsi.EndOfFile.QuadPart);  
          12.   
          13. )fsi.EndOfFile.QuadPart, NULL, NULL);  
          14.          KdPrint((  
          15.   
          16. }  
       
  • 相关阅读:
    如何删除Windows的服务
    在使用ORACLE时常用到的命令和脚本
    windows 查看端口使用情况
    jQuery获取及设置单选框,多选框,文本框内容
    disabled="disabled" readonly="readonly" type="hidden"提交表单的区别
    @Column标记持久化详细说明
    jQuery核心及其工具
    Hibernate JPA注解说明
    php要点
    jQuery中的动画与效果
  • 原文地址:https://www.cnblogs.com/ansen312/p/5865322.html
Copyright © 2011-2022 走看看