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=7... ============================================================================== --- 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/rd... ============================================================================== --- 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