内核中文件操作

文件操作也是比较有用的功能, 而且这部分功能也比较有用. 当然全部记录下来也没有什么营养. 学内核还是要学内核的架构. 关于这个函数的使用. 我觉得不经常使用的使用一次就可以了. 就像Win32下面的函数. 很多基本都用不上. 不过也没有什么问题!! 能够查就行. 不过一些非常常用的函数还查. 就有点….所以函数应该把套路稍微记下..

 

没有什么好说的, 直接上代码:

/*
	Windows内核下文件操作!
	编译方法参见makefile.
*/
#include <ntddk.h>
#define BUFFER_SIZE 1024
//===========================================================================
//写入文件试验
NTSTATUS CreateWriteFileTest() {
	HANDLE hFile = NULL;
	PUCHAR pBuffer = NULL;
	NTSTATUS Status;
	LARGE_INTEGER L_number;
	IO_STATUS_BLOCK Io_Status;
	OBJECT_ATTRIBUTES Obj_Attributes;
	//或者写成 "\\Device\\HarddiskVolume1\\1.LOG"
	UNICODE_STRING UStFileName = RTL_CONSTANT_STRING( L"\\??\\C:\\Joen.log" );

	do {
		//初始化objectAttributes 对大小写敏感
		InitializeObjectAttributes( &Obj_Attributes,&UStFileName, OBJ_CASE_INSENSITIVE,	NULL, NULL );

		//打开文件, 用于重写.文件不存在返回错误.同时会覆盖原来文件的内容
		Status = ZwCreateFile( &hFile, GENERIC_WRITE,&Obj_Attributes, &Io_Status, NULL,FILE_ATTRIBUTE_NORMAL,
			FILE_SHARE_WRITE,FILE_OVERWRITE,FILE_SYNCHRONOUS_IO_NONALERT, NULL, 0 );
		if ( !NT_SUCCESS(Status) ) {

			//创建文件, 即使存在该文件存在.也创建覆盖
			Status = ZwCreateFile( &hFile, GENERIC_WRITE,&Obj_Attributes, &Io_Status, NULL,FILE_ATTRIBUTE_NORMAL,
				FILE_SHARE_WRITE,FILE_OPEN_IF,FILE_SYNCHRONOUS_IO_NONALERT, NULL, 0 );
			if ( !NT_SUCCESS(Status) ) {
				break;
			}
		}

		//分配内存
		pBuffer = (PUCHAR)ExAllocatePool(PagedPool, BUFFER_SIZE );
		if ( !pBuffer ) {
			KdPrint(( "内存分配失败!\n" ));
			Status = STATUS_UNSUCCESSFUL;
			break;
		}

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

		//写文件
		Status = ZwWriteFile( hFile,NULL,NULL,NULL,&Io_Status, pBuffer,BUFFER_SIZE, NULL, NULL );
		if ( !NT_SUCCESS(Status) ) {
			KdPrint(( "WriteFile Error!\n" ));
			break;
		}else {
			KdPrint(( "文件写入长度%d!\n",Io_Status.Information ));
		}	

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

		//追加数据, 设置文件偏移指针64位的
		L_number.QuadPart = 1024i64;

		//对文件进行附加写
		Status = ZwWriteFile( hFile, NULL, NULL, NULL, &Io_Status, pBuffer, BUFFER_SIZE, &L_number, NULL );
		if ( !NT_SUCCESS(Status) ) {
			KdPrint(( "文件写入失败!\n" ));
			break;
		}else {
			KdPrint(( "文件写入长度%d!\n",Io_Status.Information ));
		}

		Status = STATUS_SUCCESS;
	}while ( FALSE );

	//关闭文件句柄
	if ( hFile ) {
		ZwClose( hFile );
	}
	if ( pBuffer ) {
		ExFreePool(pBuffer);
	}
	return Status;
}
//===========================================================================
//打开文件进行追加内容试验
NTSTATUS OpenWriteFileTest() {
	HANDLE hFile = NULL;
	PUCHAR pBuffer = NULL;
	NTSTATUS Status;
	IO_STATUS_BLOCK Io_Status;
	OBJECT_ATTRIBUTES Obj_Attributes;
	//或者写成 "\\Device\\HarddiskVolume1\\1.LOG"
	UNICODE_STRING UStFileName = RTL_CONSTANT_STRING( L"\\??\\C:\\Joen.log" );
	FILE_STANDARD_INFORMATION File_Information;

	do {
		//初始化objectAttributes 对大小写敏感
		InitializeObjectAttributes( &Obj_Attributes,&UStFileName, OBJ_CASE_INSENSITIVE,	NULL, NULL );

		//打开文件, 进行读取, 文件不存在会返回错误. 同时对文件进行追加
		Status = ZwOpenFile( &hFile, GENERIC_ALL,&Obj_Attributes, &Io_Status,
			FILE_SHARE_READ|FILE_SHARE_WRITE,FILE_SYNCHRONOUS_IO_NONALERT );
		if ( !NT_SUCCESS(Status) ) {
			KdPrint(( "打开文件失败!\n" ));
			break;
		}

		//分配内存
		pBuffer = (PUCHAR)ExAllocatePool(PagedPool, BUFFER_SIZE );
		if ( !pBuffer ) {
			KdPrint(( "内存分配失败!\n" ));
			Status = STATUS_UNSUCCESSFUL;
			break;
		}

		//读取文件
		Status = ZwReadFile( hFile,NULL,NULL,NULL,&Io_Status,pBuffer,BUFFER_SIZE,NULL,NULL);
		if ( !NT_SUCCESS(Status) ) {
			KdPrint(( "读取文件失败!\n" ));
			break;
		}

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

		//查询文件长度
		Status = ZwQueryInformationFile( hFile,	&Io_Status,&File_Information,
			sizeof(FILE_STANDARD_INFORMATION),FileStandardInformation );
		if ( !NT_SUCCESS(Status) ) {
			KdPrint(( "查询文件长度失败!\n" ));
			break;
		}else {
			KdPrint(( "文件长度%d\n", File_Information.EndOfFile.QuadPart ));
		}

		//文件长度中间扩展下(根据实验扩展出来都是0)
		File_Information.EndOfFile.QuadPart+= 1024;

		//修改当前文件指针
		Status = ZwSetInformationFile( hFile,	&Io_Status,&File_Information.EndOfFile.QuadPart,
			sizeof(FILE_POSITION_INFORMATION),FilePositionInformation);
		if ( !NT_SUCCESS(Status) ) {
			KdPrint(( "设置文件长度失败!\n" ));
		}

		//写文件
		Status = ZwWriteFile( hFile,NULL,NULL,NULL,&Io_Status, pBuffer,BUFFER_SIZE,
			&File_Information.EndOfFile, NULL );
		if ( !NT_SUCCESS(Status) ) {
			KdPrint(( "写入文件失败!\n" ));
			break;
		}else {
			KdPrint(( "文件真正写入文件长度 %d\n", Io_Status.Information ));
		}

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

		//查询文件长度
		Status = ZwQueryInformationFile( hFile,	&Io_Status,&File_Information,
			sizeof(FILE_STANDARD_INFORMATION),FileStandardInformation );
		if ( !NT_SUCCESS(Status) ) {
			KdPrint(( "查询文件长度失败!\n" ));
			break;
		}else {
			KdPrint(( "文件长度%d\n", File_Information.EndOfFile.QuadPart ));
		}

		//对文件进行附加写
		Status = ZwWriteFile( hFile, NULL, NULL, NULL, &Io_Status, pBuffer, BUFFER_SIZE,
			&File_Information.EndOfFile, NULL );
		if ( !NT_SUCCESS(Status) ) {
			KdPrint(( "文件写入错误!\n" ));
			break;
		}
		Status = STATUS_SUCCESS;
	}while ( FALSE );

	//关闭文件句柄
	if ( hFile ) {
		ZwClose( hFile );
	}
	if ( pBuffer ) {
		ExFreePool(pBuffer);
	}
	return Status;
}
//===========================================================================
//文件属性测试
NTSTATUS FileAttributeTest() {
	HANDLE hFile = NULL;
	NTSTATUS Status;
	IO_STATUS_BLOCK Io_Status;
#if DBG
	TIME_FIELDS SysTime = {0};
#endif
	OBJECT_ATTRIBUTES Obj_Attributes;
	UNICODE_STRING UStFileName = RTL_CONSTANT_STRING( L"\\??\\C:\\Joen.log" );
	FILE_BASIC_INFORMATION		File_BasicInfo = {0};
	PFILE_NAME_INFORMATION		pFile_NameInfo = NULL;
	FILE_STANDARD_INFORMATION	File_StdInfo;
	FILE_POSITION_INFORMATION	File_PostInfo;

	do {
		//初始化objectAttributes 对大小写敏感
		InitializeObjectAttributes( &Obj_Attributes,&UStFileName, OBJ_CASE_INSENSITIVE,	NULL, NULL );

		//打开文件, 进行读取, 文件不存在会返回错误. 同时对文件进行追加
		Status = ZwOpenFile( &hFile, GENERIC_ALL,&Obj_Attributes, &Io_Status,
			FILE_SHARE_READ|FILE_SHARE_WRITE,FILE_SYNCHRONOUS_IO_NONALERT );
		if ( !NT_SUCCESS(Status) ) {
			KdPrint(( "打开文件失败!\n" ));
			break;
		}

		//查询文件长度, 这里假设文件长度不会超过4G了
		Status = ZwQueryInformationFile( hFile,	&Io_Status, &File_StdInfo,
			sizeof(FILE_STANDARD_INFORMATION), FileStandardInformation );
		if ( !NT_SUCCESS(Status) ) {
			KdPrint(( "查询文件信息失败!\n" ));
			break;
		}else {
			KdPrint(( "文件占用族大小: %d, 距离文件结尾还有%d个字节(文件长度).多少个链接文件%d, 是否准备删除%d, 是否是目录%d\n",
				File_StdInfo.AllocationSize.LowPart, File_StdInfo.EndOfFile.LowPart,
				File_StdInfo.NumberOfLinks,
				File_StdInfo.DeletePending, File_StdInfo.Directory ));
		}

		//查询文件时间信息, 和属性. 当然也可以设置
		Status = ZwQueryInformationFile( hFile,	&Io_Status, &File_BasicInfo,
			sizeof(FILE_BASIC_INFORMATION),FileBasicInformation );
		if ( !NT_SUCCESS(Status) ) {
			KdPrint(( "查询文件信息失败!\n" ));
			break;
		}else {
#if DBG
			//系统时间转成本地时间
			ExSystemTimeToLocalTime(&File_BasicInfo.CreationTime, &File_BasicInfo.CreationTime);
			ExSystemTimeToLocalTime(&File_BasicInfo.LastAccessTime, &File_BasicInfo.LastAccessTime);
			ExSystemTimeToLocalTime(&File_BasicInfo.LastWriteTime, &File_BasicInfo.LastWriteTime);

			KdPrint(( "年/月/日   时/分/秒 \n" ));
			RtlTimeToTimeFields( &File_BasicInfo.CreationTime, &SysTime );
			KdPrint(( "文件创建的时间:   %d/%d/%d   %d:%d:%d\n",
				SysTime.Year, SysTime.Month, SysTime.Day, SysTime.Hour, SysTime.Minute, SysTime.Second ));

			//最后访问时间是只有日期的..
			RtlTimeToTimeFields( &File_BasicInfo.LastAccessTime, &SysTime );
			KdPrint(( "文件最后访问时间: %d/%d/%d   %d:%d:%d\n",
				SysTime.Year, SysTime.Month, SysTime.Day, SysTime.Hour, SysTime.Minute, SysTime.Second ));

			RtlTimeToTimeFields( &File_BasicInfo.LastWriteTime, &SysTime );
			KdPrint(( "文件最后写时间:   %d/%d/%d   %d:%d:%d\n",
				SysTime.Year, SysTime.Month, SysTime.Day, SysTime.Hour, SysTime.Minute, SysTime.Second ));

// 			RtlTimeToTimeFields( &File_BasicInfo.ChangeTime, &SysTime );
// 			KdPrint(( "修改修改时间: %d/%d/%d   %d/%d/%d\n",
// 				SysTime.Year, SysTime.Month, SysTime.Day, SysTime.Hour, SysTime.Minute, SysTime.Second ));
//
			if ( File_BasicInfo.FileAttributes & FILE_ATTRIBUTE_ARCHIVE ) {
				KdPrint(( "文件是一个普通文件\n" ));
			}
			if ( File_BasicInfo.FileAttributes & FILE_ATTRIBUTE_NORMAL ) {
				KdPrint(( "文件没有设置属性\n" ));
			}
			if ( File_BasicInfo.FileAttributes & FILE_ATTRIBUTE_DIRECTORY ){
				KdPrint(( "文件是一个目录\n" ));
			}
			if ( File_BasicInfo.FileAttributes & FILE_ATTRIBUTE_READONLY ) {
				KdPrint(( "文件是只读的\n" ));
			}
			if( File_BasicInfo.FileAttributes & FILE_ATTRIBUTE_HIDDEN ) {
				KdPrint(( "文件是隐藏的\n" ));
			}
			if( File_BasicInfo.FileAttributes & FILE_ATTRIBUTE_SYSTEM ) {
				KdPrint(( "文件是系统文件\n" ));
			}
#endif
		}

		pFile_NameInfo = (PFILE_NAME_INFORMATION)ExAllocatePool(PagedPool, BUFFER_SIZE );
		if ( !pFile_NameInfo ) {
			KdPrint(( "内存分配失败!\n" ));
			break;
		}
		RtlZeroMemory( pFile_NameInfo,BUFFER_SIZE );
		pFile_NameInfo->FileNameLength = BUFFER_SIZE;

		//查询文件名称信息
		Status = ZwQueryInformationFile( hFile,	&Io_Status, pFile_NameInfo,
			BUFFER_SIZE,FileNameInformation );
		if ( !NT_SUCCESS(Status) ) {
			KdPrint(( "查询文件名称信息失败!\n" ));
			break;
		}else {
			KdPrint(( "文件名称长度:%d, 文件名称:%ws \n", pFile_NameInfo->FileNameLength,
				pFile_NameInfo->FileName ));
		}

		//修改当前文件指针, 当然也是可以查询的
		File_PostInfo.CurrentByteOffset.QuadPart = 100i64;
		Status = ZwSetInformationFile( hFile, &Io_Status,&File_PostInfo,
			sizeof(FILE_POSITION_INFORMATION),FilePositionInformation );
		if ( !NT_SUCCESS(Status) ) {
			KdPrint(( "设置文件当前指针失败\n" ));
		}else {
			KdPrint(( "设置文件当前指针成功\n" ));
		}
	} while ( FALSE );

	if ( hFile ) {
		ZwClose( hFile );
	}
	if ( pFile_NameInfo ) {
		ExFreePool( pFile_NameInfo );
	}
	return Status;
}

NTSTATUS DriverEntry( PDRIVER_OBJECT pDriverObj, PUNICODE_STRING pUSzReg ) {
	NTSTATUS Status;

	Status = CreateWriteFileTest();			//创建新文件写入试验
	if ( !NT_SUCCESS(Status) ) {
		KdPrint(( "CreateWriteFileTest调用遇到错误!" ));
		return Status;
	}

	Status = OpenWriteFileTest();			//打开文件进行追加写入文件
	if ( !NT_SUCCESS(Status) ) {
		KdPrint(( "OpenWriteFileTest 调用遇到错误!" ));
		return Status;
	}

	Status = FileAttributeTest();			//文件属性设置
	if ( !NT_SUCCESS(Status) ) {
		KdPrint(( "FileAttributeTest 调用遇到错误!" ));
		return Status;
	}
	return -1;
}

 

网友评论:

  1. minecraft free download 2018 说:

    Hello, after reading this amazing article i am also delighted to share my
    knowledge here with colleagues.

  2. minecraft free download 2018 说:

    I really love your website.. Great colors & theme. Did you build this
    amazing site yourself? Please reply back as I’m hoping to create my very own site and would love to
    know where you got this from or exactly what the theme is named.
    Appreciate it!

发表评论

发表评论前,请选对水果: 苹果