阅读:3849回复:28
求教:如何在create中利用file_object读取打开的文件的内容
如何在create中利用file_object读取打开的文件的内容,用IoBuildSynchronousFsdRequest可行否?我要读取文件头部,来判断是否是加密过的文件,哪位给段代码呀,谢谢!
|
|
沙发#
发布于:2007-07-10 15:15
我也在做这一部分啊
我也需要 顶上去 |
|
板凳#
发布于:2007-07-10 16:46
自己顶一个
|
|
地板#
发布于:2007-07-10 22:33
|
|
地下室#
发布于:2007-07-11 08:18
关注,一涉及到关键问题,高手们都沉默了。
|
|
|
5楼#
发布于:2007-07-11 09:44
引用第4楼linuxyf于2007-07-11 08:18发表的 : 不会把,这也算是关键问题? |
|
6楼#
发布于:2007-07-11 19:42
我贴出我的代码,大家一起研究看看,有问题啊,现在。。。
#define MARKSTRING "waintech20070708" #define MARKLEN 16 extern PWIT_THREAD pmythread; static NTSTATUS MyIrpComplete ( PDEVICE_OBJECT dev, PIRP irp, PVOID context); // 在create中调用 NTSTATUS SpyBuildMyRWIrp( IN PDEVICE_OBJECT olddev, IN PIRP oldirp ) { PIRP irp; PVOID Buffer = NULL; ULONG Length = MARKLEN; LARGE_INTEGER offset; CHAR RWFlag = 1; MY_READ_CONTEXT my_context; NTSTATUS Status = STATUS_SUCCESS; PFILE_OBJECT pFileObject; PIO_STACK_LOCATION irpsp; pFileObject = IoGetCurrentIrpStackLocation(oldirp)->FileObject; Buffer = ExAllocatePoolWithTag(NonPagedPool, 4096, FILESPY_POOL_TAG); if(Buffer == NULL) { return STATUS_INSUFFICIENT_RESOURCES; } //RtlCopyMemory( Buffer, MARKSTRING, MARKLEN); offset.QuadPart = 0; if(RWFlag) irp = IoBuildAsynchronousFsdRequest(IRP_MJ_READ,olddev,Buffer,Length,&offset,NULL); else irp = IoBuildAsynchronousFsdRequest(IRP_MJ_WRITE,olddev,Buffer,Length,&offset,NULL); if(irp == NULL) { return STATUS_INSUFFICIENT_RESOURCES; } irp->Flags = IRP_NOCACHE | IRP_READ_OPERATION; irp->Tail.Overlay.Thread = oldirp->Tail.Overlay.Thread; irp->Tail.Overlay.OriginalFileObject = pFileObject; irp->RequestorMode = KernelMode; irp->Flags = 0x43; // irpsp = IoGetNextIrpStackLocation(irp); irpsp->FileObject = pFileObject;// We need a FileObject to identify the file we are reading irpsp->FileObject->CurrentByteOffset = offset; irpsp->DeviceObject = olddev; KeInitializeEvent(&my_context.event,NotificationEvent,FALSE); IoSetCompletionRoutine(irp,MyIrpComplete,&my_context,TRUE,TRUE,TRUE); //Buffer是缓冲。在Irp中被用做UserBuffer接收数据。offset是 这次读的偏移量。以上代码构造一个读irp.请注意,此时您还没有设置FileObject.实际上我是这样发出请求的: WITDoItInThread(pmythread, "11111111111111111111111111111", do_something); // 关键: FileObject是否只需要设置此元素???如果我的加密标识放在文件尾部,我怎么得倒尾部的offset呢??? Status = IoCallDriver(olddev,irp); WITDoItInThread(pmythread, "xxxxxxxxxxxxxxxxxxxxx", do_something); //irp = NULL; return STATUS_SUCCESS; if(Status == STATUS_PENDING) { WITDoItInThread(pmythread, "aaaaaaaaaaaaaaaaaaaaaa", do_something); KeWaitForSingleObject(&my_context.event,Executive,KernelMode,FALSE,NULL); WITDoItInThread(pmythread, "bbbbbbbbbbbbbbbbbbbbbbbbb", do_something); } { ANSI_STRING tempstr; RtlInitAnsiString( &tempstr, "waintech20070708" ); //WITDoItInThread(pmythread, "ccccccccccccccccccccccccccccc", do_something); WITDoItInThread(pmythread, Buffer, do_something); if(!RtlCompareMemory(MARKSTRING , &tempstr, MARKLEN)) { //KdPrint(("spy! SpyBuildMyRWIrp jjjjjjjjjjjjjjjjjjjjjjjjj: %s", Buffer)); WITDoItInThread(pmythread, Buffer, do_something); } } //IoCompleteRequest( irp, IO_NO_INCREMENT ); ExFreePoolWithTag(Buffer, FILESPY_POOL_TAG); return STATUS_SUCCESS; } // 再看看MyIrpComplete如何收场: // 一个通用的irp完成函数: static NTSTATUS MyIrpComplete ( PDEVICE_OBJECT dev, PIRP irp, PVOID context) { PFILESPY_DEVICE_EXTENSION DevExt = (PFILESPY_DEVICE_EXTENSION) dev->DeviceExtension; PMY_READ_CONTEXT my_context = (PMY_READ_CONTEXT)context; KeSetEvent(&my_context->event,IO_NO_INCREMENT,FALSE); my_context->Information = irp->IoStatus.Information; my_context->Status = irp->IoStatus.Status; // 释放irp,过程非常复杂 WITDoItInThread(pmythread, "eeeeeeeeeeeeeeeeeee", do_something); if (irp->MdlAddress) { MmUnmapLockedPages( MmGetSystemAddressForMdl(irp->MdlAddress), irp->MdlAddress); MmUnlockPages(irp->MdlAddress); IoFreeMdl(irp->MdlAddress); } WITDoItInThread(pmythread, "fffffffffffffffffff", do_something); IoFreeIrp(irp); WITDoItInThread(pmythread, "ggggggggggggggggggg", do_something); // 返回处理未结束.??? return STATUS_MORE_PROCESSING_REQUIRED; } WITDoItInThread函数该成kdprint即可测试。 |
|
7楼#
发布于:2007-07-11 19:45
在调用IoCallDriver开始,出现黑屏或兰屏,我调试了N次了,无奈啊。。。
|
|
8楼#
发布于:2007-07-11 21:38
引用第7楼wengzuhong于2007-07-11 19:45发表的 : 错误是啥? |
|
9楼#
发布于:2007-07-12 04:50
FileObject in IRP has not been fully constructed in MJ_CREATE dispatch routine. You cannot use it for read.
|
|
10楼#
发布于:2007-07-12 09:40
引用第9楼michaelgz于2007-07-12 04:50发表的 : 那该啥时候读,如何读? |
|
11楼#
发布于:2007-07-12 10:21
错误: 我就没抓到错误,只出现黑屏,直接重启,我还想问,我的softice为什么没抓到信息,是不是少了什么设置? 而且系统也没有dump,郁闷。
|
|
12楼#
发布于:2007-07-12 23:00
我用windbg,
|
|
13楼#
发布于:2007-07-12 23:00
我用windbg,
|
|
14楼#
发布于:2007-07-13 09:12
我也有段代码,可是读出来的数据总是一样是0x4e9052eb 20534654
NTSTATUS MakeAsynchronousRequest ( PDEVICE_OBJECT TopOfDeviceStack, PVOID ReadBuffer, ULONG NumBytes ) /*++ Arguments: TopOfDeviceStack - WriteBuffer - Buffer to be sent to the TopOfDeviceStack. NumBytes - Size of buffer to be sent to the TopOfDeviceStack. --*/ { NTSTATUS status; PIRP irp; LARGE_INTEGER startingOffset; PIO_STACK_LOCATION nextStack; PVOID context; IO_STATUS_BLOCK IoStatusBlock; KEVENT event; MY_READ_CONTEXT myReadContext; startingOffset.QuadPart = (LONGLONG) 0; irp = IoAllocateIrp( TopOfDeviceStack->StackSize, TRUE ); if (NULL == irp) { return STATUS_INSUFFICIENT_RESOURCES; } // // Obtain a pointer to the stack location of the first driver that will be // invoked. This is where the function codes and the parameters are set. // // irp->Flags=IRP_BUFFERED_IO; //irp->AssociatedIrp.SystemBuffer = ReadBuffer; //irp->MdlAddress = NULL; //nextStack = IoGetNextIrpStackLocation( irp ); //nextStack->MajorFunction = IRP_MJ_READ; //nextStack->Parameters.Read.Length = NumBytes; //nextStack->Parameters.Read.ByteOffset= startingOffset; irp = IoBuildAsynchronousFsdRequest( IRP_MJ_READ, TopOfDeviceStack, ReadBuffer, NumBytes, &startingOffset, // Optional &IoStatusBlock ); //DbgPrint("%X",IoStatusBlock.Status); //DbgPrint("%X",IoStatusBlock.Information); //if (NULL == irp) { // return STATUS_INSUFFICIENT_RESOURCES; //} // // Allocate memory for context structure to be passed to the completion routine. // //myReadContext.context = ExAllocatePoolWithTag(NonPagedPool, sizeof(ULONG_PTR), 'ITag'); //if (NULL == myReadContext.context ) { // IoFreeIrp(irp); // return STATUS_INSUFFICIENT_RESOURCES; //} myReadContext.event=&event; KeInitializeEvent(&event, NotificationEvent, FALSE); IoSetCompletionRoutine(irp, MakeAsynchronousRequestCompletion, &myReadContext,//context, TRUE, TRUE, TRUE); // // If you want to change any value in the IRP stack, you must // first obtain the stack location by calling IoGetNextIrpStackLocation. // This is the location that is initialized by the IoBuildxxx requests and // is the one that the target device driver is going to view. // //nextStack = IoGetNextIrpStackLocation(irp); // // Change the MajorFunction code to something appropriate. // //nextStack->MajorFunction = IRP_MJ_READ; memset(ReadBuffer,'1',READ_BUFF_SIZE); DbgPrint("%X",*((ULONG*)ReadBuffer)); // //DbgPrint("%X",nextStack->MajorFunction); status=IoCallDriver(TopOfDeviceStack, irp); if(status==STATUS_PENDING) { KeWaitForSingleObject(&event, Executive,KernelMode,0,0); //status=irp->IoStatus.Status; } DbgPrint("%X %X",((ULONG*)ReadBuffer)[0],((ULONG*)ReadBuffer)[1]); return status; } NTSTATUS MakeAsynchronousRequestCompletion( IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp, IN PVOID Context ) { PMDL mdl, nextMdl; PMY_READ_CONTEXT pMyReadContext=(PMY_READ_CONTEXT)Context; // // If the target device object is set up to do buffered i/o // (TopOfDeviceStack->Flags and DO_BUFFERED_IO), then // IoBuildAsynchronousFsdRequest request allocates a system buffer // for read and write operation. If you stop the completion of the IRP // here, you must free that buffer. // //if(Irp->AssociatedIrp.SystemBuffer && (Irp->Flags & IRP_DEALLOCATE_BUFFER) ) { // ExFreePool(Irp->AssociatedIrp.SystemBuffer); //} // // If the target device object is set up do direct i/o (DO_DIRECT_IO), then // IoBuildAsynchronousFsdRequest creates an MDL to describe the buffer // and locks the pages. If you stop the completion of the IRP, you must unlock // the pages and free the MDL. // //else if (Irp->MdlAddress != NULL) { // for (mdl = Irp->MdlAddress; mdl != NULL; mdl = nextMdl) { // nextMdl = mdl->Next; // MmUnlockPages( mdl ); IoFreeMdl( mdl ); // This function will also unmap pages. // } // Irp->MdlAddress = NULL; //} //if(pMyReadContext->context) { // ExFreePool(pMyReadContext->context); //} // // If you intend to queue the IRP and reuse it for another request, // make sure you call IoReuseIrp(Irp, STATUS_SUCCESS) before you reuse. // DbgPrint("Information %X",Irp->IoStatus.Information); DbgPrint("Status %X",Irp->IoStatus.Status); IoFreeIrp(Irp); KeSetEvent(pMyReadContext->event,IO_NO_INCREMENT,FALSE); // // NOTE: this is the only status that you can return for driver-created asynchronous IRPs. // return STATUS_MORE_PROCESSING_REQUIRED; } |
|
15楼#
发布于:2007-07-13 11:08
上楼,你在哪儿调用此函数?
|
|
16楼#
发布于:2007-07-13 11:11
IFS中关于如何利用自己的IRP来实现IO操作的文章,
名字大概是:”Rolling Your Own“, 我记得前段时间我也贴在坛子里了, 所以,大家在问问题前一定要先搜,再问! |
|
|
17楼#
发布于:2007-07-13 11:12
|
|
|
18楼#
发布于:2007-07-13 11:25
谢谢了,先
|
|
19楼#
发布于:2007-07-16 14:10
终于搞定了,总结一下:不要怀疑调用IoBuildDeviceIoControlRequest,下发Irp来读取文件片断有问题,导致蓝屏出错原因往往是有些file_object对象无效或者还没完全生成,加了些屏蔽条件就好了。
下面是我的,希望对大家有帮助 sfcreate中: if(!SfIsObjectFile(FileObject)) break; FileCtx.FsContext = FileObject->FsContext; if ((IrpSp->Parameters.Create.SecurityContext->DesiredAccess == FILE_READ_ATTRIBUTES) ) //FILE_READ_DATA break; BOOLEAN SfIsObjectFile( IN PFILE_OBJECT FileObject ) { PFSRTL_COMMON_FCB_HEADER fcb = (PFSRTL_COMMON_FCB_HEADER) FileObject->FsContext; if (!fcb) { return FALSE; } if (fcb->NodeTypeCode == FAT_NTC_FCB) return TRUE; else if (fcb->NodeTypeCode == NTFS_NTC_FCB) return TRUE; return FALSE; } |
|
上一页
下一页