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);  
    }  
  • 相关阅读:
    第四十七讲 ASP.NET实例编程(六)
    第四十四讲 ASP.NET实例编程(三)
    第四十一讲 ASP.NET消息处理(二)
    第四十三讲 ASP.NET实例编程(二)
    第四十二讲 ASP.NET实例编程(一)
    第四十六讲 ASP.NET实例编程(五)
    第四十八讲 ASP.NET实战编程(一)
    第四十讲 ASP.NET消息处理(一)
    第四十五讲 ASP.NET实例编程(四)
    第三十九 ASP.NET编码
  • 原文地址:https://www.cnblogs.com/IMyLife/p/4826198.html
Copyright © 2011-2022 走看看