阅读:1429回复:3
请高手帮我分析下原因~~~~拜托
这是调试时候蓝屏的代码:
NTSTATUS SfRead( IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp ) { LARGE_INTEGER offset; PIO_STACK_LOCATION irpsp = IoGetCurrentIrpStackLocation(Irp); offset.QuadPart = irpsp->Parameters.Read.ByteOffset.QuadPart; PFILE_OBJECT file_object = irpsp->FileObject; PSFILTER_DEVICE_EXTENSION devExt = (PSFILTER_DEVICE_EXTENSION)DeviceObject->DeviceExtension; // // 现在还没有对自己设备的控制设备进行读操作,所以要返回错误 // 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; } //// 直接交给下层驱动处理 if (devExt->StorageStackDeviceObject == NULL) { return SfPassThrough(DeviceObject,Irp); } // 对文件的读操作 switch (irpsp->MinorFunction) { case IRP_MN_NORMAL: { KEVENT waitEvent; void *buffer; ULONG Length; NTSTATUS status; KeInitializeEvent(&waitEvent,NotificationEvent,FALSE); IoCopyCurrentIrpStackLocationToNext(Irp); IoSetCompletionRoutine(Irp,SfReadCompletion,&waitEvent,true,true,true); status = IoCallDriver(devExt->AttachedToDeviceObject,Irp); if (STATUS_PENDING == status) { status = KeWaitForSingleObject(&waitEvent,Executive,KernelMode,FALSE,NULL); } if (Irp->IoStatus.Status == STATUS_SUCCESS) { if (Irp->MdlAddress != NULL) buffer = MmGetSystemAddressForMdlSafe(Irp->MdlAddress,NormalPagePriority); else buffer = Irp->UserBuffer; Length = Irp->IoStatus.Information; } Irp->IoStatus.Information = Length; Irp->IoStatus.Status = STATUS_SUCCESS; //移动文件指针,防止读取相同的位置 irpsp->FileObject->CurrentByteOffset.QuadPart = Length + offset.QuadPart; IoCompleteRequest(Irp,IO_NO_INCREMENT); return STATUS_SUCCESS; }break; } IoSkipCurrentIrpStackLocation(Irp); return IoCallDriver(((PSFILTER_DEVICE_EXTENSION)DeviceObject->DeviceExtension)->AttachedToDeviceObject,Irp); } NTSTATUS SfReadCompletion( IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp, IN PVOID Context ) { ASSERT(Context != NULL); if (Irp->PendingReturned) { IoMarkIrpPending(Irp); } KeSetEvent(&Context, IO_NO_INCREMENT, FALSE); return STATUS_MORE_PROCESSING_REQUIRED; } 调试后蓝屏的分析信息是MULTIPLE_IRP_COMPLETE_REQUESTS (44). 我把代码改成在完成例程中执行就不会蓝屏.我一直不知道原因是什么..... 这个是改过的代码: NTSTATUS SfRead( IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp ) { PSFILTER_DEVICE_EXTENSION devExt = (PSFILTER_DEVICE_EXTENSION)DeviceObject->DeviceExtension; // // 现在还没有对自己设备的控制设备进行读操作,所以要返回错误 // 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; } if (devExt->StorageStackDeviceObject == NULL) { return SfPassThrough(DeviceObject,Irp); } IoCopyCurrentIrpStackLocationToNext(Irp); IoSetCompletionRoutine(Irp,SfReadCompletion,NULL,true,true,true); return IoCallDriver(devExt->AttachedToDeviceObject,Irp); } NTSTATUS SfReadCompletion( IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp, IN PVOID Context ) { PIO_STACK_LOCATION irpsp = IoGetCurrentIrpStackLocation(Irp); PFILE_OBJECT file_object = irpsp->FileObject; KdPrint(("Read file name : %ws\n",file_object->FileName.Buffer)); void *buffer; switch (irpsp->MinorFunction) { case IRP_MN_NORMAL: { if (Irp->MdlAddress != NULL) buffer = MmGetSystemAddressForMdlSafe(Irp->MdlAddress,NormalPagePriority); else buffer = Irp->UserBuffer; }break; } if (Irp->PendingReturned) { IoMarkIrpPending(Irp); } return Irp->IoStatus.Status; } 这样改以后就不蓝屏了~~郁闷啊..... |
|
沙发#
发布于:2009-08-25 17:47
One problem is:
KeSetEvent(&Context, IO_NO_INCREMENT, FALSE); Should it be: KeSetEvent(Context, IO_NO_INCREMENT, FALSE); |
|
板凳#
发布于:2009-08-27 13:38
谢谢前辈
|
|
地板#
发布于:2009-11-17 16:04
读取文件应该在完成以后才计算偏移和长度吧。
|
|