joshua_yu
驱动小牛
驱动小牛
  • 注册日期2004-12-06
  • 最后登录2010-12-01
  • 粉丝0
  • 关注0
  • 积分428分
  • 威望54点
  • 贡献值0点
  • 好评度41点
  • 原创分0分
  • 专家分0分
阅读:2894回复:4

tooflat老大,关于\"DispatchCreate中读取文件\"的问题

楼主#
更多 发布于:2005-03-31 08:16
tooflat,看了你前面的\"DispatchCreate中读取文件问题\"的帖子,感觉非常高兴,因为我也需要在Create里面用流文件对象读文件,可是参考了OSR上面关于流文件的例子后,无法正确读取文件内容,请问你是怎么实现的,能不能给我一些指导?谢谢了!

最新喜欢:

znsoftznsoft
tooflat
论坛版主
论坛版主
  • 注册日期2002-07-08
  • 最后登录2014-03-11
  • 粉丝2
  • 关注0
  • 积分1007分
  • 威望551点
  • 贡献值3点
  • 好评度476点
  • 原创分0分
  • 专家分0分
沙发#
发布于: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;
}
joshua_yu
驱动小牛
驱动小牛
  • 注册日期2004-12-06
  • 最后登录2010-12-01
  • 粉丝0
  • 关注0
  • 积分428分
  • 威望54点
  • 贡献值0点
  • 好评度41点
  • 原创分0分
  • 专家分0分
板凳#
发布于:2005-03-31 12:24
真是太感谢了,我先给分,然后再仔细研究一下...
joshua_yu
驱动小牛
驱动小牛
  • 注册日期2004-12-06
  • 最后登录2010-12-01
  • 粉丝0
  • 关注0
  • 积分428分
  • 威望54点
  • 贡献值0点
  • 好评度41点
  • 原创分0分
  • 专家分0分
地板#
发布于:2005-03-31 12:43
怎么分没有给成,给分的菜单没有了,回头我再开一个新的帖子给分。
tooflat
论坛版主
论坛版主
  • 注册日期2002-07-08
  • 最后登录2014-03-11
  • 粉丝2
  • 关注0
  • 积分1007分
  • 威望551点
  • 贡献值3点
  • 好评度476点
  • 原创分0分
  • 专家分0分
地下室#
发布于: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;
}
游客

返回顶部