阅读:2895回复:4
tooflat老大,关于\"DispatchCreate中读取文件\"的问题
tooflat,看了你前面的\"DispatchCreate中读取文件问题\"的帖子,感觉非常高兴,因为我也需要在Create里面用流文件对象读文件,可是参考了OSR上面关于流文件的例子后,无法正确读取文件内容,请问你是怎么实现的,能不能给我一些指导?谢谢了!
|
|
最新喜欢:znsoft |
沙发#
发布于:2005-03-31 11:16
NTSTATUS
SfCreate( IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp ) { // ... MyIrp = IoAllocateIrp(DeviceObject->StackSize, FALSE); if (!MyIrp) { KdPrint((\"sfilter!SfCreate: IoAllocateIrp failed\\n\")); Status = STATUS_INSUFFICIENT_RESOURCES; break; } try { SwapFileObject = IoCreateStreamFileObjectLite(FileObject, NULL); } except (STATUS_INSUFFICIENT_RESOURCES) { IoFreeIrp(MyIrp); Status = STATUS_INSUFFICIENT_RESOURCES; break; } if (!SwapFileObject) { IoFreeIrp(MyIrp); Status = STATUS_INSUFFICIENT_RESOURCES; break; } RtlCopyMemory(SwapFileObject, FileObject, sizeof(FILE_OBJECT)); SwapFileObject->Flags |= FO_STREAM_FILE; IrpSp->FileObject = SwapFileObject; KeInitializeEvent(&Event, NotificationEvent, FALSE); IoCopyCurrentIrpStackLocationToNext(Irp); IoSetCompletionRoutine(Irp, SfCreateCompletion, &Event, TRUE, TRUE, TRUE); Status = IoCallDriver(DevExt->AttachedToDeviceObject, Irp); if (STATUS_PENDING == Status) { KeWaitForSingleObject(&Event, Executive, KernelMode, TRUE, NULL); Status = Irp->IoStatus.Status; } if (NT_SUCCESS(Status) && (STATUS_REPARSE != Status)) { // 在这里读写文件 // ... ... Status = SfIssueCleanupIrpSynchronously( DevExt->AttachedToDeviceObject, MyIrp, SwapFileObject ); if (!NT_SUCCESS(Status)) { KdPrint((\"sfilter!SfCreate: SfIssueCleanupIrpSynchronously failed, return %x\\n\", Status)); if (SwapFileObject->PrivateCacheMap != NULL) { CcUninitializeCacheMap(SwapFileObject, NULL, NULL); } } } SwapFileObject->FileName.Buffer = NULL; SwapFileObject->FileName.Length = 0; SwapFileObject->FileName.MaximumLength = 0; ObDereferenceObject(SwapFileObject); IrpSp->FileObject = FileObject; IoFreeIrp(MyIrp); // ... } NTSTATUS SfIssueCleanupIrpSynchronously( IN PDEVICE_OBJECT NextDeviceObject, IN PIRP Irp, IN PFILE_OBJECT FileObject ) { PIO_STACK_LOCATION IrpSp = NULL; IO_STATUS_BLOCK IoStatus; KEVENT Event; KeInitializeEvent(&Event, NotificationEvent, FALSE); KeClearEvent(&FileObject->Event); Irp->Tail.Overlay.OriginalFileObject = FileObject; Irp->Tail.Overlay.Thread = PsGetCurrentThread(); Irp->Overlay.AsynchronousParameters.UserApcRoutine = (PIO_APC_ROUTINE) NULL; Irp->RequestorMode = KernelMode; Irp->UserEvent = &Event; Irp->UserIosb = &IoStatus; Irp->Flags = IRP_SYNCHRONOUS_API | IRP_CLOSE_OPERATION; IrpSp = IoGetNextIrpStackLocation(Irp); IrpSp->MajorFunction = IRP_MJ_CLEANUP; IrpSp->FileObject = FileObject; if (STATUS_PENDING == IoCallDriver(NextDeviceObject, Irp)) { KeWaitForSingleObject(&Event, Executive, KernelMode, FALSE, NULL); } return IoStatus.Status; } |
|
板凳#
发布于:2005-03-31 12:24
真是太感谢了,我先给分,然后再仔细研究一下...
|
|
地板#
发布于:2005-03-31 12:43
怎么分没有给成,给分的菜单没有了,回头我再开一个新的帖子给分。
|
|
地下室#
发布于:2005-05-08 15:42
前面给的代码有问题,在ntfs下不行,下面的代码在ntfs下OK
NTSTATUS SfPreCreateCompletion( IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp, IN PVOID Context ) { UNREFERENCED_PARAMETER(DeviceObject); if (Irp->PendingReturned) KeSetEvent((PKEVENT)Context, IO_NO_INCREMENT, FALSE); return STATUS_MORE_PROCESSING_REQUIRED; } NTSTATUS SfPreCreate( IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp, IN PIO_STACK_LOCATION IrpSp, IN PFILE_OBJECT FileObject ) { PSFILTER_DEVICE_EXTENSION DevExt = (PSFILTER_DEVICE_EXTENSION) DeviceObject->DeviceExtension; PFILE_OBJECT MyFileObject = NULL; PIRP MyIrp; NTSTATUS Status; ULONG CreateOptions = IrpSp->Parameters.Create.Options; PWSTR MyBuffer; do { MyBuffer = ExAllocatePoolWithTag(PagedPool, FileObject->FileName.MaximumLength, SFLT_POOL_TAG); if (!MyBuffer) { KdPrint((\"sfilter!SfPreCreate: ExAllocatePoolWithTag failed\\n\")); Status = STATUS_INSUFFICIENT_RESOURCES; break; } MyIrp = IoAllocateIrp(DeviceObject->StackSize, FALSE); if (!MyIrp) { KdPrint((\"sfilter!SfPreCreate: IoAllocateIrp failed\\n\")); ExFreePoolWithTag(MyBuffer, SFLT_POOL_TAG); Status = STATUS_INSUFFICIENT_RESOURCES; break; } try { MyFileObject = IoCreateStreamFileObjectLite(FileObject, NULL); } except(STATUS_INSUFFICIENT_RESOURCES) { KdPrint((\"sfilter!SfPreCreate: IoCreateStreamFileObjectLite failed\\n\")); IoFreeIrp(MyIrp); ExFreePoolWithTag(MyBuffer, SFLT_POOL_TAG); Status = STATUS_INSUFFICIENT_RESOURCES; break; } if (!MyFileObject) { KdPrint((\"sfilter!SfPreCreate: IoCreateStreamFileObjectLite failed\\n\")); IoFreeIrp(MyIrp); ExFreePoolWithTag(MyBuffer, SFLT_POOL_TAG); Status = STATUS_INSUFFICIENT_RESOURCES; break; } RtlCopyMemory(MyBuffer, FileObject->FileName.Buffer, FileObject->FileName.MaximumLength); // // Clear some flags, or the ntfs will failed the create request // MyFileObject->Flags = FileObject->Flags & ~(FO_STREAM_FILE | FO_HANDLE_CREATED | FO_CLEANUP_COMPLETE); KeInitializeEvent(&MyFileObject->Lock, SynchronizationEvent, FALSE); KeInitializeEvent(&MyFileObject->Event, NotificationEvent, FALSE); MyFileObject->FileName.Buffer = MyBuffer; MyFileObject->FileName.Length = FileObject->FileName.Length; MyFileObject->FileName.MaximumLength = FileObject->FileName.MaximumLength; MyFileObject->RelatedFileObject = FileObject->RelatedFileObject; IrpSp->FileObject = MyFileObject; IrpSp->Parameters.Create.Options &= 0x00FFFFFF; IrpSp->Parameters.Create.Options |= (FILE_OPEN) << 24; IrpSp->Parameters.Create.Options &= ~FILE_DELETE_ON_CLOSE; IoCopyCurrentIrpStackLocationToNext(Irp); IoSetCompletionRoutine(Irp, SfPreCreateCompletion, &MyFileObject->Event, TRUE, TRUE, TRUE); Status = IoCallDriver(DevExt->AttachedToDeviceObject, Irp); if (STATUS_PENDING == Status) { KeWaitForSingleObject(&MyFileObject->Event, Executive, KernelMode, TRUE, NULL); Status = Irp->IoStatus.Status; } if (NT_SUCCESS(Status) && (STATUS_REPARSE != Status)) { // U can read write file here MyFileObject->Flags |= FO_HANDLE_CREATED; Status = SfIssueCleanupIrpSynchronously( DevExt->AttachedToDeviceObject, MyIrp, MyFileObject ); if (!NT_SUCCESS(Status)) { KdPrint((\"sfilter!SfPreCreate: SfIssueCleanupIrpSynchronously failed, return %x\\n\", Status)); if (MyFileObject->PrivateCacheMap != NULL) { CcUninitializeCacheMap(MyFileObject, NULL, NULL); } } } // // !!! DON\'T use ExFreePoolWithTag, becoz the MyBuffer may be freed and // be placed by underlying driver below us, so the TAG may not be our // TAG when it returns to us, so and DON\'T ExFreePool(MyBuffer) too // ExFreePool(MyFileObject->FileName.Buffer); // // Clear the FileName field, or we may free the buffer twice // MyFileObject->FileName.Buffer = NULL; MyFileObject->FileName.Length = 0; MyFileObject->FileName.MaximumLength = 0; MyFileObject->RelatedFileObject = NULL; MyFileObject->Flags |= FO_STREAM_FILE; ObDereferenceObject(MyFileObject); IrpSp->FileObject = FileObject; IrpSp->Parameters.Create.Options = CreateOptions; IoFreeIrp(MyIrp); } while (FALSE); return Status; } |
|