内核模式下的文件操作

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. ZwClose(hFile);
  12. }
  13. 除了可以用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. (!NT_SUCCESS(status))
    5. ));
    6. ));
    7. (FILE_BASIC_INFORMATION), FileBasicInformation);
    8. (NT_SUCCESS(status))
    9. {
    10. ));
    11. }
    12. (FILE_BASIC_INFORMATION),FileBasicInformation);
    13. (NT_SUCCESS(status))
    14. ));
    15. }
    16. 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. pBuffer = ()ExAllocatePool(PagedPool, BUFFER_SIZE);
      5. RtlFillMemory(pBuffer, BUFFER_SIZE, );
      6. status = ZwWriteFile(hFile, NULL, NULL, NULL, &iostatus, pBuffer, BUFFER_SIZE, NULL, NULL);
      7. RtlFillMemory(pBuffer, BUFFER_SIZE, );
      8. ZwClose(hFile);
      9. ExFreePool(pBuffer);
      10. }
      11. 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. hFile;
        3. NTSTATUS status = ZwCreateFile(&hFile, GENERIC_READ, &objattr, &iostatus, NULL,
        4. FILE_STANDARD_INFORMATION fsi;
        5. (FILE_STANDARD_INFORMATION), FileStandardInformation);
        6. pBuffer = ()ExAllocatePool(PagedPool, ()fsi.EndOfFile.QuadPart);
        7. )fsi.EndOfFile.QuadPart, NULL, NULL);
        8. KdPrint((
        9. }

     

时间: 2024-11-10 07:40:38

内核模式下的文件操作的相关文章

内核模式下的字符串操作

分类: WINDOWS 1)ASCII字符串和宽字符串    在应用程序中使用两种字符:a) char型字符串,负责记录ANSI字符集,它是指向一个char数组的指针,每个char型变量大小是一个字节,字符串是以0标志字符串结束的:b) wchar_t型的宽字符串,负责描述unicode字符集,它是指向一个wchar_t数组的指针,wchar_t字符大小为两个字节,字符串以0标志字符串结束.   例: ANSI字符构造如下:   char *str1 = "ASCE";   UNICO

YJX_Driver_038_内核模式下的字串操作

1. 内核模式下的字串操作 A.ASCII字符串和UNICODE字符串 B.ANSI_STRING字符串和UNICODE_STRING字符串 C.字符串的初始化与销毁 D.字符串复制,比较,(大小写,整数和字串)相互转换 E.ANSI_STRING字符串和UNICODE_STRING字符串相互转换 2. A.ASNI字符串和UNICODE字符串 在C语言中,有ANSI和UNICODE 两个不同字串类型. char* s1="abc"; //CHAR * s1="abc&quo

Windows内核函数(3) - 内核模式下的注册表操作

Windows内核函数(3) - 内核模式下的注册表操作 2010-12-13 13:37:16|  分类: 驱动编程 |  标签:status  hkey  ulsize  注册  kdprint  |举报|字号 订阅 注册表里的几个概念: 1.       创建关闭注册表项 NTSTATUS   ZwCreateKey(    OUT PHANDLE  KeyHandle,    IN ACCESS_MASK  DesiredAccess, //访问权限,一般为KEY_ALL_ACCLESS

Windows核心编程笔记(7)----内核模式下的线程同步

1.内核对象同步与用户模式下同步对比 使用内核对象的唯一缺点就是性能,调用内核对象函数时,调用线程必须从用户模式切换到内核模式,这种切换是相当 耗时的. 内核对象(进程.线程.作业)要么处于触发态,要么处于未触发状态.进程内核对象在创建时总是处于未触发状态, 当进程终止时,操作系统会自动使进程内核对象变成触发状态.当进程内核对象处于触发状态后,将永远保持这种状态, 再也不能变回未触发状态. 2.等待内核对象 WaitForSingleObject等待单个内核对象,WaitForMultipleO

Linux(C/C++)下的文件操作open、fopen与freopen

Linux(C/C++)下的文件操作open.fopen与freopen open是linux下的底层系统调用函数,fopen与freopen c/c++下的标准I/O库函数,带输入/输出缓冲. linxu下的fopen是open的封装函数,fopen终于还是要调用底层的系统调用open. 所以在linux下假设须要对设备进行明白的控制.那最好使用底层系统调用(open), open相应的文件操作有:close, read, write,ioctl 等. fopen 相应的文件操作有:fclos

WIN7-X64内核模式下编程实现导出表列表查看

内核模式下查看导出表需要注意的事项比在用户模式下要考虑更加周详: X64环境倒不是变化太多,指针定是64位的,数据数据及指针指向的数据类型需要注意: 不费话,直接上源码,VS2010+WDK7600下编译通过: /// /// @file aux_list.c /// @author cntom90151 /// @date2015-09-24 /// #include <ntddk.h> #include <WinDef.h> #include <aux_klib.h>

熟练掌握doc命令下的文件操作

这里以介绍操作php脚本为例 熟练掌握doc命令下的文件操作

转:Windows8内核模式下开发NDIS应用-NDIS Filter讲解

http://blog.csdn.net/itcastcpp/article/details/7752075 在Win8系统下开发驱动程序,需要数字证书,还需要驱动签名认证.不能像XP下面那样疯狂滴耍流氓了. 由于Win8系统的内核做了大幅度的修改,它和XP系统的内核起了很大的变化,最显著的就是刚才说的:需要签名和证书.  还有就是:不能随意的HOOK SSDT了. 在开发NDIS驱动程序的时候,WDK开发包提供了一个新的框架,叫着NDIS FilterNDIS Filter是一个例子工程.假入

【vim】正常模式下的一般操作

正常模式一般用于浏览文本,其实也就是通过键盘命令让光标在文本中跳来跳去,在任何模式下按一次或两次<Esc>会进入正常模式. 基本思想 vim对光标的定位操作非常精确和高效,这是它的一个非常好用的地方.但是,由于按键和按键组合太多太复杂,会让好多初学者望而却步. 其实,vim的光标定位是有规律的,就好像当初学五笔打字一样,看起来要记很多字根,其实键盘上字根的排列是非常有规律的,一旦清楚这些规律,学习就会心里有数很多. 对于vim来说,它的很多操作都遵循<数量><动作>&l