您的位置:首页 > 编程语言

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

2015-09-01 22:17 281 查看
打开和关闭文件
下面的函数用于打开一个文件。
函数原型:
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_READ、FILE_SHARE_WRITE、FILE_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);
续.....~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: