Author: pschweitzer
Date: Sat Jul 15 10:05:32 2017
New Revision: 75353
URL:
http://svn.reactos.org/svn/reactos?rev=75353&view=rev
Log:
[RDBSS]
Implement RxNotifyChangeDirectory(), RxLowIoNotifyChangeDirectoryCompletion(),
RxCancelNotifyChangeDirectoryRequestsForVNetRoot()
This means the first parts of the directory watch are here. Though, NFS driver doesn't
support these, but at least, it reduces the UNIMPLEMENTED spam!
CORE-11327
Modified:
trunk/reactos/sdk/include/ddk/mrx.h
trunk/reactos/sdk/lib/drivers/rdbsslib/rdbss.c
Modified: trunk/reactos/sdk/include/ddk/mrx.h
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/sdk/include/ddk/mrx.h?rev=…
==============================================================================
--- trunk/reactos/sdk/include/ddk/mrx.h [iso-8859-1] (original)
+++ trunk/reactos/sdk/include/ddk/mrx.h [iso-8859-1] Sat Jul 15 10:05:32 2017
@@ -1,5 +1,8 @@
#ifndef _RXMINIRDR_
#define _RXMINIRDR_
+
+#define RxSetIoStatusStatus(R, S) (R)->CurrentIrp->IoStatus.Status = (S)
+#define RxSetIoStatusInfo(R, I) (R)->CurrentIrp->IoStatus.Information = (I)
#define RxShouldPostCompletion() ((KeGetCurrentIrql() >= DISPATCH_LEVEL))
Modified: trunk/reactos/sdk/lib/drivers/rdbsslib/rdbss.c
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/sdk/lib/drivers/rdbsslib/r…
==============================================================================
--- trunk/reactos/sdk/lib/drivers/rdbsslib/rdbss.c [iso-8859-1] (original)
+++ trunk/reactos/sdk/lib/drivers/rdbsslib/rdbss.c [iso-8859-1] Sat Jul 15 10:05:32 2017
@@ -913,13 +913,100 @@
UNIMPLEMENTED;
}
+/*
+ * @implemented
+ */
NTSTATUS
RxCancelNotifyChangeDirectoryRequestsForVNetRoot(
PV_NET_ROOT VNetRoot,
BOOLEAN ForceFilesClosed)
{
- UNIMPLEMENTED;
- return STATUS_NOT_IMPLEMENTED;
+ KIRQL OldIrql;
+ NTSTATUS Status;
+ PLIST_ENTRY Entry;
+ PRX_CONTEXT Context;
+ LIST_ENTRY ContextsToCancel;
+
+ /* Init a list for the contexts to cancel */
+ InitializeListHead(&ContextsToCancel);
+
+ /* Lock our list lock */
+ KeAcquireSpinLock(&RxStrucSupSpinLock, &OldIrql);
+
+ /* Now, browse all the active contexts, to find the associated ones */
+ Entry = RxActiveContexts.Flink;
+ while (Entry != &RxActiveContexts)
+ {
+ Context = CONTAINING_RECORD(Entry, RX_CONTEXT, ContextListEntry);
+ Entry = Entry->Flink;
+
+ /* Not the IRP we're looking for, ignore */
+ if (Context->MajorFunction != IRP_MJ_DIRECTORY_CONTROL ||
+ Context->MinorFunction != IRP_MN_NOTIFY_CHANGE_DIRECTORY)
+ {
+ continue;
+ }
+
+ /* Not the VNetRoot we're looking for, ignore */
+ if (Context->pFcb == NULL ||
+ (PV_NET_ROOT)Context->NotifyChangeDirectory.pVNetRoot != VNetRoot)
+ {
+ continue;
+ }
+
+ /* No cancel routine (can't be cancel, then), ignore */
+ if (Context->MRxCancelRoutine == NULL)
+ {
+ continue;
+ }
+
+ /* At that point, we found a matching context
+ * If we're not asked to force close, then fail - it's still open
+ */
+ if (!ForceFilesClosed)
+ {
+ Status = STATUS_FILES_OPEN;
+ break;
+ }
+
+ /* Mark our context as cancelled */
+ SetFlag(Context->Flags, RX_CONTEXT_FLAG_CANCELLED);
+
+ /* Move it to our list */
+ RemoveEntryList(&Context->ContextListEntry);
+ InsertTailList(&ContextsToCancel, &Context->ContextListEntry);
+
+ InterlockedIncrement((volatile long *)&Context->ReferenceCount);
+ }
+
+ /* Done with the contexts */
+ KeReleaseSpinLock(&RxStrucSupSpinLock, OldIrql);
+
+ if (Status != STATUS_SUCCESS)
+ {
+ return Status;
+ }
+
+ /* Now, handle all our "extracted" contexts */
+ while (!IsListEmpty(&ContextsToCancel))
+ {
+ Entry = RemoveHeadList(&ContextsToCancel);
+ Context = CONTAINING_RECORD(Entry, RX_CONTEXT, ContextListEntry);
+
+ /* If they had an associated IRP (should be always true) */
+ if (Context->CurrentIrp != NULL)
+ {
+ /* Then, call cancel routine */
+ ASSERT(Context->MRxCancelRoutine != NULL);
+ DPRINT1("Canceling %p with %p\n", Context,
Context->MRxCancelRoutine);
+ Context->MRxCancelRoutine(Context);
+ }
+
+ /* And delete the context */
+ RxDereferenceAndDeleteRxContext(Context);
+ }
+
+ return Status;
}
VOID
@@ -5329,6 +5416,25 @@
* @implemented
*/
NTSTATUS
+NTAPI
+RxLowIoNotifyChangeDirectoryCompletion(
+ PRX_CONTEXT RxContext)
+{
+ PAGED_CODE();
+
+ DPRINT("Completing NCD with: %lx, %lx\n",
RxContext->IoStatusBlock.Status, RxContext->IoStatusBlock.Information);
+
+ /* Just copy back the IO_STATUS to the IRP */
+ RxSetIoStatusStatus(RxContext, RxContext->IoStatusBlock.Status);
+ RxSetIoStatusInfo(RxContext, RxContext->IoStatusBlock.Information);
+
+ return RxContext->IoStatusBlock.Status;
+}
+
+/*
+ * @implemented
+ */
+NTSTATUS
RxLowIoReadShell(
PRX_CONTEXT RxContext)
{
@@ -5469,12 +5575,63 @@
return Status;
}
+/*
+ * @implemented
+ */
NTSTATUS
RxNotifyChangeDirectory(
PRX_CONTEXT RxContext)
{
- UNIMPLEMENTED;
- return STATUS_NOT_IMPLEMENTED;
+ PIRP Irp;
+ NTSTATUS Status;
+ PIO_STACK_LOCATION Stack;
+
+ PAGED_CODE();
+
+ /* The IRP can abviously wait */
+ SetFlag(RxContext->Flags, RX_CONTEXT_FLAG_WAIT);
+
+ /* Initialize its lowio */
+ RxInitializeLowIoContext(&RxContext->LowIoContext,
LOWIO_OP_NOTIFY_CHANGE_DIRECTORY);
+
+ _SEH2_TRY
+ {
+ /* Lock user buffer */
+ Stack = RxContext->CurrentIrpSp;
+ RxLockUserBuffer(RxContext, IoWriteAccess,
Stack->Parameters.NotifyDirectory.Length);
+
+ /* Copy parameters from IO_STACK */
+ RxContext->LowIoContext.ParamsFor.NotifyChangeDirectory.WatchTree =
BooleanFlagOn(Stack->Flags, SL_WATCH_TREE);
+ RxContext->LowIoContext.ParamsFor.NotifyChangeDirectory.CompletionFilter =
Stack->Parameters.NotifyDirectory.CompletionFilter;
+
RxContext->LowIoContext.ParamsFor.NotifyChangeDirectory.NotificationBufferLength =
Stack->Parameters.NotifyDirectory.Length;
+
+ /* If we have an associated MDL */
+ Irp = RxContext->CurrentIrp;
+ if (Irp->MdlAddress != NULL)
+ {
+ /* Then, call mini-rdr */
+
RxContext->LowIoContext.ParamsFor.NotifyChangeDirectory.pNotificationBuffer =
MmGetSystemAddressForMdlSafe(Irp->MdlAddress, NormalPagePriority);
+ if
(RxContext->LowIoContext.ParamsFor.NotifyChangeDirectory.pNotificationBuffer != NULL)
+ {
+ Status = RxLowIoSubmit(RxContext,
RxLowIoNotifyChangeDirectoryCompletion);
+ }
+ else
+ {
+ Status = STATUS_INSUFFICIENT_RESOURCES;
+ }
+ }
+ else
+ {
+ Status = STATUS_INVALID_PARAMETER;
+ }
+ }
+ _SEH2_FINALLY
+ {
+ /* All correct */
+ }
+ _SEH2_END;
+
+ return Status;
}
NTSTATUS