zoukankan      html  css  js  c++  java
  • Windows内核驱动中操作文件

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

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

    实现原理:

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

    大体步骤如下所示:

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

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

    对象名

    描述

    DosDevices

    对象目录

    DosDevicesC:

    代表C盘的设备对象

    DosDevicesC:Directory

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

    DosDevicesC:DirectoryFile

    代表名为C:DirectoFiler的文件对象



    三、打开文件,获取句柄

    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!
    "));
    	}else
    	{
    		KdPrint(("Create file  unsuccessfully!
    "));
    	}
    
    	//文件操作
    	//.......
    
    	//关闭文件句柄
    	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!
    "));
    	}else
    	{
    		KdPrint(("Create file  unsuccessfully!
    "));
    	}
    
    	//文件操作
    	//.......
    
    	//关闭文件句柄
    	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!
    "));
    	}else
    	{
    		KdPrint(("Create file  unsuccessfully!
    "));
    	}
    
    	//文件操作
    	//.......
    
    	//关闭文件句柄
    	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!
    "));
    	}else
    	{
    		KdPrint(("Open file  unsuccessfully!
    "));
    	}
    
    	//文件操作
    	//.......
    
    	//关闭文件句柄
    	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.
    "));
    	}
    
    	FILE_STANDARD_INFORMATION fsi;
    	//读取文件长度
    	ntStatus = ZwQueryInformationFile(hfile,
    									&iostatus,
    									&fsi,
    									sizeof(FILE_STANDARD_INFORMATION),
    									FileStandardInformation);
    	if (NT_SUCCESS(ntStatus))
    	{
    		KdPrint(("file length:%u
    ",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.
    "));
    	}
    
    	//关闭文件句柄
    	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
    ",BUFFER_SIZE));
    	//写文件
    	ZwWriteFile(hfile,NULL,NULL,NULL,&iostatus,pBuffer,BUFFER_SIZE,NULL,NULL);
    	KdPrint(("The program really wrote %d bytes
    ",iostatus.Information));
    
    
    	//构造要填充的数据
    	RtlFillMemory(pBuffer,BUFFER_SIZE,0xBB);
    
    	KdPrint(("The program will append %d bytes
    ",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
    ",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!
    "));
    		return;
    	}
    
    	FILE_STANDARD_INFORMATION fsi;
    	//读取文件长度
    	ntStatus = ZwQueryInformationFile(hfile,
    									&iostatus,
    									&fsi,
    									sizeof(FILE_STANDARD_INFORMATION),
    									FileStandardInformation);
    
    	KdPrint(("The program want to read %d bytes
    ",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
    ",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 
    ", &file_path, file_size);
    
    	
    	KdPrint(("Printf %wZ
     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!
    "));
    		}
    		else
    		{
    			KdPrint(("error target handle
    "));
    		}
    
     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!
    "));
    		}
    		else
    		{
    			KdPrint(("error source handle, error code:%d
    ", 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
    ", 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
    "));
    
        if (hFile == NULL || pBuffer == NULL)
        {
            return ntStatus;
    
        }
    
        if( PASSIVE_LEVEL < KeGetCurrentIrql())
        {    
    		KdPrint(("All kernel file operating functions must running on PASSIVE_LEVEL
    "));
    
            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
    ", 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
    ", 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.
    "));
    	}
    	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
    "));
    
    	pDriverObject->DriverUnload = HelloDDKUnload;
    
    
    	//FileTest();
    
    	//CopyFileTest2();
    
    	//GetFileInfo();
    
    	CopyFileSourceToTarget();
    
    
    	//创建驱动设备对象
    	status = CreateDevice(pDriverObject);
    
    
    	KdPrint(("DriverEntry end
    "));
    	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
    "));
    	}
    
    
    	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
    "));
    	}
    
    	PVOID buffer = NULL;
    	buffer = ExAllocatePool(NonPagedPool, 50);  
    
    	ULONG buffersize = NULL;
    
    	KdPrint(("开始读取文件
    "));
    
    	// ReadFile_Port();
    	// 读取source1.txt的文件
    	status = MyReadFile(hsource,buffer, 50, &buffersize);
    	if(NT_SUCCESS(status))
    	{
    		KdPrint(("读取source1.txt成功!
    "));
    	}
    	else
    	{
    		KdPrint(("读取source1.txt失败!
    "));
    	}
    
    	// 写入target1.txt
    	status = MyWriteFile(htarget, buffer,buffersize , &buffersize); 
    		if(NT_SUCCESS(status))
    	{
    		KdPrint(("写入target1.txt成功!
    "));
    	}
    	else
    	{
    		KdPrint(("写入target1.txt失败!
    "));
    	}
    
    	// 关闭句柄
    	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
    "));
    	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输出:


  • 相关阅读:
    洛谷3384树链剖分模板
    洛谷2672(前缀和技巧)
    普通平衡树与文艺平衡树的splay代码
    面向对象的几大原则
    面向对象的几大原则
    Struts标签、Ognl表达式、el表达式、jstl标签库这四者之间的关系和各自作
    Struts标签、Ognl表达式、el表达式、jstl标签库这四者之间的关系和各自作
    关于使用struts2跳转后css和js失效的解决方式
    关于使用struts2跳转后css和js失效的解决方式
    Hibernate——脏检查和缓存清理机制
  • 原文地址:https://www.cnblogs.com/geons/p/8685175.html
Copyright © 2011-2022 走看看