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);
}
/*