mirror of
https://github.com/reactos/reactos.git
synced 2025-01-10 08:10:18 +00:00
- More of the same for NtNotifyChangeDirectoryFile.
svn path=/trunk/; revision=22776
This commit is contained in:
parent
363f94ff5d
commit
8a2e062765
1 changed files with 58 additions and 29 deletions
|
@ -972,7 +972,7 @@ NtFlushBuffersFile(IN HANDLE FileHandle,
|
||||||
NTSTATUS
|
NTSTATUS
|
||||||
NTAPI
|
NTAPI
|
||||||
NtNotifyChangeDirectoryFile(IN HANDLE FileHandle,
|
NtNotifyChangeDirectoryFile(IN HANDLE FileHandle,
|
||||||
IN HANDLE Event OPTIONAL,
|
IN HANDLE EventHandle OPTIONAL,
|
||||||
IN PIO_APC_ROUTINE ApcRoutine OPTIONAL,
|
IN PIO_APC_ROUTINE ApcRoutine OPTIONAL,
|
||||||
IN PVOID ApcContext OPTIONAL,
|
IN PVOID ApcContext OPTIONAL,
|
||||||
OUT PIO_STATUS_BLOCK IoStatusBlock,
|
OUT PIO_STATUS_BLOCK IoStatusBlock,
|
||||||
|
@ -982,80 +982,109 @@ NtNotifyChangeDirectoryFile(IN HANDLE FileHandle,
|
||||||
IN BOOLEAN WatchTree)
|
IN BOOLEAN WatchTree)
|
||||||
{
|
{
|
||||||
PIRP Irp;
|
PIRP Irp;
|
||||||
|
PKEVENT Event = NULL;
|
||||||
PDEVICE_OBJECT DeviceObject;
|
PDEVICE_OBJECT DeviceObject;
|
||||||
PFILE_OBJECT FileObject;
|
PFILE_OBJECT FileObject;
|
||||||
PIO_STACK_LOCATION IoStack;
|
PIO_STACK_LOCATION IoStack;
|
||||||
KPROCESSOR_MODE PreviousMode = ExGetPreviousMode();
|
KPROCESSOR_MODE PreviousMode = ExGetPreviousMode();
|
||||||
NTSTATUS Status = STATUS_SUCCESS;
|
NTSTATUS Status = STATUS_SUCCESS;
|
||||||
|
BOOLEAN LockedForSync = FALSE;
|
||||||
PAGED_CODE();
|
PAGED_CODE();
|
||||||
|
|
||||||
if(PreviousMode != KernelMode)
|
/* Check if we're called from user mode */
|
||||||
|
if (PreviousMode != KernelMode)
|
||||||
{
|
{
|
||||||
|
/* Enter SEH for probing */
|
||||||
_SEH_TRY
|
_SEH_TRY
|
||||||
{
|
{
|
||||||
|
/* Probe the I/O STatus block */
|
||||||
ProbeForWrite(IoStatusBlock,
|
ProbeForWrite(IoStatusBlock,
|
||||||
sizeof(IO_STATUS_BLOCK),
|
sizeof(IO_STATUS_BLOCK),
|
||||||
sizeof(ULONG));
|
sizeof(ULONG));
|
||||||
if(BufferSize) ProbeForWrite(Buffer, BufferSize, sizeof(ULONG));
|
|
||||||
|
/* Probe the buffer */
|
||||||
|
if (BufferSize) ProbeForWrite(Buffer, BufferSize, sizeof(ULONG));
|
||||||
}
|
}
|
||||||
_SEH_HANDLE
|
_SEH_HANDLE
|
||||||
{
|
{
|
||||||
|
/* Get the exception code */
|
||||||
Status = _SEH_GetExceptionCode();
|
Status = _SEH_GetExceptionCode();
|
||||||
}
|
}
|
||||||
_SEH_END;
|
_SEH_END;
|
||||||
|
|
||||||
if(!NT_SUCCESS(Status)) return Status;
|
/* Check if probing failed */
|
||||||
|
if (!NT_SUCCESS(Status)) return Status;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Get File Object */
|
||||||
Status = ObReferenceObjectByHandle(FileHandle,
|
Status = ObReferenceObjectByHandle(FileHandle,
|
||||||
FILE_LIST_DIRECTORY,
|
FILE_LIST_DIRECTORY,
|
||||||
IoFileObjectType,
|
IoFileObjectType,
|
||||||
PreviousMode,
|
PreviousMode,
|
||||||
(PVOID *)&FileObject,
|
(PVOID*)&FileObject,
|
||||||
NULL);
|
NULL);
|
||||||
if (Status != STATUS_SUCCESS) return(Status);
|
if (!NT_SUCCESS(Status)) return Status;
|
||||||
|
|
||||||
DeviceObject = FileObject->DeviceObject;
|
/* Check if we have an event handle */
|
||||||
|
if (EventHandle)
|
||||||
Irp = IoAllocateIrp(DeviceObject->StackSize, FALSE);
|
|
||||||
if (!Irp)
|
|
||||||
{
|
{
|
||||||
ObDereferenceObject(FileObject);
|
/* Reference it */
|
||||||
return STATUS_UNSUCCESSFUL;
|
Status = ObReferenceObjectByHandle(EventHandle,
|
||||||
|
EVENT_MODIFY_STATE,
|
||||||
|
ExEventObjectType,
|
||||||
|
PreviousMode,
|
||||||
|
(PVOID *)&Event,
|
||||||
|
NULL);
|
||||||
|
if (Status != STATUS_SUCCESS) return Status;
|
||||||
|
KeClearEvent(Event);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!Event) Event = &FileObject->Event;
|
/* Check if we should use Sync IO or not */
|
||||||
|
if (FileObject->Flags & FO_SYNCHRONOUS_IO)
|
||||||
|
{
|
||||||
|
/* Lock it */
|
||||||
|
IopLockFileObject(FileObject);
|
||||||
|
LockedForSync = TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
/* Trigger FileObject/Event dereferencing */
|
/* Clear File Object event */
|
||||||
Irp->Tail.Overlay.OriginalFileObject = FileObject;
|
KeClearEvent(&FileObject->Event);
|
||||||
|
|
||||||
|
/* Get the device object */
|
||||||
|
DeviceObject = IoGetRelatedDeviceObject(FileObject);
|
||||||
|
|
||||||
|
/* Allocate the IRP */
|
||||||
|
Irp = IoAllocateIrp(DeviceObject->StackSize, FALSE);
|
||||||
|
if (!Irp) return IopCleanupFailedIrp(FileObject, Event);
|
||||||
|
|
||||||
|
/* Set up the IRP */
|
||||||
Irp->RequestorMode = PreviousMode;
|
Irp->RequestorMode = PreviousMode;
|
||||||
Irp->UserIosb = IoStatusBlock;
|
Irp->UserIosb = IoStatusBlock;
|
||||||
Irp->Tail.Overlay.Thread = PsGetCurrentThread();
|
|
||||||
Irp->UserEvent = Event;
|
Irp->UserEvent = Event;
|
||||||
KeResetEvent( Event );
|
Irp->Tail.Overlay.Thread = PsGetCurrentThread();
|
||||||
Irp->UserBuffer = Buffer;
|
Irp->Tail.Overlay.OriginalFileObject = FileObject;
|
||||||
Irp->Overlay.AsynchronousParameters.UserApcRoutine = ApcRoutine;
|
Irp->Overlay.AsynchronousParameters.UserApcRoutine = ApcRoutine;
|
||||||
Irp->Overlay.AsynchronousParameters.UserApcContext = ApcContext;
|
Irp->Overlay.AsynchronousParameters.UserApcContext = ApcContext;
|
||||||
|
|
||||||
|
/* Set up Stack Data */
|
||||||
IoStack = IoGetNextIrpStackLocation(Irp);
|
IoStack = IoGetNextIrpStackLocation(Irp);
|
||||||
|
|
||||||
IoStack->MajorFunction = IRP_MJ_DIRECTORY_CONTROL;
|
IoStack->MajorFunction = IRP_MJ_DIRECTORY_CONTROL;
|
||||||
IoStack->MinorFunction = IRP_MN_NOTIFY_CHANGE_DIRECTORY;
|
IoStack->MinorFunction = IRP_MN_NOTIFY_CHANGE_DIRECTORY;
|
||||||
IoStack->Flags = 0;
|
|
||||||
IoStack->Control = 0;
|
|
||||||
IoStack->DeviceObject = DeviceObject;
|
|
||||||
IoStack->FileObject = FileObject;
|
IoStack->FileObject = FileObject;
|
||||||
|
|
||||||
if (WatchTree) IoStack->Flags = SL_WATCH_TREE;
|
/* Set parameters */
|
||||||
|
|
||||||
IoStack->Parameters.NotifyDirectory.CompletionFilter = CompletionFilter;
|
IoStack->Parameters.NotifyDirectory.CompletionFilter = CompletionFilter;
|
||||||
IoStack->Parameters.NotifyDirectory.Length = BufferSize;
|
IoStack->Parameters.NotifyDirectory.Length = BufferSize;
|
||||||
|
if (WatchTree) IoStack->Flags = SL_WATCH_TREE;
|
||||||
|
|
||||||
Status = IoCallDriver(FileObject->DeviceObject,Irp);
|
/* Perform the call */
|
||||||
|
return IopPerformSynchronousRequest(DeviceObject,
|
||||||
/* FIXME: Should we wait here or not for synchronously opened files? */
|
Irp,
|
||||||
|
FileObject,
|
||||||
return Status;
|
FALSE,
|
||||||
|
PreviousMode,
|
||||||
|
LockedForSync,
|
||||||
|
IopOtherTransfer);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
|
Loading…
Reference in a new issue