FILE_BASIC_INFORMATION 的理解

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

 

示例代码:

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((" 文件创建失败! /n"));

    }

    else

    {

       KdPrint((" 文件创建成功! /n"));

    }

 

    // 文件操作

    //......

    // 关闭文件句柄

    ZwClose(hFile);

}

 

 

2.  文件的创建

除了可以用 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
    );

 

 

3.  获取或修改文件属性

获取和修改文件属性,包括获取文件大小,获取或修改文件指针位置,获取或修改文件名,获取或修改文件属性(只读属性,隐藏属性),获取或修改文件创建,修改日期。

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;

 

示例代码:

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, F

ILE_OPEN, FILE_SYNCHRONOUS_IO_NONALERT, NULL, 0);

   

    if (!NT_SUCCESS(status))

    {

       KdPrint((" 文件打开失败! /n"));

    }

    else

    {

       KdPrint((" 文件打开成功! /n"));

 

       FILE_BASIC_INFORMATION fbi;

        // 查询文件基本信息

status = ZwQueryInformationFile(hFile, &iostatus, &fbi, sizeof(FILE_BASIC_INFORMATION),

FileBasicInformation);

 

        if (NT_SUCCESS(status))

        {

           KdPrint((" 查询文件属性成功! /n"));

        }

      

       // 设置文件只读属性  

        fbi.FileAttributes |= FILE_ATTRIBUTE_READONLY;

status = ZwSetInformationFile(hFile, &iostatus, &fbi, sizeof(FILE_BASIC_INFORMATION),

FileBasicInformation);

 

        if (NT_SUCCESS(status))

        {

           KdPrint((" 设置文件只读属性成功! /n"));

        }

       // 关闭文件句柄

        ZwClose(hFile);

    }  

}

 

 

4.  文件的写操作

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. I nformation 记录实际写了多少字节。

 

示例代码:

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

}

 

 

5.       文件的读操作

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 来实现。

 

示例代码:

#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/n", iostatus.Information));

 

         // 关闭文件句柄

         ZwClose(hFile);

         // 释放内存

         ExFreePool(pBuffer);

}

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值