Windows内核编程基础篇之文件操作(二)

                           打开和关闭文件
      下面的函数用于打开一个文件。
      函数原型:
NTSTATUS ZwCreateFile(
  _Out_    PHANDLE            FileHandle,
  _In_     ACCESS_MASK        DesiredAccess,
  _In_     POBJECT_ATTRIBUTES ObjectAttributes,
  _Out_    PIO_STATUS_BLOCK   IoStatusBlock,
  _In_opt_ PLARGE_INTEGER     AllocationSize,
  _In_     ULONG              FileAttributes,
  _In_     ULONG              ShareAccess,
  _In_     ULONG              CreateDisposition,
  _In_     ULONG              CreateOptions,
  _In_opt_ PVOID              EaBuffer,
  _In_     ULONG              EaLength
);
    参数说明: 
     FileHandle:一个句柄的指针。如果这个函数成功调用,那么打开的文件句柄就返回在这个地址内。
     DisiredAddress: 申请的权限,如果打开写文件内容,请使用 FILE_WITE_DATA;如果需要读写文件内容,请使用 FILE_READ_DATA;如果血药删除文件或者把文件改名,使用 DELETE;若要设置文件属性,请使用 FILE_WRITE_ATTRIBUTES。反之,读写文件属性则使用 FILE_READ_ATTRIBUTES。这些条件可用 | (位或) 来组合。有两个宏分别组合了常用的读写权限,分别为 GENERIC_READ GENERIC_WRITE。还有一个宏代表全部权限,是 GENERIC_ALL,此外想同步地打开文件,加上 SYNCHRONZINE
     ObjectAttribute: 对象描述。
     IoStatusBlock:也是一个结构体,这个机构体在内核开发中经常使用,用于表示一个操作的结果。具体结构如下:
typedef struct _IO_STATUS_BLOCK {
  union {
    NTSTATUS Status;
    PVOID    Pointer;
  };
  ULONG_PTR Information;
} IO_STATUS_BLOCK, *PIO_STATUS_BLOCK;
     一般地,返回结果在 status中,成则为 STATUS_SUCCESS,相反,则为一个错误代码。错误信息代码 如下:
FILE_CREATED: 文件 被成功的新建
FILE_OPENED:  文件被打开了
FILE_OVERWRITTEN   : 文件被覆盖了
FILE_SUPERESEDED   : 文件被替代
FILE_EXISTS: 文件已经存在。
FILE_DOES_NOT_EXIST : 文件打开失败。
        ZwCreateFile的参数: AllocationSize。这个参数用的 很少,我们通常都设置为 NULL
      FileAttributes: 控制新建的文件的属性。通常,我们设置为: FILE_ATTRIBUTE_NORMAL
     ShareAccess  : 这是在本代码打开 这个文件的时候,允许别的代码同时打开这个文件所持有的权限。可以设置的标志位有: FILE_SHARE_READFILE_SHARE_WRITEFILE_SHARE_DELETE。当然也可以用 按位 或 组合。
     下面接着说 ZwCreateFile的参数: CreateDisposition。该参数说明了文件打开的目的。可以设置为下面的值(不能组合):
FILE_CREATE: 新建文件。若文件已经存在,则这个请求失败。
FILE_OPEN     : 打开文件。若文件不存在,则请求失败
FILE_OPEN_IF : 打开或者新建。若文件存在,则打卡,若不存在,则失败
FILE_OVERWRITE: 覆盖。若文件存在,则打开并覆盖文件内容,相反,则请求失败.
FILE_OVERWRITE_IF  : 新建或覆盖。若打开的文件已经存在则打开它,并覆盖其内容,相反,则简单地生成新文件。
    ZwCreateFile的最后一个参数是: CreateOptions 。可以设置为: FILE_NON_DIRECTORY_FILE  |    FILE_SYNCHRONOUS_IO_NONALERT。这样设置,文件此时同步打开,而且打开的是文件(不是文件目录。创建目录用 FILE_DIRECTORY_FILE)。同步打开文件的意义是:以后每次操作文件的时候,比如写文件,调用函数ZwCreateFile 在ZwCreateFile函数返回的时候,文件写操作已经得到完成,而不会有返回STATUS_PENDING(未决)的情况。
    要同步打开, DesiredAccess 必须包含 SYNCHRONIZE

     下面备注下 下面的情况:
     若不想通过缓冲操作文件,希望每次读/写文件都是直接往磁盘上操作的,在填写参数 CreateOptions 时,应带有 标记 FILE_NO_INTERMEDIATE_BUFFERING。注意,带上了这个标记,每次操作文件读/写必须以磁盘扇区大小对齐(常见的是512字节),否则,将返回出错。
    下面的这个示例来自 <天书夜读-从汇编到Windows内核编程>,关于文件的打开与关闭。
//---要返回的文件句柄
HANDLE file_handle = NULL;
//--返回值
NTSTATUS status;
//--初始化含有文件路径的 OBJECT_ATTRIBUTES
OBJECT_ATTRIBUTES object_attributes;
UNICODE_STRING ufile_name = RTL_CONST_STRING(l"\\?\\D:test.dat");
InitializeObjectAttributes(
            &object_attributes,
			&ufile_name,
			OBJ_CASE_INSENSITIVE | OBJ_KERNEL_HANDLE,
			NULL,
			NULL);
//--- OPEN_IF 的方式打开
status = ZwCreateFile(
        &file_handle,
		GENERIC_READ | GENERIC_WRITE,
		&object_attributes,
		&io_status,
		NULL,
		FILE_ATTRIBUTES_NORMAL,
		FILE_SHARE_READ,
		FILE_OPEN_IF,
		FILE_NON_DIRECTORY_FILE | FILE_RANDON_ACCESS | FILE_SYNCHRONOUS_IO_NONALERT,
		NULL,
		0); 
       上面的写法:\\?\\Dtest.dat 。说明下。这里并不是简单的写成:D\\test.dat。因为,ZwCreateFile使用的是对象路径,”D:“是一个符号连接对象,符号链接对象一般都在“\\??\\” 路径下。
       文件句柄的关闭很简单,调用ZwClose 即可。内核句柄的关闭不需要和打开在同一进程中。比如:
ZwClose(file_handle);
    续.....~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

你可能感兴趣的:(Windows内核编程基础篇之文件操作(二))