[RDBSS]
[reactos.git] / reactos / sdk / lib / drivers / rdbsslib / rdbss.c
index fffce15..5a9a832 100644 (file)
@@ -30,6 +30,7 @@
 #include <pseh/pseh2.h>
 #include <limits.h>
 #include <dfs.h>
+#include <copysup.h>
 
 #define NDEBUG
 #include <debug.h>
@@ -61,6 +62,13 @@ VOID
 RxAddToTopLevelIrpAllocatedContextsList(
     PRX_TOPLEVELIRP_CONTEXT TopLevelContext);
 
+VOID
+RxAssert(
+    PVOID Assert,
+    PVOID File,
+    ULONG Line,
+    PVOID Message);
+
 NTSTATUS
 NTAPI
 RxCommonCleanup(
@@ -336,6 +344,15 @@ NTAPI
 RxLowIoReadShellCompletion(
     PRX_CONTEXT RxContext);
 
+NTSTATUS
+RxLowIoWriteShell(
+    IN PRX_CONTEXT RxContext);
+
+NTSTATUS
+NTAPI
+RxLowIoWriteShellCompletion(
+    PRX_CONTEXT RxContext);
+
 PVOID
 RxNewMapUserBuffer(
     PRX_CONTEXT RxContext);
@@ -350,6 +367,11 @@ RxpQueryInfoMiniRdr(
     FILE_INFORMATION_CLASS FileInfoClass,
     PVOID Buffer);
 
+VOID
+RxPurgeNetFcb(
+    PFCB Fcb,
+    PRX_CONTEXT LocalContext);
+
 NTSTATUS
 RxQueryAlternateNameInfo(
     PRX_CONTEXT RxContext,
@@ -426,6 +448,38 @@ RxSearchForCollapsibleOpen(
     ACCESS_MASK DesiredAccess,
     ULONG ShareAccess);
 
+NTSTATUS
+RxSetAllocationInfo(
+    PRX_CONTEXT RxContext);
+
+NTSTATUS
+RxSetBasicInfo(
+    PRX_CONTEXT RxContext);
+
+NTSTATUS
+RxSetDispositionInfo(
+    PRX_CONTEXT RxContext);
+
+NTSTATUS
+RxSetEndOfFileInfo(
+    PRX_CONTEXT RxContext);
+
+NTSTATUS
+RxSetPipeInfo(
+    PRX_CONTEXT RxContext);
+
+NTSTATUS
+RxSetPositionInfo(
+    PRX_CONTEXT RxContext);
+
+NTSTATUS
+RxSetRenameInfo(
+    PRX_CONTEXT RxContext);
+
+NTSTATUS
+RxSetSimpleInfo(
+    PRX_CONTEXT RxContext);
+
 VOID
 RxSetupNetFileObject(
     PRX_CONTEXT RxContext);
@@ -450,6 +504,24 @@ NTSTATUS
 RxXXXControlFileCallthru(
     PRX_CONTEXT Context);
 
+PVOID
+NTAPI
+_RxAllocatePoolWithTag(
+    _In_ POOL_TYPE PoolType,
+    _In_ SIZE_T NumberOfBytes,
+    _In_ ULONG Tag);
+
+VOID
+NTAPI
+_RxFreePool(
+    _In_ PVOID Buffer);
+
+VOID
+NTAPI
+_RxFreePoolWithTag(
+    _In_ PVOID Buffer,
+    _In_ ULONG Tag);
+
 WCHAR RxStarForTemplate = '*';
 WCHAR Rx8QMdot3QM[] = L">>>>>>>>.>>>*";
 BOOLEAN DisableByteRangeLockingOnReadOnlyFiles = FALSE;
@@ -460,6 +532,7 @@ NPAGED_LOOKASIDE_LIST RxContextLookasideList;
 FAST_MUTEX RxContextPerFileSerializationMutex;
 RDBSS_DATA RxData;
 FCB RxDeviceFCB;
+BOOLEAN RxLoudLowIoOpsEnabled = FALSE;
 RX_FSD_DISPATCH_VECTOR RxDeviceFCBVector[IRP_MJ_MAXIMUM_FUNCTION + 1] =
 {
     { RxCommonDispatchProblem },
@@ -534,16 +607,60 @@ UCHAR RxSpaceForTheWrappersDeviceObject[sizeof(*RxFileSystemDeviceObject)];
 KSPIN_LOCK TopLevelIrpSpinLock;
 LIST_ENTRY TopLevelIrpAllocatedContextsList;
 BOOLEAN RxForceQFIPassThrough = FALSE;
+BOOLEAN RxNoAsync = FALSE;
 
 DECLARE_CONST_UNICODE_STRING(unknownId, L"???");
 
+#if RDBSS_ASSERTS
+#ifdef ASSERT
+#undef ASSERT
+#endif
+
+#define ASSERT(exp)                               \
+    if (!(exp))                                   \
+    {                                             \
+        RxAssert(#exp, __FILE__, __LINE__, NULL); \
+    }
+#endif
+
+#if RX_POOL_WRAPPER
+#undef RxAllocatePool
+#undef RxAllocatePoolWithTag
+#undef RxFreePool
+
+#define RxAllocatePool(P, S) _RxAllocatePoolWithTag(P, S, 0)
+#define RxAllocatePoolWithTag _RxAllocatePoolWithTag
+#define RxFreePool _RxFreePool
+#define RxFreePoolWithTag _RxFreePoolWithTag
+#endif
+
 /* FUNCTIONS ****************************************************************/
 
+/*
+ * @implemented
+ */
 VOID
 CheckForLoudOperations(
     PRX_CONTEXT RxContext)
 {
-    UNIMPLEMENTED;
+    PAGED_CODE();
+
+#define ALLSCR_LENGTH (sizeof(L"all.scr") - sizeof(UNICODE_NULL))
+
+    /* Are loud operations enabled? */
+    if (RxLoudLowIoOpsEnabled)
+    {
+        PFCB Fcb;
+
+        /* If so, the operation will be loud only if filename ends with all.scr */
+        Fcb = (PFCB)RxContext->pFcb;
+        if (RtlCompareMemory(Add2Ptr(Fcb->PrivateAlreadyPrefixedName.Buffer, (Fcb->PrivateAlreadyPrefixedName.Length - ALLSCR_LENGTH)),
+                             L"all.scr", ALLSCR_LENGTH) == ALLSCR_LENGTH)
+        {
+            SetFlag(RxContext->LowIoContext.Flags, LOWIO_CONTEXT_FLAG_LOUDOPS);
+        }
+    }
+#undef ALLSCR_LENGTH
 }
 
 /*
@@ -573,51 +690,57 @@ __RxInitializeTopLevelIrpContext(
     }
 }
 
-NTSTATUS
-NTAPI
-RxAcquireExclusiveFcbResourceInMRx(
-    _Inout_ PMRX_FCB Fcb)
+/*
+ * @implemented
+ */
+VOID
+__RxWriteReleaseResources(
+    PRX_CONTEXT RxContext,
+    BOOLEAN ResourceOwnerSet,
+    ULONG LineNumber,
+    PCSTR FileName,
+    ULONG SerialNumber)
 {
-    UNIMPLEMENTED;
-    return STATUS_NOT_IMPLEMENTED;
-}
+    PFCB Fcb;
 
-BOOLEAN
-NTAPI
-RxAcquireFcbForLazyWrite(
-    PVOID Context,
-    BOOLEAN Wait)
-{
-    UNIMPLEMENTED;
-    return FALSE;
-}
+    PAGED_CODE();
 
-BOOLEAN
-NTAPI
-RxAcquireFcbForReadAhead(
-    PVOID Context,
-    BOOLEAN Wait)
-{
-    UNIMPLEMENTED;
-    return FALSE;
-}
+    ASSERT(RxContext != NULL);
 
-VOID
-NTAPI
-RxAcquireFileForNtCreateSection(
-    PFILE_OBJECT FileObject)
-{
-    UNIMPLEMENTED;
-}
+    Fcb = (PFCB)RxContext->pFcb;
+    ASSERT(Fcb != NULL);
 
-NTSTATUS
-NTAPI
-RxAcquireForCcFlush(
-    PFILE_OBJECT FileObject,
-    PDEVICE_OBJECT DeviceObject)
-{
-    UNIMPLEMENTED;
-    return STATUS_NOT_IMPLEMENTED;
+    /* If FCB resource was acquired, release it */
+    if (RxContext->FcbResourceAcquired)
+    {
+        /* Taking care of owner */
+        if (ResourceOwnerSet)
+        {
+            RxReleaseFcbForThread(RxContext, Fcb, RxContext->LowIoContext.ResourceThreadId);
+        }
+        else
+        {
+            RxReleaseFcb(RxContext, Fcb);
+        }
+
+        RxContext->FcbResourceAcquired = FALSE;
+    }
+
+    /* If FCB paging resource was acquired, release it */
+    if (RxContext->FcbPagingIoResourceAcquired)
+    {
+        /* Taking care of owner */
+        if (ResourceOwnerSet)
+        {
+            RxReleasePagingIoResourceForThread(RxContext, Fcb, RxContext->LowIoContext.ResourceThreadId);
+        }
+        else
+        {
+            RxReleasePagingIoResource(RxContext, Fcb);
+        }
+
+        /* No need to release boolean here, RxReleasePagingIoResource() takes care of it */
+    }
 }
 
 /*
@@ -643,6 +766,7 @@ RxAddToTopLevelIrpAllocatedContextsList(
  * @implemented
  */
 VOID
+NTAPI
 RxAddToWorkque(
     IN PRX_CONTEXT RxContext,
     IN PIRP Irp)
@@ -692,6 +816,106 @@ RxAddToWorkque(
     ExQueueWorkItem((PWORK_QUEUE_ITEM)&RxContext->WorkQueueItem, Queue);
 }
 
+/*
+ * @implemented
+ */
+VOID
+RxAdjustFileTimesAndSize(
+    PRX_CONTEXT Context)
+{
+    PFCB Fcb;
+    PFOBX Fobx;
+    NTSTATUS Status;
+    PFILE_OBJECT FileObject;
+    LARGE_INTEGER CurrentTime;
+    FILE_BASIC_INFORMATION FileBasicInfo;
+    FILE_END_OF_FILE_INFORMATION FileEOFInfo;
+    BOOLEAN FileModified, SetLastChange, SetLastAccess, SetLastWrite, NeedUpdate;
+
+    PAGED_CODE();
+
+    FileObject = Context->CurrentIrpSp->FileObject;
+    /* If Cc isn't initialized, the file was not read nor written, nothing to do */
+    if (FileObject->PrivateCacheMap == NULL)
+    {
+        return;
+    }
+
+    /* Get now */
+    KeQuerySystemTime(&CurrentTime);
+
+    Fobx = (PFOBX)Context->pFobx;
+    /* Was the file modified? */
+    FileModified = BooleanFlagOn(FileObject->Flags, FO_FILE_MODIFIED);
+    /* We'll set last write if it was modified and user didn't update yet */
+    SetLastWrite = FileModified && !BooleanFlagOn(Fobx->Flags, FOBX_FLAG_USER_SET_LAST_WRITE);
+    /* File was accessed if: written or read (fastio), we'll update last access if user didn't */
+    SetLastAccess = SetLastWrite ||
+                    (BooleanFlagOn(FileObject->Flags, FO_FILE_FAST_IO_READ) &&
+                     !BooleanFlagOn(Fobx->Flags, FOBX_FLAG_USER_SET_LAST_ACCESS));
+    /* We'll set last change if it was modified and user didn't update yet */
+    SetLastChange = FileModified && !BooleanFlagOn(Fobx->Flags, FOBX_FLAG_USER_SET_LAST_CHANGE);
+
+    /* Nothing to update? Job done */
+    if (!FileModified && !SetLastWrite && !SetLastAccess && !SetLastChange)
+    {
+        return;
+    }
+
+    Fcb = (PFCB)Context->pFcb;
+    /* By default, we won't issue any MRxSetFileInfoAtCleanup call */
+    NeedUpdate = FALSE;
+    RtlZeroMemory(&FileBasicInfo, sizeof(FileBasicInfo));
+
+    /* Update lastwrite time if required */
+    if (SetLastWrite)
+    {
+        NeedUpdate = TRUE;
+        Fcb->LastWriteTime.QuadPart = CurrentTime.QuadPart;
+        FileBasicInfo.LastWriteTime.QuadPart = CurrentTime.QuadPart;
+    }
+
+    /* Update lastaccess time if required */
+    if (SetLastAccess)
+    {
+        NeedUpdate = TRUE;
+        Fcb->LastAccessTime.QuadPart = CurrentTime.QuadPart;
+        FileBasicInfo.LastAccessTime.QuadPart = CurrentTime.QuadPart;
+    }
+
+    /* Update lastchange time if required */
+    if (SetLastChange)
+    {
+        NeedUpdate = TRUE;
+        Fcb->LastChangeTime.QuadPart = CurrentTime.QuadPart;
+        FileBasicInfo.ChangeTime.QuadPart = CurrentTime.QuadPart;
+    }
+
+    /* If one of the date was modified, issue a call to mini-rdr */
+    if (NeedUpdate)
+    {
+        Context->Info.FileInformationClass = FileBasicInformation;
+        Context->Info.Buffer = &FileBasicInfo;
+        Context->Info.Length = sizeof(FileBasicInfo);
+
+        MINIRDR_CALL(Status, Context, Fcb->MRxDispatch, MRxSetFileInfoAtCleanup, (Context));
+        (void)Status;
+    }
+
+    /* If the file was modified, update its EOF */
+    if (FileModified)
+    {
+        FileEOFInfo.EndOfFile.QuadPart = Fcb->Header.FileSize.QuadPart;
+
+        Context->Info.FileInformationClass = FileEndOfFileInformation;
+        Context->Info.Buffer = &FileEOFInfo;
+        Context->Info.Length = sizeof(FileEOFInfo);
+
+        MINIRDR_CALL(Status, Context, Fcb->MRxDispatch, MRxSetFileInfoAtCleanup, (Context));
+        (void)Status;
+    }
+}
+
 /*
  * @implemented
  */
@@ -715,7 +939,7 @@ RxAllocateCanonicalNameBuffer(
         return STATUS_OBJECT_PATH_INVALID;
     }
 
-    CanonicalName->Buffer = ExAllocatePoolWithTag(PagedPool | POOL_COLD_ALLOCATION, CanonicalLength, RX_MISC_POOLTAG);
+    CanonicalName->Buffer = RxAllocatePoolWithTag(PagedPool | POOL_COLD_ALLOCATION, CanonicalLength, RX_MISC_POOLTAG);
     if (CanonicalName->Buffer == NULL)
     {
         return STATUS_INSUFFICIENT_RESOURCES;
@@ -731,6 +955,179 @@ RxAllocateCanonicalNameBuffer(
     return STATUS_SUCCESS;
 }
 
+/*
+ * @implemented
+ */
+VOID
+RxCancelNotifyChangeDirectoryRequestsForFobx(
+   PFOBX Fobx)
+{
+    KIRQL OldIrql;
+    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 FOBX we're looking for, ignore */
+        if ((PFOBX)Context->pFobx != Fobx)
+        {
+            continue;
+        }
+
+        /* No cancel routine (can't be cancel, then), ignore */
+        if (Context->MRxCancelRoutine == NULL)
+        {
+            continue;
+        }
+
+        /* 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);
+
+    /* 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);
+    }
+}
+
+/*
+ * @implemented
+ */
+NTSTATUS
+RxCancelNotifyChangeDirectoryRequestsForVNetRoot(
+   PV_NET_ROOT VNetRoot,
+   BOOLEAN ForceFilesClosed)
+{
+    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
 NTAPI
 RxCancelRoutine(
@@ -761,7 +1158,7 @@ RxCanonicalizeFileNameByServerSpecs(
     }
 
     /* Validate name is correct */
-    for (NextChar = 0; CurChar + 1 < MaxChars; NextChar = CurChar + 1)
+    for (NextChar = 0, CurChar = 0; CurChar + 1 < MaxChars; NextChar = CurChar + 1)
     {
         USHORT i;
 
@@ -923,25 +1320,15 @@ RxCanonicalizeNameAndObtainNetRoot(
     return Status;
 }
 
-NTSTATUS
+VOID
 NTAPI
-RxChangeBufferingState(
-    PSRV_OPEN SrvOpen,
-    PVOID Context,
-    BOOLEAN ComputeNewState)
-{
-    UNIMPLEMENTED;
-    return STATUS_NOT_IMPLEMENTED;
-}
-
-VOID
-NTAPI
-RxCheckFcbStructuresForAlignment(
-    VOID)
+RxCheckFcbStructuresForAlignment(
+    VOID)
 {
     UNIMPLEMENTED;
 }
 
+#if DBG
 NTSTATUS
 RxCheckShareAccess(
     _In_ ACCESS_MASK DesiredAccess,
@@ -959,6 +1346,7 @@ RxCheckShareAccess(
 
     return IoCheckShareAccess(DesiredAccess, DesiredShareAccess, FileObject, ShareAccess, Update);
 }
+#endif
 
 /*
  * @implemented
@@ -1010,13 +1398,209 @@ RxCheckShareAccessPerSrvOpens(
     return STATUS_SUCCESS;
 }
 
+VOID
+RxCleanupPipeQueues(
+    PRX_CONTEXT Context)
+{
+    UNIMPLEMENTED;
+}
+
+/*
+ * @implemented
+ */
 NTSTATUS
 RxCloseAssociatedSrvOpen(
     IN PFOBX Fobx,
     IN PRX_CONTEXT RxContext OPTIONAL)
 {
-    UNIMPLEMENTED;
-    return STATUS_NOT_IMPLEMENTED;
+    PFCB Fcb;
+    NTSTATUS Status;
+    PSRV_OPEN SrvOpen;
+    BOOLEAN CloseSrvOpen;
+    PRX_CONTEXT LocalContext;
+
+    PAGED_CODE();
+
+    /* Assume SRV_OPEN is already closed */
+    CloseSrvOpen = FALSE;
+    /* If we have a FOBX, we'll have to close it */
+    if (Fobx != NULL)
+    {
+        /* If the FOBX isn't closed yet */
+        if (!BooleanFlagOn(Fobx->Flags, FOBX_FLAG_SRVOPEN_CLOSED))
+        {
+            SrvOpen = Fobx->SrvOpen;
+            Fcb = (PFCB)SrvOpen->pFcb;
+            /* Check whether we've to close SRV_OPEN first */
+            if (!BooleanFlagOn(SrvOpen->Flags, SRVOPEN_FLAG_CLOSED))
+            {
+                CloseSrvOpen = TRUE;
+            }
+            else
+            {
+                ASSERT(RxIsFcbAcquiredExclusive(Fcb));
+
+                /* Not much to do */
+                SetFlag(Fobx->Flags, FOBX_FLAG_SRVOPEN_CLOSED);
+
+                if (SrvOpen->OpenCount > 0)
+                {
+                    --SrvOpen->OpenCount;
+                }
+            }
+        }
+
+        /* No need to close SRV_OPEN, so close FOBX */
+        if (!CloseSrvOpen)
+        {
+            RxMarkFobxOnClose(Fobx);
+
+            return STATUS_SUCCESS;
+        }
+    }
+    else
+    {
+        /* No FOBX? No RX_CONTEXT, ok, job done! */
+        if (RxContext == NULL)
+        {
+            return STATUS_SUCCESS;
+        }
+
+        /* Get the FCB from RX_CONTEXT */
+        Fcb = (PFCB)RxContext->pFcb;
+        SrvOpen = NULL;
+    }
+
+    /* If we don't have RX_CONTEXT, allocte one, we'll need it */
+    if (RxContext == NULL)
+    {
+        ASSERT(Fobx != NULL);
+
+        LocalContext = RxCreateRxContext(NULL, Fcb->RxDeviceObject, RX_CONTEXT_FLAG_MUST_SUCCEED_NONBLOCKING | RX_CONTEXT_FLAG_WAIT);
+        if (LocalContext == NULL)
+        {
+            return STATUS_INSUFFICIENT_RESOURCES;
+        }
+
+        LocalContext->MajorFunction = 2;
+        LocalContext->pFcb = RX_GET_MRX_FCB(Fcb);
+        LocalContext->pFobx = (PMRX_FOBX)Fobx;
+        LocalContext->pRelevantSrvOpen = (PMRX_SRV_OPEN)Fobx->SrvOpen;
+    }
+    else
+    {
+        LocalContext = RxContext;
+    }
+
+    ASSERT(RxIsFcbAcquiredExclusive(Fcb));
+
+    /* Now, close the FOBX */
+    if (Fobx != NULL)
+    {
+        RxMarkFobxOnClose(Fobx);
+    }
+    else
+    {
+        InterlockedDecrement((volatile long *)&Fcb->OpenCount);
+    }
+
+    /* If not a "standard" file, SRV_OPEN can be null */
+    if (SrvOpen == NULL)
+    {
+        ASSERT((NodeType(Fcb) == RDBSS_NTC_OPENTARGETDIR_FCB) || (NodeType(Fcb) == RDBSS_NTC_IPC_SHARE) || (NodeType(Fcb) == RDBSS_NTC_MAILSLOT));
+        RxDereferenceNetFcb(Fcb);
+
+        if (LocalContext != RxContext)
+        {
+            RxDereferenceAndDeleteRxContext(LocalContext);
+        }
+
+        return STATUS_SUCCESS;
+    }
+
+    /* If SRV_OPEN isn't in a good condition, nothing to close */
+    if (SrvOpen->Condition != Condition_Good)
+    {
+        if (LocalContext != RxContext)
+        {
+            RxDereferenceAndDeleteRxContext(LocalContext);
+        }
+
+        return STATUS_SUCCESS;
+    }
+
+    /* Decrease open count */
+    if (SrvOpen->OpenCount > 0)
+    {
+        --SrvOpen->OpenCount;
+    }
+
+    /* If we're the only one left, is there a FOBX handled by Scavenger? */
+    if (SrvOpen->OpenCount == 1)
+    {
+        if (!IsListEmpty(&SrvOpen->FobxList))
+        {
+            if (!IsListEmpty(&CONTAINING_RECORD(SrvOpen->FobxList.Flink, FOBX, FobxQLinks)->ScavengerFinalizationList))
+            {
+                SetFlag(SrvOpen->Flags, SRVOPEN_FLAG_CLOSE_DELAYED);
+            }
+        }
+    }
+
+    /* Nothing left, purge FCB */
+    if (SrvOpen->OpenCount == 0 && RxContext == NULL)
+    {
+        RxPurgeNetFcb(Fcb, LocalContext);
+    }
+
+    /* Already closed? Job done! */
+    SrvOpen = Fobx->SrvOpen;
+    if (SrvOpen == NULL ||
+        (SrvOpen->OpenCount != 0 && !BooleanFlagOn(SrvOpen->Flags, SRVOPEN_FLAG_BUFFERING_STATE_CHANGE_PENDING)) ||
+        BooleanFlagOn(SrvOpen->Flags, SRVOPEN_FLAG_CLOSED))
+    {
+        SetFlag(Fobx->Flags, FOBX_FLAG_SRVOPEN_CLOSED);
+        if (LocalContext != RxContext)
+        {
+            RxDereferenceAndDeleteRxContext(LocalContext);
+        }
+
+        return STATUS_SUCCESS;
+    }
+
+    ASSERT(RxIsFcbAcquiredExclusive(Fcb));
+
+    /* Inform mini-rdr about closing */
+    MINIRDR_CALL(Status, LocalContext, Fcb->MRxDispatch, MRxCloseSrvOpen, (LocalContext));
+    DPRINT("MRxCloseSrvOpen returned: %lx, called with RX_CONTEXT %p for FOBX %p (FCB %p, SRV_OPEN %p)\n ",
+           Status, RxContext, Fobx, Fcb, SrvOpen);
+
+    /* And mark as such */
+    SetFlag(SrvOpen->Flags, SRVOPEN_FLAG_CLOSED);
+    SrvOpen->Key = (PVOID)-1;
+
+    /* If we were delayed, we're not! */
+    if (BooleanFlagOn(SrvOpen->Flags, SRVOPEN_FLAG_CLOSE_DELAYED))
+    {
+        InterlockedDecrement(&((PSRV_CALL)Fcb->pNetRoot->pSrvCall)->NumberOfCloseDelayedFiles);
+    }
+
+    /* Clear access */
+    RxRemoveShareAccessPerSrvOpens(SrvOpen);
+    RxPurgeChangeBufferingStateRequestsForSrvOpen(SrvOpen);
+
+    /* Dereference */
+    RxDereferenceSrvOpen(SrvOpen, LHS_ExclusiveLockHeld);
+
+    /* Mark the FOBX closed as well */
+    SetFlag(Fobx->Flags, FOBX_FLAG_SRVOPEN_CLOSED);
+
+    if (LocalContext != RxContext)
+    {
+        RxDereferenceAndDeleteRxContext(LocalContext);
+    }
+
+    return Status;
 }
 
 /*
@@ -1202,6 +1786,9 @@ RxCollapseOrCreateSrvOpen(
     return Status;
 }
 
+/*
+ * @implemented
+ */
 NTSTATUS
 NTAPI
 RxCommonCleanup(
@@ -1210,9 +1797,13 @@ RxCommonCleanup(
 #define BugCheckFileId RDBSS_BUG_CHECK_CLEANUP
     PFCB Fcb;
     PFOBX Fobx;
+    ULONG OpenCount;
     NTSTATUS Status;
-    BOOLEAN NeedPurge;
+    PNET_ROOT NetRoot;
     PFILE_OBJECT FileObject;
+    LARGE_INTEGER TruncateSize;
+    PLARGE_INTEGER TruncateSizePtr;
+    BOOLEAN NeedPurge, FcbTableAcquired, OneLeft, IsFile, FcbAcquired, LeftForDelete;
 
     PAGED_CODE();
 
@@ -1252,6 +1843,8 @@ RxCommonCleanup(
         return Status;
     }
 
+    FcbAcquired = TRUE;
+
     Fobx->AssociatedFileObject = NULL;
 
     /* In case SRV_OPEN used is part of FCB */
@@ -1278,123 +1871,405 @@ RxCommonCleanup(
         return STATUS_SUCCESS;
     }
 
-    UNIMPLEMENTED;
-    return STATUS_NOT_IMPLEMENTED;
-#undef BugCheckFileId
-}
-
-NTSTATUS
-NTAPI
-RxCommonClose(
-    PRX_CONTEXT Context)
-{
-#define BugCheckFileId RDBSS_BUG_CHECK_CLOSE
-    PFCB Fcb;
-    PFOBX Fobx;
-    NTSTATUS Status;
-    PFILE_OBJECT FileObject;
-    BOOLEAN DereferenceFobx, AcquiredFcb;
+    /* Report the fact that file could be set as delete on close */
+    if (BooleanFlagOn(Fobx->Flags, FOBX_FLAG_DELETE_ON_CLOSE))
+    {
+        SetFlag(Fcb->FcbState, FCB_STATE_DELETE_ON_CLOSE);
+    }
 
-    PAGED_CODE();
+    /* Cancel any pending notification */
+    RxCancelNotifyChangeDirectoryRequestsForFobx(Fobx);
 
-    Fcb = (PFCB)Context->pFcb;
-    Fobx = (PFOBX)Context->pFobx;
-    FileObject = Context->CurrentIrpSp->FileObject;
-    DPRINT("RxCommonClose(%p); FOBX: %p, FCB: %p, FO: %p\n", Context, Fobx, Fcb, FileObject);
+    /* Backup open count before we start playing with it */
+    OpenCount = Fcb->ShareAccess.OpenCount;
 
-    Status = RxAcquireExclusiveFcb(Context, Fcb);
-    if (!NT_SUCCESS(Status))
-    {
-        return Status;
-    }
+    NetRoot = (PNET_ROOT)Fcb->pNetRoot;
+    FcbTableAcquired = FALSE;
+    LeftForDelete = FALSE;
+    OneLeft = (Fcb->UncleanCount == 1);
 
-    AcquiredFcb = TRUE;
     _SEH2_TRY
     {
-        BOOLEAN Freed;
+        /* Unclean count and delete on close? Verify whether we're the one */
+        if (OneLeft && BooleanFlagOn(Fcb->FcbState, FCB_STATE_DELETE_ON_CLOSE))
+        {
+            if (RxAcquireFcbTableLockExclusive(&NetRoot->FcbTable, FALSE))
+            {
+                FcbTableAcquired = TRUE;
+            }
+            else
+            {
+                RxReleaseFcb(Context, Fcb);
 
-        /* Check our FCB type is expected */
-        if (NodeType(Fcb) != RDBSS_NTC_STORAGE_TYPE_UNKNOWN &&
-            (NodeType(Fcb) < RDBSS_NTC_STORAGE_TYPE_DIRECTORY || (NodeType(Fcb) > RDBSS_NTC_STORAGE_TYPE_FILE &&
-            (NodeType(Fcb) < RDBSS_NTC_SPOOLFILE || NodeType(Fcb) > RDBSS_NTC_OPENTARGETDIR_FCB))))
+                RxAcquireFcbTableLockExclusive(&NetRoot->FcbTable, TRUE);
+
+                Status = RxAcquireExclusiveFcb(Context, Fcb);
+                if (Status != STATUS_SUCCESS)
+                {
+                    RxReleaseFcbTableLock(&NetRoot->FcbTable);
+                    return Status;
+                }
+
+                FcbTableAcquired = TRUE;
+            }
+
+            /* That means we'll perform the delete on close! */
+            if (Fcb->UncleanCount == 1)
+            {
+                LeftForDelete = TRUE;
+            }
+            else
+            {
+                RxReleaseFcbTableLock(&NetRoot->FcbTable);
+                FcbTableAcquired = FALSE;
+            }
+        }
+
+        IsFile = FALSE;
+        TruncateSizePtr = NULL;
+        /* Handle cleanup for pipes and printers */
+        if (NetRoot->Type == NET_ROOT_PIPE || NetRoot->Type == NET_ROOT_PRINT)
         {
-            RxBugCheck(NodeType(Fcb), 0, 0);
+            RxCleanupPipeQueues(Context);
         }
+        /* Handle cleanup for files */
+        else if (NetRoot->Type == NET_ROOT_DISK || NetRoot->Type == NET_ROOT_WILD)
+        {
+            Context->LowIoContext.Flags |= LOWIO_CONTEXT_FLAG_SAVEUNLOCKS;
+            if (NodeType(Fcb) == RDBSS_NTC_STORAGE_TYPE_FILE)
+            {
+                /* First, unlock */
+                FsRtlFastUnlockAll(&Fcb->Specific.Fcb.FileLock, FileObject, RxGetRequestorProcess(Context), Context);
 
-        RxReferenceNetFcb(Fcb);
+                /* If there are still locks to release, proceed */
+                if (Context->LowIoContext.ParamsFor.Locks.LockList != NULL)
+                {
+                    RxInitializeLowIoContext(&Context->LowIoContext, LOWIO_OP_UNLOCK_MULTIPLE);
+                    Context->LowIoContext.ParamsFor.Locks.Flags = 0;
+                    Status = RxLowIoLockControlShell(Context);
+                }
 
-        DereferenceFobx = FALSE;
-        /* If we're not closing FS */
-        if (Fobx != NULL)
-        {
-            PSRV_OPEN SrvOpen;
-            PSRV_CALL SrvCall;
+                /* Fix times and size */
+                RxAdjustFileTimesAndSize(Context);
 
-            SrvOpen = (PSRV_OPEN)Fobx->pSrvOpen;
-            SrvCall = (PSRV_CALL)Fcb->pNetRoot->pSrvCall;
-            /* Handle delayed close */
-            if (NodeType(Fcb) != RDBSS_NTC_STORAGE_TYPE_DIRECTORY)
-            {
-                if (!BooleanFlagOn(Fcb->FcbState, FCB_STATE_DELETE_ON_CLOSE | FCB_STATE_ORPHANED))
+                /* If we're the only one left... */
+                if (OneLeft)
                 {
-                    if (BooleanFlagOn(Fcb->FcbState, FCB_STATE_COLLAPSING_ENABLED))
+                    /* And if we're supposed to delete on close */
+                    if (LeftForDelete)
                     {
-                        DPRINT("Delay close for FOBX: %p, SrvOpen %p\n", Fobx, SrvOpen);
+                        /* Update the sizes */
+                        RxAcquirePagingIoResource(Context, Fcb);
+                        Fcb->Header.FileSize.QuadPart = 0;
+                        Fcb->Header.ValidDataLength.QuadPart = 0;
+                        RxReleasePagingIoResource(Context, Fcb);
+                    }
+                    /* Otherwise, call the mini-rdr to adjust sizes */
+                    else
+                    {
+                        /* File got grown up, fill with zeroes */
+                        if (!BooleanFlagOn(Fcb->FcbState, FCB_STATE_PAGING_FILE) &&
+                            (Fcb->Header.ValidDataLength.QuadPart < Fcb->Header.FileSize.QuadPart))
+                        {
+                            MINIRDR_CALL(Status, Context, Fcb->MRxDispatch, MRxZeroExtend, (Context));
+                            Fcb->Header.ValidDataLength.QuadPart = Fcb->Header.FileSize.QuadPart;
+                        }
 
-                        if (SrvOpen->OpenCount == 1 && !BooleanFlagOn(SrvOpen->Flags, SRVOPEN_FLAG_COLLAPSING_DISABLED))
+                        /* File was truncated, let mini-rdr proceed */
+                        if (BooleanFlagOn(Fcb->FcbState, FCB_STATE_TRUNCATE_ON_CLOSE))
                         {
-                            if (InterlockedIncrement(&SrvCall->NumberOfCloseDelayedFiles) >= SrvCall->MaximumNumberOfCloseDelayedFiles)
-                            {
-                                InterlockedDecrement(&SrvCall->NumberOfCloseDelayedFiles);
-                            }
-                            else
-                            {
-                                DereferenceFobx = TRUE;
-                                SetFlag(SrvOpen->Flags, SRVOPEN_FLAG_CLOSE_DELAYED);
-                            }
+                            MINIRDR_CALL(Status, Context, Fcb->MRxDispatch, MRxTruncate, (Context));
+                            ClearFlag(Fcb->FcbState, FCB_STATE_TRUNCATE_ON_CLOSE);
+
+                            /* Keep track of file change for Cc uninit */
+                            TruncateSize.QuadPart = Fcb->Header.FileSize.QuadPart;
+                            TruncateSizePtr = &TruncateSize;
                         }
                     }
                 }
-            }
-
-            /* If we reach maximum of delayed close/or if there are no delayed close */
-            if (!DereferenceFobx)
-            {
-                PNET_ROOT NetRoot;
 
-                NetRoot = (PNET_ROOT)Fcb->pNetRoot;
-                if (NetRoot->Type != NET_ROOT_PRINT)
+                /* If RxMarkFobxOnCleanup() asked for purge, make sure we're the only one left first */
+                if (NeedPurge)
                 {
-                    /* Delete if asked */
-                    if (BooleanFlagOn(Fobx->Flags, FOBX_FLAG_DELETE_ON_CLOSE))
+                    if (!OneLeft)
                     {
-                        RxScavengeRelatedFobxs(Fcb);
-                        RxSynchronizeWithScavenger(Context);
-
-                        RxReleaseFcb(Context, Fcb);
-
-                        RxAcquireFcbTableLockExclusive(&NetRoot->FcbTable, TRUE);
-                        RxOrphanThisFcb(Fcb);
-                        RxReleaseFcbTableLock(&NetRoot->FcbTable);
-
-                        Status = RxAcquireExclusiveFcb(Context, Fcb);
-                        ASSERT(NT_SUCCESS(Status));
+                        NeedPurge = FALSE;
                     }
                 }
-            }
+                /* Otherwise, try to see whether we can purge */
+                else
+                {
+                    NeedPurge = (OneLeft && (LeftForDelete || !BooleanFlagOn(Fcb->FcbState, FCB_STATE_COLLAPSING_ENABLED)));
+                }
 
-            RxMarkFobxOnClose(Fobx);
+                IsFile = TRUE;
+            }
         }
 
-        if (DereferenceFobx)
+        /* We have to still be there! */
+        ASSERT(Fcb->UncleanCount != 0);
+        InterlockedDecrement((volatile long *)&Fcb->UncleanCount);
+
+        if (BooleanFlagOn(FileObject->Flags, FO_NO_INTERMEDIATE_BUFFERING))
         {
-            ASSERT(Fobx != NULL);
-            RxDereferenceNetFobx(Fobx, LHS_SharedLockHeld);
+            --Fcb->UncachedUncleanCount;
         }
-        else
-        {
-            RxCloseAssociatedSrvOpen(Fobx, Context);
-            if (Fobx != NULL)
+
+        /* Inform mini-rdr about ongoing cleanup */
+        MINIRDR_CALL(Status, Context, Fcb->MRxDispatch, MRxCleanupFobx, (Context));
+
+        ASSERT(Fobx->SrvOpen->UncleanFobxCount != 0);
+        --Fobx->SrvOpen->UncleanFobxCount;
+
+        /* Flush cache */
+        if (DisableFlushOnCleanup)
+        {
+            /* Only if we're the last standing */
+            if (Fcb->NonPaged->SectionObjectPointers.DataSectionObject != NULL &&
+                Fcb->UncleanCount == Fcb->UncachedUncleanCount)
+            {
+                DPRINT("Flushing %p due to last cached handle cleanup\n", Context);
+                RxFlushFcbInSystemCache(Fcb, TRUE);
+            }
+        }
+        else
+        {
+            /* Always */
+            if (Fcb->NonPaged->SectionObjectPointers.DataSectionObject != NULL)
+            {
+                DPRINT("Flushing %p on cleanup\n", Context);
+                RxFlushFcbInSystemCache(Fcb, TRUE);
+            }
+        }
+
+        /* If only remaining uncached & unclean, then flush and purge */
+        if (!BooleanFlagOn(FileObject->Flags, FO_NO_INTERMEDIATE_BUFFERING))
+        {
+            if (Fcb->UncachedUncleanCount != 0)
+            {
+                if (Fcb->UncachedUncleanCount == Fcb->UncleanCount &&
+                    Fcb->NonPaged->SectionObjectPointers.DataSectionObject != NULL)
+                {
+                    DPRINT("Flushing FCB in system cache for %p\n", Context);
+                    RxPurgeFcbInSystemCache(Fcb, NULL, 0, FALSE, TRUE);
+                }
+            }
+        }
+
+        /* If purge required, and not about to delete, flush */
+        if (!LeftForDelete && NeedPurge)
+        {
+            DPRINT("Flushing FCB in system cache for %p\n", Context);
+            RxFlushFcbInSystemCache(Fcb, TRUE);
+        }
+
+        /* If it was a file, drop cache */
+        if (IsFile)
+        {
+            DPRINT("Uninit cache map for file\n");
+            RxUninitializeCacheMap(Context, FileObject, TruncateSizePtr);
+        }
+
+        /* If that's the one left for deletion, or if it needs purge, flush */
+        if (LeftForDelete || NeedPurge)
+        {
+            RxPurgeFcbInSystemCache(Fcb, NULL, 0, FALSE, !LeftForDelete);
+            /* If that's for deletion, also remove from FCB table */
+            if (LeftForDelete)
+            {
+                RxRemoveNameNetFcb(Fcb);
+                RxReleaseFcbTableLock(&NetRoot->FcbTable);
+                FcbTableAcquired = FALSE;
+            }
+        }
+
+        /* Remove any share access */
+        if (OpenCount != 0 && NetRoot->Type == NET_ROOT_DISK)
+        {
+            RxRemoveShareAccess(FileObject, &Fcb->ShareAccess, "Cleanup the share access", "ClnUpShr");
+        }
+
+        /* In case there's caching, on a file, and we were asked to drop collapsing, handle it */
+        if (NodeType(Fcb) == RDBSS_NTC_STORAGE_TYPE_FILE && BooleanFlagOn(Fobx->Flags, FOBX_FLAG_DISABLE_COLLAPSING) &&
+            RxWriteCacheingAllowed(Fcb, Fobx->pSrvOpen))
+        {
+            NTSTATUS InternalStatus;
+            PRX_CONTEXT InternalContext;
+
+            /* If we can properly set EOF, there's no need to drop collapsing, try to do it */
+            InternalStatus = STATUS_UNSUCCESSFUL;
+            InternalContext = RxCreateRxContext(Context->CurrentIrp,
+                                                Fcb->RxDeviceObject,
+                                                RX_CONTEXT_FLAG_WAIT | RX_CONTEXT_FLAG_MUST_SUCCEED_NONBLOCKING);
+            if (InternalContext != NULL)
+            {
+                FILE_END_OF_FILE_INFORMATION FileEOF;
+
+                InternalStatus = STATUS_SUCCESS;
+
+                /* Initialize the context for file information set */
+                InternalContext->pFcb = RX_GET_MRX_FCB(Fcb);
+                InternalContext->pFobx = (PMRX_FOBX)Fobx;
+                InternalContext->pRelevantSrvOpen = Fobx->pSrvOpen;
+
+                /* Get EOF from the FCB */
+                FileEOF.EndOfFile.QuadPart = Fcb->Header.FileSize.QuadPart;
+                InternalContext->Info.FileInformationClass = FileEndOfFileInformation;
+                InternalContext->Info.Buffer = &FileEOF;
+                InternalContext->Info.Length = sizeof(FileEOF);
+
+                /* Call the mini-rdr */
+                MINIRDR_CALL_THROUGH(InternalStatus, Fcb->MRxDispatch, MRxSetFileInfo, (InternalContext));
+
+                /* We're done */
+                RxDereferenceAndDeleteRxContext(InternalContext);
+            }
+
+            /* We tried, so, clean the FOBX flag */
+            ClearFlag(Fobx->Flags, FOBX_FLAG_DISABLE_COLLAPSING);
+            /* If it failed, then, disable collapsing on the FCB */
+            if (!NT_SUCCESS(InternalStatus))
+            {
+                ClearFlag(Fcb->FcbState, FCB_STATE_COLLAPSING_ENABLED);
+            }
+        }
+
+        /* We're clean! */
+        SetFlag(FileObject->Flags, FO_CLEANUP_COMPLETE);
+
+        FcbAcquired = FALSE;
+        RxReleaseFcb(Context, Fcb);
+    }
+    _SEH2_FINALLY
+    {
+        if (FcbAcquired)
+        {
+            RxReleaseFcb(Context, Fcb);
+        }
+
+        if (FcbTableAcquired)
+        {
+            RxReleaseFcbTableLock(&NetRoot->FcbTable);
+        }
+    }
+    _SEH2_END;
+
+    return Status;
+#undef BugCheckFileId
+}
+
+NTSTATUS
+NTAPI
+RxCommonClose(
+    PRX_CONTEXT Context)
+{
+#define BugCheckFileId RDBSS_BUG_CHECK_CLOSE
+    PFCB Fcb;
+    PFOBX Fobx;
+    NTSTATUS Status;
+    PFILE_OBJECT FileObject;
+    BOOLEAN DereferenceFobx, AcquiredFcb;
+
+    PAGED_CODE();
+
+    Fcb = (PFCB)Context->pFcb;
+    Fobx = (PFOBX)Context->pFobx;
+    FileObject = Context->CurrentIrpSp->FileObject;
+    DPRINT("RxCommonClose(%p); FOBX: %p, FCB: %p, FO: %p\n", Context, Fobx, Fcb, FileObject);
+
+    Status = RxAcquireExclusiveFcb(Context, Fcb);
+    if (!NT_SUCCESS(Status))
+    {
+        return Status;
+    }
+
+    AcquiredFcb = TRUE;
+    _SEH2_TRY
+    {
+        BOOLEAN Freed;
+
+        /* Check our FCB type is expected */
+        if (NodeType(Fcb) != RDBSS_NTC_STORAGE_TYPE_UNKNOWN &&
+            (NodeType(Fcb) < RDBSS_NTC_STORAGE_TYPE_DIRECTORY || (NodeType(Fcb) > RDBSS_NTC_STORAGE_TYPE_FILE &&
+            (NodeType(Fcb) < RDBSS_NTC_SPOOLFILE || NodeType(Fcb) > RDBSS_NTC_OPENTARGETDIR_FCB))))
+        {
+            RxBugCheck(NodeType(Fcb), 0, 0);
+        }
+
+        RxReferenceNetFcb(Fcb);
+
+        DereferenceFobx = FALSE;
+        /* If we're not closing FS */
+        if (Fobx != NULL)
+        {
+            PSRV_OPEN SrvOpen;
+            PSRV_CALL SrvCall;
+
+            SrvOpen = (PSRV_OPEN)Fobx->pSrvOpen;
+            SrvCall = (PSRV_CALL)Fcb->pNetRoot->pSrvCall;
+            /* Handle delayed close */
+            if (NodeType(Fcb) != RDBSS_NTC_STORAGE_TYPE_DIRECTORY)
+            {
+                if (!BooleanFlagOn(Fcb->FcbState, FCB_STATE_DELETE_ON_CLOSE | FCB_STATE_ORPHANED))
+                {
+                    if (BooleanFlagOn(Fcb->FcbState, FCB_STATE_COLLAPSING_ENABLED))
+                    {
+                        DPRINT("Delay close for FOBX: %p, SrvOpen %p\n", Fobx, SrvOpen);
+
+                        if (SrvOpen->OpenCount == 1 && !BooleanFlagOn(SrvOpen->Flags, SRVOPEN_FLAG_COLLAPSING_DISABLED))
+                        {
+                            if (InterlockedIncrement(&SrvCall->NumberOfCloseDelayedFiles) >= SrvCall->MaximumNumberOfCloseDelayedFiles)
+                            {
+                                InterlockedDecrement(&SrvCall->NumberOfCloseDelayedFiles);
+                            }
+                            else
+                            {
+                                DereferenceFobx = TRUE;
+                                SetFlag(SrvOpen->Flags, SRVOPEN_FLAG_CLOSE_DELAYED);
+                            }
+                        }
+                    }
+                }
+            }
+
+            /* If we reach maximum of delayed close/or if there are no delayed close */
+            if (!DereferenceFobx)
+            {
+                PNET_ROOT NetRoot;
+
+                NetRoot = (PNET_ROOT)Fcb->pNetRoot;
+                if (NetRoot->Type != NET_ROOT_PRINT)
+                {
+                    /* Delete if asked */
+                    if (BooleanFlagOn(Fobx->Flags, FOBX_FLAG_DELETE_ON_CLOSE))
+                    {
+                        RxScavengeRelatedFobxs(Fcb);
+                        RxSynchronizeWithScavenger(Context);
+
+                        RxReleaseFcb(Context, Fcb);
+
+                        RxAcquireFcbTableLockExclusive(&NetRoot->FcbTable, TRUE);
+                        RxOrphanThisFcb(Fcb);
+                        RxReleaseFcbTableLock(&NetRoot->FcbTable);
+
+                        Status = RxAcquireExclusiveFcb(Context, Fcb);
+                        ASSERT(NT_SUCCESS(Status));
+                    }
+                }
+            }
+
+            RxMarkFobxOnClose(Fobx);
+        }
+
+        if (DereferenceFobx)
+        {
+            ASSERT(Fobx != NULL);
+            RxDereferenceNetFobx(Fobx, LHS_SharedLockHeld);
+        }
+        else
+        {
+            RxCloseAssociatedSrvOpen(Fobx, Context);
+            if (Fobx != NULL)
             {
                 RxDereferenceNetFobx(Fobx, LHS_ExclusiveLockHeld);
             }
@@ -1436,6 +2311,9 @@ RxCommonClose(
 #undef BugCheckFileId
 }
 
+/*
+ * @implemented
+ */
 NTSTATUS
 NTAPI
 RxCommonCreate(
@@ -1558,7 +2436,65 @@ RxCommonCreate(
                 Status = RxCreateFromNetRoot(Context, &NetRootName);
                 if (Status == STATUS_SHARING_VIOLATION)
                 {
-                    UNIMPLEMENTED;
+                    ASSERT(!BooleanFlagOn(Context->Create.Flags, RX_CONTEXT_CREATE_FLAG_REPARSE));
+
+                    /* If that happens for file creation, fail for real */
+                    if (Context->Create.NtCreateParameters.Disposition == FILE_CREATE)
+                    {
+                        Status = STATUS_OBJECT_NAME_COLLISION;
+                    }
+                    else
+                    {
+                        /* Otherwise, if possible, attempt to scavenger current FOBX
+                         * to check whether a dormant FOBX is the reason for sharing violation
+                         */
+                        if (Context->Create.TryForScavengingOnSharingViolation &&
+                            !Context->Create.ScavengingAlreadyTried)
+                        {
+                            /* Only doable with a VNetRoot */
+                            if (Context->Create.pVNetRoot != NULL)
+                            {
+                                PV_NET_ROOT VNetRoot;
+                                NT_CREATE_PARAMETERS SavedParameters;
+
+                                /* Save create parameters */
+                                RtlCopyMemory(&SavedParameters, &Context->Create.NtCreateParameters, sizeof(NT_CREATE_PARAMETERS));
+
+                                /* Reference the VNetRoot for the scavenging time */
+                                VNetRoot = (PV_NET_ROOT)Context->Create.pVNetRoot;
+                                RxReferenceVNetRoot(VNetRoot);
+
+                                /* Prepare the RX_CONTEXT for reuse */
+                                RxpPrepareCreateContextForReuse(Context);
+                                RxReinitializeContext(Context);
+
+                                /* Copy what we saved */
+                                RtlCopyMemory(&Context->Create.NtCreateParameters, &SavedParameters, sizeof(NT_CREATE_PARAMETERS));
+
+                                /* And recopy what can be */
+                                RxCopyCreateParameters(Context);
+
+                                /* And start purging, then scavenging FOBX */
+                                RxPurgeRelatedFobxs((PNET_ROOT)VNetRoot->pNetRoot, Context,
+                                                    DONT_ATTEMPT_FINALIZE_ON_PURGE, NULL);
+                                RxScavengeFobxsForNetRoot((PNET_ROOT)VNetRoot->pNetRoot,
+                                                          NULL, TRUE);
+
+                                /* Ask for a second round */
+                                Status = STATUS_MORE_PROCESSING_REQUIRED;
+
+                                /* Keep track we already scavenged */
+                                Context->Create.ScavengingAlreadyTried = TRUE;
+
+                                /* Reference our SRV_CALL for CBS handling */
+                                RxReferenceSrvCall(VNetRoot->pNetRoot->pSrvCall);
+                                RxpProcessChangeBufferingStateRequests((PSRV_CALL)VNetRoot->pNetRoot->pSrvCall, FALSE);
+
+                                /* Drop our extra reference */
+                                RxDereferenceVNetRoot(VNetRoot, LHS_LockNotHeld);
+                            }
+                        }
+                    }
                 }
                 else if (Status == STATUS_REPARSE)
                 {
@@ -1644,7 +2580,7 @@ RxCommonDevFCBClose(
     /* Our FOBX if set, has to be a VNetRoot */
     if (NetRoot != NULL)
     {
-        RxAcquirePrefixTableLockShared(Context->RxDeviceObject->pRxNetNameTable, TRUE);
+        RxAcquirePrefixTableLockExclusive(Context->RxDeviceObject->pRxNetNameTable, TRUE);
         if (NetRoot->NodeTypeCode == RDBSS_NTC_V_NETROOT)
         {
             --NetRoot->NumberOfOpens;
@@ -1806,6 +2742,18 @@ NTAPI
 RxCommonFileSystemControl(
     PRX_CONTEXT Context)
 {
+    PIRP Irp;
+    ULONG ControlCode;
+    PIO_STACK_LOCATION Stack;
+
+    PAGED_CODE();
+
+    Irp = Context->CurrentIrp;
+    Stack = Context->CurrentIrpSp;
+    ControlCode = Stack->Parameters.FileSystemControl.FsControlCode;
+
+    DPRINT1("RxCommonFileSystemControl: %p, %p, %d, %lx\n", Context, Irp, Stack->MinorFunction, ControlCode);
+
     UNIMPLEMENTED;
     return STATUS_NOT_IMPLEMENTED;
 }
@@ -2242,6 +3190,7 @@ RxCommonRead(
 
             if (!NT_SUCCESS(Irp->IoStatus.Status))
             {
+                Status = Irp->IoStatus.Status;
                 _SEH2_LEAVE;
             }
 
@@ -2433,113 +3382,1325 @@ RxCommonRead(
                 ClearFlag(Fcb->FcbState, FCB_STATE_READAHEAD_DEFERRED);
             }
 
-            /* If it's consistent, forward to mini-rdr */
-            if (Fcb->CachedNetRootType != NET_ROOT_DISK || BooleanFlagOn(Fcb->FcbState, FCB_STATE_READAHEAD_DEFERRED) ||
-                ByteOffset.QuadPart < Fcb->Header.ValidDataLength.QuadPart)
+            /* If it's consistent, forward to mini-rdr */
+            if (Fcb->CachedNetRootType != NET_ROOT_DISK || BooleanFlagOn(Fcb->FcbState, FCB_STATE_READAHEAD_DEFERRED) ||
+                ByteOffset.QuadPart < Fcb->Header.ValidDataLength.QuadPart)
+            {
+                LowIoContext->ParamsFor.ReadWrite.ByteCount = ReadLength;
+                LowIoContext->ParamsFor.ReadWrite.ByteOffset = ByteOffset.QuadPart;
+
+                RxItsTheSameContext();
+
+                if (InFsp && ReadCachingDisabled)
+                {
+                    ExSetResourceOwnerPointer((PagingIo ? Fcb->Header.PagingIoResource : Fcb->Header.Resource),
+                                              (PVOID)((ULONG_PTR)RxContext | 3));
+                    OwnerSet = TRUE;
+                }
+
+                Status = RxLowIoReadShell(RxContext);
+
+                RxItsTheSameContext();
+            }
+            else
+            {
+                if (ByteOffset.QuadPart > FileSize)
+                {
+                    ReadLength = 0;
+                    Irp->IoStatus.Information = ReadLength;
+                    _SEH2_LEAVE;
+                }
+
+                if (ByteOffset.QuadPart + ReadLength > FileSize)
+                {
+                    ReadLength = FileSize - ByteOffset.QuadPart;
+                }
+
+                SystemBuffer = RxNewMapUserBuffer(RxContext);
+                RtlZeroMemory(SystemBuffer, ReadLength);
+                Irp->IoStatus.Information = ReadLength;
+            }
+        }
+    }
+    _SEH2_FINALLY
+    {
+        RxItsTheSameContext();
+
+        /* Post if required */
+        if (PostRequest)
+        {
+            InterlockedIncrement((volatile long *)&RxContext->ReferenceCount);
+            Status = RxFsdPostRequest(RxContext);
+        }
+        else
+        {
+            /* Update FO in case of sync IO */
+            if (!IsPipe && !PagingIo)
+            {
+                if (BooleanFlagOn(FileObject->Flags, FO_SYNCHRONOUS_IO))
+                {
+                    FileObject->CurrentByteOffset.QuadPart = ByteOffset.QuadPart + Irp->IoStatus.Information;
+                }
+            }
+        }
+
+        /* Set FastIo if read was a success */
+        if (NT_SUCCESS(Status) && Status != STATUS_PENDING)
+        {
+            if (!IsPipe && !PagingIo)
+            {
+                SetFlag(FileObject->Flags, FO_FILE_FAST_IO_READ);
+            }
+        }
+
+        /* In case we're done (not expected any further processing */
+        if (_SEH2_AbnormalTermination() || Status != STATUS_PENDING || PostRequest)
+        {
+            /* Release everything that can be */
+            if (ReadCachingDisabled)
+            {
+                if (PagingIo)
+                {
+                    if (OwnerSet)
+                    {
+                        RxReleasePagingIoResourceForThread(RxContext, Fcb, LowIoContext->ResourceThreadId);
+                    }
+                    else
+                    {
+                        RxReleasePagingIoResource(RxContext, Fcb);
+                    }
+                }
+                else
+                {
+                    if (OwnerSet)
+                    {
+                        RxReleaseFcbForThread(RxContext, Fcb, LowIoContext->ResourceThreadId);
+                    }
+                    else
+                    {
+                        RxReleaseFcb(RxContext, Fcb);
+                    }
+                }
+            }
+
+            /* Dereference/Delete context */
+            if (PostRequest)
+            {
+                RxDereferenceAndDeleteRxContext(RxContext);
+            }
+            else
+            {
+                if (BooleanFlagOn(RxContext->FlagsForLowIo, RXCONTEXT_FLAG4LOWIO_PIPE_SYNC_OPERATION))
+                {
+                    RxResumeBlockedOperations_Serially(RxContext, &Fobx->Specific.NamedPipe.ReadSerializationQueue);
+                }
+            }
+
+            /* We cannot return more than asked */
+            if (Status == STATUS_SUCCESS)
+            {
+                ASSERT(Irp->IoStatus.Information <= Stack->Parameters.Read.Length);
+            }
+        }
+        else
+        {
+            ASSERT(!Sync);
+
+            RxDereferenceAndDeleteRxContext(RxContext);
+        }
+    }
+    _SEH2_END;
+
+    return Status;
+}
+
+NTSTATUS
+NTAPI
+RxCommonSetEa(
+    PRX_CONTEXT Context)
+{
+    UNIMPLEMENTED;
+    return STATUS_NOT_IMPLEMENTED;
+}
+
+/*
+ * @implemented
+ */
+NTSTATUS
+NTAPI
+RxCommonSetInformation(
+    PRX_CONTEXT Context)
+{
+    PIRP Irp;
+    PFCB Fcb;
+    PFOBX Fobx;
+    NTSTATUS Status;
+    PNET_ROOT NetRoot;
+    PIO_STACK_LOCATION Stack;
+    FILE_INFORMATION_CLASS Class;
+    BOOLEAN CanWait, FcbTableAcquired, FcbAcquired;
+
+    PAGED_CODE();
+
+    Fcb = (PFCB)Context->pFcb;
+    Fobx = (PFOBX)Context->pFobx;
+    DPRINT("RxCommonSetInformation(%p), FCB: %p, FOBX: %p\n", Context, Fcb, Fobx);
+
+    Irp = Context->CurrentIrp;
+    Stack = Context->CurrentIrpSp;
+    Class = Stack->Parameters.SetFile.FileInformationClass;
+    DPRINT("Buffer: %p, Length: %lx, Class: %ld, ReplaceIfExists: %d\n",
+           Irp->AssociatedIrp.SystemBuffer, Stack->Parameters.SetFile.Length,
+           Class, Stack->Parameters.SetFile.ReplaceIfExists);
+
+    Status = STATUS_SUCCESS;
+    CanWait = BooleanFlagOn(Context->Flags, RX_CONTEXT_FLAG_WAIT);
+    FcbTableAcquired = FALSE;
+    FcbAcquired = FALSE;
+    NetRoot = (PNET_ROOT)Fcb->pNetRoot;
+
+#define _SEH2_TRY_RETURN(S) S; goto try_exit
+
+    _SEH2_TRY
+    {
+        /* Valide the node type first */
+        if (NodeType(Fcb) != RDBSS_NTC_STORAGE_TYPE_UNKNOWN &&
+            NodeType(Fcb) != RDBSS_NTC_STORAGE_TYPE_DIRECTORY)
+        {
+            if (NodeType(Fcb) == RDBSS_NTC_STORAGE_TYPE_FILE)
+            {
+                if (!BooleanFlagOn(Fcb->FcbState, FCB_STATE_PAGING_FILE))
+                {
+                    Status = STATUS_SUCCESS;
+                }
+            }
+            else if (NodeType(Fcb) != RDBSS_NTC_SPOOLFILE)
+            {
+                if (NodeType(Fcb) == RDBSS_NTC_MAILSLOT)
+                {
+                    _SEH2_TRY_RETURN(Status = STATUS_NOT_IMPLEMENTED);
+                }
+                else
+                {
+                    DPRINT1("Illegal type of file provided: %x\n", NodeType(Fcb));
+                    _SEH2_TRY_RETURN(Status = STATUS_INVALID_PARAMETER);
+                }
+            }
+        }
+
+        /* We don't autorize advance operation */
+        if (Class == FileEndOfFileInformation && Stack->Parameters.SetFile.AdvanceOnly)
+        {
+            DPRINT1("Not allowed\n");
+
+            _SEH2_TRY_RETURN(Status = STATUS_SUCCESS);
+        }
+
+        /* For these to classes, we'll have to deal with the FCB table (removal)
+         * We thus need the exclusive FCB table lock
+         */
+        if (Class == FileDispositionInformation || Class == FileRenameInformation)
+        {
+            RxPurgeRelatedFobxs(NetRoot, Context, TRUE, Fcb);
+            RxScavengeFobxsForNetRoot(NetRoot, Fcb, TRUE);
+
+            if (!RxAcquireFcbTableLockExclusive(&NetRoot->FcbTable, CanWait))
+            {
+                Context->PostRequest = TRUE;
+                _SEH2_TRY_RETURN(Status = STATUS_PENDING);
+            }
+
+            FcbTableAcquired = TRUE;
+        }
+
+        /* Finally, if not paging file, we need exclusive FCB lock */
+        if (!BooleanFlagOn(Fcb->FcbState, FCB_STATE_PAGING_FILE))
+        {
+            Status = RxAcquireExclusiveFcb(Context, Fcb);
+            if (Status == STATUS_LOCK_NOT_GRANTED)
+            {
+                Context->PostRequest = TRUE;
+                _SEH2_TRY_RETURN(Status = STATUS_SUCCESS);
+            }
+            else if (Status != STATUS_SUCCESS)
+            {
+                _SEH2_LEAVE;
+            }
+
+            FcbAcquired = TRUE;
+        }
+
+        Status = STATUS_SUCCESS;
+
+        /* And now, perform the job! */
+        switch (Class)
+        {
+            case FileBasicInformation:
+                Status = RxSetBasicInfo(Context);
+                break;
+
+            case FileDispositionInformation:
+            {
+                PFILE_DISPOSITION_INFORMATION FDI;
+
+                /* Check whether user wants deletion */
+                FDI = Irp->AssociatedIrp.SystemBuffer;
+                if (FDI->DeleteFile)
+                {
+                    /* If so, check whether it's doable */
+                    if (!MmFlushImageSection(&Fcb->NonPaged->SectionObjectPointers, MmFlushForDelete))
+                    {
+                        Status = STATUS_CANNOT_DELETE;
+                    }
+
+                    /* And if doable, already remove from FCB table */
+                    if (Status == STATUS_SUCCESS)
+                    {
+                        ASSERT(FcbAcquired && FcbTableAcquired);
+                        RxRemoveNameNetFcb(Fcb);
+
+                        RxReleaseFcbTableLock(&NetRoot->FcbTable);
+                        FcbTableAcquired = FALSE;
+                    }
+                }
+
+                /* If it succeed, perform the operation */
+                if (Status == STATUS_SUCCESS)
+                {
+                    Status = RxSetDispositionInfo(Context);
+                }
+
+                break;
+            }
+
+            case FilePositionInformation:
+                Status = RxSetPositionInfo(Context);
+                break;
+
+            case FileAllocationInformation:
+                Status = RxSetAllocationInfo(Context);
+                break;
+
+            case FileEndOfFileInformation:
+                Status = RxSetEndOfFileInfo(Context);
+                break;
+
+            case FilePipeInformation:
+            case FilePipeLocalInformation:
+            case FilePipeRemoteInformation:
+                Status = RxSetPipeInfo(Context);
+                break;
+
+            case FileRenameInformation:
+            case FileLinkInformation:
+            case FileMoveClusterInformation:
+                /* If we can wait, try to perform the operation right now */
+                if (CanWait)
+                {
+                    /* Of course, collapsing is not doable anymore, file is
+                     * in an inbetween state
+                     */
+                    ClearFlag(Fcb->FcbState, FCB_STATE_COLLAPSING_ENABLED);
+
+                    /* Set the information */
+                    Status = RxSetRenameInfo(Context);
+                    /* If it succeed, drop the current entry from FCB table */
+                    if (Status == STATUS_SUCCESS && Class == FileRenameInformation)
+                    {
+                        ASSERT(FcbAcquired && FcbTableAcquired);
+                        RxRemoveNameNetFcb(Fcb);
+                    }
+                    _SEH2_TRY_RETURN(Status);
+                }
+                /* Can't wait? Post for async retry */
+                else
+                {
+                    Status = RxFsdPostRequest(Context);
+                    _SEH2_TRY_RETURN(Status);
+                }
+                break;
+
+            case FileValidDataLengthInformation:
+                if (!MmCanFileBeTruncated(&Fcb->NonPaged->SectionObjectPointers, NULL))
+                {
+                    Status = STATUS_USER_MAPPED_FILE;
+                }
+                break;
+
+            case FileShortNameInformation:
+                Status = RxSetSimpleInfo(Context);
+                break;
+
+            default:
+                DPRINT1("Insupported class: %x\n", Class);
+                Status = STATUS_INVALID_PARAMETER;
+
+                break;
+        }
+
+try_exit: NOTHING;
+        /* If mini-rdr was OK and wants a re-post on this, do it */
+        if (Status == STATUS_SUCCESS)
+        {
+            if (Context->PostRequest)
+            {
+                Status = RxFsdPostRequest(Context);
+            }
+        }
+    }
+    _SEH2_FINALLY
+    {
+        /* Release any acquired lock */
+        if (FcbAcquired)
+        {
+            RxReleaseFcb(Context, Fcb);
+        }
+
+        if (FcbTableAcquired)
+        {
+            RxReleaseFcbTableLock(&NetRoot->FcbTable);
+        }
+    }
+    _SEH2_END;
+
+#undef _SEH2_TRY_RETURN
+
+    return Status;
+}
+
+NTSTATUS
+NTAPI
+RxCommonSetQuotaInformation(
+    PRX_CONTEXT Context)
+{
+    UNIMPLEMENTED;
+    return STATUS_NOT_IMPLEMENTED;
+}
+
+NTSTATUS
+NTAPI
+RxCommonSetSecurity(
+    PRX_CONTEXT Context)
+{
+    UNIMPLEMENTED;
+    return STATUS_NOT_IMPLEMENTED;
+}
+
+NTSTATUS
+NTAPI
+RxCommonSetVolumeInformation(
+    PRX_CONTEXT Context)
+{
+    UNIMPLEMENTED;
+    return STATUS_NOT_IMPLEMENTED;
+}
+
+NTSTATUS
+NTAPI
+RxCommonUnimplemented(
+    PRX_CONTEXT Context)
+{
+    UNIMPLEMENTED;
+    return STATUS_NOT_IMPLEMENTED;
+}
+
+NTSTATUS
+NTAPI
+RxCommonWrite(
+    PRX_CONTEXT RxContext)
+{
+    PIRP Irp;
+    PFCB Fcb;
+    PFOBX Fobx;
+    NTSTATUS Status;
+    PNET_ROOT NetRoot;
+    PSRV_OPEN SrvOpen;
+    PFILE_OBJECT FileObject;
+    PIO_STACK_LOCATION Stack;
+    LARGE_INTEGER ByteOffset;
+    NODE_TYPE_CODE NodeTypeCode;
+    PLOWIO_CONTEXT LowIoContext;
+    PRDBSS_DEVICE_OBJECT RxDeviceObject;
+    ULONG WriteLength, CapturedRxContextSerialNumber = RxContext->SerialNumber;
+    LONGLONG FileSize, ValidDataLength, InitialFileSize, InitialValidDataLength;
+    BOOLEAN CanWait, PagingIo, NoCache, Sync, NormalFile, WriteToEof, IsPipe, NoPreposting, InFsp, RecursiveWriteThrough, CalledByLazyWriter, SwitchBackToAsync, ExtendingFile, ExtendingValidData, UnwindOutstandingAsync, ResourceOwnerSet, PostIrp, ContextReferenced;
+
+    PAGED_CODE();
+
+    Fcb = (PFCB)RxContext->pFcb;
+    NodeTypeCode = NodeType(Fcb);
+    /* Validate FCB type */
+    if (NodeTypeCode != RDBSS_NTC_STORAGE_TYPE_FILE && NodeTypeCode != RDBSS_NTC_VOLUME_FCB &&
+        NodeTypeCode != RDBSS_NTC_SPOOLFILE && NodeTypeCode != RDBSS_NTC_MAILSLOT)
+    {
+        return STATUS_INVALID_DEVICE_REQUEST;
+    }
+
+    /* We'll write to file, keep track of it */
+    Fcb->IsFileWritten = TRUE;
+
+    Stack = RxContext->CurrentIrpSp;
+    /* Set write through if asked */
+    if (BooleanFlagOn(Stack->Flags, SL_WRITE_THROUGH))
+    {
+        SetFlag(RxContext->Flags, RX_CONTEXT_FLAG_WRITE_THROUGH);
+    }
+
+    Fobx = (PFOBX)RxContext->pFobx;
+    DPRINT("RxCommonWrite(%p) FOBX: %p, FCB: %p\n", RxContext, Fobx, Fcb);
+
+    /* Get some parameters */
+    Irp = RxContext->CurrentIrp;
+    NoPreposting = BooleanFlagOn(RxContext->Flags, RX_CONTEXT_FLAG_NO_PREPOSTING_NEEDED);
+    InFsp = BooleanFlagOn(RxContext->Flags, RX_CONTEXT_FLAG_IN_FSP);
+    CanWait = BooleanFlagOn(RxContext->Flags, RX_CONTEXT_FLAG_WAIT);
+    PagingIo = BooleanFlagOn(Irp->Flags, IRP_PAGING_IO);
+    NoCache = BooleanFlagOn(Irp->Flags, IRP_NOCACHE);
+    Sync = !BooleanFlagOn(RxContext->Flags, RX_CONTEXT_FLAG_ASYNC_OPERATION);
+    WriteLength = Stack->Parameters.Write.Length;
+    ByteOffset.QuadPart = Stack->Parameters.Write.ByteOffset.QuadPart;
+    DPRINT("Writing: %lx@%I64x %s %s %s %s\n", WriteLength, ByteOffset.QuadPart,
+           (CanWait ? "CW" : "!CW"), (PagingIo ? "PI" : "!PI"), (NoCache ? "NC" : "!NC"), (Sync ? "S" : "!S"));
+
+    RxItsTheSameContext();
+
+    RxContext->FcbResourceAcquired = FALSE;
+    RxContext->FcbPagingIoResourceAcquired = FALSE;
+
+    LowIoContext = &RxContext->LowIoContext;
+    CheckForLoudOperations(RxContext);
+    if (BooleanFlagOn(LowIoContext->Flags, LOWIO_CONTEXT_FLAG_LOUDOPS))
+    {
+        DPRINT("LoudWrite %I64x/%lx on %lx vdl/size/alloc %I64x/%I64x/%I64x\n",
+                ByteOffset, WriteLength,
+                Fcb, Fcb->Header.ValidDataLength, Fcb->Header.FileSize, Fcb->Header.AllocationSize);
+    }
+
+    RxDeviceObject = RxContext->RxDeviceObject;
+    /* Update stats */
+    if (!BooleanFlagOn(RxContext->Flags, RX_CONTEXT_FLAG_IN_FSP) && Fcb->CachedNetRootType == NET_ROOT_DISK)
+    {
+        InterlockedIncrement((volatile long *)&RxDeviceObject->WriteOperations);
+
+        if (ByteOffset.QuadPart != Fobx->Specific.DiskFile.PredictedWriteOffset)
+        {
+            InterlockedIncrement((volatile long *)&RxDeviceObject->RandomWriteOperations);
+        }
+        Fobx->Specific.DiskFile.PredictedWriteOffset = ByteOffset.QuadPart + WriteLength;
+
+        if (PagingIo)
+        {
+            ExInterlockedAddLargeStatistic(&RxDeviceObject->PagingWriteBytesRequested, WriteLength);
+        }
+        else if (NoCache)
+        {
+            ExInterlockedAddLargeStatistic(&RxDeviceObject->NonPagingWriteBytesRequested, WriteLength);
+        }
+        else
+        {
+            ExInterlockedAddLargeStatistic(&RxDeviceObject->CacheWriteBytesRequested, WriteLength);
+        }
+    }
+
+    NetRoot = (PNET_ROOT)Fcb->NetRoot;
+    IsPipe = (NetRoot->Type == NET_ROOT_PIPE);
+    /* Keep track for normal writes */
+    if (NetRoot->Type == NET_ROOT_DISK || NetRoot->Type == NET_ROOT_WILD)
+    {
+        NormalFile = TRUE;
+    }
+    else
+    {
+        NormalFile = FALSE;
+    }
+
+    /* Zero-length write is immediate success */
+    if (NormalFile && WriteLength == 0)
+    {
+        return STATUS_SUCCESS;
+    }
+
+    /* Check whether we have input data */
+    if (Irp->UserBuffer == NULL && Irp->MdlAddress == NULL)
+    {
+        return STATUS_INVALID_PARAMETER;
+    }
+
+    /* Are we writting to EOF? */
+    WriteToEof = ((ByteOffset.LowPart == FILE_WRITE_TO_END_OF_FILE) && (ByteOffset.HighPart == -1));
+    /* FIXME: validate length/offset */
+
+    /* Get our SRV_OPEN in case of normal write */
+    if (Fobx != NULL)
+    {
+        SrvOpen = (PSRV_OPEN)Fobx->pSrvOpen;
+    }
+    else
+    {
+        SrvOpen = NULL;
+    }
+
+    FileObject = Stack->FileObject;
+
+    /* If we have caching enabled, check whether we have to defer write */
+    if (!NoCache)
+    {
+        if (RxWriteCacheingAllowed(Fcb, SrvOpen))
+        {
+            if (!CcCanIWrite(FileObject, WriteLength,
+                             (CanWait && !BooleanFlagOn(RxContext->Flags, RX_CONTEXT_FLAG_IN_FSP)),
+                             BooleanFlagOn(RxContext->Flags, RX_CONTEXT_FLAG_DEFERRED_WRITE)))
+            {
+                BOOLEAN Retrying;
+
+                Retrying = BooleanFlagOn(RxContext->Flags, RX_CONTEXT_FLAG_DEFERRED_WRITE);
+
+                RxPrePostIrp(RxContext, Irp);
+
+                SetFlag(RxContext->Flags, RX_CONTEXT_FLAG_DEFERRED_WRITE);
+
+                CcDeferWrite(FileObject, (PCC_POST_DEFERRED_WRITE)RxAddToWorkque, RxContext, Irp, WriteLength, Retrying);
+
+                return STATUS_PENDING;
+            }
+        }
+    }
+
+    /* Initialize the low IO context for write */
+    RxInitializeLowIoContext(LowIoContext, LOWIO_OP_WRITE);
+
+    /* Initialize our (many) booleans */
+    RecursiveWriteThrough = FALSE;
+    CalledByLazyWriter = FALSE;
+    SwitchBackToAsync = FALSE;
+    ExtendingFile = FALSE;
+    ExtendingValidData = FALSE;
+    UnwindOutstandingAsync = FALSE;
+    ResourceOwnerSet = FALSE;
+    PostIrp = FALSE;
+    ContextReferenced = FALSE;
+
+#define _SEH2_TRY_RETURN(S) S; goto try_exit
+
+    _SEH2_TRY
+    {
+        /* No volume FCB here! */
+        ASSERT((NodeTypeCode == RDBSS_NTC_STORAGE_TYPE_FILE) ||
+               (NodeTypeCode == RDBSS_NTC_SPOOLFILE) ||
+               (NodeTypeCode == RDBSS_NTC_MAILSLOT));
+
+        /* Writing to EOF on a paging file is non sense */
+        ASSERT(!(WriteToEof && PagingIo));
+
+        RxItsTheSameContext();
+
+        /* Start locking stuff */
+        if (!PagingIo && !NoPreposting)
+        {
+            /* If it's already acquired, all fine */
+            if (RxContext->FcbResourceAcquired)
+            {
+                ASSERT(!IsPipe);
+            }
+            else
+            {
+                /* Otherwise, try to acquire shared (excepted for pipes) */
+                if (IsPipe)
+                {
+                    Status = RxAcquireExclusiveFcb(RxContext, Fcb);
+                }
+                else if (CanWait ||
+                         (!NoCache && RxWriteCacheingAllowed(Fcb, SrvOpen)))
+                {
+                    Status = RxAcquireSharedFcb(RxContext, Fcb);
+                }
+                else
+                {
+                    Status = RxAcquireSharedFcbWaitForEx(RxContext, Fcb);
+                }
+
+                /* We'll post IRP to retry */
+                if (Status == STATUS_LOCK_NOT_GRANTED)
+                {
+                    PostIrp = TRUE;
+                    DPRINT1("Failed to acquire lock!\n");
+                    _SEH2_TRY_RETURN(Status);
+                }
+
+                /* We'll just fail */
+                if (Status != STATUS_SUCCESS)
+                {
+                    _SEH2_TRY_RETURN(Status);
+                }
+
+                /* Resource acquired */
+                RxContext->FcbResourceAcquired = TRUE;
+            }
+
+            /* At that point, resource is acquired */
+            if (IsPipe)
+            {
+                ASSERT(RxContext->FcbResourceAcquired);
+            }
+            else
+            {
+                BOOLEAN IsDormant;
+
+                /* Now, check whether we have to promote shared lock */
+                if (NodeTypeCode == RDBSS_NTC_STORAGE_TYPE_FILE && Fobx != NULL)
+                {
+                    IsDormant = BooleanFlagOn(Fobx->Flags, FOBX_FLAG_MARKED_AS_DORMANT);
+                }
+                else
+                {
+                    IsDormant = FALSE;
+                }
+
+                /* We're writing beyond VDL, we'll need an exclusive lock if not dormant */
+                if (RxIsFcbAcquiredShared(Fcb) &&
+                    ByteOffset.QuadPart + WriteLength > Fcb->Header.ValidDataLength.QuadPart)
+                {
+                    if (!IsDormant)
+                    {
+                        RxReleaseFcb(RxContext, Fcb);
+                        RxContext->FcbResourceAcquired = FALSE;
+
+                        Status = RxAcquireExclusiveFcb(RxContext, Fcb);
+                        if (Status == STATUS_LOCK_NOT_GRANTED)
+                        {
+                            PostIrp = TRUE;
+                            DPRINT1("Failed to acquire lock!\n");
+                            _SEH2_TRY_RETURN(Status);
+                        }
+
+                        if (Status != STATUS_SUCCESS)
+                        {
+                            _SEH2_TRY_RETURN(Status);
+                        }
+
+                        RxContext->FcbResourceAcquired = TRUE;
+                    }
+                }
+
+                /* If we're writing in VDL, or if we're dormant, shared lock is enough */
+                if (ByteOffset.QuadPart + WriteLength <= Fcb->Header.ValidDataLength.QuadPart ||
+                    IsDormant)
+                {
+                    if (RxIsFcbAcquiredExclusive(Fcb))
+                    {
+                        RxConvertToSharedFcb(RxContext, Fcb);
+                    }
+                }
+                else
+                {
+                    /* We're extending file, disable collapsing */
+                    ASSERT(RxIsFcbAcquiredExclusive(Fcb));
+
+                    DPRINT("Disabling collapsing\n");
+
+                    if (NodeTypeCode == RDBSS_NTC_STORAGE_TYPE_FILE && Fobx != NULL)
+                    {
+                        SetFlag(Fobx->Flags, FOBX_FLAG_DISABLE_COLLAPSING);
+                    }
+                }
+
+                ASSERT(RxContext->FcbResourceAcquired);
+            }
+
+            /* Keep track of the acquired resource */
+            LowIoContext->Resource = Fcb->Header.Resource;
+        }
+        else
+        {
+            /* Paging IO */
+            ASSERT(!IsPipe);
+
+            /* Lock the paging resource */
+            RxAcquirePagingIoResourceShared(RxContext, Fcb, TRUE);
+
+            /* Keep track of the acquired resource */
+            LowIoContext->Resource = Fcb->Header.PagingIoResource;
+        }
+
+        if (IsPipe)
+        {
+            UNIMPLEMENTED;
+            _SEH2_TRY_RETURN(Status = STATUS_NOT_IMPLEMENTED);
+        }
+
+        /* If it's a non cached write, or if caching is disallowed */
+        if (NoCache || !RxWriteCacheingAllowed(Fcb, SrvOpen))
+        {
+            /* If cache was previously enabled, we'll have to flush before writing */
+            if (!PagingIo && Fcb->NonPaged->SectionObjectPointers.DataSectionObject != NULL)
+            {
+                LARGE_INTEGER FlushOffset;
+
+                /* FCB is lock */
+                ASSERT(RxIsFcbAcquiredExclusive(Fcb) || RxIsFcbAcquiredShared(Fcb));
+
+                /* If shared, we'll have to relock exclusive */
+                if (!RxIsFcbAcquiredExclusive(Fcb))
+                {
+                    /* Release and retry exclusive */
+                    RxReleaseFcb(RxContext, Fcb);
+                    RxContext->FcbResourceAcquired = FALSE;
+
+                    Status = RxAcquireExclusiveFcb(RxContext, Fcb);
+                    if (Status == STATUS_LOCK_NOT_GRANTED)
+                    {
+                        PostIrp = TRUE;
+                        DPRINT1("Failed to acquire lock for flush!\n");
+                        _SEH2_TRY_RETURN(Status);
+                    }
+
+                    if (Status != STATUS_SUCCESS)
+                    {
+                        _SEH2_TRY_RETURN(Status);
+                    }
+
+                    RxContext->FcbResourceAcquired = TRUE;
+                }
+
+                /* Get the length to flush */
+                if (WriteToEof)
+                {
+                    RxGetFileSizeWithLock(Fcb, &FlushOffset.QuadPart);
+                }
+                else
+                {
+                    FlushOffset.QuadPart = ByteOffset.QuadPart;
+                }
+
+                /* Perform the flushing */
+                RxAcquirePagingIoResource(RxContext, Fcb);
+                CcFlushCache(&Fcb->NonPaged->SectionObjectPointers, &FlushOffset,
+                             WriteLength, &Irp->IoStatus);
+                RxReleasePagingIoResource(RxContext, Fcb);
+
+                /* Cannot continue if flushing failed */
+                if (!NT_SUCCESS(Irp->IoStatus.Status))
+                {
+                    _SEH2_TRY_RETURN(Status = Irp->IoStatus.Status);
+                }
+
+                /* Synchronize */
+                RxAcquirePagingIoResource(RxContext, Fcb);
+                RxReleasePagingIoResource(RxContext, Fcb);
+
+                /* And purge */
+                CcPurgeCacheSection(&Fcb->NonPaged->SectionObjectPointers,
+                                    &FlushOffset, WriteLength, FALSE);
+            }
+        }
+
+        /* If not paging IO, check if write is allowed */
+        if (!PagingIo)
+        {
+            if (!FsRtlCheckLockForWriteAccess(&Fcb->Specific.Fcb.FileLock, Irp))
+            {
+                _SEH2_TRY_RETURN(Status = STATUS_FILE_LOCK_CONFLICT);
+            }
+        }
+
+        /* Get file sizes */
+        ValidDataLength = Fcb->Header.ValidDataLength.QuadPart;
+        RxGetFileSizeWithLock(Fcb, &FileSize);
+        ASSERT(ValidDataLength <= FileSize);
+
+        /* If paging IO, we cannot write past file size
+         * so fix write length if needed
+         */
+        if (PagingIo)
+        {
+            if (ByteOffset.QuadPart >= FileSize)
+            {
+                _SEH2_TRY_RETURN(Status = STATUS_SUCCESS);
+            }
+
+            if (WriteLength > FileSize - ByteOffset.QuadPart)
+            {
+                WriteLength = FileSize - ByteOffset.QuadPart;
+            }
+        }
+
+        /* If we're being called by the lazywrite */
+        if (Fcb->Specific.Fcb.LazyWriteThread == PsGetCurrentThread())
+        {
+            CalledByLazyWriter = TRUE;
+
+            /* Fail if we're beyong VDL */
+            if (BooleanFlagOn(Fcb->Header.Flags, FSRTL_FLAG_USER_MAPPED_FILE))
+            {
+                if ((ByteOffset.QuadPart + WriteLength > ValidDataLength) &&
+                    (ByteOffset.QuadPart < FileSize))
+                {
+                    if (ByteOffset.QuadPart + WriteLength > ((ValidDataLength + PAGE_SIZE - 1) & ~(PAGE_SIZE - 1)))
+                    {
+                        _SEH2_TRY_RETURN(Status = STATUS_FILE_LOCK_CONFLICT);
+                    }
+                }
+            }
+        }
+
+        /* If that's a recursive synchronous page write */
+        if (BooleanFlagOn(Irp->Flags, IRP_SYNCHRONOUS_PAGING_IO) &&
+            BooleanFlagOn(RxContext->Flags, RX_CONTEXT_FLAG_RECURSIVE_CALL))
+        {
+            PIRP TopIrp;
+
+            /* Check the top level IRP on the FastIO path */
+            TopIrp = RxGetTopIrpIfRdbssIrp();
+            if (TopIrp != NULL && (ULONG_PTR)TopIrp > FSRTL_FAST_IO_TOP_LEVEL_IRP)
+            {
+                PIO_STACK_LOCATION IrpStack;
+
+                ASSERT(NodeType(TopIrp) == IO_TYPE_IRP);
+
+                /* If the top level IRP was a cached write for this file, keep track */
+                IrpStack = IoGetCurrentIrpStackLocation(TopIrp);
+                if (IrpStack->MajorFunction == IRP_MJ_WRITE &&
+                    IrpStack->FileObject->FsContext == FileObject->FsContext)
+                {
+                    RecursiveWriteThrough = TRUE;
+                    SetFlag(RxContext->Flags, RX_CONTEXT_FLAG_WRITE_THROUGH);
+                }
+            }
+        }
+
+        /* Now, deal with file size and VDL */
+        if (!CalledByLazyWriter && !RecursiveWriteThrough &&
+            (WriteToEof || ByteOffset.QuadPart + WriteLength > ValidDataLength))
+        {
+            /* Not sync? Let's make it sync, just the time we extended */
+            if (!Sync)
+            {
+                CanWait = TRUE;
+                SetFlag(RxContext->Flags, RX_CONTEXT_FLAG_WAIT);
+                ClearFlag(RxContext->Flags, RX_CONTEXT_FLAG_ASYNC_OPERATION);
+                Sync = TRUE;
+
+                /* Keep track we'll have to switch back to async */
+                if (NoCache)
+                {
+                    SwitchBackToAsync = TRUE;
+                }
+            }
+
+            /* Release all the locks */
+            RxWriteReleaseResources(RxContext, 0);
+
+            /* Acquire exclusive */
+            Status = RxAcquireExclusiveFcb(RxContext, Fcb);
+            if (Status == STATUS_LOCK_NOT_GRANTED)
+            {
+                PostIrp = TRUE;
+                DPRINT1("Failed to acquire lock for extension!\n");
+                _SEH2_TRY_RETURN(Status);
+            }
+
+            if (Status != STATUS_SUCCESS)
+            {
+                _SEH2_TRY_RETURN(Status);
+            }
+
+            RxContext->FcbResourceAcquired = TRUE;
+
+            RxItsTheSameContext();
+
+            /* Get the sizes again, to be sure they didn't change in the meantime */
+            ValidDataLength = Fcb->Header.ValidDataLength.QuadPart;
+            RxGetFileSizeWithLock(Fcb, &FileSize);
+            ASSERT(ValidDataLength <= FileSize);
+
+            /* Check we can switch back to async? */
+            if ((SwitchBackToAsync && Fcb->NonPaged->SectionObjectPointers.DataSectionObject != NULL) ||
+                (ByteOffset.QuadPart + WriteLength > FileSize) || RxNoAsync)
+            {
+                SwitchBackToAsync = FALSE;
+            }
+
+            /* If paging IO, check we don't try to extend the file */
+            if (PagingIo)
+            {
+                if (ByteOffset.QuadPart >= FileSize)
+                {
+                    _SEH2_TRY_RETURN(Status = STATUS_SUCCESS);
+                }
+
+                if (WriteLength > FileSize - ByteOffset.QuadPart)
+                {
+                    WriteLength = FileSize - ByteOffset.QuadPart;
+                }
+            }
+        }
+
+        /* Save our initial sizes for potential rollback */
+        InitialFileSize = FileSize;
+        InitialValidDataLength = ValidDataLength;
+        /* If writing to EOF, update byte offset with file size */
+        if (WriteToEof)
+        {
+            ByteOffset.QuadPart = FileSize;
+        }
+
+        /* Check again whether we're allowed to write */
+        if (!PagingIo)
+        {
+            if (!FsRtlCheckLockForWriteAccess(&Fcb->Specific.Fcb.FileLock, Irp ))
+            {
+                _SEH2_TRY_RETURN(Status = STATUS_FILE_LOCK_CONFLICT);
+            }
+
+            /* Do we have to extend? */
+            if (NormalFile && (ByteOffset.QuadPart + WriteLength > FileSize))
+            {
+                DPRINT("Need to extend file\n");
+                ExtendingFile = TRUE;
+                SetFlag(LowIoContext->ParamsFor.ReadWrite.Flags, LOWIO_READWRITEFLAG_EXTENDING_FILESIZE);
+            }
+        }
+
+        /* Let's start to extend */
+        if (ExtendingFile)
+        {
+            /* If we're past allocating, inform mini-rdr */
+            FileSize = ByteOffset.QuadPart + WriteLength;
+            if (FileSize > Fcb->Header.AllocationSize.QuadPart)
+            {
+                LARGE_INTEGER NewAllocationSize;
+
+                DPRINT("Extending %p\n", RxContext);
+
+                if (NoCache)
+                {
+                    C_ASSERT(sizeof(LONGLONG) == sizeof(LARGE_INTEGER));
+                    MINIRDR_CALL(Status, RxContext, Fcb->MRxDispatch, MRxExtendForNonCache,
+                                 (RxContext, (PLARGE_INTEGER)&FileSize, &NewAllocationSize));
+                }
+                else
+                {
+                    C_ASSERT(sizeof(LONGLONG) == sizeof(LARGE_INTEGER));
+                    MINIRDR_CALL(Status, RxContext, Fcb->MRxDispatch, MRxExtendForCache,
+                                 (RxContext, (PLARGE_INTEGER)&FileSize, &NewAllocationSize));
+                }
+
+                if (!NT_SUCCESS(Status))
+                {
+                    _SEH2_TRY_RETURN(Status);
+                }
+
+                if (FileSize > NewAllocationSize.QuadPart)
+                {
+                    NewAllocationSize.QuadPart = FileSize;
+                }
+
+                /* And update FCB */
+                Fcb->Header.AllocationSize.QuadPart = NewAllocationSize.QuadPart;
+            }
+
+            /* Set the new sizes */
+            RxSetFileSizeWithLock(Fcb, &FileSize);
+            RxAdjustAllocationSizeforCC(Fcb);
+
+            /* And inform Cc */
+            if (CcIsFileCached(FileObject))
+            {
+                CcSetFileSizes(FileObject, (PCC_FILE_SIZES)&Fcb->Header.AllocationSize);
+            }
+        }
+
+        /* Do we have to extend VDL? */
+        if (!CalledByLazyWriter && !RecursiveWriteThrough)
+        {
+            if (WriteToEof || ByteOffset.QuadPart + WriteLength > ValidDataLength)
+            {
+                ExtendingValidData = TRUE;
+                SetFlag(LowIoContext->ParamsFor.ReadWrite.Flags, LOWIO_READWRITEFLAG_EXTENDING_VDL);
+            }
+        }
+
+        /* If none cached write */
+        if (PagingIo || NoCache || !RxWriteCacheingAllowed(Fcb, SrvOpen))
+        {
+            /* Switch back to async, if asked to */
+            if (SwitchBackToAsync)
+            {
+                CanWait = FALSE;
+                Sync = FALSE;
+
+                ClearFlag(RxContext->Flags, RX_CONTEXT_FLAG_WAIT);
+                SetFlag(RxContext->Flags, RX_CONTEXT_FLAG_ASYNC_OPERATION);
+            }
+
+            /* If not synchronous, keep track of writes to be finished */
+            if (!Sync)
+            {
+                if (Fcb->NonPaged->OutstandingAsyncEvent == NULL)
+                {
+                    Fcb->NonPaged->OutstandingAsyncEvent = &Fcb->NonPaged->TheActualEvent;
+                    KeInitializeEvent(Fcb->NonPaged->OutstandingAsyncEvent,
+                                      NotificationEvent, FALSE);
+                }
+
+                if (ExInterlockedAddUlong(&Fcb->NonPaged->OutstandingAsyncWrites,
+                                          1,
+                                          &RxStrucSupSpinLock) == 0)
+                {
+                    KeResetEvent(Fcb->NonPaged->OutstandingAsyncEvent);
+                }
+
+                UnwindOutstandingAsync = TRUE;
+                LowIoContext->ParamsFor.ReadWrite.NonPagedFcb = Fcb->NonPaged;
+            }
+
+            /* Set our LOWIO_CONTEXT information */
+            LowIoContext->ParamsFor.ReadWrite.ByteOffset = ByteOffset.QuadPart;
+            LowIoContext->ParamsFor.ReadWrite.ByteCount = WriteLength;
+
+            RxItsTheSameContext();
+
+            /* We have to be locked */
+            ASSERT(RxContext->FcbResourceAcquired || RxContext->FcbPagingIoResourceAcquired);
+
+            /* Update thread ID if we're in FSP */
+            if (InFsp)
+            {
+                LowIoContext->ResourceThreadId = (ULONG_PTR)RxContext | 3;
+
+                if (RxContext->FcbResourceAcquired)
+                {
+                    ExSetResourceOwnerPointer(Fcb->Header.Resource, (PVOID)((ULONG_PTR)RxContext | 3));
+                }
+
+                if (RxContext->FcbPagingIoResourceAcquired)
+                {
+                    ExSetResourceOwnerPointer(Fcb->Header.PagingIoResource, (PVOID)((ULONG_PTR)RxContext | 3));
+                }
+
+                ResourceOwnerSet = TRUE;
+            }
+
+            /* And perform the write */
+            Status = RxLowIoWriteShell(RxContext);
+
+            RxItsTheSameContext();
+
+            /* Not outstanding write anymore */
+            if (UnwindOutstandingAsync && Status == STATUS_PENDING)
+            {
+                UnwindOutstandingAsync = FALSE;
+            }
+        }
+        /* Cached write */
+        else
+        {
+            /* If cache wasn't enabled yet, do it */
+            if (FileObject->PrivateCacheMap == NULL)
+            {
+                if (BooleanFlagOn(FileObject->Flags, FO_CLEANUP_COMPLETE))
+                {
+                    _SEH2_TRY_RETURN(Status = STATUS_FILE_CLOSED);
+                }
+
+                RxAdjustAllocationSizeforCC(Fcb);
+
+                CcInitializeCacheMap(FileObject, (PCC_FILE_SIZES)&Fcb->Header.AllocationSize,
+                                     FALSE, &RxData.CacheManagerCallbacks, Fcb);
+
+                CcSetReadAheadGranularity(FileObject, NetRoot->DiskParameters.ReadAheadGranularity);
+            }
+
+            /* If that's a MDL backed write */
+            if (BooleanFlagOn(RxContext->MinorFunction, IRP_MN_MDL))
+            {
+                /* Shouldn't happen */
+                ASSERT(FALSE);
+                ASSERT(CanWait);
+
+                /* Perform it, though */
+                CcPrepareMdlWrite(FileObject, &ByteOffset, WriteLength,
+                                  &Irp->MdlAddress, &Irp->IoStatus);
+
+                Status = Irp->IoStatus.Status;
+            }
+            else
+            {
+                PVOID SystemBuffer;
+                ULONG BreakpointsSave;
+
+                /* Map the user buffer */
+                SystemBuffer = RxNewMapUserBuffer(RxContext);
+                if (SystemBuffer == NULL)
+                {
+                    _SEH2_TRY_RETURN(Status = STATUS_INSUFFICIENT_RESOURCES);
+                }
+
+                RxSaveAndSetExceptionNoBreakpointFlag(RxContext, BreakpointsSave);
+
+                RxItsTheSameContext();
+
+                /* And deal with Cc */
+                if (!CcCopyWrite(FileObject, &ByteOffset, WriteLength, CanWait,
+                                 SystemBuffer))
+                {
+                    RxRestoreExceptionNoBreakpointFlag(RxContext, BreakpointsSave);
+
+                    RxItsTheSameContext();
+
+                    DPRINT1("CcCopyWrite failed for: %p %I64d %d %lx\n",
+                            FileObject, Fcb->Header.FileSize.QuadPart, WriteLength, Status);
+
+                    PostIrp = TRUE;
+                }
+                else
+                {
+                    Irp->IoStatus.Status = STATUS_SUCCESS;
+                    Irp->IoStatus.Information = WriteLength;
+
+                    RxRestoreExceptionNoBreakpointFlag(RxContext, BreakpointsSave);
+
+                    RxItsTheSameContext();
+
+                    DPRINT("CcCopyWrite succeed for: %p %I64d %d %lx\n",
+                           FileObject, Fcb->Header.FileSize.QuadPart, WriteLength, Status);
+                }
+            }
+        }
+
+try_exit: NOTHING;
+
+        /* If we've to post the IRP */
+        if (PostIrp)
+        {
+            /* Reset the file size if required */
+            if (ExtendingFile && !IsPipe)
             {
-                LowIoContext->ParamsFor.ReadWrite.ByteCount = ReadLength;
-                LowIoContext->ParamsFor.ReadWrite.ByteOffset = ByteOffset.QuadPart;
+                ASSERT(RxWriteCacheingAllowed(Fcb, SrvOpen));
+                ASSERT(Fcb->Header.PagingIoResource != NULL);
 
-                RxItsTheSameContext();
+                RxAcquirePagingIoResource(RxContext, Fcb);
+                RxSetFileSizeWithLock(Fcb, &InitialFileSize);
+                RxReleasePagingIoResource(RxContext, Fcb);
 
-                if (InFsp && ReadCachingDisabled)
+                if (FileObject->SectionObjectPointer->SharedCacheMap != NULL)
                 {
-                    ExSetResourceOwnerPointer((PagingIo ? Fcb->Header.PagingIoResource : Fcb->Header.Resource),
-                                              (PVOID)((ULONG_PTR)RxContext | 3));
-                    OwnerSet = TRUE;
+                    *CcGetFileSizePointer(FileObject) = Fcb->Header.FileSize;
                 }
+            }
 
-                Status = RxLowIoReadShell(RxContext);
+            InterlockedIncrement((volatile long *)&RxContext->ReferenceCount);
+            ContextReferenced = TRUE;
 
-                RxItsTheSameContext();
-            }
-            else
+            /* Release locks */
+            ASSERT(!ResourceOwnerSet);
+            RxWriteReleaseResources(RxContext, ResourceOwnerSet);
+
+#ifdef RDBSS_TRACKER
+            ASSERT(RxContext->AcquireReleaseFcbTrackerX == 0);
+#endif
+
+            /* And post the request */
+            Status = RxFsdPostRequest(RxContext);
+        }
+        else
+        {
+            if (!IsPipe)
             {
-                if (ByteOffset.QuadPart > FileSize)
+                /* Update FILE_OBJECT if synchronous write succeed */
+                if (!PagingIo)
                 {
-                    ReadLength = 0;
-                    Irp->IoStatus.Information = ReadLength;
-                    _SEH2_LEAVE;
+                    if (NT_SUCCESS(Status) && BooleanFlagOn(FileObject->Flags, FO_SYNCHRONOUS_IO))
+                    {
+                        FileObject->CurrentByteOffset.QuadPart = ByteOffset.QuadPart + Irp->IoStatus.Information;
+                    }
                 }
 
-                if (ByteOffset.QuadPart + ReadLength > FileSize)
+                /* If write succeed, ,also update FILE_OBJECT flags */
+                if (NT_SUCCESS(Status) && Status != STATUS_PENDING)
                 {
-                    ReadLength = FileSize - ByteOffset.QuadPart;
-                }
+                    /* File was modified */
+                    if (!PagingIo)
+                    {
+                        SetFlag(FileObject->Flags, FO_FILE_MODIFIED);
+                    }
 
-                SystemBuffer = RxNewMapUserBuffer(RxContext);
-                RtlZeroMemory(SystemBuffer, ReadLength);
-                Irp->IoStatus.Information = ReadLength;
+                    /* If was even extended */
+                    if (ExtendingFile)
+                    {
+                        SetFlag(FileObject->Flags, FO_FILE_SIZE_CHANGED);
+                    }
+
+                    /* If VDL was extended, update FCB and inform Cc */
+                    if (ExtendingValidData)
+                    {
+                        LONGLONG LastOffset;
+
+                        LastOffset = ByteOffset.QuadPart + Irp->IoStatus.Information;
+                        if (FileSize < LastOffset)
+                        {
+                            LastOffset = FileSize;
+                        }
+
+                        Fcb->Header.ValidDataLength.QuadPart = LastOffset;
+
+                        if (NoCache && CcIsFileCached(FileObject))
+                        {
+                            CcSetFileSizes(FileObject, (PCC_FILE_SIZES)&Fcb->Header.AllocationSize);
+                        }
+                    }
+                }
             }
         }
     }
     _SEH2_FINALLY
     {
-        RxItsTheSameContext();
-
-        /* Post if required */
-        if (PostRequest)
-        {
-            InterlockedIncrement((volatile long *)&RxContext->ReferenceCount);
-            Status = RxFsdPostRequest(RxContext);
-        }
-        else
+        /* Finally, if we failed while extension was required */
+        if (_SEH2_AbnormalTermination() && (ExtendingFile || ExtendingValidData))
         {
-            /* Update FO in case of sync IO */
-            if (!IsPipe && !PagingIo)
+            /* Rollback! */
+            if (!IsPipe)
             {
-                if (BooleanFlagOn(FileObject->Flags, FO_SYNCHRONOUS_IO))
+                ASSERT(Fcb->Header.PagingIoResource != NULL);
+
+                RxAcquirePagingIoResource(RxContext, Fcb);
+                RxSetFileSizeWithLock(Fcb, &InitialFileSize);
+                Fcb->Header.ValidDataLength.QuadPart = InitialValidDataLength;
+                RxReleasePagingIoResource(RxContext, Fcb);
+
+                if (FileObject->SectionObjectPointer->SharedCacheMap != NULL)
                 {
-                    FileObject->CurrentByteOffset.QuadPart = ByteOffset.QuadPart + Irp->IoStatus.Information;
+                    *CcGetFileSizePointer(FileObject) = Fcb->Header.FileSize;
                 }
             }
         }
 
-        /* Set FastIo if read was a success */
-        if (NT_SUCCESS(Status) && Status != STATUS_PENDING)
+        /* One async write less */
+        if (UnwindOutstandingAsync)
         {
-            if (!IsPipe && !PagingIo)
-            {
-                SetFlag(FileObject->Flags, FO_FILE_FAST_IO_READ);
-            }
+            ASSERT(!IsPipe);
+
+            ExInterlockedAddUlong(&Fcb->NonPaged->OutstandingAsyncWrites, -1, &RxStrucSupSpinLock);
+            KeSetEvent(Fcb->NonPaged->OutstandingAsyncEvent, IO_NO_INCREMENT, FALSE);
         }
 
-        /* In case we're done (not expected any further processing */
-        if (_SEH2_AbnormalTermination() || Status != STATUS_PENDING || PostRequest)
+        /* And now, cleanup everything */
+        if (_SEH2_AbnormalTermination() || Status != STATUS_PENDING || PostIrp)
         {
-            /* Release everything that can be */
-            if (ReadCachingDisabled)
+            /* If we didn't post, release every lock (for posting, it's already done) */
+            if (!PostIrp)
             {
-                if (PagingIo)
-                {
-                    if (OwnerSet)
-                    {
-                        RxReleasePagingIoResourceForThread(RxContext, Fcb, LowIoContext->ResourceThreadId);
-                    }
-                    else
-                    {
-                        RxReleasePagingIoResource(RxContext, Fcb);
-                    }
-                }
-                else
-                {
-                    if (OwnerSet)
-                    {
-                        RxReleaseFcbForThread(RxContext, Fcb, LowIoContext->ResourceThreadId);
-                    }
-                    else
-                    {
-                        RxReleaseFcb(RxContext, Fcb);
-                    }
-                }
+                RxWriteReleaseResources(RxContext, ResourceOwnerSet);
             }
 
-            /* Dereference/Delete context */
-            if (PostRequest)
+            /* If the context was referenced - posting, dereference it */
+            if (ContextReferenced)
             {
                 RxDereferenceAndDeleteRxContext(RxContext);
             }
-            else
+
+            /* If that's a pipe operation, resume any blocked one */
+            if (!PostIrp)
             {
                 if (BooleanFlagOn(RxContext->FlagsForLowIo, RXCONTEXT_FLAG4LOWIO_PIPE_SYNC_OPERATION))
                 {
@@ -2547,96 +4708,79 @@ RxCommonRead(
                 }
             }
 
-            /* We cannot return more than asked */
+            /* Sanity check for write */
             if (Status == STATUS_SUCCESS)
             {
-                ASSERT(Irp->IoStatus.Information <= Stack->Parameters.Read.Length);
+                ASSERT(Irp->IoStatus.Information <= Stack->Parameters.Write.Length);
             }
         }
+        /* Just dereference our context */
         else
         {
             ASSERT(!Sync);
-
             RxDereferenceAndDeleteRxContext(RxContext);
         }
     }
     _SEH2_END;
 
+#undef _SEH2_TRY_RETURN
+
     return Status;
 }
 
+/*
+ * @implemented
+ */
 NTSTATUS
 NTAPI
-RxCommonSetEa(
-    PRX_CONTEXT Context)
+RxCompleteMdl(
+    IN PRX_CONTEXT RxContext)
 {
-    UNIMPLEMENTED;
-    return STATUS_NOT_IMPLEMENTED;
-}
+    PIRP Irp;
+    PFILE_OBJECT FileObject;
+    PIO_STACK_LOCATION Stack;
 
-NTSTATUS
-NTAPI
-RxCommonSetInformation(
-    PRX_CONTEXT Context)
-{
-    UNIMPLEMENTED;
-    return STATUS_NOT_IMPLEMENTED;
-}
+#define BugCheckFileId RDBSS_BUG_CHECK_CACHESUP
 
-NTSTATUS
-NTAPI
-RxCommonSetQuotaInformation(
-    PRX_CONTEXT Context)
-{
-    UNIMPLEMENTED;
-    return STATUS_NOT_IMPLEMENTED;
-}
+    PAGED_CODE();
 
-NTSTATUS
-NTAPI
-RxCommonSetSecurity(
-    PRX_CONTEXT Context)
-{
-    UNIMPLEMENTED;
-    return STATUS_NOT_IMPLEMENTED;
-}
+    Irp = RxContext->CurrentIrp;
+    Stack = RxContext->CurrentIrpSp;
+    FileObject = Stack->FileObject;
 
-NTSTATUS
-NTAPI
-RxCommonSetVolumeInformation(
-    PRX_CONTEXT Context)
-{
-    UNIMPLEMENTED;
-    return STATUS_NOT_IMPLEMENTED;
-}
+    /* We can only complete for IRP_MJ_READ and IRP_MJ_WRITE */
+    switch (RxContext->MajorFunction)
+    {
+        /* Call the Cc function */
+        case IRP_MJ_READ:
+            CcMdlReadComplete(FileObject, Irp->MdlAddress);
+            break;
 
-NTSTATUS
-NTAPI
-RxCommonUnimplemented(
-    PRX_CONTEXT Context)
-{
-    UNIMPLEMENTED;
-    return STATUS_NOT_IMPLEMENTED;
-}
+        case IRP_MJ_WRITE:
+            /* If here, we can wait */
+            ASSERT(BooleanFlagOn(RxContext->Flags, RX_CONTEXT_FLAG_WAIT));
 
-NTSTATUS
-NTAPI
-RxCommonWrite(
-    PRX_CONTEXT Context)
-{
-    UNIMPLEMENTED;
-    return STATUS_NOT_IMPLEMENTED;
-}
+            /* Call the Cc function */
+            CcMdlWriteComplete(FileObject, &Stack->Parameters.Write.ByteOffset, Irp->MdlAddress);
 
-NTSTATUS
-NTAPI
-RxCompleteMdl(
-    IN PRX_CONTEXT RxContext)
-{
-    PAGED_CODE();
+            Irp->IoStatus.Status = STATUS_SUCCESS;
+            break;
 
-    UNIMPLEMENTED;
-    return STATUS_NOT_IMPLEMENTED;
+        default:
+            DPRINT1("Invalid major for RxCompleteMdl: %d\n", RxContext->MajorFunction);
+            RxBugCheck(RxContext->MajorFunction, 0, 0);
+            break;
+    }
+
+    /* MDL was freed */
+    Irp->MdlAddress = NULL;
+
+    /* And complete the IRP */
+    RxCompleteRequest(RxContext, STATUS_SUCCESS);
+
+#undef BugCheckFileId
+
+    return STATUS_SUCCESS;
 }
 
 /*
@@ -3102,7 +5246,7 @@ RxDriverEntry(
 
         RxInitializeDispatcher();
 
-        ExInitializeNPagedLookasideList(&RxContextLookasideList, ExAllocatePoolWithTag, ExFreePool, 0, sizeof(RX_CONTEXT), RX_IRPC_POOLTAG, 4);
+        ExInitializeNPagedLookasideList(&RxContextLookasideList, RxAllocatePoolWithTag, RxFreePool, 0, sizeof(RX_CONTEXT), RX_IRPC_POOLTAG, 4);
 
         InitializeListHead(&RxIrpsList);
         KeInitializeSpinLock(&RxIrpsListSpinLock);
@@ -3149,6 +5293,7 @@ RxDriverEntry(
 #endif
 }
 
+#if DBG
 /*
  * @implemented
  */
@@ -3175,7 +5320,11 @@ RxDumpWantedAccess(
 {
     PAGED_CODE();
 }
+#endif
 
+/*
+ * @implemented
+ */
 BOOLEAN
 NTAPI
 RxFastIoCheckIfPossible(
@@ -3186,8 +5335,116 @@ RxFastIoCheckIfPossible(
     PIO_STATUS_BLOCK IoStatus,
     PDEVICE_OBJECT DeviceObject)
 {
-    UNIMPLEMENTED;
-    return FALSE;
+    PFCB Fcb;
+    PSRV_OPEN SrvOpen;
+    LARGE_INTEGER LargeLength;
+
+    PAGED_CODE();
+
+    /* Get the FCB to validate it */
+    Fcb = FileObject->FsContext;
+    if (NodeType(Fcb) != RDBSS_NTC_STORAGE_TYPE_FILE)
+    {
+        DPRINT1("Not a file, FastIO not possible!\n");
+        return FALSE;
+    }
+
+    if (FileObject->DeletePending)
+    {
+        DPRINT1("File delete pending\n");
+        return FALSE;
+    }
+
+    /* If there's a pending write operation, deny fast operation */
+    if (Fcb->NonPaged->OutstandingAsyncWrites != 0)
+    {
+        DPRINT1("Write operations to be completed\n");
+        return FALSE;
+    }
+
+    /* Deny read on orphaned node */
+    SrvOpen = (PSRV_OPEN)((PFOBX)FileObject->FsContext2)->pSrvOpen;
+    if (BooleanFlagOn(SrvOpen->Flags, SRVOPEN_FLAG_ORPHANED))
+    {
+        DPRINT1("SRV_OPEN orphaned\n");
+        return FALSE;
+    }
+
+    if (BooleanFlagOn(Fcb->FcbState, FCB_STATE_ORPHANED))
+    {
+        DPRINT1("FCB orphaned\n");
+        return FALSE;
+    }
+
+    /* If there's a buffering state change pending, deny fast operation (it might change
+     * cache status)
+     */
+    if (BooleanFlagOn(SrvOpen->Flags, SRVOPEN_FLAG_BUFFERING_STATE_CHANGE_PENDING))
+    {
+        DPRINT1("Buffering change pending\n");
+        return FALSE;
+    }
+
+    /* File got renamed/deleted, deny operation */
+    if (BooleanFlagOn(SrvOpen->Flags, SRVOPEN_FLAG_FILE_DELETED) ||
+        BooleanFlagOn(SrvOpen->Flags, SRVOPEN_FLAG_FILE_RENAMED))
+    {
+        DPRINT1("File renamed/deleted\n");
+        return FALSE;
+    }
+
+    /* Process pending change buffering state operations */
+    FsRtlEnterFileSystem();
+    RxProcessChangeBufferingStateRequestsForSrvOpen(SrvOpen);
+    FsRtlExitFileSystem();
+
+    LargeLength.QuadPart = Length;
+
+    /* If operation to come is a read operation */
+    if (CheckForReadOperation)
+    {
+        /* Check that read cache is enabled */
+        if (!BooleanFlagOn(Fcb->FcbState, FCB_STATE_READCACHING_ENABLED))
+        {
+            DPRINT1("Read caching disabled\n");
+            return FALSE;
+        }
+
+        /* Check whether there's a lock conflict */
+        if (!FsRtlFastCheckLockForRead(&Fcb->Specific.Fcb.FileLock,
+                                       FileOffset,
+                                       &LargeLength,
+                                       LockKey,
+                                       FileObject,
+                                       PsGetCurrentProcess()))
+        {
+            DPRINT1("FsRtlFastCheckLockForRead failed\n");
+            return FALSE;
+        }
+
+        return TRUE;
+    }
+
+    /* Check that write cache is enabled */
+    if (!BooleanFlagOn(Fcb->FcbState, FCB_STATE_WRITECACHING_ENABLED))
+    {
+        DPRINT1("Write caching disabled\n");
+        return FALSE;
+    }
+
+    /* Check whether there's a lock conflict */
+    if (!FsRtlFastCheckLockForWrite(&Fcb->Specific.Fcb.FileLock,
+                                    FileOffset,
+                                    &LargeLength,
+                                    LockKey,
+                                    FileObject,
+                                    PsGetCurrentProcess()))
+    {
+        DPRINT1("FsRtlFastCheckLockForWrite failed\n");
+        return FALSE;
+    }
+
+    return TRUE;
 }
 
 BOOLEAN
@@ -3215,6 +5472,9 @@ RxFastIoDeviceControl(
     }
 }
 
+/*
+ * @implemented
+ */
 BOOLEAN
 NTAPI
 RxFastIoRead(
@@ -3227,10 +5487,37 @@ RxFastIoRead(
     PIO_STATUS_BLOCK IoStatus,
     PDEVICE_OBJECT DeviceObject)
 {
-    UNIMPLEMENTED;
-    return FALSE;
+    BOOLEAN Ret;
+    RX_TOPLEVELIRP_CONTEXT TopLevelContext;
+
+    PAGED_CODE();
+
+    DPRINT("RxFastIoRead: %p (%p, %p)\n", FileObject, FileObject->FsContext,
+                                          FileObject->FsContext2);
+    DPRINT("Reading %ld at %I64x\n", Length, FileOffset->QuadPart);
+
+    /* Prepare a TLI context */
+    ASSERT(RxIsThisTheTopLevelIrp(NULL));
+    RxInitializeTopLevelIrpContext(&TopLevelContext, (PIRP)FSRTL_FAST_IO_TOP_LEVEL_IRP,
+                                   (PRDBSS_DEVICE_OBJECT)DeviceObject);
+
+    Ret = FsRtlCopyRead2(FileObject, FileOffset, Length, Wait, LockKey, Buffer,
+                         IoStatus, DeviceObject, &TopLevelContext);
+    if (Ret)
+    {
+        DPRINT("Read OK\n");
+    }
+    else
+    {
+        DPRINT1("Read failed!\n");
+    }
+
+    return Ret;
 }
 
+/*
+ * @implemented
+ */
 BOOLEAN
 NTAPI
 RxFastIoWrite(
@@ -3243,19 +5530,39 @@ RxFastIoWrite(
     PIO_STATUS_BLOCK IoStatus,
     PDEVICE_OBJECT DeviceObject)
 {
-    UNIMPLEMENTED;
-    return FALSE;
-}
+    PFOBX Fobx;
+    BOOLEAN Ret;
+    RX_TOPLEVELIRP_CONTEXT TopLevelContext;
 
-NTSTATUS
-NTAPI
-RxFinalizeConnection(
-    IN OUT PNET_ROOT NetRoot,
-    IN OUT PV_NET_ROOT VNetRoot OPTIONAL,
-    IN LOGICAL ForceFilesClosed)
-{
-    UNIMPLEMENTED;
-    return STATUS_NOT_IMPLEMENTED;
+    PAGED_CODE();
+
+    Fobx = (PFOBX)FileObject->FsContext2;
+    if (BooleanFlagOn(Fobx->Flags, FOBX_FLAG_BAD_HANDLE))
+    {
+        return FALSE;
+    }
+
+    DPRINT("RxFastIoWrite: %p (%p, %p)\n", FileObject, FileObject->FsContext,
+                                           FileObject->FsContext2);
+    DPRINT("Writing %ld at %I64x\n", Length, FileOffset->QuadPart);
+
+    /* Prepare a TLI context */
+    ASSERT(RxIsThisTheTopLevelIrp(NULL));
+    RxInitializeTopLevelIrpContext(&TopLevelContext, (PIRP)FSRTL_FAST_IO_TOP_LEVEL_IRP,
+                                   (PRDBSS_DEVICE_OBJECT)DeviceObject);
+
+    Ret = FsRtlCopyWrite2(FileObject, FileOffset, Length, Wait, LockKey, Buffer,
+                          IoStatus, DeviceObject, &TopLevelContext);
+    if (Ret)
+    {
+        DPRINT("Write OK\n");
+    }
+    else
+    {
+        DPRINT1("Write failed!\n");
+    }
+
+    return Ret;
 }
 
 NTSTATUS
@@ -3276,7 +5583,6 @@ RxFindOrCreateFcb(
     VNetRoot = (PV_NET_ROOT)RxContext->Create.pVNetRoot;
     ASSERT(NetRoot == VNetRoot->NetRoot);
 
-    TableAcquired = FALSE;
     Status = STATUS_SUCCESS;
     AcquiredExclusive = FALSE;
 
@@ -3316,6 +5622,11 @@ RxFindOrCreateFcb(
     /* If FCB was not found or is not covering full path, prepare for more work */
     if (Fcb == NULL || Fcb->FcbTableEntry.Path.Length != NetRootName->Length)
     {
+        if (Fcb != NULL)
+        {
+            DPRINT1("FCB was found and it's not covering the whole path: %wZ - %wZ\n", &Fcb->FcbTableEntry.Path, NetRootName);
+        }
+
         if (!AcquiredExclusive)
         {
             RxReleaseFcbTableLock(&NetRoot->FcbTable);
@@ -3553,7 +5864,7 @@ RxFreeCanonicalNameBuffer(
 
     if (Context->Create.CanonicalNameBuffer != NULL)
     {
-        ExFreePoolWithTag(Context->Create.CanonicalNameBuffer, RX_MISC_POOLTAG);
+        RxFreePoolWithTag(Context->Create.CanonicalNameBuffer, RX_MISC_POOLTAG);
         Context->Create.CanonicalNameBuffer = NULL;
         Context->AlsoCanonicalNameBuffer = NULL;
     }
@@ -4006,7 +6317,7 @@ RxFspDispatch(
         RxContext->LastExecutionThread = PsGetCurrentThread();
         SetFlag(RxContext->Flags, (RX_CONTEXT_FLAG_IN_FSP | RX_CONTEXT_FLAG_WAIT));
 
-        DPRINT("Dispatch: MN: %d, Ctxt: %p, IRP: %p, THRD: %lx #%lx", RxContext->MinorFunction,
+        DPRINT("Dispatch: MN: %d, Ctxt: %p, IRP: %p, THRD: %lx #%lx\n", RxContext->MinorFunction,
                RxContext, RxContext->CurrentIrp, RxContext->LastExecutionThread,
                RxContext->SerialNumber);
 
@@ -4227,6 +6538,25 @@ RxGetTopDeviceObjectIfRdbssIrp(
     return TopDevice;
 }
 
+/*
+ * @implemented
+ */
+PIRP
+RxGetTopIrpIfRdbssIrp(
+    VOID)
+{
+    PIRP Irp = NULL;
+    PRX_TOPLEVELIRP_CONTEXT TopLevel;
+
+    TopLevel = (PRX_TOPLEVELIRP_CONTEXT)IoGetTopLevelIrp();
+    if (RxIsThisAnRdbssTopLevelContext(TopLevel))
+    {
+        Irp = TopLevel->Irp;
+    }
+
+    return Irp;
+}
+
 /*
  * @implemented
  */
@@ -4352,15 +6682,6 @@ RxInitializeRegistrationStructures(
     return STATUS_SUCCESS;
 }
 
-NTSTATUS
-NTAPI
-RxInitializeRxTimer(
-    VOID)
-{
-    UNIMPLEMENTED;
-    return STATUS_NOT_IMPLEMENTED;
-}
-
 /*
  * @implemented
  */
@@ -4416,12 +6737,43 @@ RxIsMemberOfTopLevelIrpAllocatedContextsList(
     return Found;
 }
 
+/*
+ * @implemented
+ */
 BOOLEAN
 RxIsOkToPurgeFcb(
     PFCB Fcb)
 {
-    UNIMPLEMENTED;
-    return FALSE;
+    PLIST_ENTRY Entry;
+
+    /* No associated SRV_OPEN, it's OK to purge */
+    if (IsListEmpty(&Fcb->SrvOpenList))
+    {
+        return TRUE;
+    }
+
+    /* Only allow to purge if all the associated SRV_OPEN
+     * - have no outstanding opens ongoing
+     * - have only read attribute set
+     */
+    for (Entry = Fcb->SrvOpenList.Flink;
+         Entry != &Fcb->SrvOpenList;
+         Entry = Entry->Flink)
+    {
+        PSRV_OPEN SrvOpen;
+
+        SrvOpen = CONTAINING_RECORD(Entry, SRV_OPEN, SrvOpenQLinks);
+
+        /* Failing previous needs, don't allow purge */
+        if (SrvOpen->UncleanFobxCount != 0 ||
+            (SrvOpen->DesiredAccess & 0xFFEFFFFF) != FILE_READ_ATTRIBUTES)
+        {
+            return FALSE;
+        }
+    }
+
+    /* All correct, allow purge */
+    return TRUE;
 }
 
 /*
@@ -4564,6 +6916,33 @@ RxLowIoIoCtlShellCompletion(
     return Status;
 }
 
+NTSTATUS
+RxLowIoLockControlShell(
+    IN PRX_CONTEXT RxContext)
+{
+    UNIMPLEMENTED;
+    return STATUS_NOT_IMPLEMENTED;
+}
+
+/*
+ * @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
  */
@@ -4691,31 +7070,252 @@ RxLowIoReadShellCompletion(
         }
         else
         {
-            RxReleaseFcbForThread(RxContext, Fcb, LowIoContext->ResourceThreadId);
+            RxReleaseFcbForThread(RxContext, Fcb, LowIoContext->ResourceThreadId);
+        }
+    }
+
+    if (IsPipe)
+    {
+        UNIMPLEMENTED;
+    }
+
+    /* Final sanity checks */
+    ASSERT(Status != STATUS_RETRY);
+    ASSERT(Irp->IoStatus.Information <= Stack->Parameters.Read.Length);
+    ASSERT(RxContext->MajorFunction == IRP_MJ_READ);
+
+    return Status;
+}
+
+/*
+ * @implemented
+ */
+NTSTATUS
+RxLowIoWriteShell(
+    IN PRX_CONTEXT RxContext)
+{
+    PFCB Fcb;
+    NTSTATUS Status;
+
+    PAGED_CODE();
+
+    DPRINT("RxLowIoWriteShell(%p)\n", RxContext);
+
+    Fcb = (PFCB)RxContext->pFcb;
+
+    ASSERT(!BooleanFlagOn(Fcb->FcbState, FCB_STATE_FILE_IS_BUF_COMPRESSED) &&
+           !BooleanFlagOn(Fcb->FcbState, FCB_STATE_FILE_IS_DISK_COMPRESSED));
+
+    /* Always update stats for disks */
+    if (Fcb->CachedNetRootType == NET_ROOT_DISK)
+    {
+        ExInterlockedAddLargeStatistic(&RxContext->RxDeviceObject->NetworkWriteBytesRequested, RxContext->LowIoContext.ParamsFor.ReadWrite.ByteCount);
+    }
+
+    /* And forward the write to the mini-rdr */
+    Status = RxLowIoSubmit(RxContext, RxLowIoWriteShellCompletion);
+    DPRINT("RxLowIoWriteShell(%p), Status: %lx\n", RxContext, Status);
+
+    return Status;
+}
+
+NTSTATUS
+NTAPI
+RxLowIoWriteShellCompletion(
+    PRX_CONTEXT RxContext)
+{
+    PIRP Irp;
+    PFCB Fcb;
+    NTSTATUS Status;
+    BOOLEAN PagingIo;
+    PLOWIO_CONTEXT LowIoContext;
+
+    PAGED_CODE();
+
+    DPRINT("RxLowIoWriteShellCompletion(%p)\n", RxContext);
+
+    Status = RxContext->IoStatusBlock.Status;
+    DPRINT("In %p, Status: %lx, Information: %lx\n", RxContext, Status, RxContext->IoStatusBlock.Information);
+
+    Irp = RxContext->CurrentIrp;
+
+    /* Set IRP information from the RX_CONTEXT status block */
+    Irp->IoStatus.Information = RxContext->IoStatusBlock.Information;
+
+    LowIoContext = &RxContext->LowIoContext;
+    ASSERT(RxLowIoIsBufferLocked(LowIoContext));
+
+    /* Perform a few sanity checks */
+    Fcb = (PFCB)RxContext->pFcb;
+    if (Status == STATUS_SUCCESS)
+    {
+        if (BooleanFlagOn(RxContext->FlagsForLowIo, RXCONTEXT_FLAG4LOWIO_THIS_IO_BUFFERED))
+        {
+            ASSERT(!BooleanFlagOn(Fcb->FcbState, FCB_STATE_FILE_IS_BUF_COMPRESSED) &&
+                   !BooleanFlagOn(Fcb->FcbState, FCB_STATE_FILE_IS_DISK_COMPRESSED));
+        }
+
+        ASSERT(!BooleanFlagOn(Fcb->FcbState, FCB_STATE_FILE_IS_SHADOWED));
+    }
+
+    PagingIo = BooleanFlagOn(Irp->Flags, IRP_PAGING_IO);
+    if (Status != STATUS_SUCCESS && PagingIo)
+    {
+        DPRINT1("Paging IO failed %p (%p) %lx\n", Fcb, Fcb->NetRoot, Status);
+    }
+
+    /* In case of async call, perform last bits not done in RxCommonWrite */
+    if (!BooleanFlagOn(LowIoContext->Flags, LOWIO_CONTEXT_FLAG_SYNCCALL))
+    {
+        PFILE_OBJECT FileObject;
+        PIO_STACK_LOCATION Stack;
+
+        /* We only succeed if we wrote what was asked for */
+        if (NT_SUCCESS(Status) && !BooleanFlagOn(RxContext->FlagsForLowIo, RXCONTEXT_FLAG4LOWIO_PIPE_OPERATION))
+        {
+            ASSERT(Irp->IoStatus.Information == LowIoContext->ParamsFor.ReadWrite.ByteCount);
+        }
+
+        /* If write succeed, ,also update FILE_OBJECT flags */
+        Stack = RxContext->CurrentIrpSp;
+        FileObject = Stack->FileObject;
+        if (!PagingIo)
+        {
+            SetFlag(FileObject->Flags, FO_FILE_MODIFIED);
+        }
+
+        if (BooleanFlagOn(LowIoContext->ParamsFor.ReadWrite.Flags, LOWIO_READWRITEFLAG_EXTENDING_FILESIZE))
+        {
+            SetFlag(FileObject->Flags, FO_FILE_SIZE_CHANGED);
+        }
+
+        /* If VDL was extended, fix attributes */
+        if (BooleanFlagOn(LowIoContext->ParamsFor.ReadWrite.Flags, LOWIO_READWRITEFLAG_EXTENDING_VDL))
+        {
+            LONGLONG LastOffset, FileSize;
+
+            LastOffset = LowIoContext->ParamsFor.ReadWrite.ByteOffset +
+                         Irp->IoStatus.Information;
+            RxGetFileSizeWithLock(Fcb, &FileSize);
+
+            if (FileSize < LastOffset)
+            {
+                LastOffset = FileSize;
+            }
+
+            Fcb->Header.ValidDataLength.QuadPart = LastOffset;
+        }
+
+        /* One less outstanding write */
+        if (!BooleanFlagOn(RxContext->FlagsForLowIo, RXCONTEXT_FLAG4LOWIO_PIPE_SYNC_OPERATION))
+        {
+            PNON_PAGED_FCB NonPagedFcb;
+
+            NonPagedFcb = LowIoContext->ParamsFor.ReadWrite.NonPagedFcb;
+            if (NonPagedFcb != NULL)
+            {
+                if (ExInterlockedAddUlong(&NonPagedFcb->OutstandingAsyncWrites,
+                                          -1, &RxStrucSupSpinLock) == 1)
+                {
+                    KeSetEvent(NonPagedFcb->OutstandingAsyncEvent, IO_NO_INCREMENT, FALSE);
+                }
+            }
+        }
+
+        /* Release paging resource if acquired */
+        if (RxContext->FcbPagingIoResourceAcquired)
+        {
+            RxReleasePagingIoResourceForThread(RxContext, Fcb, LowIoContext->ResourceThreadId);
+        }
+
+        /* Resume blocked operations for pipes */
+        if (BooleanFlagOn(RxContext->FlagsForLowIo, RXCONTEXT_FLAG4LOWIO_PIPE_SYNC_OPERATION))
+        {
+            RxResumeBlockedOperations_Serially(RxContext,
+                                               &((PFOBX)RxContext->pFobx)->Specific.NamedPipe.WriteSerializationQueue);
+        }
+        else
+        {
+            /* And release FCB only for files */
+            if (RxContext->FcbResourceAcquired)
+            {
+                RxReleaseFcbForThread(RxContext, Fcb, LowIoContext->ResourceThreadId);
+            }
+        }
+
+        /* Final sanity checks */
+        ASSERT(Status != STATUS_RETRY);
+        ASSERT((Status != STATUS_SUCCESS) || (Irp->IoStatus.Information <= Stack->Parameters.Write.Length));
+        ASSERT(RxContext->MajorFunction == IRP_MJ_WRITE);
+
+        if (BooleanFlagOn(RxContext->FlagsForLowIo, RXCONTEXT_FLAG4LOWIO_PIPE_OPERATION))
+        {
+            UNIMPLEMENTED;
+        }
+    }
+
+    return Status;
+}
+
+/*
+ * @implemented
+ */
+NTSTATUS
+RxNotifyChangeDirectory(
+    PRX_CONTEXT RxContext)
+{
+    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;
         }
     }
-
-    if (IsPipe)
+    _SEH2_FINALLY
     {
-        UNIMPLEMENTED;
+        /* All correct */
     }
-
-    /* Final sanity checks */
-    ASSERT(Status != STATUS_RETRY);
-    ASSERT(Irp->IoStatus.Information <= Stack->Parameters.Read.Length);
-    ASSERT(RxContext->MajorFunction == IRP_MJ_READ);
+    _SEH2_END;
 
     return Status;
 }
 
-NTSTATUS
-RxNotifyChangeDirectory(
-    PRX_CONTEXT RxContext)
-{
-    UNIMPLEMENTED;
-    return STATUS_NOT_IMPLEMENTED;
-}
-
 NTSTATUS
 RxPostStackOverflowRead (
     IN PRX_CONTEXT RxContext)
@@ -4777,7 +7377,7 @@ RxpQueryInfoMiniRdr(
     Fcb = (PFCB)RxContext->pFcb;
 
     /* Set the RX_CONTEXT */
-    RxContext->Info.FsInformationClass = FileInfoClass;
+    RxContext->Info.FileInformationClass = FileInfoClass;
     RxContext->Info.Buffer = Buffer;
 
     /* Pass down */
@@ -4825,7 +7425,7 @@ RxPrefixClaim(
         RxContext->MajorFunction = IRP_MJ_CREATE;
 
         /* Fake canon name */
-        RxContext->PrefixClaim.SuppliedPathName.Buffer = ExAllocatePoolWithTag(NonPagedPool, QueryRequest->PathNameLength, RX_MISC_POOLTAG);
+        RxContext->PrefixClaim.SuppliedPathName.Buffer = RxAllocatePoolWithTag(NonPagedPool, QueryRequest->PathNameLength, RX_MISC_POOLTAG);
         if (RxContext->PrefixClaim.SuppliedPathName.Buffer == NULL)
         {
             Status = STATUS_INSUFFICIENT_RESOURCES;
@@ -4885,7 +7485,7 @@ Leave:
     {
         if (RxContext->PrefixClaim.SuppliedPathName.Buffer != NULL)
         {
-            ExFreePoolWithTag(RxContext->PrefixClaim.SuppliedPathName.Buffer, RX_MISC_POOLTAG);
+            RxFreePoolWithTag(RxContext->PrefixClaim.SuppliedPathName.Buffer, RX_MISC_POOLTAG);
         }
 
         RxpPrepareCreateContextForReuse(RxContext);
@@ -4896,6 +7496,9 @@ Leave:
     return Status;
 }
 
+/*
+ * @implemented
+ */
 NTSTATUS
 NTAPI
 RxPrepareToReparseSymbolicLink(
@@ -4905,8 +7508,74 @@ RxPrepareToReparseSymbolicLink(
     BOOLEAN NewPathIsAbsolute,
     PBOOLEAN ReparseRequired)
 {
-    UNIMPLEMENTED;
-    return STATUS_NOT_IMPLEMENTED;
+    PWSTR NewBuffer;
+    USHORT NewLength;
+    PFILE_OBJECT FileObject;
+
+    /* Assume no reparse is required first */
+    *ReparseRequired = FALSE;
+
+    /* Only supported for IRP_MJ_CREATE */
+    if (RxContext->MajorFunction != IRP_MJ_CREATE)
+    {
+        return STATUS_INVALID_PARAMETER;
+    }
+
+    /* If symbolic link is not embedded, and DELETE is specified, fail */
+    if (!SymbolicLinkEmbeddedInOldPath)
+    {
+        /* Excepted if DELETE is the only flag specified, then, open has to succeed
+         * See: https://msdn.microsoft.com/en-us/library/windows/hardware/ff554649(v=vs.85).aspx (remarks)
+         */
+        if (BooleanFlagOn(RxContext->Create.NtCreateParameters.DesiredAccess, DELETE) &&
+            BooleanFlagOn(RxContext->Create.NtCreateParameters.DesiredAccess, ~DELETE))
+        {
+            return STATUS_ACCESS_DENIED;
+        }
+    }
+
+    /* At that point, assume reparse will be required */
+    *ReparseRequired = TRUE;
+
+    /* If new path isn't absolute, it's up to us to make it absolute */
+    if (!NewPathIsAbsolute)
+    {
+        /* The prefix will be \Device\Mup */
+        NewLength = NewPath->Length + (sizeof(L"\\Device\\Mup") - sizeof(UNICODE_NULL));
+        NewBuffer = ExAllocatePoolWithTag(PagedPool | POOL_COLD_ALLOCATION, NewLength,
+                                          RX_MISC_POOLTAG);
+        if (NewBuffer == NULL)
+        {
+            return STATUS_INSUFFICIENT_RESOURCES;
+        }
+
+        /* Copy data for the new path */
+        RtlMoveMemory(NewBuffer, L"\\Device\\Mup", (sizeof(L"\\Device\\Mup") - sizeof(UNICODE_NULL)));
+        RtlMoveMemory(Add2Ptr(NewBuffer, (sizeof(L"\\Device\\Mup") - sizeof(UNICODE_NULL))),
+                      NewPath->Buffer, NewPath->Length);
+    }
+    /* Otherwise, use caller path as it */
+    else
+    {
+        NewLength = NewPath->Length;
+        NewBuffer = NewPath->Buffer;
+    }
+
+    /* Get the FILE_OBJECT we'll modify */
+    FileObject = RxContext->CurrentIrpSp->FileObject;
+
+    /* Free old path first */
+    ExFreePoolWithTag(FileObject->FileName.Buffer, 0);
+    /* And setup new one */
+    FileObject->FileName.Length = NewLength;
+    FileObject->FileName.MaximumLength = NewLength;
+    FileObject->FileName.Buffer = NewBuffer;
+
+    /* And set reparse flag */
+    SetFlag(RxContext->Create.Flags, RX_CONTEXT_CREATE_FLAG_REPARSE);
+
+    /* Done! */
+    return STATUS_SUCCESS;
 }
 
 /*
@@ -4967,6 +7636,29 @@ RxPrePostIrp(
     IoMarkIrpPending(Irp);
 }
 
+/*
+ * @implemented
+ */
+NTSTATUS
+RxpSetInfoMiniRdr(
+    PRX_CONTEXT RxContext,
+    FILE_INFORMATION_CLASS Class)
+{
+    PFCB Fcb;
+    NTSTATUS Status;
+
+    /* Initialize parameters in RX_CONTEXT */
+    RxContext->Info.FileInformationClass = Class;
+    RxContext->Info.Buffer = RxContext->CurrentIrp->AssociatedIrp.SystemBuffer;
+    RxContext->Info.Length = RxContext->CurrentIrpSp->Parameters.SetFile.Length;
+
+    /* And call mini-rdr */
+    Fcb = (PFCB)RxContext->pFcb;
+    MINIRDR_CALL(Status, RxContext, Fcb->MRxDispatch, MRxSetFileInfo, (RxContext));
+
+    return Status;
+}
+
 VOID
 NTAPI
 RxpUnregisterMinirdr(
@@ -4975,6 +7667,28 @@ RxpUnregisterMinirdr(
     UNIMPLEMENTED;
 }
 
+/*
+ * @implemented
+ */
+VOID
+RxPurgeNetFcb(
+    PFCB Fcb,
+    PRX_CONTEXT LocalContext)
+{
+    NTSTATUS Status;
+
+    PAGED_CODE();
+
+    /* First, flush */
+    MmFlushImageSection(&Fcb->NonPaged->SectionObjectPointers, MmFlushForWrite);
+
+    /* And force close */
+    RxReleaseFcb(NULL, Fcb);
+    MmForceSectionClosed(&Fcb->NonPaged->SectionObjectPointers, TRUE);
+    Status = RxAcquireExclusiveFcb(NULL, Fcb);
+    ASSERT(Status == STATUS_SUCCESS);
+}
+
 NTSTATUS
 RxQueryAlternateNameInfo(
     PRX_CONTEXT RxContext,
@@ -5151,14 +7865,14 @@ RxQueryDirectory(
             {
                 Fobx->ContainsWildCards = FsRtlDoesNameContainWildCards(FileName);
 
-                Fobx->UnicodeQueryTemplate.Buffer = RxAllocatePoolWithTag(PagedPool, FileName->Length, 'cDxR');
+                Fobx->UnicodeQueryTemplate.Buffer = RxAllocatePoolWithTag(PagedPool, FileName->Length, RX_DIRCTL_POOLTAG);
                 if (Fobx->UnicodeQueryTemplate.Buffer != NULL)
                 {
                     /* UNICODE_STRING; length has to be even */
                     if ((FileName->Length & 1) != 0)
                     {
                         Status = STATUS_INVALID_PARAMETER;
-                        RxFreePool(Fobx->UnicodeQueryTemplate.Buffer);
+                        RxFreePoolWithTag(Fobx->UnicodeQueryTemplate.Buffer, RX_DIRCTL_POOLTAG);
                     }
                     else
                     {
@@ -5359,14 +8073,14 @@ RxReadRegistryParameters(
     Status = ZwQueryValueKey(KeyHandle, &ParamName, KeyValuePartialInformation, PartialInfo, sizeof(Buffer), &ResultLength);
     if (NT_SUCCESS(Status) && PartialInfo->Type == REG_DWORD)
     {
-        DisableByteRangeLockingOnReadOnlyFiles = ((ULONG)PartialInfo->Data != 0);
+        DisableByteRangeLockingOnReadOnlyFiles = (*(PULONG)PartialInfo->Data != 0);
     }
 
     RtlInitUnicodeString(&ParamName, L"ReadAheadGranularity");
     Status = ZwQueryValueKey(KeyHandle, &ParamName, KeyValuePartialInformation, PartialInfo, sizeof(Buffer), &ResultLength);
     if (NT_SUCCESS(Status) && PartialInfo->Type == REG_DWORD)
     {
-        ULONG Granularity = (ULONG)PartialInfo->Data;
+        ULONG Granularity = *(PULONG)PartialInfo->Data;
 
         if (Granularity > 16)
         {
@@ -5380,7 +8094,7 @@ RxReadRegistryParameters(
     Status = ZwQueryValueKey(KeyHandle, &ParamName, KeyValuePartialInformation, PartialInfo, sizeof(Buffer), &ResultLength);
     if (NT_SUCCESS(Status) && PartialInfo->Type == REG_DWORD)
     {
-        DisableFlushOnCleanup = ((ULONG)PartialInfo->Data != 0);
+        DisableFlushOnCleanup = (*(PULONG)PartialInfo->Data != 0);
     }
 
     ZwClose(KeyHandle);
@@ -5466,7 +8180,8 @@ RxRegisterMinirdr(
         RxInitializePrefixTable(RDBSSDevice->pRxNetNameTable, 0, FALSE);
         RDBSSDevice->RxNetNameTableInDeviceObject.IsNetNameTable = TRUE;
         ScavengerTimeLimit.QuadPart = MrdrDispatch->ScavengerTimeout * 10000000LL;
-        RxInitializeRdbssScavenger(&RDBSSDevice->RdbssScavengerInDeviceObject, ScavengerTimeLimit);
+        RDBSSDevice->pRdbssScavenger = &RDBSSDevice->RdbssScavengerInDeviceObject;
+        RxInitializeRdbssScavenger(RDBSSDevice->pRdbssScavenger, ScavengerTimeLimit);
     }
 
     RDBSSDevice->pAsynchronousRequestsCompletionEvent = NULL;
@@ -5474,40 +8189,6 @@ RxRegisterMinirdr(
     return STATUS_SUCCESS;
 }
 
-VOID
-NTAPI
-RxReleaseFcbFromLazyWrite(
-    PVOID Context)
-{
-    UNIMPLEMENTED;
-}
-
-VOID
-NTAPI
-RxReleaseFcbFromReadAhead(
-    PVOID Context)
-{
-    UNIMPLEMENTED;
-}
-
-VOID
-NTAPI
-RxReleaseFileForNtCreateSection(
-    PFILE_OBJECT FileObject)
-{
-    UNIMPLEMENTED;
-}
-
-NTSTATUS
-NTAPI
-RxReleaseForCcFlush(
-    PFILE_OBJECT FileObject,
-    PDEVICE_OBJECT DeviceObject)
-{
-    UNIMPLEMENTED;
-    return STATUS_NOT_IMPLEMENTED;
-}
-
 /*
  * @implemented
  */
@@ -5562,6 +8243,10 @@ RxRemoveOverflowEntry(
     return Context;
 }
 
+#if DBG
+/*
+ * @implemented
+ */
 VOID
 RxRemoveShareAccess(
     _Inout_ PFILE_OBJECT FileObject,
@@ -5569,7 +8254,59 @@ RxRemoveShareAccess(
     _In_ PSZ where,
     _In_ PSZ wherelogtag)
 {
-    UNIMPLEMENTED;
+    PAGED_CODE();
+
+    RxDumpCurrentAccess(where, "before", wherelogtag, ShareAccess);
+    IoRemoveShareAccess(FileObject, ShareAccess);
+    RxDumpCurrentAccess(where, "after", wherelogtag, ShareAccess);
+}
+#endif
+
+/*
+ * @implemented
+ */
+VOID
+RxRemoveShareAccessPerSrvOpens(
+    IN OUT PSRV_OPEN SrvOpen)
+{
+    ACCESS_MASK DesiredAccess;
+    BOOLEAN ReadAccess;
+    BOOLEAN WriteAccess;
+    BOOLEAN DeleteAccess;
+
+    PAGED_CODE();
+
+    /* Get access that were granted to SRV_OPEN */
+    DesiredAccess = SrvOpen->DesiredAccess;
+    ReadAccess = (DesiredAccess & (FILE_READ_DATA | FILE_EXECUTE)) != 0;
+    WriteAccess = (DesiredAccess & (FILE_WRITE_DATA | FILE_APPEND_DATA)) != 0;
+    DeleteAccess = (DesiredAccess & DELETE) != 0;
+
+    /* If any, drop them */
+    if ((ReadAccess) || (WriteAccess) || (DeleteAccess))
+    {
+        BOOLEAN SharedRead;
+        BOOLEAN SharedWrite;
+        BOOLEAN SharedDelete;
+        ULONG DesiredShareAccess;
+        PSHARE_ACCESS ShareAccess;
+
+        ShareAccess = &((PFCB)SrvOpen->pFcb)->ShareAccessPerSrvOpens;
+        DesiredShareAccess = SrvOpen->ShareAccess;
+
+        ShareAccess->Readers -= ReadAccess;
+        ShareAccess->Writers -= WriteAccess;
+        ShareAccess->Deleters -= DeleteAccess;
+
+        ShareAccess->OpenCount--;
+
+        SharedRead = (DesiredShareAccess & FILE_SHARE_READ) != 0;
+        SharedWrite = (DesiredShareAccess & FILE_SHARE_WRITE) != 0;
+        SharedDelete = (DesiredShareAccess & FILE_SHARE_DELETE) != 0;
+        ShareAccess->SharedRead -= SharedRead;
+        ShareAccess->SharedWrite -= SharedWrite;
+        ShareAccess->SharedDelete -= SharedDelete;
+    }
 }
 
 NTSTATUS
@@ -5757,6 +8494,158 @@ TryAgain:
     return Status;
 }
 
+NTSTATUS
+RxSetAllocationInfo(
+    PRX_CONTEXT RxContext)
+{
+    UNIMPLEMENTED;
+    return STATUS_NOT_IMPLEMENTED;
+}
+
+/*
+ * @implemented
+ */
+NTSTATUS
+RxSetBasicInfo(
+    PRX_CONTEXT RxContext)
+{
+    NTSTATUS Status;
+
+    PAGED_CODE();
+
+#define FILE_ATTRIBUTE_VOLUME 0x8
+#define VALID_FILE_ATTRIBUTES (                                   \
+    FILE_ATTRIBUTE_READONLY | FILE_ATTRIBUTE_HIDDEN |             \
+    FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_VOLUME |               \
+    FILE_ATTRIBUTE_ARCHIVE | FILE_ATTRIBUTE_DEVICE |              \
+    FILE_ATTRIBUTE_TEMPORARY | FILE_ATTRIBUTE_SPARSE_FILE |       \
+    FILE_ATTRIBUTE_REPARSE_POINT | FILE_ATTRIBUTE_COMPRESSED |    \
+    FILE_ATTRIBUTE_OFFLINE | FILE_ATTRIBUTE_NOT_CONTENT_INDEXED | \
+    FILE_ATTRIBUTE_ENCRYPTED | FILE_ATTRIBUTE_INTEGRITY_STREAM)
+#define VALID_DIR_ATTRIBUTES (VALID_FILE_ATTRIBUTES | FILE_ATTRIBUTE_DIRECTORY)
+
+    /* First of all, call the mini-rdr */
+    Status = RxpSetInfoMiniRdr(RxContext, FileBasicInformation);
+    /* If it succeed, perform last bits */
+    if (NT_SUCCESS(Status))
+    {
+        PIRP Irp;
+        PFCB Fcb;
+        PFOBX Fobx;
+        PFILE_OBJECT FileObject;
+        ULONG Attributes, CleanAttr;
+        PFILE_BASIC_INFORMATION BasicInfo;
+
+        Fcb = (PFCB)RxContext->pFcb;
+        Fobx = (PFOBX)RxContext->pFobx;
+        Irp = RxContext->CurrentIrp;
+        BasicInfo = Irp->AssociatedIrp.SystemBuffer;
+        FileObject = RxContext->CurrentIrpSp->FileObject;
+
+        /* If caller provided flags, handle the change */
+        Attributes = BasicInfo->FileAttributes;
+        if (Attributes != 0)
+        {
+            /* Clean our flags first, with only stuff we support */
+            if (NodeType(Fcb) == RDBSS_NTC_STORAGE_TYPE_DIRECTORY)
+            {
+                CleanAttr = (Attributes & VALID_DIR_ATTRIBUTES) | FILE_ATTRIBUTE_DIRECTORY;
+            }
+            else
+            {
+                CleanAttr = Attributes & VALID_FILE_ATTRIBUTES;
+            }
+
+            /* Handle the temporary mark (set/unset depending on caller) */
+            if (BooleanFlagOn(Attributes, FILE_ATTRIBUTE_TEMPORARY))
+            {
+                SetFlag(Fcb->FcbState, FCB_STATE_TEMPORARY);
+                SetFlag(FileObject->Flags, FO_TEMPORARY_FILE);
+            }
+            else
+            {
+                ClearFlag(Fcb->FcbState, FCB_STATE_TEMPORARY);
+                ClearFlag(FileObject->Flags, FO_TEMPORARY_FILE);
+            }
+
+            /* And set new attributes */
+            Fcb->Attributes = CleanAttr;
+        }
+
+        /* If caller provided a creation time, set it */
+        if (BasicInfo->CreationTime.QuadPart != 0LL)
+        {
+            Fcb->CreationTime.QuadPart = BasicInfo->CreationTime.QuadPart;
+            SetFlag(Fobx->Flags, FOBX_FLAG_USER_SET_CREATION);
+        }
+
+        /* If caller provided a last access time, set it */
+        if (BasicInfo->LastAccessTime.QuadPart != 0LL)
+        {
+            Fcb->LastAccessTime.QuadPart = BasicInfo->LastAccessTime.QuadPart;
+            SetFlag(Fobx->Flags, FOBX_FLAG_USER_SET_LAST_ACCESS);
+        }
+
+        /* If caller provided a last write time, set it */
+        if (BasicInfo->LastWriteTime.QuadPart != 0LL)
+        {
+            Fcb->LastWriteTime.QuadPart = BasicInfo->LastWriteTime.QuadPart;
+            SetFlag(Fobx->Flags, FOBX_FLAG_USER_SET_LAST_WRITE);
+        }
+
+        /* If caller provided a last change time, set it */
+        if (BasicInfo->ChangeTime.QuadPart != 0LL)
+        {
+            Fcb->LastChangeTime.QuadPart = BasicInfo->ChangeTime.QuadPart;
+            SetFlag(Fobx->Flags, FOBX_FLAG_USER_SET_LAST_CHANGE);
+        }
+    }
+
+    /* Done */
+    return Status;
+}
+
+NTSTATUS
+RxSetDispositionInfo(
+    PRX_CONTEXT RxContext)
+{
+    UNIMPLEMENTED;
+    return STATUS_NOT_IMPLEMENTED;
+}
+
+NTSTATUS
+RxSetEndOfFileInfo(
+    PRX_CONTEXT RxContext)
+{
+    UNIMPLEMENTED;
+    return STATUS_NOT_IMPLEMENTED;
+}
+
+NTSTATUS
+RxSetPipeInfo(
+    PRX_CONTEXT RxContext)
+{
+    UNIMPLEMENTED;
+    return STATUS_NOT_IMPLEMENTED;
+}
+
+NTSTATUS
+RxSetPositionInfo(
+    PRX_CONTEXT RxContext)
+{
+    UNIMPLEMENTED;
+    return STATUS_NOT_IMPLEMENTED;
+}
+
+NTSTATUS
+RxSetRenameInfo(
+    PRX_CONTEXT RxContext)
+{
+    UNIMPLEMENTED;
+    return STATUS_NOT_IMPLEMENTED;
+}
+
+#if DBG
 /*
  * @implemented
  */
@@ -5775,6 +8664,15 @@ RxSetShareAccess(
     IoSetShareAccess(DesiredAccess, DesiredShareAccess, FileObject, ShareAccess);
     RxDumpCurrentAccess(where, "after", wherelogtag, ShareAccess);
 }
+#endif
+
+NTSTATUS
+RxSetSimpleInfo(
+    PRX_CONTEXT RxContext)
+{
+    UNIMPLEMENTED;
+    return STATUS_NOT_IMPLEMENTED;
+}
 
 /*
  * @implemented
@@ -6001,7 +8899,7 @@ RxTryToBecomeTheTopLevelIrp(
     /* If not TLC provider, allocate one */
     if (TopLevelContext == NULL)
     {
-        TopLevelContext = RxAllocatePoolWithTag(NonPagedPool, sizeof(RX_TOPLEVELIRP_CONTEXT), '??xR');
+        TopLevelContext = RxAllocatePoolWithTag(NonPagedPool, sizeof(RX_TOPLEVELIRP_CONTEXT), RX_TLC_POOLTAG);
         if (TopLevelContext == NULL)
         {
             return FALSE;
@@ -6024,6 +8922,7 @@ RxTryToBecomeTheTopLevelIrp(
     return TRUE;
 }
 
+#if DBG
 /*
  * @implemented
  */
@@ -6040,6 +8939,7 @@ RxUpdateShareAccess(
     IoUpdateShareAccess(FileObject, ShareAccess);
     RxDumpCurrentAccess(where, "after", wherelogtag, ShareAccess);
 }
+#endif
 
 /*
  * @implemented
@@ -6129,7 +9029,7 @@ RxUnwindTopLevelIrp(
     if (BooleanFlagOn(TopLevelContext->Flags, RX_TOPLEVELCTX_FLAG_FROM_POOL))
     {
         RxRemoveFromTopLevelIrpAllocatedContextsList(TopLevelContext);
-        ExFreePool(TopLevelContext);
+        RxFreePoolWithTag(TopLevelContext, RX_TLC_POOLTAG);
     }
 }