Author: ion Date: Sun Jul 2 23:11:26 2006 New Revision: 22776
URL: http://svn.reactos.org/svn/reactos?rev=22776&view=rev Log: - More of the same for NtNotifyChangeDirectoryFile.
Modified: trunk/reactos/ntoskrnl/io/iomgr/iofunc.c
Modified: trunk/reactos/ntoskrnl/io/iomgr/iofunc.c URL: http://svn.reactos.org/svn/reactos/trunk/reactos/ntoskrnl/io/iomgr/iofunc.c?... ============================================================================== --- trunk/reactos/ntoskrnl/io/iomgr/iofunc.c (original) +++ trunk/reactos/ntoskrnl/io/iomgr/iofunc.c Sun Jul 2 23:11:26 2006 @@ -972,7 +972,7 @@ NTSTATUS NTAPI NtNotifyChangeDirectoryFile(IN HANDLE FileHandle, - IN HANDLE Event OPTIONAL, + IN HANDLE EventHandle OPTIONAL, IN PIO_APC_ROUTINE ApcRoutine OPTIONAL, IN PVOID ApcContext OPTIONAL, OUT PIO_STATUS_BLOCK IoStatusBlock, @@ -982,80 +982,109 @@ IN BOOLEAN WatchTree) { PIRP Irp; + PKEVENT Event = NULL; PDEVICE_OBJECT DeviceObject; PFILE_OBJECT FileObject; PIO_STACK_LOCATION IoStack; KPROCESSOR_MODE PreviousMode = ExGetPreviousMode(); NTSTATUS Status = STATUS_SUCCESS; + BOOLEAN LockedForSync = FALSE; PAGED_CODE();
- if(PreviousMode != KernelMode) - { + /* Check if we're called from user mode */ + if (PreviousMode != KernelMode) + { + /* Enter SEH for probing */ _SEH_TRY { + /* Probe the I/O STatus block */ ProbeForWrite(IoStatusBlock, sizeof(IO_STATUS_BLOCK), sizeof(ULONG)); - if(BufferSize) ProbeForWrite(Buffer, BufferSize, sizeof(ULONG)); + + /* Probe the buffer */ + if (BufferSize) ProbeForWrite(Buffer, BufferSize, sizeof(ULONG)); } _SEH_HANDLE { + /* Get the exception code */ Status = _SEH_GetExceptionCode(); } _SEH_END;
- if(!NT_SUCCESS(Status)) return Status; - } - + /* Check if probing failed */ + if (!NT_SUCCESS(Status)) return Status; + } + + /* Get File Object */ Status = ObReferenceObjectByHandle(FileHandle, FILE_LIST_DIRECTORY, IoFileObjectType, PreviousMode, - (PVOID *)&FileObject, + (PVOID*)&FileObject, NULL); - if (Status != STATUS_SUCCESS) return(Status); - - DeviceObject = FileObject->DeviceObject; - + if (!NT_SUCCESS(Status)) return Status; + + /* Check if we have an event handle */ + if (EventHandle) + { + /* Reference it */ + Status = ObReferenceObjectByHandle(EventHandle, + EVENT_MODIFY_STATE, + ExEventObjectType, + PreviousMode, + (PVOID *)&Event, + NULL); + if (Status != STATUS_SUCCESS) return Status; + KeClearEvent(Event); + } + + /* Check if we should use Sync IO or not */ + if (FileObject->Flags & FO_SYNCHRONOUS_IO) + { + /* Lock it */ + IopLockFileObject(FileObject); + LockedForSync = TRUE; + } + + /* Clear File Object event */ + KeClearEvent(&FileObject->Event); + + /* Get the device object */ + DeviceObject = IoGetRelatedDeviceObject(FileObject); + + /* Allocate the IRP */ Irp = IoAllocateIrp(DeviceObject->StackSize, FALSE); - if (!Irp) - { - ObDereferenceObject(FileObject); - return STATUS_UNSUCCESSFUL; - } - - if (!Event) Event = &FileObject->Event; - - /* Trigger FileObject/Event dereferencing */ - Irp->Tail.Overlay.OriginalFileObject = FileObject; + if (!Irp) return IopCleanupFailedIrp(FileObject, Event); + + /* Set up the IRP */ Irp->RequestorMode = PreviousMode; Irp->UserIosb = IoStatusBlock; + Irp->UserEvent = Event; Irp->Tail.Overlay.Thread = PsGetCurrentThread(); - Irp->UserEvent = Event; - KeResetEvent( Event ); - Irp->UserBuffer = Buffer; + Irp->Tail.Overlay.OriginalFileObject = FileObject; Irp->Overlay.AsynchronousParameters.UserApcRoutine = ApcRoutine; Irp->Overlay.AsynchronousParameters.UserApcContext = ApcContext;
+ /* Set up Stack Data */ IoStack = IoGetNextIrpStackLocation(Irp); - IoStack->MajorFunction = IRP_MJ_DIRECTORY_CONTROL; IoStack->MinorFunction = IRP_MN_NOTIFY_CHANGE_DIRECTORY; - IoStack->Flags = 0; - IoStack->Control = 0; - IoStack->DeviceObject = DeviceObject; IoStack->FileObject = FileObject;
- if (WatchTree) IoStack->Flags = SL_WATCH_TREE; - + /* Set parameters */ IoStack->Parameters.NotifyDirectory.CompletionFilter = CompletionFilter; IoStack->Parameters.NotifyDirectory.Length = BufferSize; - - Status = IoCallDriver(FileObject->DeviceObject,Irp); - - /* FIXME: Should we wait here or not for synchronously opened files? */ - - return Status; + if (WatchTree) IoStack->Flags = SL_WATCH_TREE; + + /* Perform the call */ + return IopPerformSynchronousRequest(DeviceObject, + Irp, + FileObject, + FALSE, + PreviousMode, + LockedForSync, + IopOtherTransfer); }
/*