Author: pschweitzer
Date: Wed Jul 5 06:11:10 2017
New Revision: 75286
URL:
http://svn.reactos.org/svn/reactos?rev=75286&view=rev
Log:
[RXCE]
- Implement RxFinalizeConnection(), RxOrphanSrvOpens()
- Stub RxOrphanSrvOpensForThisFcb()
[RDBSS]
- Fix a bug in RxCommonDevFCBClose() where prefix table wasn't acquire exclusively;
this was problematic due to potential prefix table removal on dereference
- Stub RxCancelNotifyChangeDirectoryRequestsForVNetRoot()
This commit basically allows you to delete a NFS share you would have made use of in
ReactOS.
Like net use z: \\share\path can be deleted through net use /delete z:
Note that if you access the share using cmd tools (dir, copy, more, and so on), dismount
will work.
If you attempt to access with Explorer, then, handles will be kept open and dismount will
fail.
CORE-8204
CORE-11327
Modified:
trunk/reactos/sdk/include/ddk/fcb.h
trunk/reactos/sdk/include/ddk/mrxfcb.h
trunk/reactos/sdk/include/ddk/rxcontx.h
trunk/reactos/sdk/include/ddk/rxprocs.h
trunk/reactos/sdk/lib/drivers/rdbsslib/rdbss.c
trunk/reactos/sdk/lib/drivers/rxce/rxce.c
Modified: trunk/reactos/sdk/include/ddk/fcb.h
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/sdk/include/ddk/fcb.h?rev=…
==============================================================================
--- trunk/reactos/sdk/include/ddk/fcb.h [iso-8859-1] (original)
+++ trunk/reactos/sdk/include/ddk/fcb.h [iso-8859-1] Wed Jul 5 06:11:10 2017
@@ -619,18 +619,18 @@
_In_ BOOLEAN ForceFinalize);
#ifdef __REACTOS__
-#define FILL_IN_FCB(Fcb, a, nl, ct, lat, lwt, lct, as, fs, vdl) \
- (Fcb)->Attributes = a; \
- (Fcb)->NumberOfLinks = nl; \
- (Fcb)->CreationTime.QuadPart = ct; \
- (Fcb)->LastAccessTime.QuadPart = lat; \
- (Fcb)->LastWriteTime.QuadPart = lwt; \
- (Fcb)->LastChangeTime.QuadPart = lct; \
- (Fcb)->ActualAllocationLength = as; \
- (Fcb)->Header.AllocationSize.QuadPart = as; \
- (Fcb)->Header.FileSize.QuadPart = fs; \
- (Fcb)->Header.ValidDataLength.QuadPart = vdl; \
- (Fcb)->FcbState |= FCB_STATE_TIME_AND_SIZE_ALREADY_SET
+#define FILL_IN_FCB(Fcb, a, nl, ct, lat, lwt, lct, as, fs, vdl) \
+ (Fcb)->Attributes = a; \
+ (Fcb)->NumberOfLinks = nl; \
+ (Fcb)->CreationTime.QuadPart = ct; \
+ (Fcb)->LastAccessTime.QuadPart = lat; \
+ (Fcb)->LastWriteTime.QuadPart = lwt; \
+ (Fcb)->LastChangeTime.QuadPart = lct; \
+ (Fcb)->ActualAllocationLength = as; \
+ (Fcb)->Header.AllocationSize.QuadPart = as; \
+ (Fcb)->Header.FileSize.QuadPart = fs; \
+ (Fcb)->Header.ValidDataLength.QuadPart = vdl; \
+ SetFlag((Fcb)->FcbState, FCB_STATE_TIME_AND_SIZE_ALREADY_SET)
#define TRACKER_ACQUIRE_FCB 0x61616161
#define TRACKER_RELEASE_FCB_NO_BUFF_PENDING 0x72727272
Modified: trunk/reactos/sdk/include/ddk/mrxfcb.h
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/sdk/include/ddk/mrxfcb.h?r…
==============================================================================
--- trunk/reactos/sdk/include/ddk/mrxfcb.h [iso-8859-1] (original)
+++ trunk/reactos/sdk/include/ddk/mrxfcb.h [iso-8859-1] Wed Jul 5 06:11:10 2017
@@ -31,6 +31,7 @@
#define NET_ROOT_PIPE ((UCHAR)1)
#define NET_ROOT_PRINT ((UCHAR)3)
#define NET_ROOT_WILD ((UCHAR)4)
+#define NET_ROOT_MAILSLOT ((UCHAR)5)
typedef UCHAR NET_ROOT_TYPE, *PNET_ROOT_TYPE;
Modified: trunk/reactos/sdk/include/ddk/rxcontx.h
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/sdk/include/ddk/rxcontx.h?…
==============================================================================
--- trunk/reactos/sdk/include/ddk/rxcontx.h [iso-8859-1] (original)
+++ trunk/reactos/sdk/include/ddk/rxcontx.h [iso-8859-1] Wed Jul 5 06:11:10 2017
@@ -435,6 +435,11 @@
ExReleaseFastMutex(Mutex); \
}
+NTSTATUS
+RxCancelNotifyChangeDirectoryRequestsForVNetRoot(
+ PV_NET_ROOT VNetRoot,
+ BOOLEAN ForceFilesClosed);
+
VOID
RxCancelNotifyChangeDirectoryRequestsForFobx(
PFOBX Fobx
Modified: trunk/reactos/sdk/include/ddk/rxprocs.h
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/sdk/include/ddk/rxprocs.h?…
==============================================================================
--- trunk/reactos/sdk/include/ddk/rxprocs.h [iso-8859-1] (original)
+++ trunk/reactos/sdk/include/ddk/rxprocs.h [iso-8859-1] Wed Jul 5 06:11:10 2017
@@ -693,6 +693,12 @@
RxOrphanThisFcb(
_In_ PFCB Fcb);
+VOID
+RxOrphanSrvOpensForThisFcb(
+ _In_ PFCB Fcb,
+ _In_ PV_NET_ROOT ThisVNetRoot,
+ _In_ BOOLEAN OrphanAll);
+
#define RxEqualConnectionId(C1, C2) RtlEqualMemory(C1, C2, sizeof(RX_CONNECTION_ID))
NTSTATUS
Modified: trunk/reactos/sdk/lib/drivers/rdbsslib/rdbss.c
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/sdk/lib/drivers/rdbsslib/r…
==============================================================================
--- trunk/reactos/sdk/lib/drivers/rdbsslib/rdbss.c [iso-8859-1] (original)
+++ trunk/reactos/sdk/lib/drivers/rdbsslib/rdbss.c [iso-8859-1] Wed Jul 5 06:11:10 2017
@@ -792,6 +792,15 @@
UNIMPLEMENTED;
}
+NTSTATUS
+RxCancelNotifyChangeDirectoryRequestsForVNetRoot(
+ PV_NET_ROOT VNetRoot,
+ BOOLEAN ForceFilesClosed)
+{
+ UNIMPLEMENTED;
+ return STATUS_NOT_IMPLEMENTED;
+}
+
VOID
NTAPI
RxCancelRoutine(
@@ -2066,7 +2075,7 @@
/* 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;
@@ -3787,17 +3796,6 @@
}
NTSTATUS
-NTAPI
-RxFinalizeConnection(
- IN OUT PNET_ROOT NetRoot,
- IN OUT PV_NET_ROOT VNetRoot OPTIONAL,
- IN LOGICAL ForceFilesClosed)
-{
- UNIMPLEMENTED;
- return STATUS_NOT_IMPLEMENTED;
-}
-
-NTSTATUS
RxFindOrCreateFcb(
PRX_CONTEXT RxContext,
PUNICODE_STRING NetRootName)
Modified: trunk/reactos/sdk/lib/drivers/rxce/rxce.c
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/sdk/lib/drivers/rxce/rxce.…
==============================================================================
--- trunk/reactos/sdk/lib/drivers/rxce/rxce.c [iso-8859-1] (original)
+++ trunk/reactos/sdk/lib/drivers/rxce/rxce.c [iso-8859-1] Wed Jul 5 06:11:10 2017
@@ -2438,6 +2438,182 @@
/*
* @implemented
*/
+NTSTATUS
+NTAPI
+RxFinalizeConnection(
+ IN OUT PNET_ROOT NetRoot,
+ IN OUT PV_NET_ROOT VNetRoot OPTIONAL,
+ IN LOGICAL ForceFilesClosed)
+{
+ NTSTATUS Status;
+ PRX_PREFIX_TABLE PrefixTable;
+ ULONG UncleanAny, UncleanDir;
+ LONG FilesOpen, AdditionalRef;
+ BOOLEAN PrefixLocked, FcbTableLocked, ForceClose;
+
+ PAGED_CODE();
+
+ ASSERT(NodeType(NetRoot) == RDBSS_NTC_NETROOT);
+
+ /* Get a BOOLEAN out of LOGICAL
+ * -1 is like FALSE but also drops extra V_NET_ROOT reference in case of failure
+ */
+ ForceClose = (ForceFilesClosed == TRUE ? TRUE : FALSE);
+
+ /* First, delete any notification change */
+ Status = RxCancelNotifyChangeDirectoryRequestsForVNetRoot(VNetRoot, ForceClose);
+ /* If it failed, continue if forced */
+ if (Status != STATUS_SUCCESS && !ForceFilesClosed)
+ {
+ return Status;
+ }
+ /* Reset status, in case notification deletion failed */
+ Status = STATUS_SUCCESS;
+
+ PrefixTable = NetRoot->pSrvCall->RxDeviceObject->pRxNetNameTable;
+
+ PrefixLocked = FALSE;
+ FcbTableLocked = FALSE;
+ FilesOpen = 0;
+ AdditionalRef = 0;
+ UncleanAny = 0;
+ UncleanDir = 0;
+ _SEH2_TRY
+ {
+ RxAcquirePrefixTableLockExclusive(PrefixTable, TRUE);
+ PrefixLocked = TRUE;
+
+ RxReferenceNetRoot(NetRoot);
+
+ RxAcquireFcbTableLockExclusive(&NetRoot->FcbTable, TRUE);
+ FcbTableLocked = TRUE;
+
+ /* If our V_NET_ROOT wasn't finalized yet, proceed! */
+ if (!VNetRoot->ConnectionFinalizationDone)
+ {
+ USHORT Bucket;
+ PRX_FCB_TABLE FcbTable;
+
+ DPRINT("Finalizing connection %p: %wZ\n", NetRoot,
&NetRoot->PrefixEntry.Prefix);
+
+ /* We'll browse all its associated FCB to check whether they're
open/orphaned */
+ FcbTable = &NetRoot->FcbTable;
+ for (Bucket = 0; Bucket < FcbTable->NumberOfBuckets; ++Bucket)
+ {
+ PLIST_ENTRY BucketList, Entry;
+
+ BucketList = &FcbTable->HashBuckets[Bucket];
+ Entry = BucketList->Flink;
+ while (Entry != BucketList)
+ {
+ PFCB Fcb;
+
+ Fcb = CONTAINING_RECORD(Entry, FCB, FcbTableEntry.HashLinks);
+ Entry = Entry->Flink;
+
+ /* FCB for this connection, go ahead */
+ if (Fcb->VNetRoot == VNetRoot)
+ {
+ /* It's still open, and no force? Fail and keep track */
+ if (Fcb->UncleanCount > 0 && !ForceClose)
+ {
+ Status = STATUS_CONNECTION_IN_USE;
+ if (NodeType(Fcb) == RDBSS_NTC_STORAGE_TYPE_DIRECTORY)
+ {
+ ++UncleanDir;
+ }
+ else
+ {
+ ++UncleanAny;
+ }
+ }
+ else
+ {
+ /* Else, force purge */
+ ASSERT(NodeTypeIsFcb(Fcb));
+
+ Status = RxAcquireExclusiveFcb(NULL, Fcb);
+ ASSERT(Status == STATUS_SUCCESS);
+
+ ClearFlag(Fcb->FcbState, FCB_STATE_COLLAPSING_ENABLED);
+
+ RxScavengeRelatedFobxs(Fcb);
+ RxPurgeFcb(Fcb);
+
+ /* We don't need to release FCB lock, FCB finalize will
take care of it */
+ }
+ }
+ }
+ }
+
+ /* No files left, our V_NET_ROOT is finalized */
+ if (VNetRoot->NumberOfFobxs == 0)
+ {
+ VNetRoot->ConnectionFinalizationDone = TRUE;
+ }
+ }
+
+ /* Keep Number of open files and track of the extra reference */
+ FilesOpen = VNetRoot->NumberOfFobxs;
+ AdditionalRef = VNetRoot->AdditionalReferenceForDeleteFsctlTaken;
+ /* If force close, caller doesn't want to keep connection alive
+ * and wants it totally close, so drop the V_NET_ROOT too
+ */
+ if (ForceClose)
+ {
+ RxFinalizeVNetRoot(VNetRoot, FALSE, TRUE);
+ }
+ }
+ _SEH2_FINALLY
+ {
+ /* Release what was acquired */
+ if (FcbTableLocked)
+ {
+ RxReleaseFcbTableLock(&NetRoot->FcbTable);
+ }
+
+ /* If close is forced, only fix status if there are open files */
+ if (ForceClose)
+ {
+ if (Status != STATUS_SUCCESS && UncleanAny != 0)
+ {
+ Status = STATUS_FILES_OPEN;
+ }
+ }
+ /* Else, fix status and fail closing if there are open files */
+ else
+ {
+ if ((Status != STATUS_SUCCESS && UncleanAny != 0) || FilesOpen >
0)
+ {
+ Status = STATUS_FILES_OPEN;
+ }
+ }
+
+ DPRINT("UncleanAny: %ld, UncleanDir: %ld, FilesOpen: %ld\n",
UncleanAny, UncleanDir, FilesOpen);
+
+ /* If we're are asked to remove the extra ref, or if closing was a success,
do it;
+ * only if it was still referenced!
+ */
+ if ((ForceFilesClosed == 0xFF || Status == STATUS_SUCCESS) &&
AdditionalRef != 0)
+ {
+ VNetRoot->AdditionalReferenceForDeleteFsctlTaken = 0;
+ RxDereferenceVNetRoot(VNetRoot, LHS_ExclusiveLockHeld);
+ }
+
+ if (PrefixLocked)
+ {
+ RxDereferenceNetRoot(NetRoot, LHS_ExclusiveLockHeld);
+ RxReleasePrefixTableLock(PrefixTable);
+ }
+ }
+ _SEH2_END;
+
+ return Status;
+}
+
+/*
+ * @implemented
+ */
VOID
RxFinalizeFcbTable(
IN OUT PRX_FCB_TABLE FcbTable)
@@ -5434,6 +5610,67 @@
RxOrphanSrvOpens(
IN PV_NET_ROOT ThisVNetRoot)
{
+ PFCB Fcb;
+ USHORT Bucket;
+ PNET_ROOT NetRoot;
+ PRX_FCB_TABLE FcbTable;
+ PRX_PREFIX_TABLE PrefixTable;
+
+ PAGED_CODE();
+
+ /* Mailslot won't have any SRV_OPEN (to orphan) */
+ NetRoot = (PNET_ROOT)ThisVNetRoot->pNetRoot;
+ if (NetRoot->Type == NET_ROOT_MAILSLOT)
+ {
+ return;
+ }
+
+ PrefixTable = NetRoot->pSrvCall->RxDeviceObject->pRxNetNameTable;
+ ASSERT(RxIsPrefixTableLockExclusive(PrefixTable));
+
+ FcbTable = &NetRoot->FcbTable;
+ RxAcquireFcbTableLockExclusive(FcbTable, TRUE);
+
+ _SEH2_TRY
+ {
+ /* Now, we'll browse all the FCBs attached, and orphan related SRV_OPENs */
+ for (Bucket = 0; Bucket < FcbTable->NumberOfBuckets; ++Bucket)
+ {
+ PLIST_ENTRY BucketList, Entry;
+
+ BucketList = &FcbTable->HashBuckets[Bucket];
+ Entry = BucketList->Flink;
+ while (Entry != BucketList)
+ {
+ Fcb = CONTAINING_RECORD(Entry, FCB, FcbTableEntry.HashLinks);
+ Entry = Entry->Flink;
+
+ ASSERT(NodeTypeIsFcb(Fcb));
+ RxOrphanSrvOpensForThisFcb(Fcb, ThisVNetRoot, FALSE);
+ }
+ }
+
+ /* Of course, don't forget about NULL-entry */
+ if (FcbTable->TableEntryForNull != NULL)
+ {
+ Fcb = CONTAINING_RECORD(FcbTable->TableEntryForNull, FCB,
FcbTableEntry.HashLinks);
+ ASSERT(NodeTypeIsFcb(Fcb));
+ RxOrphanSrvOpensForThisFcb(Fcb, ThisVNetRoot, FALSE);
+ }
+ }
+ _SEH2_FINALLY
+ {
+ RxReleaseFcbTableLock(FcbTable);
+ }
+ _SEH2_END;
+}
+
+VOID
+RxOrphanSrvOpensForThisFcb(
+ IN PFCB Fcb,
+ IN PV_NET_ROOT ThisVNetRoot,
+ IN BOOLEAN OrphanAll)
+{
UNIMPLEMENTED;
}