阅读:1434回复:10
谁帮我看一下哪里有问题-----文件的读取。
NTSTATUS
SfRead ( IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp ) { PIO_STACK_LOCATION irpSp = IoGetCurrentIrpStackLocation(Irp); PFILE_OBJECT file_object = irpSp->FileObject; PSFILTER_DEVICE_EXTENSION devExt = DeviceObject->DeviceExtension; NTSTATUS status; LARGE_INTEGER offset; ULONG length; void *buffer; PMDL mdl; KEVENT waitEvent; // Irp;DeviceObject;length;offset;status;buffer;mdl // 对控制设备的操作,我直接失败 // 这是老牛的原话 if (IS_MY_CONTROL_DEVICE_OBJECT(DeviceObject)) { Irp->IoStatus.Status = STATUS_INVALID_DEVICE_REQUEST; Irp->IoStatus.Information = 0; IoCompleteRequest(Irp, IO_NO_INCREMENT); return STATUS_INVALID_DEVICE_REQUEST; } // 对文件系统的其他设备的操作,passthru if (devExt->StorageStackDeviceObject == NULL) { DbgPrint("其他设备对sfread的调用直接PASS\n"); return SfPassThrough(DeviceObject, Irp); } // 到这里说明是对卷的文件操作 // DbgPrint("关注:设置完成历程!\n"); // 初始化事件 KeInitializeEvent( &waitEvent, NotificationEvent, FALSE ); // 因为我们要等待完成,所以必须拷贝当前调用栈 IoCopyCurrentIrpStackLocationToNext ( Irp ); // 设置完成函数,并把事件的指针当上下文传入 IoSetCompletionRoutine( Irp, SfReadCompletion, &waitEvent, //context parameter TRUE, TRUE, TRUE ); status = IoCallDriver( devExt->AttachedToDeviceObject, Irp ); // // Wait for the operation to complete // if (STATUS_PENDING == status) { status = KeWaitForSingleObject( &waitEvent, Executive, KernelMode, FALSE, NULL ); ASSERT( STATUS_SUCCESS == status ); return STATUS_SUCCESS; } // 以下代码用来得到读偏移量(从irpSp中)和长度: offset.QuadPart = irpSp->Parameters.Read.ByteOffset.QuadPart; length = irpSp->Parameters.Read.Length; // DbgPrint("end \n"); switch(irpSp->MinorFunction) { // 我先保留文件的偏移位置 case IRP_MN_NORMAL: if (Irp->MdlAddress != NULL) { buffer = MmGetSystemAddressForMdlSafe(Irp->MdlAddress, NormalPagePriority); } else { buffer = Irp->UserBuffer; } DbgPrint("输出出:IRP_MN_NORMAL buffer = %s\n", buffer); // ..........如果有数据,就往buffer中写入............... Irp->IoStatus.Information = length; Irp->IoStatus.Status = STATUS_SUCCESS; Irp->Tail.Overlay.OriginalFileObject-> CurrentByteOffset.QuadPart = offset.QuadPart + length; IoCompleteRequest(Irp, IO_NO_INCREMENT); return STATUS_SUCCESS; case IRP_MN_MDL: // DbgPrint("观察:IRP_MN_MDL\n"); mdl = MyMdlMemoryAllocate(length); if (mdl == NULL) { return STATUS_SUCCESS; } Irp->MdlAddress = mdl; // ..........如果有数据,就往buffer中写入............... Irp->IoStatus.Information = length; Irp->IoStatus.Status = STATUS_SUCCESS; Irp->Tail.Overlay.OriginalFileObject-> CurrentByteOffset.QuadPart = offset.QuadPart + length; IoCompleteRequest(Irp, IO_NO_INCREMENT); return STATUS_SUCCESS; case IRP_MN_COMPLETE: Irp->IoStatus.Information = length; Irp->IoStatus.Status = STATUS_SUCCESS; Irp->Tail.Overlay.OriginalFileObject-> CurrentByteOffset.QuadPart = offset.QuadPart + length; IoCompleteRequest(Irp, IO_NO_INCREMENT); return STATUS_SUCCESS; default: break; } return STATUS_SUCCESS; } 这个是驱动小妹给的,不知道怎么让他在debugview中显示出来。迷糊~~~~~~ |
|
沙发#
发布于:2007-11-28 22:37
为什么我照上面那么弄机子根本跑不起来
|
|
板凳#
发布于:2007-11-21 09:00
谢谢
|
|
地板#
发布于:2007-11-21 08:39
最好不要在系统启动前加载过滤驱动,因为有DbgPrint("输出出:IRP_MN_NORMAL buffer = %s\n", buffer);可能系统启动不了。
在进入系统之后再去启动程序 因为有大哥说%s\n", buffer可能没结束标志,很可能使系统重起。如果要想系统没关系, 最好把 DbgPrint("输出出:IRP_MN_NORMAL buffer = %s\n", buffer); 注销掉 // ..........如果有数据,就往buffer中写入............... |
|
地下室#
发布于:2007-11-20 15:49
if (STATUS_PENDING == status)
{ status = KeWaitForSingleObject( &waitEvent, Executive, KernelMode, FALSE, NULL ); ASSERT( STATUS_SUCCESS == status ); return STATUS_SUCCESS; // 这句注销掉 } |
|
5楼#
发布于:2007-11-20 15:09
没有出现输出很多的数据。
|
|
6楼#
发布于:2007-11-20 14:18
你新见一个文本文件,然后往里面写入数据。如“驱动小妹”
然后加载驱动,打开DBGVIEW 打开后, 打开你刚才的文本文件。 在DBGVIEW中,你可以在很多DbgPrint("输出出:IRP_MN_NORMAL buffer = %s\n", buffer); 中看到“驱动小妹”的数据。 也可以在打开文件的状态“保存”文件。 在DBGVIEW中看到文件中的数据。 你试试 |
|
7楼#
发布于:2007-11-20 13:43
Just a quick look and I see BSOD already because some IRPs are completed twice and some IRPs are simply by-passed.
|
|
8楼#
发布于:2007-11-20 10:21
会不会这里没问题,在绑定卷时出的问题?
|
|
9楼#
发布于:2007-11-20 10:06
看不出,顶一下
|
|
|
10楼#
发布于:2007-11-20 08:38
高手大虾们近来看一下吧~~~~~~
|
|