Windows内核驱动中操作文件

本页主题:如何在windows内核驱动中对文件操作,实现对文件的拷贝、粘贴、删除、查询信息等,这是很常用也是很简单的方法。

部分内容参考:http://www.cppblog.com/aurain/archive/2009/12/31/104563.html

实现原理:

一、在Windows执行体中,通过文件对象来代表文件,该文件对象是一种由对象管理器管理的执行体对象。例如:目录也是由文件对象代表的。
内核组件通过对象名来引用文件,即在文件的全路径前面加\DosDevices。(在Windows 2000及后续操作系统中,\??等同于\DosDevices)。例如,文件C:\WINDOWS\example.txt的对象名为\DosDevices\C:\WINDOWS\example.txt。你需要用对象名来打开文件以获取句柄。

大体步骤如下所示:

1、打开文件,返回文件句柄。注意文件路径一定要初始化才能操作。
2、调用合适的ZwXxxFile 函数以完成对文件的操作。
3、调用ZwClose函数关闭打开的文件句柄。

二、下表对第一步骤的对象名作简单的总结:

对象名

描述

\DosDevices

对象目录

\DosDevices\C:

代表C盘的设备对象

\DosDevices\C:\Directory

代表名为C:\Director的文件对象

\DosDevices\C:\Directory\File

代表名为C:\Directo\Filer的文件对象



三、打开文件,获取句柄

1. 定义各一个OBJECT_ATTRIBUTES结构体变量,然后调用InitializeObjectAttributes函数初始化该变量。关键是设置改变量的ObjectName字段为文件对象名。
2. 调用IoCreateFile, ZwCreateFile, 或者 ZwOpenFile,传递上面定义的结构体变量,成功就会返回执行该文件的句柄。
注:驱动一般用ZwCreateFile和ZwOpenFile,IoCreateFile很少使用
    当调用ZwCreateFile,ZwOpenFile或IoCreateFile时,Windows执行体创建一个代表该文件的新的文件对象,并返回一个指向该对象的句柄。文件对象一直存在,知道你关闭了所有指向它的文件句柄。

zw文件操作属性
读文件
ZwReadFile
写文件
ZwWriteFile
读文件属性 
ZwQueryInformationFile  
写文件属性 ZwSetInformationFile

测试:打开文件,如果没有则创建文件,获取句柄

#pragma INITCODE
VOID CreateFileTest() 
{
	OBJECT_ATTRIBUTES objectAttributes;
	IO_STATUS_BLOCK iostatus;
	HANDLE hfile;
	UNICODE_STRING logFileUnicodeString;

	//初始化UNICODE_STRING字符串
	RtlInitUnicodeString( &logFileUnicodeString, 
		L"\\??\\C:\\1.log");
	//或者写成 "\\Device\\HarddiskVolume1\\1.LOG"


	//初始化objectAttributes
	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 succussfully!\n"));
	}else
	{
		KdPrint(("Create file  unsuccessfully!\n"));
	}

	//文件操作
	//.......

	//关闭文件句柄
	ZwClose(hfile);
}
四、测试:通过句柄,对文件进行读写、拷贝(环境是VS2012 WDK7.1)

Driver.h

/************************************************************************
* 文件名称:Driver.h                                                 
* 作    者:Geons
* 完成日期:2016年3月30日18:42:38
*************************************************************************/
#pragma once

#ifdef __cplusplus
extern "C"
{
#endif
#include <NTDDK.h>
#include <ntstrsafe.h>
#ifdef __cplusplus
}
#endif 

#define PAGEDCODE code_seg("PAGE")
#define LOCKEDCODE code_seg()
#define INITCODE code_seg("INIT")

#define PAGEDDATA data_seg("PAGE")
#define LOCKEDDATA data_seg()
#define INITDATA data_seg("INIT")

#define arraysize(p) (sizeof(p)/sizeof((p)[0]))

typedef struct _DEVICE_EXTENSION {
	PDEVICE_OBJECT pDevice;
	UNICODE_STRING ustrDeviceName;	//设备名称
	UNICODE_STRING ustrSymLinkName;	//符号链接名
} DEVICE_EXTENSION, *PDEVICE_EXTENSION;

// 函数声明

NTSTATUS CreateDevice (IN PDRIVER_OBJECT pDriverObject);
VOID HelloDDKUnload (IN PDRIVER_OBJECT pDriverObject);
NTSTATUS HelloDDKDispatchRoutine(IN PDEVICE_OBJECT pDevObj,
								 IN PIRP pIrp);
VOID CopyFileSourceToTarget();


MyFileDriver.cpp(包含了文件操作的很多个测试,接口已经暴露在Entry里面,可以在里面自己测试,默认是拷贝两个文件)

/************************************************************************
* 文件名称:Driver.cpp                                                 
* 作    者:Geons<span style="white-space:pre">	</span>
* 完成日期:2016年3月30日18:50:13
*************************************************************************/

#include "Driver.h"

#pragma INITCODE
VOID CreateFileTest() 
{
	OBJECT_ATTRIBUTES objectAttributes;
	IO_STATUS_BLOCK iostatus;
	HANDLE hfile;
	UNICODE_STRING logFileUnicodeString;

	//初始化UNICODE_STRING字符串
	RtlInitUnicodeString( &logFileUnicodeString, 
		L"\\??\\C:\\1.log");
	//或者写成 "\\Device\\HarddiskVolume1\\1.LOG"


	//初始化objectAttributes
	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 succussfully!\n"));
	}else
	{
		KdPrint(("Create file  unsuccessfully!\n"));
	}

	//文件操作
	//.......

	//关闭文件句柄
	ZwClose(hfile);
}


#pragma INITCODE
VOID OpenFileTest2() 
{
	OBJECT_ATTRIBUTES objectAttributes;
	IO_STATUS_BLOCK iostatus;
	HANDLE hfile;
	UNICODE_STRING logFileUnicodeString;

	//初始化UNICODE_STRING字符串
	RtlInitUnicodeString( &logFileUnicodeString, 
		L"\\??\\C:\\1.log");
	//或者写成 "\\Device\\HarddiskVolume1\\1.LOG"


	//初始化objectAttributes
	InitializeObjectAttributes(&objectAttributes, 
							&logFileUnicodeString,
							OBJ_CASE_INSENSITIVE, 
							NULL, 
							NULL );

	//创建文件
	NTSTATUS ntStatus = ZwOpenFile( &hfile, 
							GENERIC_ALL,
							&objectAttributes, 
							&iostatus, 
							FILE_SHARE_READ|FILE_SHARE_WRITE,
							FILE_SYNCHRONOUS_IO_NONALERT);
	if ( NT_SUCCESS(ntStatus))
	{
		KdPrint(("Create file succussfully!\n"));
	}else
	{
		KdPrint(("Create file  unsuccessfully!\n"));
	}

	//文件操作
	//.......

	//关闭文件句柄
	ZwClose(hfile);
}


#pragma INITCODE
VOID OpenFileTest1() 
{
	OBJECT_ATTRIBUTES objectAttributes;
	IO_STATUS_BLOCK iostatus;
	HANDLE hfile;
	UNICODE_STRING logFileUnicodeString;

	//初始化UNICODE_STRING字符串
	RtlInitUnicodeString( &logFileUnicodeString, 
		L"\\??\\C:\\1.log");
	//或者写成 "\\Device\\HarddiskVolume1\\1.LOG"

	//初始化objectAttributes
	InitializeObjectAttributes(&objectAttributes,
							&logFileUnicodeString,
							OBJ_CASE_INSENSITIVE,//对大小写敏感 
							NULL, 
							NULL );

	//创建文件
	NTSTATUS ntStatus = ZwCreateFile( &hfile, 
							GENERIC_READ,
							&objectAttributes, 
							&iostatus, 
							NULL,
							FILE_ATTRIBUTE_NORMAL, 
							FILE_SHARE_WRITE,
							FILE_OPEN,//对文件打开,如果不存在则返回错误 
							FILE_SYNCHRONOUS_IO_NONALERT, 
							NULL, 
							0 );
	if ( NT_SUCCESS(ntStatus))
	{
		KdPrint(("Open file succussfully!\n"));
	}else
	{
		KdPrint(("Open file  unsuccessfully!\n"));
	}

	//文件操作
	//.......

	//关闭文件句柄
	ZwClose(hfile);
}


#pragma INITCODE
VOID FileAttributeTest() 
{
	OBJECT_ATTRIBUTES objectAttributes;
	IO_STATUS_BLOCK iostatus;
	HANDLE hfile;
	UNICODE_STRING logFileUnicodeString;

	//初始化UNICODE_STRING字符串
	RtlInitUnicodeString( &logFileUnicodeString, 
		L"\\??\\C:\\1.log");
	//或者写成 "\\Device\\HarddiskVolume1\\1.LOG"

	//初始化objectAttributes
	InitializeObjectAttributes(&objectAttributes,
							&logFileUnicodeString,
							OBJ_CASE_INSENSITIVE,//对大小写敏感 
							NULL, 
							NULL );

	//创建文件
	NTSTATUS ntStatus = ZwCreateFile( &hfile, 
							GENERIC_READ,
							&objectAttributes, 
							&iostatus, 
							NULL,
							FILE_ATTRIBUTE_NORMAL, 
							0,
							FILE_OPEN,//对文件打开,如果不存在则返回错误 
							FILE_SYNCHRONOUS_IO_NONALERT, 
							NULL, 
							0 );
	if (NT_SUCCESS(ntStatus))
	{ 
		KdPrint(("open file successfully.\n"));
	}

	FILE_STANDARD_INFORMATION fsi;
	//读取文件长度
	ntStatus = ZwQueryInformationFile(hfile,
									&iostatus,
									&fsi,
									sizeof(FILE_STANDARD_INFORMATION),
									FileStandardInformation);
	if (NT_SUCCESS(ntStatus))
	{
		KdPrint(("file length:%u\n",fsi.EndOfFile.QuadPart));
	}
	
	//修改当前文件指针
	FILE_POSITION_INFORMATION fpi;
	fpi.CurrentByteOffset.QuadPart = 100i64;
	ntStatus = ZwSetInformationFile(hfile,
								&iostatus,
								&fpi,
								sizeof(FILE_POSITION_INFORMATION),
								FilePositionInformation);
	if (NT_SUCCESS(ntStatus))
	{
		KdPrint(("update the file pointer successfully.\n"));
	}

	//关闭文件句柄
	ZwClose(hfile);
}


#pragma INITCODE
VOID WriteFileTest() 
{
	OBJECT_ATTRIBUTES objectAttributes;
	IO_STATUS_BLOCK iostatus;
	HANDLE hfile;
	UNICODE_STRING logFileUnicodeString;

	//初始化UNICODE_STRING字符串
	RtlInitUnicodeString( &logFileUnicodeString, 
		L"\\??\\C:\\1.log");
	//或者写成 "\\Device\\HarddiskVolume1\\1.LOG"

	//初始化objectAttributes
	InitializeObjectAttributes(&objectAttributes,
							&logFileUnicodeString,
							OBJ_CASE_INSENSITIVE,//对大小写敏感 
							NULL, 
							NULL );

	//创建文件
	NTSTATUS ntStatus = ZwCreateFile( &hfile, 
							GENERIC_WRITE,
							&objectAttributes, 
							&iostatus, 
							NULL,
							FILE_ATTRIBUTE_NORMAL, 
							FILE_SHARE_WRITE,
							FILE_OPEN_IF,//即使存在该文件,也创建 
							FILE_SYNCHRONOUS_IO_NONALERT, 
							NULL, 
							0 );
#define BUFFER_SIZE 1024
	PUCHAR pBuffer = (PUCHAR)ExAllocatePool(PagedPool,BUFFER_SIZE);
	//构造要填充的数据
	RtlFillMemory(pBuffer,BUFFER_SIZE,0xAA);

	KdPrint(("The program will write %d bytes\n",BUFFER_SIZE));
	//写文件
	ZwWriteFile(hfile,NULL,NULL,NULL,&iostatus,pBuffer,BUFFER_SIZE,NULL,NULL);
	KdPrint(("The program really wrote %d bytes\n",iostatus.Information));


	//构造要填充的数据
	RtlFillMemory(pBuffer,BUFFER_SIZE,0xBB);

	KdPrint(("The program will append %d bytes\n",BUFFER_SIZE));
	//追加数据
	LARGE_INTEGER number;
	number.QuadPart = 1024i64;//设置文件指针
	//对文件进行附加写
	ZwWriteFile(hfile,NULL,NULL,NULL,&iostatus,pBuffer,BUFFER_SIZE,&number,NULL);
	KdPrint(("The program really appended %d bytes\n",iostatus.Information));

	
	ExFreePool(pBuffer);

	//关闭文件句柄
	ZwClose(hfile);

}

#pragma INITCODE
VOID ReadFileTest() 
{
	OBJECT_ATTRIBUTES objectAttributes;
	IO_STATUS_BLOCK iostatus;
	HANDLE hfile;
	UNICODE_STRING logFileUnicodeString;

	//初始化UNICODE_STRING字符串
	RtlInitUnicodeString( &logFileUnicodeString, 
		L"\\??\\C:\\1.log");
	//或者写成 "\\Device\\HarddiskVolume1\\1.LOG"

	//初始化objectAttributes
	
	//初始化objectAttributes
	InitializeObjectAttributes(&objectAttributes, 
							&logFileUnicodeString,
							OBJ_CASE_INSENSITIVE, 
							NULL, 
							NULL );

	//创建文件
	NTSTATUS ntStatus = ZwOpenFile( &hfile, 
							GENERIC_ALL,
							&objectAttributes, 
							&iostatus, 
							FILE_SHARE_READ|FILE_SHARE_WRITE,
							FILE_SYNCHRONOUS_IO_NONALERT);

	if (!NT_SUCCESS(ntStatus))
	{
		KdPrint(("The file is not exist!\n"));
		return;
	}

	FILE_STANDARD_INFORMATION fsi;
	//读取文件长度
	ntStatus = ZwQueryInformationFile(hfile,
									&iostatus,
									&fsi,
									sizeof(FILE_STANDARD_INFORMATION),
									FileStandardInformation);

	KdPrint(("The program want to read %d bytes\n",fsi.EndOfFile.QuadPart));

	//为读取的文件分配缓冲区
 	PUCHAR pBuffer = (PUCHAR)ExAllocatePool(PagedPool,
								(LONG)fsi.EndOfFile.QuadPart);

	//读取文件
	ZwReadFile(hfile,NULL,
				NULL,NULL,
				&iostatus,
				pBuffer,
				(LONG)fsi.EndOfFile.QuadPart,
				NULL,NULL);
	KdPrint(("The program really read %d bytes\n",iostatus.Information));

	
	//释放缓冲区
	ExFreePool(pBuffer);

	//关闭文件句柄
	ZwClose(hfile);

}

#pragma INITCODE
VOID fun_StrTest()
{
	WCHAR dst_buf[512] = {0};
	UNICODE_STRING dst;
	NTSTATUS status;
	UNICODE_STRING file_path = RTL_CONSTANT_STRING(L"\\??\\c:\\winddk\\7600.16385.1\\inc\\cifs.h");
	USHORT file_size = 1024;

	//初始化字符串
	RtlInitEmptyUnicodeString(&dst, dst_buf, sizeof(WCHAR)*512);

	// 调用RTl打印
	status = RtlStringCbPrintfW(dst.Buffer, 512*sizeof(WCHAR), L"file path = %wZ file size = %d \r\n", &file_path, file_size);

	
	KdPrint(("Printf %wZ\n size:%d", &file_path, file_size));


	dst.Length = wcslen(dst.Buffer)*sizeof(WCHAR);



}

/////////////////////////////////////////////////////////
//功能:实现两个文件的Copy
//作者:Geons
//时间:2016年3月29日08:35:41
/////////////////////////////////////////////////////////

#pragma INITCODE
NTSTATUS CopyFileTest2()
{
	// 目标句柄
	HANDLE target = NULL, source = NULL;

	// 定义缓冲区
	PVOID buffer = NULL;
	LARGE_INTEGER offset = {0};
	IO_STATUS_BLOCK io_status = {0};
	IO_STATUS_BLOCK io_open_status;
	IO_STATUS_BLOCK io_open_status2;



		// 初始化文件路径的OBJECT_ATTRIBUTES
		OBJECT_ATTRIBUTES object_attributes;
		OBJECT_ATTRIBUTES object_attributes_source;

		UNICODE_STRING log_ufile_name;
		UNICODE_STRING log_source_file_name;


		// 初始化成UNICODESTRING字符串
		RtlInitUnicodeString(&log_ufile_name,L"\\??\\C:\\target1.txt");
		RtlInitUnicodeString(&log_source_file_name,L"\\??\\C:\\source1.txt");

		//初始化Objectattribultes
		InitializeObjectAttributes(&object_attributes,
									&log_ufile_name,
									OBJ_CASE_INSENSITIVE,
									NULL,
									NULL);

		InitializeObjectAttributes(&object_attributes_source,
									&log_source_file_name,
									OBJ_CASE_INSENSITIVE,
									NULL,
									NULL);

		// 打开句柄
		NTSTATUS status_source;
		NTSTATUS status = ZwCreateFile(&target,
			GENERIC_READ|GENERIC_WRITE,
			&object_attributes,
			&io_open_status,
			NULL,
			FILE_ATTRIBUTE_NORMAL,
			FILE_SHARE_READ,
			FILE_OPEN_IF,
			FILE_SYNCHRONOUS_IO_NONALERT,
			NULL,
			0);

		if(NT_SUCCESS(status))
		{
			KdPrint(("oepn targe handle successfully!\n"));
		}
		else
		{
			KdPrint(("error target handle\n"));
		}

 status_source = ZwCreateFile(&source,
			GENERIC_READ|GENERIC_WRITE,
			&object_attributes_source,
			&io_open_status2,
			NULL,
			FILE_ATTRIBUTE_NORMAL,
			FILE_SHARE_READ,
			FILE_OPEN_IF,
			FILE_SYNCHRONOUS_IO_NONALERT,
			NULL,
			0);
 		if(NT_SUCCESS(status_source))
		{
			KdPrint(("open source handle successfully!\n"));
		}
		else
		{
			KdPrint(("error source handle, error code:%d\n", status_source));
		}
		

		ULONG length = 1024*4;
			// 读取旧文件
		status = ZwReadFile(source,
							NULL,
							NULL,
							NULL,
							&io_status,
							buffer,
							length,
							&offset,
							NULL);

			if(!NT_SUCCESS(status))
			{
				if(status == STATUS_END_OF_FILE)
				{
					// 拷贝完成
					status = STATUS_SUCCESS;

				}
			}

			//获取实际长度
			length = io_status.Information;

			KdPrint(("length : %d", length));
			// 写入字节
			status = ZwWriteFile(target, NULL, NULL, NULL, &io_status, buffer, length, &offset, NULL);

			if(!NT_SUCCESS(status))
			{
			}

			offset.QuadPart+=length;




	// 释放资源,关闭句柄

	if(target != NULL)
	{
		ZwClose(target);

	}
	if(source != NULL)
	{
		ZwClose(source);
	}
	if(buffer !=NULL)
	{
		ExFreePool(buffer);

	}

	return STATUS_SUCCESS;


}

///////////////////////////new code///////////////////////////////////////////////////////////////
// 读取文件句柄
NTSTATUS MyCreateFile(OUT PHANDLE lpFileHandle,
                      IN PUNICODE_STRING usFileName,
                      IN ULONG dwDesiredAccess,
                      IN ULONG dwShareAccess,
                      IN ULONG dwCreateDisposition,
                      IN ULONG dwCreateOptions)
{
    NTSTATUS ntStatus = STATUS_UNSUCCESSFUL;
    OBJECT_ATTRIBUTES oaName;
    IO_STATUS_BLOCK iosBlock;
    if (lpFileHandle != NULL && usFileName != NULL && usFileName->Buffer != NULL)
    {
        if (PASSIVE_LEVEL != KeGetCurrentIrql()) 
        {
            return ntStatus;
        }
        InitializeObjectAttributes(&oaName,
            usFileName,
            OBJ_CASE_INSENSITIVE | OBJ_KERNEL_HANDLE,
            NULL,
            NULL);
        ntStatus = ZwCreateFile(lpFileHandle,
            dwDesiredAccess,
            &oaName,
            &iosBlock,
            NULL,
            FILE_ATTRIBUTE_NORMAL,
            dwShareAccess,
            dwCreateDisposition,
            dwCreateOptions,
            NULL,
            0);
        if (!NT_SUCCESS(ntStatus))
        {    
			KdPrint(("[MyCreateFile]ZwCreateFile(%ws)failed with error:%08x\r\n", usFileName->Buffer, ntStatus));    
            return ntStatus;
        }
    }
    return ntStatus;
}


// 读取文件内容
NTSTATUS MyReadFile(IN HANDLE hFile,
                    IN PVOID pBuffer,
                    IN ULONG ulBufferSize,
                    OUT PULONG pulBytesRead)
{
    IO_STATUS_BLOCK    iosBlock;
    NTSTATUS        ntStatus = STATUS_UNSUCCESSFUL;

	KdPrint(("进入MyReadFile\n"));

    if (hFile == NULL || pBuffer == NULL)
    {
        return ntStatus;

    }

    if( PASSIVE_LEVEL < KeGetCurrentIrql())
    {    
		KdPrint(("All kernel file operating functions must running on PASSIVE_LEVEL\r\n"));

        return ntStatus;
    }


    *pulBytesRead = 0;


    ntStatus = ZwReadFile(hFile,
        NULL,
        NULL,
        NULL,
        &iosBlock,
        pBuffer,
        ulBufferSize,
        NULL,
        NULL);

    if (NT_SUCCESS(ntStatus))
    {
        //获取实际读取到的大小
        *pulBytesRead = (ULONG)iosBlock.Information;
		KdPrint(("size is %ld", *pulBytesRead));
    }
    else
    {
        KdPrint(("[MyReadFile]ZwReadFile failed with:%08x\r\n", ntStatus));
    }

    return ntStatus;
}

// 关闭文件句柄
NTSTATUS MyCloseFile(IN HANDLE hFile)
{
    return ZwClose(hFile);
}


// 读取文件2
void ReadFile_Port()  
{  
    HANDLE hFile=NULL;  
    IO_STATUS_BLOCK ioStatus;  
    NTSTATUS    ntStatus;  
    OBJECT_ATTRIBUTES object_attributes;  
  
    UNICODE_STRING uFileName=RTL_CONSTANT_STRING(L"\\??\\C:\\test.txt");  
  
    DbgPrint("ReadLog");  
  
    InitializeObjectAttributes(  
        &object_attributes,  
        &uFileName,  
        OBJ_CASE_INSENSITIVE|OBJ_KERNEL_HANDLE,  
        NULL,  
        NULL);  
      
    ntStatus=ZwCreateFile(  
        &hFile,  
        GENERIC_READ|GENERIC_WRITE,  
        &object_attributes,  
        &ioStatus,  
        NULL,  
        FILE_ATTRIBUTE_NORMAL,  
        FILE_SHARE_READ,  
        FILE_OPEN_IF,  
        FILE_NON_DIRECTORY_FILE|FILE_RANDOM_ACCESS|FILE_SYNCHRONOUS_IO_NONALERT,  
        NULL,  
        0);  
    if (ntStatus==STATUS_SUCCESS)  
    {     
        PVOID buffer;  
        ULONG Length = 10;  
        ULONG dwPort;  
        ANSI_STRING AnsiString1;  
        UNICODE_STRING UnicodeString1;  
  
        buffer = ExAllocatePool(NonPagedPool, 50);  
        ntStatus=ZwReadFile(  
            hFile,  
            NULL,  
            NULL,  
            NULL,  
            &ioStatus,  
            buffer,  
            Length,  
            NULL,  
            NULL);  
        DbgPrint("%s",buffer);  
          
        //将buffer转换成ULONG  
		RtlInitAnsiString(&AnsiString1,(PCSZ)buffer);   
        RtlAnsiStringToUnicodeString(&UnicodeString1,&AnsiString1,TRUE);  
        RtlUnicodeStringToInteger(&UnicodeString1,10,&dwPort);  
  
        DbgPrint("%d",dwPort);  
    }   
    else  
    {  
        DbgPrint("Open file error");  
    }  
      
    ZwClose(hFile);  
}  


// 写入文件
NTSTATUS MyWriteFile(IN HANDLE hFile,
                     IN PVOID pBuffer,
                     IN ULONG ulBufferSize,
                     OUT PULONG pulBytesWrite)
{
    IO_STATUS_BLOCK    iosBlock;
    NTSTATUS        ntStatus = STATUS_UNSUCCESSFUL;
    
    if (hFile == NULL || pBuffer == NULL)
    {
        return ntStatus;
    }

    // All kernel file operating functions must running on PASSIVE_LEVEL
    if (PASSIVE_LEVEL !=  KeGetCurrentIrql()) 
    {
        return ntStatus;
    }

    *pulBytesWrite = 0;

    ntStatus = ZwWriteFile(hFile,
        NULL,
        NULL,
        NULL,
        &iosBlock,
        pBuffer,
        ulBufferSize,
        NULL,
        NULL);

    if (NT_SUCCESS(ntStatus))
    {
        *pulBytesWrite = (ULONG)iosBlock.Information;
    }
    else
    {
        KdPrint(("[MyWriteFile]ZwWriteFile failed with:%08x\r\n", ntStatus));
    }

    return ntStatus;
}

#pragma INITCODE
VOID FileTest() 
{
	////创建文件实验
	//CreateFileTest();

	////打开文件实验
	//OpenFileTest1();
	////OpenFileTest2();


	////////////////////////////error code///////////////////////
	//
	//FileAttributeTest();

	////////////////////////////erro code////////////////////////

	////写文件、追加文件实验
	//WriteFileTest();

	//ReadFileTest();

	// 字符串测试

	//fun_StrTest();

	//CopyFileTest2();

}

#pragma INITCODE
VOID GetFileInfo()
{
	UNICODE_STRING filename;
	HANDLE hfile;
	IO_STATUS_BLOCK iostatus;
	OBJECT_ATTRIBUTES objectAttributes;
	RtlInitUnicodeString(&filename, L"\\??\\C:\\source1.txt");

	InitializeObjectAttributes(&objectAttributes, &filename, OBJ_CASE_INSENSITIVE, NULL, NULL);

	NTSTATUS ntStatus = ZwCreateFile(&hfile,GENERIC_READ, &objectAttributes, &iostatus, NULL, FILE_ATTRIBUTE_NORMAL,
		0, FILE_OPEN_IF, FILE_SYNCHRONOUS_IO_NONALERT, NULL, 0);
	if(NT_SUCCESS(ntStatus))
	{
		KdPrint(("open file successfully.\n"));
	}
	else
	{
		KdPrint(("open error"));
	}

	FILE_NAME_INFORMATION fsi;

	ntStatus = ZwQueryInformationFile(hfile, &iostatus, &fsi,sizeof(FILE_NAME_INFORMATION), 
		FileNameInformation);
	if(NT_SUCCESS(ntStatus))
	{
		KdPrint(("the file length : %s", fsi.FileName));
	}
	else
	{
		KdPrint(("length failed"));
	}

	ZwClose(hfile);
}

/************************************************************************
* 函数名称:DriverEntry
* 功能描述:初始化驱动程序,定位和申请硬件资源,创建内核对象
* 参数列表:
      pDriverObject:从I/O管理器中传进来的驱动对象
      pRegistryPath:驱动程序在注册表的中的路径
* 返回 值:返回初始化驱动状态
*************************************************************************/
#pragma INITCODE
extern "C" NTSTATUS DriverEntry (
			IN PDRIVER_OBJECT pDriverObject,
			IN PUNICODE_STRING pRegistryPath	) 
{

	NTSTATUS status;
	KdPrint(("Enter DriverEntry\n"));

	pDriverObject->DriverUnload = HelloDDKUnload;


	//FileTest();

	//CopyFileTest2();

	//GetFileInfo();

	CopyFileSourceToTarget();


	//创建驱动设备对象
	status = CreateDevice(pDriverObject);


	KdPrint(("DriverEntry end\n"));
	return status;
}

VOID CopyFileSourceToTarget()
{
	HANDLE hsource = NULL, htarget = NULL;
	UNICODE_STRING source_path, target_path;
	RtlInitUnicodeString(&source_path, L"\\??\\C:\\source1.txt");
	RtlInitUnicodeString(&target_path, L"\\??\\C:\\target1.txt");

	NTSTATUS status = MyCreateFile(&hsource, &source_path,GENERIC_ALL,
		FILE_SHARE_READ,FILE_OPEN_IF,FILE_SYNCHRONOUS_IO_NONALERT);

	if(NT_SUCCESS(status))
	{
		KdPrint(("source handle操作成功"));
	}
	else
	{
		KdPrint(("source failed handle\n"));
	}


	status = MyCreateFile(&htarget, &target_path,GENERIC_ALL,
		FILE_SHARE_READ,FILE_OPEN_IF,FILE_SYNCHRONOUS_IO_NONALERT);

	if(NT_SUCCESS(status))
	{
		KdPrint(("targe handle操作成功"));
	}
	else
	{
		KdPrint(("target failed handle\n"));
	}

	PVOID buffer = NULL;
	buffer = ExAllocatePool(NonPagedPool, 50);  

	ULONG buffersize = NULL;

	KdPrint(("开始读取文件\n"));

	// ReadFile_Port();
	// 读取source1.txt的文件
	status = MyReadFile(hsource,buffer, 50, &buffersize);
	if(NT_SUCCESS(status))
	{
		KdPrint(("读取source1.txt成功!\n"));
	}
	else
	{
		KdPrint(("读取source1.txt失败!\n"));
	}

	// 写入target1.txt
	status = MyWriteFile(htarget, buffer,buffersize , &buffersize); 
		if(NT_SUCCESS(status))
	{
		KdPrint(("写入target1.txt成功!\n"));
	}
	else
	{
		KdPrint(("写入target1.txt失败!\n"));
	}

	// 关闭句柄
	if(hsource != NULL)
	{
		ZwClose(hsource);
	}
	if(htarget != NULL)
	{
		ZwClose(htarget);
	}

}

/************************************************************************
* 函数名称:CreateDevice
* 功能描述:初始化设备对象
* 参数列表:
      pDriverObject:从I/O管理器中传进来的驱动对象
* 返回 值:返回初始化状态
*************************************************************************/
#pragma INITCODE
NTSTATUS CreateDevice (
		IN PDRIVER_OBJECT	pDriverObject) 
{
	NTSTATUS status;
	PDEVICE_OBJECT pDevObj;
	PDEVICE_EXTENSION pDevExt;
	
	//创建设备名称
	UNICODE_STRING devName;
	RtlInitUnicodeString(&devName,L"\\Device\\File4");
	
	//创建设备
	status = IoCreateDevice( pDriverObject,
						sizeof(DEVICE_EXTENSION),
						&(UNICODE_STRING)devName,
						FILE_DEVICE_UNKNOWN,
						0, TRUE,
						&pDevObj );
	if (!NT_SUCCESS(status))
		return status;

	pDevObj->Flags |= DO_BUFFERED_IO;
	pDevExt = (PDEVICE_EXTENSION)pDevObj->DeviceExtension;
	pDevExt->pDevice = pDevObj;
	pDevExt->ustrDeviceName = devName;
	//创建符号链接
	UNICODE_STRING symLinkName;
	RtlInitUnicodeString(&symLinkName,L"\\??\\FileSym4");
	pDevExt->ustrSymLinkName = symLinkName;
	status = IoCreateSymbolicLink( &symLinkName,&devName );
	if (!NT_SUCCESS(status)) 
	{
		IoDeleteDevice( pDevObj );
		return status;
	}
	return STATUS_SUCCESS;
}

/************************************************************************
* 函数名称:HelloDDKUnload
* 功能描述:负责驱动程序的卸载操作
* 参数列表:
      pDriverObject:驱动对象
* 返回 值:返回状态
*************************************************************************/
#pragma PAGEDCODE
VOID HelloDDKUnload (IN PDRIVER_OBJECT pDriverObject) 
{
	PDEVICE_OBJECT	pNextObj;
	KdPrint(("Enter DriverUnload\n"));
	pNextObj = pDriverObject->DeviceObject;
	while (pNextObj != NULL) 
	{
		PDEVICE_EXTENSION pDevExt = (PDEVICE_EXTENSION)
			pNextObj->DeviceExtension;

		//删除符号链接
		UNICODE_STRING pLinkName = pDevExt->ustrSymLinkName;
		IoDeleteSymbolicLink(&pLinkName);
		pNextObj = pNextObj->NextDevice;
		IoDeleteDevice( pDevExt->pDevice );
	}
}

DbgView输出:Windows内核驱动中操作文件_第1张图片


你可能感兴趣的:(Windows内核驱动中操作文件)