Windows: Add global root to name array if share name
[openafs.git] / src / WINNT / afsrdr / kernel / lib / AFSNameSupport.cpp
index f4fad07..743c3c5 100644 (file)
@@ -63,9 +63,11 @@ AFSLocateNameEntry( IN GUID *AuthGroup,
     BOOLEAN           bAllocatedSymLinkBuffer = FALSE;
     UNICODE_STRING    uniRelativeName, uniNoOpName;
     AFSObjectInfoCB  *pCurrentObject = NULL;
+    AFSObjectInfoCB  *pParentObjectInfo = NULL;
     AFSVolumeCB      *pCurrentVolume = *VolumeCB;
     BOOLEAN           bReleaseCurrentVolume = TRUE;
     BOOLEAN           bSubstitutedName = FALSE;
+    LONG              lCount;
 
     __Enter
     {
@@ -154,7 +156,7 @@ AFSLocateNameEntry( IN GUID *AuthGroup,
                               pCurrentObject->FileId.Volume,
                               pCurrentObject->FileId.Vnode,
                               pCurrentObject->FileId.Unique,
-                              ntStatus);
+                              STATUS_FILE_DELETED);
 
                 try_return( ntStatus = STATUS_FILE_DELETED);
             }
@@ -171,7 +173,7 @@ AFSLocateNameEntry( IN GUID *AuthGroup,
                               pCurrentObject->FileId.Volume,
                               pCurrentObject->FileId.Vnode,
                               pCurrentObject->FileId.Unique,
-                              ntStatus);
+                              STATUS_DELETE_PENDING);
 
                 try_return( ntStatus = STATUS_DELETE_PENDING);
             }
@@ -195,9 +197,18 @@ AFSLocateNameEntry( IN GUID *AuthGroup,
                               pCurrentObject->FileId.Vnode,
                               pCurrentObject->FileId.Unique);
 
+                //
+                // Directory TreeLock should be exclusively held
+                //
+
+                AFSAcquireExcl( pCurrentObject->Specific.Directory.DirectoryNodeHdr.TreeLock,
+                                TRUE);
+
                 ntStatus = AFSVerifyEntry( AuthGroup,
                                            pDirEntry);
 
+                AFSReleaseResource( pCurrentObject->Specific.Directory.DirectoryNodeHdr.TreeLock);
+
                 if( !NT_SUCCESS( ntStatus))
                 {
 
@@ -240,16 +251,55 @@ AFSLocateNameEntry( IN GUID *AuthGroup,
                 if( !NT_SUCCESS( ntStatus))
                 {
 
-                    AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
-                                  AFS_TRACE_LEVEL_ERROR,
-                                  "AFSLocateNameEntry (FO: %08lX) Failed to evaluate parent %wZ FID %08lX-%08lX-%08lX-%08lX Status %08lX\n",
-                                  FileObject,
-                                  &pDirEntry->NameInformation.FileName,
-                                  pCurrentObject->FileId.Cell,
-                                  pCurrentObject->FileId.Volume,
-                                  pCurrentObject->FileId.Vnode,
-                                  pCurrentObject->FileId.Unique,
-                                  ntStatus);
+                    if ( ntStatus == STATUS_NOT_A_DIRECTORY)
+                    {
+
+                        if ( pCurrentObject->ParentObjectInformation == NULL)
+                        {
+
+                            AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
+                                          AFS_TRACE_LEVEL_ERROR,
+                                          "AFSLocateNameEntry (FO: %08lX) Failed to evaluate object %wZ FID %08lX-%08lX-%08lX-%08lX PARENT NULL Status %08lX\n",
+                                          FileObject,
+                                          &pDirEntry->NameInformation.FileName,
+                                          pCurrentObject->FileId.Cell,
+                                          pCurrentObject->FileId.Volume,
+                                          pCurrentObject->FileId.Vnode,
+                                          pCurrentObject->FileId.Unique,
+                                          ntStatus);
+                        }
+                        else
+                        {
+
+                            AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
+                                          AFS_TRACE_LEVEL_ERROR,
+                                          "AFSLocateNameEntry (FO: %08lX) Failed to evaluate object %wZ FID %08lX-%08lX-%08lX-%08lX PARENT %08lX-%08lX-%08lX-%08lX Status %08lX\n",
+                                          FileObject,
+                                          &pDirEntry->NameInformation.FileName,
+                                          pCurrentObject->FileId.Cell,
+                                          pCurrentObject->FileId.Volume,
+                                          pCurrentObject->FileId.Vnode,
+                                          pCurrentObject->FileId.Unique,
+                                          pCurrentObject->ParentObjectInformation->FileId.Cell,
+                                          pCurrentObject->ParentObjectInformation->FileId.Volume,
+                                          pCurrentObject->ParentObjectInformation->FileId.Vnode,
+                                          pCurrentObject->ParentObjectInformation->FileId.Unique,
+                                          ntStatus);
+                        }
+                    }
+                    else
+                    {
+                        AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
+                                      AFS_TRACE_LEVEL_ERROR,
+                                      "AFSLocateNameEntry (FO: %08lX) Failed to evaluate parent %wZ FID %08lX-%08lX-%08lX-%08lX Status %08lX\n",
+                                      FileObject,
+                                      &pDirEntry->NameInformation.FileName,
+                                      pCurrentObject->FileId.Cell,
+                                      pCurrentObject->FileId.Volume,
+                                      pCurrentObject->FileId.Vnode,
+                                      pCurrentObject->FileId.Unique,
+                                      ntStatus);
+                    }
 
                     try_return( ntStatus);
                 }
@@ -295,6 +345,9 @@ AFSLocateNameEntry( IN GUID *AuthGroup,
                         try_return( ntStatus);
                     }
 
+                    AFSAcquireExcl( pCurrentObject->Specific.Directory.DirectoryNodeHdr.TreeLock,
+                                    TRUE);
+
                     AFSAcquireExcl( &pDirEntry->NonPaged->Lock,
                                     TRUE);
 
@@ -319,9 +372,15 @@ AFSLocateNameEntry( IN GUID *AuthGroup,
                                       pCurrentObject->FileId.Vnode,
                                       pCurrentObject->FileId.Unique);
 
+                        //
+                        // Directory TreeLock should be exclusively held
+                        //
+
                         ntStatus = AFSVerifyEntry( AuthGroup,
                                                    pDirEntry);
 
+                        AFSReleaseResource( pCurrentObject->Specific.Directory.DirectoryNodeHdr.TreeLock);
+
                         if( !NT_SUCCESS( ntStatus))
                         {
 
@@ -353,6 +412,11 @@ AFSLocateNameEntry( IN GUID *AuthGroup,
                             continue;
                         }
                     }
+                    else
+                    {
+
+                        AFSReleaseResource( pCurrentObject->Specific.Directory.DirectoryNodeHdr.TreeLock);
+                    }
 
                     //
                     // If we were given a zero length target name then deny access to the entry
@@ -361,7 +425,7 @@ AFSLocateNameEntry( IN GUID *AuthGroup,
                     if( pDirEntry->NameInformation.TargetName.Length == 0)
                     {
 
-                        ntStatus = STATUS_ACCESS_DENIED;
+                        ntStatus = STATUS_REPARSE_POINT_NOT_RESOLVED;
 
                         AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
                                       AFS_TRACE_LEVEL_ERROR,
@@ -497,7 +561,7 @@ AFSLocateNameEntry( IN GUID *AuthGroup,
                         // Dereference the current entry ..
                         //
 
-                        InterlockedDecrement( &pDirEntry->OpenReferenceCount);
+                        lCount = InterlockedDecrement( &pDirEntry->OpenReferenceCount);
 
                         AFSDbgLogMsg( AFS_SUBSYSTEM_DIRENTRY_REF_COUNTING,
                                       AFS_TRACE_LEVEL_VERBOSE,
@@ -505,7 +569,7 @@ AFSLocateNameEntry( IN GUID *AuthGroup,
                                       &pDirEntry->NameInformation.FileName,
                                       pDirEntry,
                                       NULL,
-                                      pDirEntry->OpenReferenceCount);
+                                      lCount);
 
                         //
                         // OK, need to back up one entry for the correct parent since the current
@@ -518,7 +582,7 @@ AFSLocateNameEntry( IN GUID *AuthGroup,
                         // Increment our reference on this dir entry
                         //
 
-                        InterlockedIncrement( &pDirEntry->OpenReferenceCount);
+                        lCount = InterlockedIncrement( &pDirEntry->OpenReferenceCount);
 
                         AFSDbgLogMsg( AFS_SUBSYSTEM_DIRENTRY_REF_COUNTING,
                                       AFS_TRACE_LEVEL_VERBOSE,
@@ -526,7 +590,7 @@ AFSLocateNameEntry( IN GUID *AuthGroup,
                                       &pDirEntry->NameInformation.FileName,
                                       pDirEntry,
                                       NULL,
-                                      pDirEntry->OpenReferenceCount);
+                                      lCount);
 
                         if( BooleanFlagOn( pDirEntry->ObjectInformation->Flags, AFS_OBJECT_ROOT_VOLUME))
                         {
@@ -655,35 +719,30 @@ AFSLocateNameEntry( IN GUID *AuthGroup,
                                           pCurrentObject->FileId.Vnode,
                                           pCurrentObject->FileId.Unique);
 
-                            InterlockedDecrement( &pCurrentVolume->VolumeReferenceCount);
+                            lCount = InterlockedDecrement( &pCurrentVolume->VolumeReferenceCount);
 
                             AFSDbgLogMsg( AFS_SUBSYSTEM_VOLUME_REF_COUNTING,
                                           AFS_TRACE_LEVEL_VERBOSE,
                                           "AFSLocateNameEntry Decrement count on volume %08lX Cnt %d\n",
                                           pCurrentVolume,
-                                          pCurrentVolume->VolumeReferenceCount);
-
-                            AFSReleaseResource( pCurrentVolume->VolumeLock);
+                                          lCount);
 
                             pCurrentVolume = AFSGlobalRoot;
 
-                            AFSAcquireShared( pCurrentVolume->VolumeLock,
-                                              TRUE);
-
-                            InterlockedIncrement( &pCurrentVolume->VolumeReferenceCount);
+                            lCount = InterlockedIncrement( &pCurrentVolume->VolumeReferenceCount);
 
                             AFSDbgLogMsg( AFS_SUBSYSTEM_VOLUME_REF_COUNTING,
                                           AFS_TRACE_LEVEL_VERBOSE,
                                           "AFSLocateNameEntry Increment count on volume %08lX Cnt %d\n",
                                           pCurrentVolume,
-                                          pCurrentVolume->VolumeReferenceCount);
+                                          lCount);
                         }
 
                         //
                         // Dereference our current dir entry
                         //
 
-                        InterlockedDecrement( &pDirEntry->OpenReferenceCount);
+                        lCount = InterlockedDecrement( &pDirEntry->OpenReferenceCount);
 
                         AFSDbgLogMsg( AFS_SUBSYSTEM_DIRENTRY_REF_COUNTING,
                                       AFS_TRACE_LEVEL_VERBOSE,
@@ -691,7 +750,7 @@ AFSLocateNameEntry( IN GUID *AuthGroup,
                                       &pDirEntry->NameInformation.FileName,
                                       pDirEntry,
                                       NULL,
-                                      pDirEntry->OpenReferenceCount);
+                                      lCount);
 
                         pDirEntry = pCurrentVolume->DirectoryCB;
 
@@ -699,7 +758,7 @@ AFSLocateNameEntry( IN GUID *AuthGroup,
                         // Reference the new dir entry
                         //
 
-                        InterlockedIncrement( &pDirEntry->OpenReferenceCount);
+                        lCount = InterlockedIncrement( &pDirEntry->OpenReferenceCount);
 
                         AFSDbgLogMsg( AFS_SUBSYSTEM_DIRENTRY_REF_COUNTING,
                                       AFS_TRACE_LEVEL_VERBOSE,
@@ -707,7 +766,7 @@ AFSLocateNameEntry( IN GUID *AuthGroup,
                                       &pDirEntry->NameInformation.FileName,
                                       pDirEntry,
                                       NULL,
-                                      pDirEntry->OpenReferenceCount);
+                                      lCount);
 
                         //
                         // Reset the name array
@@ -767,7 +826,7 @@ AFSLocateNameEntry( IN GUID *AuthGroup,
                     // Increment our link count
                     //
 
-                    InterlockedIncrement( &pNameArray->LinkCount);
+                    lCount = InterlockedIncrement( &pNameArray->LinkCount);
 
                     continue;
                 }
@@ -818,7 +877,7 @@ AFSLocateNameEntry( IN GUID *AuthGroup,
 
                     ASSERT( pCurrentVolume->VolumeReferenceCount > 1);
 
-                    InterlockedDecrement( &pCurrentVolume->VolumeReferenceCount);
+                    lCount = InterlockedDecrement( &pCurrentVolume->VolumeReferenceCount);
 
                     AFSDbgLogMsg( AFS_SUBSYSTEM_VOLUME_REF_COUNTING,
                                   AFS_TRACE_LEVEL_VERBOSE,
@@ -826,8 +885,6 @@ AFSLocateNameEntry( IN GUID *AuthGroup,
                                   pCurrentVolume,
                                   pCurrentVolume->VolumeReferenceCount);
 
-                    AFSReleaseResource( pCurrentVolume->VolumeLock);
-
                     ntStatus = AFSBuildMountPointTarget( AuthGroup,
                                                          pDirEntry,
                                                          &pCurrentVolume);
@@ -852,26 +909,25 @@ AFSLocateNameEntry( IN GUID *AuthGroup,
 
                         bReleaseCurrentVolume = FALSE;
 
-                        try_return( ntStatus = STATUS_ACCESS_DENIED);
+                        try_return( ntStatus);
                     }
 
                     ASSERT( pCurrentVolume->VolumeReferenceCount > 1);
 
-                    ASSERT( ExIsResourceAcquiredLite( pCurrentVolume->VolumeLock));
-
                     //
-                    // Replace the current name for the mp with the volume root of the target
+                    // The name array stores both the mount point and the target.
+                    // Insert the target.
                     //
 
-                    AFSReplaceCurrentElement( pNameArray,
-                                              pCurrentVolume->DirectoryCB);
+                    AFSInsertNextElement( pNameArray,
+                                          pCurrentVolume->DirectoryCB);
 
                     //
                     // We want to restart processing here on the new parent ...
                     // Deref and ref count the entries
                     //
 
-                    InterlockedDecrement( &pDirEntry->OpenReferenceCount);
+                    lCount = InterlockedDecrement( &pDirEntry->OpenReferenceCount);
 
                     AFSDbgLogMsg( AFS_SUBSYSTEM_DIRENTRY_REF_COUNTING,
                                   AFS_TRACE_LEVEL_VERBOSE,
@@ -879,11 +935,11 @@ AFSLocateNameEntry( IN GUID *AuthGroup,
                                   &pDirEntry->NameInformation.FileName,
                                   pDirEntry,
                                   NULL,
-                                  pDirEntry->OpenReferenceCount);
+                                  lCount);
 
                     pDirEntry = pCurrentVolume->DirectoryCB;
 
-                    InterlockedIncrement( &pDirEntry->OpenReferenceCount);
+                    lCount = InterlockedIncrement( &pDirEntry->OpenReferenceCount);
 
                     AFSDbgLogMsg( AFS_SUBSYSTEM_DIRENTRY_REF_COUNTING,
                                   AFS_TRACE_LEVEL_VERBOSE,
@@ -891,7 +947,7 @@ AFSLocateNameEntry( IN GUID *AuthGroup,
                                   &pDirEntry->NameInformation.FileName,
                                   pDirEntry,
                                   NULL,
-                                  pDirEntry->OpenReferenceCount);
+                                  lCount);
 
                     pParentDirEntry = NULL;
 
@@ -899,7 +955,7 @@ AFSLocateNameEntry( IN GUID *AuthGroup,
                     // Increment our link count
                     //
 
-                    InterlockedIncrement( &pNameArray->LinkCount);
+                    lCount = InterlockedIncrement( &pNameArray->LinkCount);
 
                     continue;
                 }
@@ -935,7 +991,8 @@ AFSLocateNameEntry( IN GUID *AuthGroup,
 
                         ntStatus = AFSProcessDFSLink( pDirEntry,
                                                       FileObject,
-                                                      &uniRemainingPath);
+                                                      &uniRemainingPath,
+                                                      AuthGroup);
                     }
                     else
                     {
@@ -1177,8 +1234,7 @@ AFSLocateNameEntry( IN GUID *AuthGroup,
                 //
                 // Need to back up one entry in the name array
                 //
-
-                InterlockedDecrement( &pDirEntry->OpenReferenceCount);
+                lCount = InterlockedDecrement( &pDirEntry->OpenReferenceCount);
 
                 AFSDbgLogMsg( AFS_SUBSYSTEM_DIRENTRY_REF_COUNTING,
                               AFS_TRACE_LEVEL_VERBOSE,
@@ -1186,7 +1242,7 @@ AFSLocateNameEntry( IN GUID *AuthGroup,
                               &pDirEntry->NameInformation.FileName,
                               pDirEntry,
                               NULL,
-                              pDirEntry->OpenReferenceCount);
+                              lCount);
 
                 pDirEntry = AFSBackupEntry( NameArray);
 
@@ -1200,7 +1256,7 @@ AFSLocateNameEntry( IN GUID *AuthGroup,
                     try_return(ntStatus = STATUS_OBJECT_PATH_INVALID);
                 }
 
-                InterlockedIncrement( &pDirEntry->OpenReferenceCount);
+                lCount = InterlockedIncrement( &pDirEntry->OpenReferenceCount);
 
                 if( BooleanFlagOn( pDirEntry->ObjectInformation->Flags, AFS_OBJECT_ROOT_VOLUME))
                 {
@@ -1501,9 +1557,18 @@ AFSLocateNameEntry( IN GUID *AuthGroup,
                                       pParentDirEntry->ObjectInformation->FileId.Vnode,
                                       pParentDirEntry->ObjectInformation->FileId.Unique);
 
+                        //
+                        // Directory TreeLock should be exclusively held
+                        //
+
+                        AFSAcquireExcl( pParentDirEntry->ObjectInformation->Specific.Directory.DirectoryNodeHdr.TreeLock,
+                                        TRUE);
+
                         ntStatus = AFSVerifyEntry( AuthGroup,
                                                    pParentDirEntry);
 
+                        AFSReleaseResource( pParentDirEntry->ObjectInformation->Specific.Directory.DirectoryNodeHdr.TreeLock);
+
                         if( !NT_SUCCESS( ntStatus))
                         {
 
@@ -1538,7 +1603,7 @@ AFSLocateNameEntry( IN GUID *AuthGroup,
                     // Increment our dir entry ref count
                     //
 
-                    InterlockedIncrement( &pDirEntry->OpenReferenceCount);
+                    lCount = InterlockedIncrement( &pDirEntry->OpenReferenceCount);
 
                     AFSDbgLogMsg( AFS_SUBSYSTEM_DIRENTRY_REF_COUNTING,
                                   AFS_TRACE_LEVEL_VERBOSE,
@@ -1546,7 +1611,7 @@ AFSLocateNameEntry( IN GUID *AuthGroup,
                                   &pDirEntry->NameInformation.FileName,
                                   pDirEntry,
                                   NULL,
-                                  pDirEntry->OpenReferenceCount);
+                                  lCount);
                 }
 
                 AFSReleaseResource( pParentDirEntry->ObjectInformation->Specific.Directory.DirectoryNodeHdr.TreeLock);
@@ -1565,7 +1630,7 @@ AFSLocateNameEntry( IN GUID *AuthGroup,
 
                 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
                               AFS_TRACE_LEVEL_ERROR,
-                              "AFSLocateNameEntry (FO: %08lX) Deleted parent %wZ FID %08lX-%08lX-%08lX-%08lX\n",
+                              "AFSLocateNameEntry (FO: %08lX) Deleted entry %wZ FID %08lX-%08lX-%08lX-%08lX\n",
                               FileObject,
                               &pDirEntry->NameInformation.FileName,
                               pCurrentObject->FileId.Cell,
@@ -1586,10 +1651,12 @@ AFSLocateNameEntry( IN GUID *AuthGroup,
                 AFSAcquireExcl( pCurrentObject->VolumeCB->ObjectInfoTree.TreeLock,
                                 TRUE);
 
-                if( InterlockedDecrement( &pDirEntry->OpenReferenceCount) == 0)
+                lCount = InterlockedDecrement( &pDirEntry->OpenReferenceCount);
+
+                if( lCount == 0)
                 {
 
-                    AFSDbgLogMsg( AFS_SUBSYSTEM_CLEANUP_PROCESSING,
+                    AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING|AFS_SUBSYSTEM_CLEANUP_PROCESSING,
                                   AFS_TRACE_LEVEL_VERBOSE,
                                   "AFSLocateNameEntry Deleting dir entry %08lX (%08lX) for %wZ\n",
                                   pDirEntry,
@@ -1603,7 +1670,7 @@ AFSLocateNameEntry( IN GUID *AuthGroup,
                     AFSDeleteDirEntry( pCurrentObject->ParentObjectInformation,
                                        pDirEntry);
 
-                    if( pCurrentObject->ObjectReferenceCount == 0)
+                    if( pCurrentObject->ObjectReferenceCount <= 0)
                     {
 
                         if( BooleanFlagOn( pCurrentObject->Flags, AFS_OBJECT_INSERTED_HASH_TREE))
@@ -1694,7 +1761,7 @@ AFSLocateNameEntry( IN GUID *AuthGroup,
             // Decrement the previous parent
             //
 
-            InterlockedDecrement( &pParentDirEntry->OpenReferenceCount);
+            lCount = InterlockedDecrement( &pParentDirEntry->OpenReferenceCount);
 
             AFSDbgLogMsg( AFS_SUBSYSTEM_DIRENTRY_REF_COUNTING,
                           AFS_TRACE_LEVEL_VERBOSE,
@@ -1702,7 +1769,7 @@ AFSLocateNameEntry( IN GUID *AuthGroup,
                           &pParentDirEntry->NameInformation.FileName,
                           pParentDirEntry,
                           NULL,
-                          pParentDirEntry->OpenReferenceCount);
+                          lCount);
 
             //
             // If we ended up substituting a name in the component then update
@@ -1845,7 +1912,7 @@ try_exit:
             if( pDirEntry != NULL)
             {
 
-                InterlockedDecrement( &pDirEntry->OpenReferenceCount);
+                lCount = InterlockedDecrement( &pDirEntry->OpenReferenceCount);
 
                 AFSDbgLogMsg( AFS_SUBSYSTEM_DIRENTRY_REF_COUNTING,
                               AFS_TRACE_LEVEL_VERBOSE,
@@ -1853,12 +1920,12 @@ try_exit:
                               &pDirEntry->NameInformation.FileName,
                               pDirEntry,
                               NULL,
-                              pDirEntry->OpenReferenceCount);
+                              lCount);
             }
             else if( pParentDirEntry != NULL)
             {
 
-                InterlockedDecrement( &pParentDirEntry->OpenReferenceCount);
+                lCount = InterlockedDecrement( &pParentDirEntry->OpenReferenceCount);
 
                 AFSDbgLogMsg( AFS_SUBSYSTEM_DIRENTRY_REF_COUNTING,
                               AFS_TRACE_LEVEL_VERBOSE,
@@ -1866,7 +1933,7 @@ try_exit:
                               &pParentDirEntry->NameInformation.FileName,
                               pParentDirEntry,
                               NULL,
-                              pParentDirEntry->OpenReferenceCount);
+                              lCount);
             }
 
             if( bReleaseCurrentVolume)
@@ -1874,17 +1941,13 @@ try_exit:
 
                 ASSERT( pCurrentVolume->VolumeReferenceCount > 1);
 
-                ASSERT( ExIsResourceAcquiredLite( pCurrentVolume->VolumeLock));
-
-                InterlockedDecrement( &pCurrentVolume->VolumeReferenceCount);
+                lCount = InterlockedDecrement( &pCurrentVolume->VolumeReferenceCount);
 
                 AFSDbgLogMsg( AFS_SUBSYSTEM_VOLUME_REF_COUNTING,
                               AFS_TRACE_LEVEL_VERBOSE,
                               "AFSLocateNameEntry Decrement3 count on volume %08lX Cnt %d\n",
                               pCurrentVolume,
-                              pCurrentVolume->VolumeReferenceCount);
-
-                AFSReleaseResource( pCurrentVolume->VolumeLock);
+                              lCount);
             }
 
             if( RootPathName->Buffer != uniFullPathName.Buffer)
@@ -1943,9 +2006,10 @@ AFSCreateDirEntry( IN GUID            *AuthGroup,
 {
 
     NTSTATUS ntStatus = STATUS_SUCCESS;
-    AFSDirectoryCB *pDirNode = NULL;
+    AFSDirectoryCB *pDirNode = NULL, *pExistingDirNode = NULL;
     UNICODE_STRING uniShortName;
     LARGE_INTEGER liFileSize = {0,0};
+    LONG lCount;
 
     __Enter
     {
@@ -2005,6 +2069,132 @@ AFSCreateDirEntry( IN GUID            *AuthGroup,
             try_return( ntStatus);
         }
 
+        AFSAcquireExcl( ParentObjectInfo->Specific.Directory.DirectoryNodeHdr.TreeLock,
+                        TRUE);
+
+        //
+        // Before attempting to insert the new entry, check if we need to validate the parent
+        //
+
+        if( BooleanFlagOn( ParentObjectInfo->Flags, AFS_OBJECT_FLAGS_VERIFY))
+        {
+
+            AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
+                          AFS_TRACE_LEVEL_VERBOSE,
+                          "AFSCreateDirEntry Verifying parent %wZ FID %08lX-%08lX-%08lX-%08lX\n",
+                          &ParentDirCB->NameInformation.FileName,
+                          ParentObjectInfo->FileId.Cell,
+                          ParentObjectInfo->FileId.Volume,
+                          ParentObjectInfo->FileId.Vnode,
+                          ParentObjectInfo->FileId.Unique);
+
+            ntStatus = AFSVerifyEntry( AuthGroup,
+                                       ParentDirCB);
+
+            if( !NT_SUCCESS( ntStatus))
+            {
+
+                AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
+                              AFS_TRACE_LEVEL_ERROR,
+                              "AFSCreateDirEntry Failed to verify parent %wZ FID %08lX-%08lX-%08lX-%08lX Status %08lX\n",
+                              &ParentDirCB->NameInformation.FileName,
+                              ParentObjectInfo->FileId.Cell,
+                              ParentObjectInfo->FileId.Volume,
+                              ParentObjectInfo->FileId.Vnode,
+                              ParentObjectInfo->FileId.Unique,
+                              ntStatus);
+
+                AFSReleaseResource( ParentObjectInfo->Specific.Directory.DirectoryNodeHdr.TreeLock);
+
+                try_return( ntStatus);
+            }
+        }
+
+        //
+        // Check for the entry in the event we raced with some other thread
+        //
+
+        AFSLocateCaseSensitiveDirEntry( ParentObjectInfo->Specific.Directory.DirectoryNodeHdr.CaseSensitiveTreeHead,
+                                        (ULONG)pDirNode->CaseSensitiveTreeEntry.HashIndex,
+                                        &pExistingDirNode);
+
+        if( pExistingDirNode != NULL)
+        {
+            if (AFSIsEqualFID( &pDirNode->ObjectInformation->FileId,
+                               &pExistingDirNode->ObjectInformation->FileId))
+            {
+
+                AFSDeleteDirEntry( ParentObjectInfo,
+                                   pDirNode);
+
+                lCount = InterlockedIncrement( &pExistingDirNode->OpenReferenceCount);
+
+                AFSDbgLogMsg( AFS_SUBSYSTEM_DIRENTRY_REF_COUNTING,
+                              AFS_TRACE_LEVEL_VERBOSE,
+                              "AFSCreateDirEntry Increment count on %wZ DE %p Cnt %d\n",
+                              &pExistingDirNode->NameInformation.FileName,
+                              pExistingDirNode,
+                              lCount);
+
+                *DirEntry = pExistingDirNode;
+
+                AFSReleaseResource( ParentObjectInfo->Specific.Directory.DirectoryNodeHdr.TreeLock);
+
+                try_return( ntStatus = STATUS_SUCCESS);
+            }
+            else
+            {
+
+                //
+                // Need to tear down this entry and rebuild it below
+                //
+
+                if( pExistingDirNode->OpenReferenceCount == 0)
+                {
+
+                    AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
+                                  AFS_TRACE_LEVEL_VERBOSE,
+                                  "AFSCreateDirEntry Different FIDs - Deleting DE %p for %wZ Old FID %08lX-%08lX-%08lX-%08lX New FID %08lX-%08lX-%08lX-%08lX\n",
+                                  pExistingDirNode,
+                                  &pExistingDirNode->NameInformation.FileName,
+                                  pExistingDirNode->ObjectInformation->FileId.Cell,
+                                  pExistingDirNode->ObjectInformation->FileId.Volume,
+                                  pExistingDirNode->ObjectInformation->FileId.Vnode,
+                                  pExistingDirNode->ObjectInformation->FileId.Unique,
+                                  pDirNode->ObjectInformation->FileId.Cell,
+                                  pDirNode->ObjectInformation->FileId.Volume,
+                                  pDirNode->ObjectInformation->FileId.Vnode,
+                                  pDirNode->ObjectInformation->FileId.Unique);
+
+                    AFSDeleteDirEntry( ParentObjectInfo,
+                                       pExistingDirNode);
+                }
+                else
+                {
+
+                    SetFlag( pExistingDirNode->Flags, AFS_DIR_ENTRY_DELETED);
+
+                    AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
+                                  AFS_TRACE_LEVEL_VERBOSE,
+                                  "AFSCreateDirEntry Different FIDs - Removing DE %p for %wZ Old FID %08lX-%08lX-%08lX-%08lX New FID %08lX-%08lX-%08lX-%08lX\n",
+                                  pExistingDirNode,
+                                  &pExistingDirNode->NameInformation.FileName,
+                                  pExistingDirNode->ObjectInformation->FileId.Cell,
+                                  pExistingDirNode->ObjectInformation->FileId.Volume,
+                                  pExistingDirNode->ObjectInformation->FileId.Vnode,
+                                  pExistingDirNode->ObjectInformation->FileId.Unique,
+                                  pDirNode->ObjectInformation->FileId.Cell,
+                                  pDirNode->ObjectInformation->FileId.Volume,
+                                  pDirNode->ObjectInformation->FileId.Vnode,
+                                  pDirNode->ObjectInformation->FileId.Unique);
+
+                    AFSRemoveNameEntry( ParentObjectInfo,
+                                        pExistingDirNode);
+                }
+
+            }
+        }
+
         AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
                       AFS_TRACE_LEVEL_VERBOSE_2,
                       "AFSCreateDirEntry Inserting dir entry in parent %wZ FID %08lX-%08lX-%08lX-%08lX Component %wZ\n",
@@ -2023,12 +2213,23 @@ AFSCreateDirEntry( IN GUID            *AuthGroup,
                                 pDirNode,
                                 TRUE);
 
+        lCount = InterlockedIncrement( &pDirNode->OpenReferenceCount);
+
+        AFSDbgLogMsg( AFS_SUBSYSTEM_DIRENTRY_REF_COUNTING,
+                      AFS_TRACE_LEVEL_VERBOSE,
+                      "AFSCreateDirEntry Increment2 count on %wZ DE %p Cnt %d\n",
+                      &pDirNode->NameInformation.FileName,
+                      pDirNode,
+                      lCount);
+
         //
         // Pass back the dir entry
         //
 
         *DirEntry = pDirNode;
 
+        AFSReleaseResource( ParentObjectInfo->Specific.Directory.DirectoryNodeHdr.TreeLock);
+
 try_exit:
 
         NOTHING;
@@ -2043,11 +2244,12 @@ AFSInsertDirectoryNode( IN AFSObjectInfoCB *ParentObjectInfo,
                         IN BOOLEAN InsertInEnumList)
 {
 
+    LONG lCount;
+
     __Enter
     {
 
-        AFSAcquireExcl( ParentObjectInfo->Specific.Directory.DirectoryNodeHdr.TreeLock,
-                        TRUE);
+        ASSERT( ExIsResourceAcquiredExclusiveLite( ParentObjectInfo->Specific.Directory.DirectoryNodeHdr.TreeLock));
 
         //
         // Insert the node into the directory node tree
@@ -2128,18 +2330,31 @@ AFSInsertDirectoryNode( IN AFSObjectInfoCB *ParentObjectInfo,
                               "AFSInsertDirectoryNode Insert DE %p to head of shortname tree for %wZ\n",
                               DirEntry,
                               &DirEntry->NameInformation.FileName);
+
+                SetFlag( DirEntry->Flags, AFS_DIR_ENTRY_INSERTED_SHORT_NAME);
             }
             else
             {
 
-                AFSInsertShortNameDirEntry( ParentObjectInfo->Specific.Directory.ShortNameTree,
-                                            DirEntry);
+                if( !NT_SUCCESS( AFSInsertShortNameDirEntry( ParentObjectInfo->Specific.Directory.ShortNameTree,
+                                                             DirEntry)))
+                {
+                    AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
+                                  AFS_TRACE_LEVEL_VERBOSE,
+                                  "AFSInsertDirectoryNode Failed to insert DE %p to shortname tree for %wZ\n",
+                                  DirEntry,
+                                  &DirEntry->NameInformation.FileName);
+                }
+                else
+                {
+                    SetFlag( DirEntry->Flags, AFS_DIR_ENTRY_INSERTED_SHORT_NAME);
 
-                AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
-                              AFS_TRACE_LEVEL_VERBOSE,
-                              "AFSInsertDirectoryNode Insert DE %p to shortname tree for %wZ\n",
-                              DirEntry,
-                              &DirEntry->NameInformation.FileName);
+                    AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
+                                  AFS_TRACE_LEVEL_VERBOSE,
+                                  "AFSInsertDirectoryNode Insert DE %p to shortname tree for %wZ\n",
+                                  DirEntry,
+                                  &DirEntry->NameInformation.FileName);
+                }
             }
         }
 
@@ -2152,7 +2367,7 @@ AFSInsertDirectoryNode( IN AFSObjectInfoCB *ParentObjectInfo,
 
             AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
                           AFS_TRACE_LEVEL_VERBOSE,
-                          "AFSInsertDirectoryNode Inserting entry %08lX %wZ FID %08lX-%08lX-%08lX-%08lXStatus %08lX\n",
+                          "AFSInsertDirectoryNode Inserting entry %08lX %wZ FID %08lX-%08lX-%08lX-%08lX\n",
                           DirEntry,
                           &DirEntry->NameInformation.FileName,
                           DirEntry->ObjectInformation->FileId.Cell,
@@ -2177,20 +2392,18 @@ AFSInsertDirectoryNode( IN AFSObjectInfoCB *ParentObjectInfo,
 
             SetFlag( DirEntry->Flags, AFS_DIR_ENTRY_INSERTED_ENUM_LIST);
 
-            InterlockedIncrement( &ParentObjectInfo->Specific.Directory.DirectoryNodeCount);
+            lCount = InterlockedIncrement( &ParentObjectInfo->Specific.Directory.DirectoryNodeCount);
 
             AFSDbgLogMsg( AFS_SUBSYSTEM_DIR_NODE_COUNT,
                           AFS_TRACE_LEVEL_VERBOSE,
                           "AFSInsertDirectoryNode Adding entry %wZ Inc Count %d to parent FID %08lX-%08lX-%08lX-%08lX\n",
-                              &DirEntry->NameInformation.FileName,
-                              ParentObjectInfo->Specific.Directory.DirectoryNodeCount,
-                              ParentObjectInfo->FileId.Cell,
-                              ParentObjectInfo->FileId.Volume,
-                              ParentObjectInfo->FileId.Vnode,
-                              ParentObjectInfo->FileId.Unique);
+                          &DirEntry->NameInformation.FileName,
+                          lCount,
+                          ParentObjectInfo->FileId.Cell,
+                          ParentObjectInfo->FileId.Volume,
+                          ParentObjectInfo->FileId.Vnode,
+                          ParentObjectInfo->FileId.Unique);
         }
-
-        AFSReleaseResource( ParentObjectInfo->Specific.Directory.DirectoryNodeHdr.TreeLock);
     }
 
     return;
@@ -2202,6 +2415,7 @@ AFSDeleteDirEntry( IN AFSObjectInfoCB *ParentObjectInfo,
 {
 
     NTSTATUS ntStatus = STATUS_SUCCESS;
+    LONG lCount;
 
     __Enter
     {
@@ -2243,7 +2457,12 @@ AFSDeleteDirEntry( IN AFSObjectInfoCB *ParentObjectInfo,
 
         ASSERT( DirEntry->ObjectInformation->ObjectReferenceCount > 0);
 
-        InterlockedDecrement( &DirEntry->ObjectInformation->ObjectReferenceCount);
+        lCount = InterlockedDecrement( &DirEntry->ObjectInformation->ObjectReferenceCount);
+
+        if( lCount <= 0)
+        {
+            SetFlag( DirEntry->ObjectInformation->Flags, AFS_OBJECT_FLAGS_DELETED);
+        }
 
         AFSDbgLogMsg( AFS_SUBSYSTEM_OBJECT_REF_COUNTING,
                       AFS_TRACE_LEVEL_VERBOSE,
@@ -2272,6 +2491,7 @@ AFSRemoveDirNodeFromParent( IN AFSObjectInfoCB *ParentObjectInfo,
 {
 
     NTSTATUS ntStatus = STATUS_SUCCESS;
+    LONG lCount;
 
     __Enter
     {
@@ -2345,7 +2565,7 @@ AFSRemoveDirNodeFromParent( IN AFSObjectInfoCB *ParentObjectInfo,
 
             ASSERT( ParentObjectInfo->Specific.Directory.DirectoryNodeCount > 0);
 
-            InterlockedDecrement( &ParentObjectInfo->Specific.Directory.DirectoryNodeCount);
+            lCount = InterlockedDecrement( &ParentObjectInfo->Specific.Directory.DirectoryNodeCount);
 
             ClearFlag( DirEntry->Flags, AFS_DIR_ENTRY_INSERTED_ENUM_LIST);
 
@@ -2353,7 +2573,7 @@ AFSRemoveDirNodeFromParent( IN AFSObjectInfoCB *ParentObjectInfo,
                           AFS_TRACE_LEVEL_VERBOSE,
                           "AFSRemoveDirNodeFromParent Removing entry %wZ Dec Count %d to parent FID %08lX-%08lX-%08lX-%08lX\n",
                           &DirEntry->NameInformation.FileName,
-                          ParentObjectInfo->Specific.Directory.DirectoryNodeCount,
+                          lCount,
                           ParentObjectInfo->FileId.Cell,
                           ParentObjectInfo->FileId.Volume,
                           ParentObjectInfo->FileId.Vnode,
@@ -2472,6 +2692,7 @@ AFSParseName( IN PIRP Irp,
     AFSFcb             *pRelatedFcb = NULL;
     BOOLEAN             bReleaseTreeLock = FALSE;
     BOOLEAN             bIsAllShare = FALSE;
+    LONG                lCount;
 
     __Enter
     {
@@ -2529,11 +2750,11 @@ AFSParseName( IN PIRP Irp,
             *FileName = pIrpSp->FileObject->FileName;
 
             //
-            // Grab the root node exclusive before returning
+            // Grab the root node while checking state
             //
 
-            AFSAcquireExcl( pVolumeCB->VolumeLock,
-                            TRUE);
+            AFSAcquireShared( pVolumeCB->VolumeLock,
+                              TRUE);
 
             if( BooleanFlagOn( pVolumeCB->ObjectInformation.Flags, AFS_OBJECT_FLAGS_OBJECT_INVALID) ||
                 BooleanFlagOn( pVolumeCB->Flags, AFS_VOLUME_FLAGS_OFFLINE))
@@ -2583,7 +2804,7 @@ AFSParseName( IN PIRP Irp,
                 }
             }
 
-            AFSConvertToShared( pVolumeCB->VolumeLock);
+            AFSReleaseResource( pVolumeCB->VolumeLock);
 
             if( BooleanFlagOn( pDirEntry->ObjectInformation->Flags, AFS_OBJECT_FLAGS_VERIFY))
             {
@@ -2598,9 +2819,18 @@ AFSParseName( IN PIRP Irp,
                               pDirEntry->ObjectInformation->FileId.Vnode,
                               pDirEntry->ObjectInformation->FileId.Unique);
 
+                //
+                // Directory TreeLock should be exclusively held
+                //
+
+                AFSAcquireExcl( pDirEntry->ObjectInformation->Specific.Directory.DirectoryNodeHdr.TreeLock,
+                                TRUE);
+
                 ntStatus = AFSVerifyEntry( AuthGroup,
                                            pDirEntry);
 
+                AFSReleaseResource( pDirEntry->ObjectInformation->Specific.Directory.DirectoryNodeHdr.TreeLock);
+
                 if( !NT_SUCCESS( ntStatus))
                 {
 
@@ -2615,8 +2845,6 @@ AFSParseName( IN PIRP Irp,
                                   pDirEntry->ObjectInformation->FileId.Unique,
                                   ntStatus);
 
-                    AFSReleaseResource( pVolumeCB->VolumeLock);
-
                     try_return( ntStatus);
                 }
             }
@@ -2644,8 +2872,6 @@ AFSParseName( IN PIRP Irp,
                               "AFSParseName (%08lX) Failed to allocate full name buffer\n",
                               Irp);
 
-                AFSReleaseResource( pVolumeCB->VolumeLock);
-
                 try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
             }
 
@@ -2711,8 +2937,6 @@ AFSParseName( IN PIRP Irp,
 
                     AFSExFreePool( uniFullName.Buffer);
 
-                    AFSReleaseResource( pVolumeCB->VolumeLock);
-
                     try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
                 }
 
@@ -2740,8 +2964,6 @@ AFSParseName( IN PIRP Irp,
 
                     AFSExFreePool( uniFullName.Buffer);
 
-                    AFSReleaseResource( pVolumeCB->VolumeLock);
-
                     try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
                 }
 
@@ -2760,8 +2982,6 @@ AFSParseName( IN PIRP Irp,
 
                 AFSExFreePool( uniFullName.Buffer);
 
-                AFSReleaseResource( pVolumeCB->VolumeLock);
-
                 try_return( ntStatus);
             }
 
@@ -2784,17 +3004,17 @@ AFSParseName( IN PIRP Irp,
             // Increment our volume reference count
             //
 
-            InterlockedIncrement( &pVolumeCB->VolumeReferenceCount);
+            lCount = InterlockedIncrement( &pVolumeCB->VolumeReferenceCount);
 
             AFSDbgLogMsg( AFS_SUBSYSTEM_VOLUME_REF_COUNTING,
                           AFS_TRACE_LEVEL_VERBOSE,
                           "AFSParseName Increment count on volume %08lX Cnt %d\n",
                           pVolumeCB,
-                          pVolumeCB->VolumeReferenceCount);
+                          lCount);
 
             *ParentDirectoryCB = pDirEntry;
 
-            InterlockedIncrement( &pDirEntry->OpenReferenceCount);
+            lCount = InterlockedIncrement( &pDirEntry->OpenReferenceCount);
 
             AFSDbgLogMsg( AFS_SUBSYSTEM_DIRENTRY_REF_COUNTING,
                           AFS_TRACE_LEVEL_VERBOSE,
@@ -2802,7 +3022,7 @@ AFSParseName( IN PIRP Irp,
                           &pDirEntry->NameInformation.FileName,
                           pDirEntry,
                           NULL,
-                          pDirEntry->OpenReferenceCount);
+                          lCount);
 
             AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
                           AFS_TRACE_LEVEL_VERBOSE_2,
@@ -2923,6 +3143,18 @@ AFSParseName( IN PIRP Irp,
             }
         }
 
+        if( FsRtlDoesNameContainWildCards( &uniFullName))
+        {
+
+            AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
+                          AFS_TRACE_LEVEL_ERROR,
+                          "AFSParseName (%08lX) Component %wZ contains wild cards\n",
+                          Irp,
+                          &uniFullName);
+
+            try_return( ntStatus = STATUS_OBJECT_NAME_INVALID);
+        }
+
         AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
                       AFS_TRACE_LEVEL_VERBOSE_2,
                       "AFSParseName (%08lX) Processing full name %wZ\n",
@@ -2940,8 +3172,8 @@ AFSParseName( IN PIRP Irp,
         // Be sure we are online and ready to go
         //
 
-        AFSAcquireExcl( AFSGlobalRoot->VolumeLock,
-                        TRUE);
+        AFSAcquireShared( AFSGlobalRoot->VolumeLock,
+                          TRUE);
 
         if( BooleanFlagOn( AFSGlobalRoot->ObjectInformation.Flags, AFS_OBJECT_FLAGS_OBJECT_INVALID) ||
             BooleanFlagOn( AFSGlobalRoot->Flags, AFS_VOLUME_FLAGS_OFFLINE))
@@ -2991,6 +3223,8 @@ AFSParseName( IN PIRP Irp,
             }
         }
 
+        AFSReleaseResource( AFSGlobalRoot->VolumeLock);
+
         if( !BooleanFlagOn( AFSGlobalRoot->ObjectInformation.Flags, AFS_OBJECT_FLAGS_DIRECTORY_ENUMERATED))
         {
 
@@ -3012,8 +3246,6 @@ AFSParseName( IN PIRP Irp,
                               Irp,
                               ntStatus);
 
-                AFSReleaseResource( AFSGlobalRoot->VolumeLock);
-
                 try_return( ntStatus);
             }
         }
@@ -3032,7 +3264,7 @@ AFSParseName( IN PIRP Irp,
                           "AFSParseName (%08lX) Returning global root access\n",
                           Irp);
 
-            InterlockedIncrement( &AFSGlobalRoot->DirectoryCB->OpenReferenceCount);
+            lCount = InterlockedIncrement( &AFSGlobalRoot->DirectoryCB->OpenReferenceCount);
 
             AFSDbgLogMsg( AFS_SUBSYSTEM_DIRENTRY_REF_COUNTING,
                           AFS_TRACE_LEVEL_VERBOSE,
@@ -3040,9 +3272,7 @@ AFSParseName( IN PIRP Irp,
                           &AFSGlobalRoot->DirectoryCB->NameInformation.FileName,
                           AFSGlobalRoot->DirectoryCB,
                           NULL,
-                          AFSGlobalRoot->DirectoryCB->OpenReferenceCount);
-
-            AFSReleaseResource( AFSGlobalRoot->VolumeLock);
+                          lCount);
 
             *VolumeCB = NULL;
 
@@ -3074,11 +3304,24 @@ AFSParseName( IN PIRP Irp,
                           &uniComponentName,
                           &uniRemainingPath);
 
+        if( FsRtlDoesNameContainWildCards( &uniFullName))
+        {
+
+            AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
+                          AFS_TRACE_LEVEL_ERROR,
+                          "AFSParseName (%08lX) Component %wZ contains wild cards\n",
+                          Irp,
+                          &uniComponentName);
+
+            try_return( ntStatus = STATUS_OBJECT_NAME_INVALID);
+        }
+
         //
         // If this is the ALL access then perform some additional processing
         //
 
-        if( RtlCompareUnicodeString( &uniComponentName,
+        if( uniComponentName.Length == 0 ||
+            RtlCompareUnicodeString( &uniComponentName,
                                      &AFSGlobalRootName,
                                      TRUE) == 0)
         {
@@ -3100,7 +3343,7 @@ AFSParseName( IN PIRP Irp,
                               "AFSParseName (%08lX) Returning global root access\n",
                               Irp);
 
-                InterlockedIncrement( &AFSGlobalRoot->DirectoryCB->OpenReferenceCount);
+                lCount = InterlockedIncrement( &AFSGlobalRoot->DirectoryCB->OpenReferenceCount);
 
                 AFSDbgLogMsg( AFS_SUBSYSTEM_DIRENTRY_REF_COUNTING,
                               AFS_TRACE_LEVEL_VERBOSE,
@@ -3108,9 +3351,7 @@ AFSParseName( IN PIRP Irp,
                               &AFSGlobalRoot->DirectoryCB->NameInformation.FileName,
                               AFSGlobalRoot->DirectoryCB,
                               NULL,
-                              AFSGlobalRoot->DirectoryCB->OpenReferenceCount);
-
-                AFSReleaseResource( AFSGlobalRoot->VolumeLock);
+                              lCount);
 
                 *VolumeCB = NULL;
 
@@ -3145,7 +3386,7 @@ AFSParseName( IN PIRP Irp,
                               "AFSParseName (%08lX) Returning root PIOCtl access\n",
                               Irp);
 
-                InterlockedIncrement( &AFSGlobalRoot->DirectoryCB->OpenReferenceCount);
+                lCount = InterlockedIncrement( &AFSGlobalRoot->DirectoryCB->OpenReferenceCount);
 
                 AFSDbgLogMsg( AFS_SUBSYSTEM_DIRENTRY_REF_COUNTING,
                               AFS_TRACE_LEVEL_VERBOSE,
@@ -3153,9 +3394,7 @@ AFSParseName( IN PIRP Irp,
                               &AFSGlobalRoot->DirectoryCB->NameInformation.FileName,
                               AFSGlobalRoot->DirectoryCB,
                               NULL,
-                              AFSGlobalRoot->DirectoryCB->OpenReferenceCount);
-
-                AFSReleaseResource( AFSGlobalRoot->VolumeLock);
+                              lCount);
 
                 ClearFlag( *ParseFlags, AFS_PARSE_FLAG_ROOT_ACCESS);
 
@@ -3176,8 +3415,6 @@ AFSParseName( IN PIRP Irp,
                           Irp,
                           &uniComponentName);
 
-            AFSReleaseResource( AFSGlobalRoot->VolumeLock);
-
             //
             // Add in the full share name to pass back
             //
@@ -3212,7 +3449,7 @@ AFSParseName( IN PIRP Irp,
 
             ClearFlag( *ParseFlags, AFS_PARSE_FLAG_ROOT_ACCESS);
 
-            InterlockedIncrement( &pDirEntry->OpenReferenceCount);
+            lCount = InterlockedIncrement( &pDirEntry->OpenReferenceCount);
 
             AFSDbgLogMsg( AFS_SUBSYSTEM_DIRENTRY_REF_COUNTING,
                           AFS_TRACE_LEVEL_VERBOSE,
@@ -3220,7 +3457,7 @@ AFSParseName( IN PIRP Irp,
                           &pDirEntry->NameInformation.FileName,
                           pDirEntry,
                           NULL,
-                          pDirEntry->OpenReferenceCount);
+                          lCount);
 
             try_return( ntStatus = STATUS_SUCCESS);
         }
@@ -3286,7 +3523,6 @@ AFSParseName( IN PIRP Irp,
 
                     if( !NT_SUCCESS( ntStatus))
                     {
-                        AFSReleaseResource( AFSGlobalRoot->VolumeLock);
 
                         if ( bIsAllShare &&
                              uniRemainingPath.Length == 0 &&
@@ -3307,6 +3543,7 @@ AFSParseName( IN PIRP Irp,
             AFSReleaseResource( AFSGlobalRoot->ObjectInformation.Specific.Directory.DirectoryNodeHdr.TreeLock);
         }
 
+
         //
         // Be sure we are starting from the correct volume
         //
@@ -3322,6 +3559,38 @@ AFSParseName( IN PIRP Irp,
             pVolumeCB = pDirEntry->ObjectInformation->VolumeCB;
 
             //
+            // Init our name array
+            //
+
+            pNameArray = AFSInitNameArray( AFSGlobalRoot->DirectoryCB,
+                                           0);
+
+            if( pNameArray == NULL)
+            {
+
+                AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
+                              AFS_TRACE_LEVEL_VERBOSE,
+                              "AFSParseName (%08lX) Failed to initialize name array\n",
+                              Irp);
+
+                try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
+            }
+
+            ntStatus = AFSInsertNextElement( pNameArray,
+                                             pVolumeCB->DirectoryCB);
+
+            if ( ntStatus)
+            {
+
+                AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
+                              AFS_TRACE_LEVEL_VERBOSE,
+                              "AFSParseName (%08lX) Failed to insert name array element\n",
+                              Irp);
+
+                try_return( ntStatus);
+            }
+
+            //
             // In this case don't add back in the 'share' name since that is where we are
             // starting. Just put the leading slash back in
             //
@@ -3371,6 +3640,23 @@ AFSParseName( IN PIRP Irp,
             pVolumeCB = AFSGlobalRoot;
 
             //
+            // Init our name array
+            //
+
+            pNameArray = AFSInitNameArray( AFSGlobalRoot->DirectoryCB,
+                                           0);
+            if( pNameArray == NULL)
+            {
+
+                AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
+                              AFS_TRACE_LEVEL_VERBOSE,
+                              "AFSParseName (%08lX) Failed to initialize name array\n",
+                              Irp);
+
+                try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
+            }
+
+            //
             // Add back in the 'share' portion of the name since we will parse it out on return
             //
 
@@ -3413,7 +3699,7 @@ AFSParseName( IN PIRP Irp,
             uniRemainingPath.Length += sizeof( WCHAR);
             uniRemainingPath.MaximumLength += sizeof( WCHAR);
 
-            InterlockedIncrement( &pVolumeCB->DirectoryCB->OpenReferenceCount);
+            lCount = InterlockedIncrement( &pVolumeCB->DirectoryCB->OpenReferenceCount);
 
             AFSDbgLogMsg( AFS_SUBSYSTEM_DIRENTRY_REF_COUNTING,
                           AFS_TRACE_LEVEL_VERBOSE,
@@ -3421,39 +3707,14 @@ AFSParseName( IN PIRP Irp,
                           &pVolumeCB->DirectoryCB->NameInformation.FileName,
                           pVolumeCB->DirectoryCB,
                           NULL,
-                          pVolumeCB->DirectoryCB->OpenReferenceCount);
+                          lCount = pVolumeCB->DirectoryCB->OpenReferenceCount);
 
             //
             // Pass back the parent being the volume root
             //
 
             *ParentDirectoryCB = pVolumeCB->DirectoryCB;
-        }
 
-        //
-        // We only need the volume shared at this point
-        //
-
-        AFSConvertToShared( pVolumeCB->VolumeLock);
-
-        //
-        // Init our name array
-        //
-
-        pNameArray = AFSInitNameArray( pVolumeCB->DirectoryCB,
-                                       0);
-
-        if( pNameArray == NULL)
-        {
-
-            AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
-                          AFS_TRACE_LEVEL_VERBOSE,
-                          "AFSParseName (%08lX) Failed to initialize name array\n",
-                          Irp);
-
-            AFSReleaseResource( pVolumeCB->VolumeLock);
-
-            try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
         }
 
         //
@@ -3472,13 +3733,13 @@ AFSParseName( IN PIRP Irp,
         // Increment our reference on the volume
         //
 
-        InterlockedIncrement( &pVolumeCB->VolumeReferenceCount);
+        lCount = InterlockedIncrement( &pVolumeCB->VolumeReferenceCount);
 
         AFSDbgLogMsg( AFS_SUBSYSTEM_VOLUME_REF_COUNTING,
                       AFS_TRACE_LEVEL_VERBOSE,
                       "AFSParseName Increment2 count on global volume %08lX Cnt %d\n",
                       pVolumeCB,
-                      pVolumeCB->VolumeReferenceCount);
+                      lCount);
 
 try_exit:
 
@@ -3500,7 +3761,6 @@ try_exit:
 
         if( *VolumeCB != NULL)
         {
-
             ASSERT( (*VolumeCB)->VolumeReferenceCount > 1);
         }
 
@@ -3526,13 +3786,13 @@ AFSCheckCellName( IN GUID *AuthGroup,
 
     NTSTATUS ntStatus = STATUS_SUCCESS;
     UNICODE_STRING uniName;
-    AFSFileID stFileID;
     AFSDirEnumEntry *pDirEnumEntry = NULL;
     AFSDeviceExt *pDevExt = (AFSDeviceExt *)AFSRDRDeviceObject->DeviceExtension;
     AFSDirHdr *pDirHdr = &AFSGlobalRoot->ObjectInformation.Specific.Directory.DirectoryNodeHdr;
     AFSDirectoryCB *pDirNode = NULL;
     UNICODE_STRING uniDirName, uniTargetName;
     AFSVolumeCB *pVolumeCB = NULL;
+    LONG lCount;
 
     __Enter
     {
@@ -3589,16 +3849,24 @@ AFSCheckCellName( IN GUID *AuthGroup,
         // OK, ask the CM about this component name
         //
 
-        stFileID = AFSGlobalRoot->ObjectInformation.FileId;
-
         ntStatus = AFSEvaluateTargetByName( AuthGroup,
-                                            &stFileID,
+                                            &AFSGlobalRoot->ObjectInformation,
                                             CellName,
                                             &pDirEnumEntry);
 
         if( !NT_SUCCESS( ntStatus))
         {
 
+            AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
+                          AFS_TRACE_LEVEL_WARNING,
+                          "AFSCheckCellName entry %wZ does not exist parent FID %08lX-%08lX-%08lX-%08lX Status %08lX\n",
+                          CellName,
+                          AFSGlobalRoot->ObjectInformation.FileId.Cell,
+                          AFSGlobalRoot->ObjectInformation.FileId.Volume,
+                          AFSGlobalRoot->ObjectInformation.FileId.Vnode,
+                          AFSGlobalRoot->ObjectInformation.FileId.Unique,
+                          ntStatus);
+
             try_return( ntStatus);
         }
 
@@ -3621,12 +3889,6 @@ AFSCheckCellName( IN GUID *AuthGroup,
         {
 
             //
-            // We have the global root on entry so drop it now
-            //
-
-            AFSReleaseResource( AFSGlobalRoot->VolumeLock);
-
-            //
             // Build the root volume entry
             //
 
@@ -3636,20 +3898,12 @@ AFSCheckCellName( IN GUID *AuthGroup,
 
             if( !NT_SUCCESS( ntStatus))
             {
-
-                //
-                // On failure this routine is expecting to hold the global root
-                //
-
-                AFSAcquireShared( AFSGlobalRoot->VolumeLock,
-                                  TRUE);
-
                 try_return( ntStatus);
             }
 
             *ShareDirEntry = pVolumeCB->DirectoryCB;
 
-            InterlockedIncrement( &pVolumeCB->DirectoryCB->OpenReferenceCount);
+            lCount = InterlockedIncrement( &pVolumeCB->DirectoryCB->OpenReferenceCount);
 
             AFSDbgLogMsg( AFS_SUBSYSTEM_DIRENTRY_REF_COUNTING,
                           AFS_TRACE_LEVEL_VERBOSE,
@@ -3657,18 +3911,20 @@ AFSCheckCellName( IN GUID *AuthGroup,
                           &pVolumeCB->DirectoryCB->NameInformation.FileName,
                           pVolumeCB->DirectoryCB,
                           NULL,
-                          pVolumeCB->DirectoryCB->OpenReferenceCount);
+                          lCount);
 
-            InterlockedDecrement( &pVolumeCB->VolumeReferenceCount);
+            lCount = InterlockedDecrement( &pVolumeCB->VolumeReferenceCount);
         }
         else
         {
 
+            lCount = InterlockedIncrement( &pDirHdr->ContentIndex);
+
             pDirNode = AFSInitDirEntry( &AFSGlobalRoot->ObjectInformation,
                                         &uniDirName,
                                         &uniTargetName,
                                         pDirEnumEntry,
-                                        (ULONG)InterlockedIncrement( &pDirHdr->ContentIndex));
+                                        (ULONG)lCount);
 
             if( pDirNode == NULL)
             {
@@ -3707,10 +3963,21 @@ AFSCheckCellName( IN GUID *AuthGroup,
             else
             {
 
-                AFSInsertCaseSensitiveDirEntry( pDirHdr->CaseSensitiveTreeHead,
-                                                pDirNode);
+                if( !NT_SUCCESS( AFSInsertCaseSensitiveDirEntry( pDirHdr->CaseSensitiveTreeHead,
+                                                                 pDirNode)))
+                {
+
+                    AFSDeleteDirEntry( &AFSGlobalRoot->ObjectInformation,
+                                       pDirNode);
+
+                    AFSReleaseResource( AFSGlobalRoot->ObjectInformation.Specific.Directory.DirectoryNodeHdr.TreeLock);
+
+                    try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
+                }
             }
 
+            ClearFlag( pDirNode->Flags, AFS_DIR_ENTRY_NOT_IN_PARENT_TREE);
+
             if( pDirHdr->CaseInsensitiveTreeHead == NULL)
             {
 
@@ -3742,19 +4009,19 @@ AFSCheckCellName( IN GUID *AuthGroup,
 
             SetFlag( pDirNode->Flags, AFS_DIR_ENTRY_INSERTED_ENUM_LIST);
 
-            InterlockedIncrement( &AFSGlobalRoot->ObjectInformation.Specific.Directory.DirectoryNodeCount);
+            lCount = InterlockedIncrement( &AFSGlobalRoot->ObjectInformation.Specific.Directory.DirectoryNodeCount);
 
             AFSDbgLogMsg( AFS_SUBSYSTEM_DIR_NODE_COUNT,
                           AFS_TRACE_LEVEL_VERBOSE,
                           "AFSCheckCellName Adding entry %wZ Inc Count %d to parent FID %08lX-%08lX-%08lX-%08lX\n",
-                              &pDirNode->NameInformation.FileName,
-                              AFSGlobalRoot->ObjectInformation.Specific.Directory.DirectoryNodeCount,
-                              AFSGlobalRoot->ObjectInformation.FileId.Cell,
-                              AFSGlobalRoot->ObjectInformation.FileId.Volume,
-                              AFSGlobalRoot->ObjectInformation.FileId.Vnode,
-                              AFSGlobalRoot->ObjectInformation.FileId.Unique);
+                          &pDirNode->NameInformation.FileName,
+                          lCount,
+                          AFSGlobalRoot->ObjectInformation.FileId.Cell,
+                          AFSGlobalRoot->ObjectInformation.FileId.Volume,
+                          AFSGlobalRoot->ObjectInformation.FileId.Vnode,
+                          AFSGlobalRoot->ObjectInformation.FileId.Unique);
 
-            InterlockedIncrement( &pDirNode->OpenReferenceCount);
+            lCount = InterlockedIncrement( &pDirNode->OpenReferenceCount);
 
             AFSDbgLogMsg( AFS_SUBSYSTEM_DIRENTRY_REF_COUNTING,
                           AFS_TRACE_LEVEL_VERBOSE,
@@ -3762,7 +4029,7 @@ AFSCheckCellName( IN GUID *AuthGroup,
                           &pDirNode->NameInformation.FileName,
                           pDirNode,
                           NULL,
-                          pDirNode->OpenReferenceCount);
+                          lCount);
 
             AFSReleaseResource( AFSGlobalRoot->ObjectInformation.Specific.Directory.DirectoryNodeHdr.TreeLock);
 
@@ -3799,6 +4066,7 @@ AFSBuildMountPointTarget( IN GUID *AuthGroup,
     ULONGLONG       ullIndex = 0;
     AFSVolumeCB *pVolumeCB = NULL;
     AFSFileID stTargetFileID;
+    LONG lCount;
 
     __Enter
     {
@@ -3866,7 +4134,7 @@ AFSBuildMountPointTarget( IN GUID *AuthGroup,
                               DirectoryCB->ObjectInformation->FileId.Vnode,
                               DirectoryCB->ObjectInformation->FileId.Unique);
 
-                try_return( ntStatus = STATUS_ACCESS_DENIED);
+                try_return( ntStatus = STATUS_REPARSE_POINT_NOT_RESOLVED);
             }
 
             AFSAcquireExcl( &DirectoryCB->NonPaged->Lock,
@@ -3974,14 +4242,14 @@ AFSBuildMountPointTarget( IN GUID *AuthGroup,
             // deadlock with invalidation
             //
 
-            InterlockedIncrement( &pVolumeCB->VolumeReferenceCount);
+            lCount = InterlockedIncrement( &pVolumeCB->VolumeReferenceCount);
 
             AFSReleaseResource( &pDevExt->Specific.RDR.VolumeTreeLock);
 
             AFSAcquireExcl( pVolumeCB->VolumeLock,
                             TRUE);
 
-            InterlockedDecrement( &pVolumeCB->VolumeReferenceCount);
+            lCount = InterlockedDecrement( &pVolumeCB->VolumeReferenceCount);
         }
 
         if( pVolumeCB->RootFcb == NULL)
@@ -4009,8 +4277,6 @@ AFSBuildMountPointTarget( IN GUID *AuthGroup,
             AFSReleaseResource( &pVolumeCB->RootFcb->NPFcb->Resource);
         }
 
-        AFSConvertToShared( pVolumeCB->VolumeLock);
-
         AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
                       AFS_TRACE_LEVEL_VERBOSE_2,
                       "AFSBuildMountPointTarget Evaluated target of %wZ FID %08lX-%08lX-%08lX-%08lX as root volume\n",
@@ -4020,13 +4286,15 @@ AFSBuildMountPointTarget( IN GUID *AuthGroup,
                       pVolumeCB->ObjectInformation.FileId.Vnode,
                       pVolumeCB->ObjectInformation.FileId.Unique);
 
-        InterlockedIncrement( &pVolumeCB->VolumeReferenceCount);
+        lCount = InterlockedIncrement( &pVolumeCB->VolumeReferenceCount);
+
+        AFSReleaseResource( pVolumeCB->VolumeLock);
 
         AFSDbgLogMsg( AFS_SUBSYSTEM_VOLUME_REF_COUNTING,
                       AFS_TRACE_LEVEL_VERBOSE,
                       "AFSBuildMountPointTarget Increment count on volume %08lX Cnt %d\n",
                       pVolumeCB,
-                      pVolumeCB->VolumeReferenceCount);
+                      lCount);
 
         *TargetVolumeCB = pVolumeCB;
 
@@ -4054,6 +4322,7 @@ AFSBuildRootVolume( IN GUID *AuthGroup,
     UNICODE_STRING uniDirName, uniTargetName;
     ULONGLONG       ullIndex = 0;
     AFSVolumeCB *pVolumeCB = NULL;
+    LONG lCount;
 
     __Enter
     {
@@ -4130,14 +4399,14 @@ AFSBuildRootVolume( IN GUID *AuthGroup,
             // deadlock with invalidation
             //
 
-            InterlockedIncrement( &pVolumeCB->VolumeReferenceCount);
+            lCount = InterlockedIncrement( &pVolumeCB->VolumeReferenceCount);
 
             AFSReleaseResource( &pDevExt->Specific.RDR.VolumeTreeLock);
 
             AFSAcquireExcl( pVolumeCB->VolumeLock,
                             TRUE);
 
-            InterlockedDecrement( &pVolumeCB->VolumeReferenceCount);
+            lCount = InterlockedDecrement( &pVolumeCB->VolumeReferenceCount);
         }
 
 
@@ -4166,8 +4435,6 @@ AFSBuildRootVolume( IN GUID *AuthGroup,
             AFSReleaseResource( &pVolumeCB->RootFcb->NPFcb->Resource);
         }
 
-        AFSConvertToShared( pVolumeCB->VolumeLock);
-
         AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
                       AFS_TRACE_LEVEL_VERBOSE_2,
                       "AFSBuildRootVolume Evaluated target of %wZ FID %08lX-%08lX-%08lX-%08lX as root volume\n",
@@ -4177,13 +4444,15 @@ AFSBuildRootVolume( IN GUID *AuthGroup,
                       pVolumeCB->ObjectInformation.FileId.Vnode,
                       pVolumeCB->ObjectInformation.FileId.Unique);
 
-        InterlockedIncrement( &pVolumeCB->VolumeReferenceCount);
+        lCount = InterlockedIncrement( &pVolumeCB->VolumeReferenceCount);
+
+        AFSReleaseResource( pVolumeCB->VolumeLock);
 
         AFSDbgLogMsg( AFS_SUBSYSTEM_VOLUME_REF_COUNTING,
                       AFS_TRACE_LEVEL_VERBOSE,
                       "AFSBuildRootVolume Increment count on volume %08lX Cnt %d\n",
                       pVolumeCB,
-                      pVolumeCB->VolumeReferenceCount);
+                      lCount);
 
         *TargetVolumeCB = pVolumeCB;
 
@@ -4198,14 +4467,14 @@ try_exit:
 NTSTATUS
 AFSProcessDFSLink( IN AFSDirectoryCB *DirEntry,
                    IN PFILE_OBJECT FileObject,
-                   IN UNICODE_STRING *RemainingPath)
+                   IN UNICODE_STRING *RemainingPath,
+                   IN GUID *AuthGroup)
 {
 
     NTSTATUS ntStatus = STATUS_INVALID_DEVICE_REQUEST;
     UNICODE_STRING uniReparseName;
     UNICODE_STRING uniMUPDeviceName;
     AFSDirEnumEntry *pDirEntry = NULL;
-    GUID *pAuthGroup = NULL;
 
     __Enter
     {
@@ -4227,13 +4496,8 @@ AFSProcessDFSLink( IN AFSDirectoryCB *DirEntry,
         if( DirEntry->NameInformation.TargetName.Length == 0)
         {
 
-            if( DirEntry->ObjectInformation->Fcb != NULL)
-            {
-                pAuthGroup = &DirEntry->ObjectInformation->Fcb->AuthGroup;
-            }
-
             ntStatus = AFSEvaluateTargetByID( DirEntry->ObjectInformation,
-                                              pAuthGroup,
+                                              AuthGroup,
                                               FALSE,
                                               &pDirEntry);
 
@@ -4254,7 +4518,7 @@ AFSProcessDFSLink( IN AFSDirectoryCB *DirEntry,
                 if( NT_SUCCESS( ntStatus))
                 {
 
-                    ntStatus = STATUS_ACCESS_DENIED;
+                    ntStatus = STATUS_REPARSE_POINT_NOT_RESOLVED;
                 }
 
                 try_return( ntStatus);