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执行体创建一个代表该文件的新的文件对象,并返回一个指向该对象的句柄。文件对象一直存在,知道你关闭了所有指向它的文件句柄。
读文件 |
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内核驱动中操作文件的更多相关文章
- linux内核驱动中对文件的读写 【转】
本文转载自:http://blog.chinaunix.net/uid-13059007-id-5766941.html 有时候需要在Linux kernel--大多是在需要调试的驱动程序--中读写文 ...
- 【转】深入Windows内核——C++中的消息机制
上节讲了消息的相关概念,本文将进一步聊聊C++中的消息机制. 从简单例子探析核心原理 在讲之前,我们先看一个简单例子:创建一个窗口和两个按钮,用来控制窗口的背景颜色.其效果 图1.效果图 Win32 ...
- 背水一战 Windows 10 (88) - 文件系统: 操作文件夹和文件
[源码下载] 背水一战 Windows 10 (88) - 文件系统: 操作文件夹和文件 作者:webabcd 介绍背水一战 Windows 10 之 文件系统 创建文件夹,重命名文件夹,删除文件夹, ...
- 嵌入式C语言自我修养 02:Linux 内核驱动中的指定初始化
2.1 什么是指定初始化 在标准 C 中,当我们定义并初始化一个数组时,常用方法如下: ] = {,,,,,,,,}; 按照这种固定的顺序,我们可以依次给 a[0] 和 a[8] 赋值.因为没有对 a ...
- 工具WinSCP:windows和Linux中进行文件传输
工具WinSCP:windows和Linux中进行文件传输 2016-09-21 [转自]使用WinSCP软件在windows和Linux中进行文件传输 当我们的开发机是Windows,服务器是Lin ...
- 在Python中操作文件之truncate()方法的使用教程
在Python中操作文件之truncate()方法的使用教程 这篇文章主要介绍了在Python中操作文件之truncate()方法的使用教程,是Python入门学习中的基础知识,需要的朋友可以参考下 ...
- 在PHP中操作文件的扩展属性
在操作系统的文件中,还存在着一种我们可以自己定义的文件属性.这些属性不是保存在文件内容中,也不是直接可以通过 ls -al 所能看到的内容.它们可以将一个键值对信息永久得关联到文件上,一般现在的 Li ...
- 《天书夜读:从汇编语言到windows内核编程》八 文件操作与注册表操作
1)Windows运用程序的文件与注册表操作进入R0层之后,都有对应的内核函数实现.在windows内核中,无论打开的是文件.注册表或者设备,都需要使用InitializeObjectAttribut ...
- linux内核驱动中对字符串的操作【转】
转自:http://www.360doc.com/content/12/1224/10/3478092_255969530.shtml Linux内核中关于字符串的相关操作,首先包含头文件: #inc ...
随机推荐
- Spring boot 的application.properties 全局配置
端口号.项目名称 application.properties: server.port=8888 server.context-path=/start 日志相关的配置 # 自定义日志配置路径 log ...
- 事件&表达式
typeFaqs.ForEach(async p => { var results = await ; p.Results = results; }); https://stackoverfl ...
- idea springboot 父子工程 子工程maven不自动import
父工程删除对spring boot启动项的引用,因为父工程 dependencyManagement,它不会自动加载包,只指定包的版本, 如果在父工程中引用了包,但是没有指定包版本,子工程将不会识别到 ...
- RocketMQ源码分析:(二)消息发送的三种方式
1. 同步传输(可靠,适用于重要的通知消息.短信通知.短信营销系统等) package com.miaoying.rocketmq.client; import lombok.extern.slf4j ...
- (转)GraphicsMagick、命令行使用示例
GraphicsMagick是从 ImageMagick 5.5.2 分支出来的,但是现在他变得更稳定和优秀,GM更小更容易安装.GM更有效率.GM的手册非常丰富GraphicsMagick的命令与I ...
- POI导入demo
前言 使用上篇博文的导入方法,写一个简单的导入demo.其实有了工具类之后就没啥难度了,也就只简单的拿数据.先写个简单的,然后想办法实现动态读取吧,这样读取其实还是比较烦的,每次该模板都要改代码,说到 ...
- 用Python制作中国地图、地球平面图及球形图
绘制地图在python中主要用到的 basemap 库,这个库是 matplotlib 库中一个用于在 Python 中绘制地图上的 2D 数据的工具包. 首先安装库: 1.安装 geos 库:Pyt ...
- C 语言 符合运算符
复合赋值 5个算术运算符 + - * / % 可以和赋值运算符 = 结合起来形成符合运算符 += -= *= /= %= total += 5 total = total + 5 note:两个运算符 ...
- springcloud相关资料收集
http://springboot.fun/ Spring Boot 中文索引 http://springcloud.fun/ Spring Cloud 中文索引 https://spring ...
- 转发自:一像素 十大经典排序算法(动图演示)原链接:https://www.cnblogs.com/onepixel/articles/7674659.html 个人收藏所用 侵删
原链接:https://www.cnblogs.com/onepixel/articles/7674659.html 个人收藏所用 侵删 0.算法概述 0.1 算法分类 十种常见排序算法可 ...