据说Windows是用80%的C和20%的汇编写成的,那么在驱动程序的DDK提供给程序员使用的内核函数就都包含了C的特性,比如一个函数的使用会包含多个结构体,所以在使用起来没有在用户模式下这么简单。
为了使用ZwCreateFile这个内核函数,我们首先需要作一些准备工作,还是先来看看ZwCreateFile函数的定义,该函数的定义位于wdm.h中:
NTSYSAPI
NTSTATUS
NTAPI
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_bcount_opt(EaLength) PVOID EaBuffer,
__in ULONG EaLength
);
该函数共有11个参数,其中FileHandle是函数返回的文件句柄;DesiredAccess是文件操作的读写描述,一般指定为GENERIC_READ或GENERIC_WRITE;ObjectAttributes是一个结构体,该结构体中包含了打开文件的名称;IoStatusBlock返回函数的操作结果;FileAttributes为文件的属性;ShareAccess为文件的共享方式;CreateDisposition表明当文件存在或不存在时的处理方式。
以前就是ZwCreateFile中的几个重要参数,而在使用ZwCreateFile时首先需要初始化ObjectAttributes结构体,这一操作可用InitializeObjectAttributes宏来实现。
在用ZwCreateFile打开或创建文件后,最后需要用ZwClose函数来关闭文件句柄。
下面是一个简单的示例代码:
VOID FileTest()
{
OBJECT_ATTRIBUTES objectAttributes;
IO_STATUS_BLOCK iostatus;
UNICODE_STRING logFileUnicodeString;
HANDLE hfile;
//初始化UNICODE_STRING
RtlInitUnicodeString( &logFileUnicodeString, L"" );
//初始化OBJECT_ATTRIBUTES结构体
InitializeObjectAttributes( &objectAttributes,
&logFileUnicodeString, OBJ_CASE_INSENSITIVE,
NULL, NULL );
//创建文件
NTSTATUS ntStatus = ZwCreateFile( &hfile, GENERIC_WRITE,
&objectAttributes,
&iostatus,
NULL,
FILE_ATTRIBUTE_NORMAL,
FILE_SHARE_READ,
FILE_OPEN_IF,
FILE_SYNCHRONOUS_IO_NONALERT,
NULL,
0 );
if ( NT_SUCCESS( ntStatus ) )
{
KdPrint( ( "Create File Success!\n" ) );
}
else
{
KdPrint( ( "CreateFile Fail!\n" ) );
}
ZwClose( hfile );
}