From 48c45bbe684fd62191ece5fe9ffa6c9ffba19b4b Mon Sep 17 00:00:00 2001 From: Pierre Schweitzer Date: Sun, 27 Jan 2013 16:18:00 +0000 Subject: [PATCH] [NTOSKRNL] Implement IoCancelFileOpen(). You can read: http://www.osronline.com/showThread.cfm?link=20807 Even though the proposed implementation is closer to W2K implementation than to W2K3 implementation In W2K3, no IRP is issued with major close. svn path=/trunk/; revision=58244 --- reactos/ntoskrnl/io/iomgr/file.c | 54 ++++++++++++++++++++++++++++++-- 1 file changed, 52 insertions(+), 2 deletions(-) diff --git a/reactos/ntoskrnl/io/iomgr/file.c b/reactos/ntoskrnl/io/iomgr/file.c index 14d3c0c8587..b09cb78e84b 100644 --- a/reactos/ntoskrnl/io/iomgr/file.c +++ b/reactos/ntoskrnl/io/iomgr/file.c @@ -2488,14 +2488,64 @@ IoSetShareAccess(IN ACCESS_MASK DesiredAccess, } /* - * @unimplemented + * @implemented */ VOID NTAPI IoCancelFileOpen(IN PDEVICE_OBJECT DeviceObject, IN PFILE_OBJECT FileObject) { - UNIMPLEMENTED; + PIRP Irp; + KEVENT Event; + NTSTATUS Status; + PIO_STACK_LOCATION Stack; + + /* Check if handles were already created for the + * open file. If so, that's over. + */ + if (FileObject->Flags & FO_HANDLE_CREATED) + KeBugCheckEx(INVALID_CANCEL_OF_FILE_OPEN, + (ULONG_PTR)FileObject, + (ULONG_PTR)DeviceObject, 0, 0); + + /* Reset the events */ + KeInitializeEvent(&Event, SynchronizationEvent, FALSE); + KeClearEvent(&FileObject->Event); + + /* Allocate the IRP we'll use */ + Irp = IopAllocateIrpMustSucceed(DeviceObject->StackSize); + /* Properly set it */ + Irp->Tail.Overlay.Thread = PsGetCurrentThread(); + Irp->UserEvent = &Event; + Irp->UserIosb = &Irp->IoStatus; + Irp->Overlay.AsynchronousParameters.UserApcRoutine = NULL; + Irp->Tail.Overlay.OriginalFileObject = FileObject; + Irp->RequestorMode = KernelMode; + Irp->Flags = IRP_CLOSE_OPERATION | IRP_SYNCHRONOUS_API; + + Stack = IoGetNextIrpStackLocation(Irp); + Stack->MajorFunction = IRP_MJ_CLEANUP; + Stack->FileObject = FileObject; + + // FIXME: Put on top of IRPs list of the thread + + /* Call the driver */ + Status = IoCallDriver(DeviceObject, Irp); + if (Status == STATUS_PENDING) + { + KeWaitForSingleObject(&Event, UserRequest, + KernelMode, FALSE, NULL); + } + + // FIXME: Remove from IRPs list + + /* Free the IRP */ + IoFreeIrp(Irp); + + /* Clear the event */ + KeClearEvent(&FileObject->Event); + /* And finally, mark the open operation as canceled */ + FileObject->Flags |= FO_FILE_OPEN_CANCELLED; } /*