本页主题:如何在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执行体创建一个代表该文件的新的文件对象,并返回一个指向该对象的句柄。文件对象一直存在,知道你关闭了所有指向它的文件句柄。
读文件 |
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();
/************************************************************************ * 文件名称: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 ); } }