Windows: Remove trailing slash on non-root directories
[openafs.git] / src / WINNT / afsrdr / kernel / lib / AFSNameSupport.cpp
index 776fa33..6448ded 100644 (file)
 // AFSLocateNameEntry
 //
 // On entry, *VolumeCB must have a held ReferenceCount provided by
-// the caller which will be released.  On successful exit, *VolumeCB
+// the caller which will not be released.  On successful exit, *OutVolumeCB
 // will be assigned the new current volume with a held ReferenceCount.
 //
 // On entry, *ParentDirectoryCB must have a held DirOpenReferenceCount
-// provided by the caller.
+// provided by the caller.  This reference will not be released.
+// On exit, if OutParentDirectoryCB is set, it will have a new reference.
+//
+// On exit, if OutDirectoryCB is set, it will have a reference.
 //
 
 NTSTATUS
 AFSLocateNameEntry( IN GUID *AuthGroup,
                     IN PFILE_OBJECT FileObject,
-                    IN UNICODE_STRING *RootPathName,
+                    IN OUT UNICODE_STRING *RootPathName,
                     IN UNICODE_STRING *ParsedPathName,
                     IN AFSNameArrayHdr *NameArray,
                     IN ULONG Flags,
-                    IN OUT AFSVolumeCB **VolumeCB,
-                    IN OUT AFSDirectoryCB **ParentDirectoryCB,
-                    OUT AFSDirectoryCB **DirectoryCB,
-                    OUT PUNICODE_STRING ComponentName)
+                    IN AFSVolumeCB *VolumeCB,
+                    IN AFSDirectoryCB *ParentDirectoryCB,
+                    OUT AFSVolumeCB **OutVolumeCB,
+                    OUT LONG *OutVolumeReferenceReason,
+                    OUT AFSDirectoryCB **OutParentDirectoryCB,
+                    OUT AFSDirectoryCB **OutDirectoryCB,
+                    OUT PUNICODE_STRING ComponentName,
+                   OUT PUNICODE_STRING TargetName)
 {
 
     NTSTATUS          ntStatus = STATUS_SUCCESS;
     UNICODE_STRING    uniPathName, uniComponentName, uniRemainingPath, uniSearchName, uniFullPathName;
     ULONG             ulCRC = 0;
     AFSDirectoryCB   *pDirEntry = NULL, *pParentDirEntry = NULL;
-    AFSDeviceExt *pDevExt = (AFSDeviceExt *) AFSRDRDeviceObject->DeviceExtension;
+    AFSDeviceExt     *pDevExt = (AFSDeviceExt *) AFSRDRDeviceObject->DeviceExtension;
     UNICODE_STRING    uniSysName;
     ULONG             ulSubstituteIndex = 0;
     BOOLEAN           bSubstituteName = FALSE;
@@ -75,19 +82,23 @@ AFSLocateNameEntry( IN GUID *AuthGroup,
     UNICODE_STRING    uniRelativeName, uniNoOpName;
     AFSObjectInfoCB  *pCurrentObject = NULL;
     AFSObjectInfoCB  *pParentObjectInfo = NULL;
-    AFSVolumeCB      *pCurrentVolume = *VolumeCB;
-    BOOLEAN           bReleaseCurrentVolume = TRUE;
+    AFSVolumeCB      *pCurrentVolume = NULL;
+    AFSVolumeCB      *pTargetVolume = NULL;
+    BOOLEAN           bReleaseCurrentVolume = FALSE;
+    LONG              VolumeReferenceReason;
     BOOLEAN           bSubstitutedName = FALSE;
     LONG              lCount;
 
     __Enter
     {
 
-        AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
+        ASSERT( *OutVolumeCB != VolumeCB);
+
+        AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING,
                       AFS_TRACE_LEVEL_VERBOSE_2,
                       "AFSLocateNameEntry (FO: %p) Processing full name %wZ\n",
                       FileObject,
-                      RootPathName);
+                      RootPathName));
 
         RtlInitUnicodeString( &uniSysName,
                               L"*@SYS");
@@ -117,7 +128,37 @@ AFSLocateNameEntry( IN GUID *AuthGroup,
 
         pParentDirEntry = NULL;
 
-        pDirEntry = *ParentDirectoryCB;
+        pDirEntry = ParentDirectoryCB;
+
+        //
+        // Increment our reference on this dir entry
+        //
+
+        lCount = InterlockedIncrement( &pDirEntry->DirOpenReferenceCount);
+
+        AFSDbgTrace(( AFS_SUBSYSTEM_DIRENTRY_REF_COUNTING,
+                      AFS_TRACE_LEVEL_VERBOSE,
+                      "AFSLocateNameEntry Increment1 count on %wZ DE %p Ccb %p Cnt %d\n",
+                      &pDirEntry->NameInformation.FileName,
+                      pDirEntry,
+                      NULL,
+                      lCount));
+
+        pCurrentVolume = VolumeCB;
+
+        VolumeReferenceReason = AFS_VOLUME_REFERENCE_LOCATE_NAME;
+
+        lCount = AFSVolumeIncrement( pCurrentVolume,
+                                     VolumeReferenceReason);
+
+        AFSDbgTrace(( AFS_SUBSYSTEM_VOLUME_REF_COUNTING,
+                      AFS_TRACE_LEVEL_VERBOSE,
+                      "AFSLocateNameEntry Increment count on volume %p Reason %u Cnt %d\n",
+                      pCurrentVolume,
+                      VolumeReferenceReason,
+                      lCount));
+
+        bReleaseCurrentVolume = TRUE;
 
         uniPathName = *ParsedPathName;
 
@@ -135,7 +176,7 @@ AFSLocateNameEntry( IN GUID *AuthGroup,
         while( TRUE)
         {
 
-            ASSERT( pCurrentVolume->VolumeReferenceCount > 1);
+            ASSERT( pCurrentVolume->VolumeReferenceCount > 0);
 
             ASSERT( pDirEntry->DirOpenReferenceCount > 0);
 
@@ -160,7 +201,7 @@ AFSLocateNameEntry( IN GUID *AuthGroup,
             if( BooleanFlagOn( pDirEntry->Flags, AFS_DIR_ENTRY_DELETED))
             {
 
-                AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
+                AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING,
                               AFS_TRACE_LEVEL_ERROR,
                               "AFSLocateNameEntry (FO: %p) Deleted parent %wZ FID %08lX-%08lX-%08lX-%08lX Status %08lX\n",
                               FileObject,
@@ -169,7 +210,7 @@ AFSLocateNameEntry( IN GUID *AuthGroup,
                               pCurrentObject->FileId.Volume,
                               pCurrentObject->FileId.Vnode,
                               pCurrentObject->FileId.Unique,
-                              STATUS_FILE_DELETED);
+                              STATUS_FILE_DELETED));
 
                 try_return( ntStatus = STATUS_FILE_DELETED);
             }
@@ -177,7 +218,7 @@ AFSLocateNameEntry( IN GUID *AuthGroup,
             if( BooleanFlagOn( pDirEntry->Flags, AFS_DIR_ENTRY_PENDING_DELETE))
             {
 
-                AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
+                AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING,
                               AFS_TRACE_LEVEL_ERROR,
                               "AFSLocateNameEntry (FO: %p) Delete pending on %wZ FID %08lX-%08lX-%08lX-%08lX Status %08lX\n",
                               FileObject,
@@ -186,7 +227,7 @@ AFSLocateNameEntry( IN GUID *AuthGroup,
                               pCurrentObject->FileId.Volume,
                               pCurrentObject->FileId.Vnode,
                               pCurrentObject->FileId.Unique,
-                              STATUS_DELETE_PENDING);
+                              STATUS_DELETE_PENDING));
 
                 try_return( ntStatus = STATUS_DELETE_PENDING);
             }
@@ -200,7 +241,7 @@ AFSLocateNameEntry( IN GUID *AuthGroup,
                   !AFSIsEnumerationInProcess( pCurrentObject)))
             {
 
-                AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
+                AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING,
                               AFS_TRACE_LEVEL_VERBOSE,
                               "AFSLocateNameEntry (FO: %p) Verifying parent %wZ FID %08lX-%08lX-%08lX-%08lX\n",
                               FileObject,
@@ -208,7 +249,7 @@ AFSLocateNameEntry( IN GUID *AuthGroup,
                               pCurrentObject->FileId.Cell,
                               pCurrentObject->FileId.Volume,
                               pCurrentObject->FileId.Vnode,
-                              pCurrentObject->FileId.Unique);
+                              pCurrentObject->FileId.Unique));
 
                 //
                 // Directory TreeLock should be exclusively held
@@ -218,14 +259,15 @@ AFSLocateNameEntry( IN GUID *AuthGroup,
                                 TRUE);
 
                 ntStatus = AFSVerifyEntry( AuthGroup,
-                                           pDirEntry);
+                                          pDirEntry,
+                                          FALSE);
 
                 AFSReleaseResource( pCurrentObject->Specific.Directory.DirectoryNodeHdr.TreeLock);
 
                 if( !NT_SUCCESS( ntStatus))
                 {
 
-                    AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
+                    AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING,
                                   AFS_TRACE_LEVEL_ERROR,
                                   "AFSLocateNameEntry (FO: %p) Failed to verify parent %wZ FID %08lX-%08lX-%08lX-%08lX Status %08lX\n",
                                   FileObject,
@@ -234,7 +276,7 @@ AFSLocateNameEntry( IN GUID *AuthGroup,
                                   pCurrentObject->FileId.Volume,
                                   pCurrentObject->FileId.Vnode,
                                   pCurrentObject->FileId.Unique,
-                                  ntStatus);
+                                  ntStatus));
 
                     try_return( ntStatus);
                 }
@@ -248,7 +290,7 @@ AFSLocateNameEntry( IN GUID *AuthGroup,
                 pCurrentObject->FileType == AFS_FILE_TYPE_UNKNOWN)
             {
 
-                AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
+                AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING,
                               AFS_TRACE_LEVEL_VERBOSE,
                               "AFSLocateNameEntry (FO: %p) Evaluating parent %wZ FID %08lX-%08lX-%08lX-%08lX\n",
                               FileObject,
@@ -256,7 +298,7 @@ AFSLocateNameEntry( IN GUID *AuthGroup,
                               pCurrentObject->FileId.Cell,
                               pCurrentObject->FileId.Volume,
                               pCurrentObject->FileId.Vnode,
-                              pCurrentObject->FileId.Unique);
+                              pCurrentObject->FileId.Unique));
 
                 ntStatus = AFSEvaluateNode( AuthGroup,
                                             pDirEntry);
@@ -267,10 +309,10 @@ AFSLocateNameEntry( IN GUID *AuthGroup,
                     if ( ntStatus == STATUS_NOT_A_DIRECTORY)
                     {
 
-                        if ( pCurrentObject->ParentObjectInformation == NULL)
+                        if ( !BooleanFlagOn( pCurrentObject->Flags, AFS_OBJECT_FLAGS_PARENT_FID))
                         {
 
-                            AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
+                            AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING,
                                           AFS_TRACE_LEVEL_ERROR,
                                           "AFSLocateNameEntry (FO: %p) Failed to evaluate object %wZ FID %08lX-%08lX-%08lX-%08lX PARENT NULL Status %08lX\n",
                                           FileObject,
@@ -279,12 +321,12 @@ AFSLocateNameEntry( IN GUID *AuthGroup,
                                           pCurrentObject->FileId.Volume,
                                           pCurrentObject->FileId.Vnode,
                                           pCurrentObject->FileId.Unique,
-                                          ntStatus);
+                                          ntStatus));
                         }
                         else
                         {
 
-                            AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
+                            AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING,
                                           AFS_TRACE_LEVEL_ERROR,
                                           "AFSLocateNameEntry (FO: %p) Failed to evaluate object %wZ FID %08lX-%08lX-%08lX-%08lX PARENT %08lX-%08lX-%08lX-%08lX Status %08lX\n",
                                           FileObject,
@@ -293,16 +335,16 @@ AFSLocateNameEntry( IN GUID *AuthGroup,
                                           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);
+                                          pCurrentObject->ParentFileId.Cell,
+                                          pCurrentObject->ParentFileId.Volume,
+                                          pCurrentObject->ParentFileId.Vnode,
+                                          pCurrentObject->ParentFileId.Unique,
+                                          ntStatus));
                         }
                     }
                     else
                     {
-                        AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
+                        AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING,
                                       AFS_TRACE_LEVEL_ERROR,
                                       "AFSLocateNameEntry (FO: %p) Failed to evaluate parent %wZ FID %08lX-%08lX-%08lX-%08lX Status %08lX\n",
                                       FileObject,
@@ -311,7 +353,7 @@ AFSLocateNameEntry( IN GUID *AuthGroup,
                                       pCurrentObject->FileId.Volume,
                                       pCurrentObject->FileId.Vnode,
                                       pCurrentObject->FileId.Unique,
-                                      ntStatus);
+                                      ntStatus));
                     }
 
                     try_return( ntStatus);
@@ -347,11 +389,19 @@ AFSLocateNameEntry( IN GUID *AuthGroup,
                         // Pass back the directory entries
                         //
 
-                        *ParentDirectoryCB = pParentDirEntry;
+                        *OutParentDirectoryCB = pParentDirEntry;
+
+                        pParentDirEntry = NULL;
+
+                        *OutDirectoryCB = pDirEntry;
+
+                        pDirEntry = NULL;
+
+                        *OutVolumeCB = pCurrentVolume;
 
-                        *DirectoryCB = pDirEntry;
+                        *OutVolumeReferenceReason = VolumeReferenceReason;
 
-                        *VolumeCB = pCurrentVolume;
+                        bReleaseCurrentVolume = FALSE;
 
                         *RootPathName = uniFullPathName;
 
@@ -375,7 +425,7 @@ AFSLocateNameEntry( IN GUID *AuthGroup,
 
                         SetFlag( pCurrentObject->Flags, AFS_OBJECT_FLAGS_VERIFY);
 
-                        AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
+                        AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING,
                                       AFS_TRACE_LEVEL_VERBOSE,
                                       "AFSLocateNameEntry (FO: %p) Verifying symlink parent %wZ FID %08lX-%08lX-%08lX-%08lX\n",
                                       FileObject,
@@ -383,21 +433,22 @@ AFSLocateNameEntry( IN GUID *AuthGroup,
                                       pCurrentObject->FileId.Cell,
                                       pCurrentObject->FileId.Volume,
                                       pCurrentObject->FileId.Vnode,
-                                      pCurrentObject->FileId.Unique);
+                                      pCurrentObject->FileId.Unique));
 
                         //
                         // Directory TreeLock should be exclusively held
                         //
 
                         ntStatus = AFSVerifyEntry( AuthGroup,
-                                                   pDirEntry);
+                                                  pDirEntry,
+                                                  FALSE);
 
                         AFSReleaseResource( pCurrentObject->Specific.Directory.DirectoryNodeHdr.TreeLock);
 
                         if( !NT_SUCCESS( ntStatus))
                         {
 
-                            AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
+                            AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING,
                                           AFS_TRACE_LEVEL_ERROR,
                                           "AFSLocateNameEntry (FO: %p) Failed to verify symlink parent %wZ FID %08lX-%08lX-%08lX-%08lX Status %08lX\n",
                                           FileObject,
@@ -406,7 +457,7 @@ AFSLocateNameEntry( IN GUID *AuthGroup,
                                           pCurrentObject->FileId.Volume,
                                           pCurrentObject->FileId.Vnode,
                                           pCurrentObject->FileId.Unique,
-                                          ntStatus);
+                                          ntStatus));
 
                             AFSReleaseResource( &pDirEntry->NonPaged->Lock);
 
@@ -440,7 +491,7 @@ AFSLocateNameEntry( IN GUID *AuthGroup,
 
                         ntStatus = STATUS_REPARSE_POINT_NOT_RESOLVED;
 
-                        AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
+                        AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING,
                                       AFS_TRACE_LEVEL_ERROR,
                                       "AFSLocateNameEntry (FO: %p) Failed to retrieve target name for symlink %wZ FID %08lX-%08lX-%08lX-%08lX Status %08lX\n",
                                       FileObject,
@@ -449,7 +500,7 @@ AFSLocateNameEntry( IN GUID *AuthGroup,
                                       pCurrentObject->FileId.Volume,
                                       pCurrentObject->FileId.Vnode,
                                       pCurrentObject->FileId.Unique,
-                                      ntStatus);
+                                      ntStatus));
 
                         AFSReleaseResource( &pDirEntry->NonPaged->Lock);
 
@@ -459,7 +510,7 @@ AFSLocateNameEntry( IN GUID *AuthGroup,
                     if( AFSIsRelativeName( &pDirEntry->NameInformation.TargetName))
                     {
 
-                        AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
+                        AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING,
                                       AFS_TRACE_LEVEL_VERBOSE,
                                       "AFSLocateNameEntry (FO: %p) Processing relative symlink target %wZ for %wZ FID %08lX-%08lX-%08lX-%08lX\n",
                                       FileObject,
@@ -468,7 +519,7 @@ AFSLocateNameEntry( IN GUID *AuthGroup,
                                       pCurrentObject->FileId.Cell,
                                       pCurrentObject->FileId.Volume,
                                       pCurrentObject->FileId.Vnode,
-                                      pCurrentObject->FileId.Unique);
+                                      pCurrentObject->FileId.Unique));
 
                         //
                         // We'll substitute this name into the current process name
@@ -576,13 +627,13 @@ AFSLocateNameEntry( IN GUID *AuthGroup,
 
                         lCount = InterlockedDecrement( &pDirEntry->DirOpenReferenceCount);
 
-                        AFSDbgLogMsg( AFS_SUBSYSTEM_DIRENTRY_REF_COUNTING,
+                        AFSDbgTrace(( AFS_SUBSYSTEM_DIRENTRY_REF_COUNTING,
                                       AFS_TRACE_LEVEL_VERBOSE,
                                       "AFSLocateNameEntry Decrement1 count on %wZ DE %p Ccb %p Cnt %d\n",
                                       &pDirEntry->NameInformation.FileName,
                                       pDirEntry,
                                       NULL,
-                                      lCount);
+                                      lCount));
 
                         ASSERT( lCount >= 0);
 
@@ -593,37 +644,88 @@ AFSLocateNameEntry( IN GUID *AuthGroup,
 
                         pDirEntry = AFSBackupEntry( pNameArray);
 
+                        pCurrentObject = pDirEntry->ObjectInformation;
+
                         //
                         // Increment our reference on this dir entry
                         //
 
                         lCount = InterlockedIncrement( &pDirEntry->DirOpenReferenceCount);
 
-                        AFSDbgLogMsg( AFS_SUBSYSTEM_DIRENTRY_REF_COUNTING,
+                        AFSDbgTrace(( AFS_SUBSYSTEM_DIRENTRY_REF_COUNTING,
                                       AFS_TRACE_LEVEL_VERBOSE,
-                                      "AFSLocateNameEntry Increment1 count on %wZ DE %p Ccb %p Cnt %d\n",
+                                      "AFSLocateNameEntry Increment2 count on %wZ DE %p Ccb %p Cnt %d\n",
                                       &pDirEntry->NameInformation.FileName,
                                       pDirEntry,
                                       NULL,
-                                      lCount);
+                                      lCount));
 
-                        if( BooleanFlagOn( pDirEntry->ObjectInformation->Flags, AFS_OBJECT_ROOT_VOLUME))
+                        if ( pParentDirEntry)
                         {
 
+                            lCount = InterlockedDecrement( &pParentDirEntry->DirOpenReferenceCount);
+
+                            AFSDbgTrace(( AFS_SUBSYSTEM_DIRENTRY_REF_COUNTING,
+                                          AFS_TRACE_LEVEL_VERBOSE,
+                                          "AFSLocateNameEntry Decrement count on %wZ DE %p Ccb %p Cnt %d\n",
+                                          &pParentDirEntry->NameInformation.FileName,
+                                          pParentDirEntry,
+                                          NULL,
+                                          lCount));
+
                             pParentDirEntry = NULL;
                         }
-                        else
+
+                        if( !BooleanFlagOn( pDirEntry->ObjectInformation->Flags, AFS_OBJECT_ROOT_VOLUME))
                         {
 
                             pParentDirEntry = AFSGetParentEntry( pNameArray);
 
                             ASSERT( pParentDirEntry != pDirEntry);
+
+                            lCount = InterlockedIncrement( &pParentDirEntry->DirOpenReferenceCount);
+
+                            AFSDbgTrace(( AFS_SUBSYSTEM_DIRENTRY_REF_COUNTING,
+                                          AFS_TRACE_LEVEL_VERBOSE,
+                                          "AFSLocateNameEntry Increment count on %wZ DE %p Ccb %p Cnt %d\n",
+                                          &pParentDirEntry->NameInformation.FileName,
+                                          pParentDirEntry,
+                                          NULL,
+                                          lCount));
+                        }
+
+                        if ( pDirEntry->ObjectInformation->VolumeCB != pCurrentVolume)
+                        {
+
+                            lCount = AFSVolumeDecrement( pCurrentVolume,
+                                                         VolumeReferenceReason);
+
+                            AFSDbgTrace(( AFS_SUBSYSTEM_VOLUME_REF_COUNTING,
+                                          AFS_TRACE_LEVEL_VERBOSE,
+                                          "AFSLocateNameEntry Decrement count on volume %p Reason %u Cnt %d\n",
+                                          pCurrentVolume,
+                                          VolumeReferenceReason,
+                                          lCount));
+
+                            pCurrentVolume = pDirEntry->ObjectInformation->VolumeCB;
+
+                            VolumeReferenceReason = AFS_VOLUME_REFERENCE_LOCATE_NAME;
+
+                            lCount = AFSVolumeIncrement( pCurrentVolume,
+                                                         VolumeReferenceReason);
+
+                            AFSDbgTrace(( AFS_SUBSYSTEM_VOLUME_REF_COUNTING,
+                                          AFS_TRACE_LEVEL_VERBOSE,
+                                          "AFSLocateNameEntry Increment count on volume %p Reason %u Cnt %d\n",
+                                          pCurrentVolume,
+                                          VolumeReferenceReason,
+                                          lCount));
                         }
                     }
                     else
                     {
 
-                        AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
+                        AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING,
                                       AFS_TRACE_LEVEL_VERBOSE,
                                       "AFSLocateNameEntry (FO: %p) Processing absolute symlink target %wZ for %wZ FID %08lX-%08lX-%08lX-%08lX\n",
                                       FileObject,
@@ -632,15 +734,15 @@ AFSLocateNameEntry( IN GUID *AuthGroup,
                                       pCurrentObject->FileId.Cell,
                                       pCurrentObject->FileId.Volume,
                                       pCurrentObject->FileId.Vnode,
-                                      pCurrentObject->FileId.Unique);
+                                      pCurrentObject->FileId.Unique));
 
                         if ( !AFSIsAbsoluteAFSName( &pDirEntry->NameInformation.TargetName))
                         {
 
-                            AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
+                            AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING,
                                           AFS_TRACE_LEVEL_ERROR,
                                           "AFSLocateNameEntry Name %wZ contains invalid server name\n",
-                                          &pDirEntry->NameInformation.TargetName);
+                                          &pDirEntry->NameInformation.TargetName));
 
                             //
                             // The correct response would be STATUS_OBJECT_PATH_INVALID
@@ -744,7 +846,7 @@ AFSLocateNameEntry( IN GUID *AuthGroup,
                         if( pCurrentVolume != AFSGlobalRoot)
                         {
 
-                            AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
+                            AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING,
                                           AFS_TRACE_LEVEL_VERBOSE,
                                           "AFSLocateNameEntry (FO: %p) Current volume not global, resetting for %wZ FID %08lX-%08lX-%08lX-%08lX\n",
                                           FileObject,
@@ -752,25 +854,31 @@ AFSLocateNameEntry( IN GUID *AuthGroup,
                                           pCurrentObject->FileId.Cell,
                                           pCurrentObject->FileId.Volume,
                                           pCurrentObject->FileId.Vnode,
-                                          pCurrentObject->FileId.Unique);
+                                          pCurrentObject->FileId.Unique));
 
-                            lCount = InterlockedDecrement( &pCurrentVolume->VolumeReferenceCount);
+                            lCount = AFSVolumeDecrement( pCurrentVolume,
+                                                         VolumeReferenceReason);
 
-                            AFSDbgLogMsg( AFS_SUBSYSTEM_VOLUME_REF_COUNTING,
+                            AFSDbgTrace(( AFS_SUBSYSTEM_VOLUME_REF_COUNTING,
                                           AFS_TRACE_LEVEL_VERBOSE,
-                                          "AFSLocateNameEntry Decrement count on volume %p Cnt %d\n",
+                                          "AFSLocateNameEntry Decrement count on volume %p Reason %u Cnt %d\n",
                                           pCurrentVolume,
-                                          lCount);
+                                          VolumeReferenceReason,
+                                          lCount));
 
                             pCurrentVolume = AFSGlobalRoot;
 
-                            lCount = InterlockedIncrement( &pCurrentVolume->VolumeReferenceCount);
+                            VolumeReferenceReason = AFS_VOLUME_REFERENCE_LOCATE_NAME;
 
-                            AFSDbgLogMsg( AFS_SUBSYSTEM_VOLUME_REF_COUNTING,
+                            lCount = AFSVolumeIncrement( pCurrentVolume,
+                                                         VolumeReferenceReason);
+
+                            AFSDbgTrace(( AFS_SUBSYSTEM_VOLUME_REF_COUNTING,
                                           AFS_TRACE_LEVEL_VERBOSE,
-                                          "AFSLocateNameEntry Increment count on volume %p Cnt %d\n",
+                                          "AFSLocateNameEntry Increment count on volume %p Reason %u Cnt %d\n",
                                           pCurrentVolume,
-                                          lCount);
+                                          VolumeReferenceReason,
+                                          lCount));
                         }
 
                         //
@@ -779,31 +887,33 @@ AFSLocateNameEntry( IN GUID *AuthGroup,
 
                         lCount = InterlockedDecrement( &pDirEntry->DirOpenReferenceCount);
 
-                        AFSDbgLogMsg( AFS_SUBSYSTEM_DIRENTRY_REF_COUNTING,
+                        AFSDbgTrace(( AFS_SUBSYSTEM_DIRENTRY_REF_COUNTING,
                                       AFS_TRACE_LEVEL_VERBOSE,
                                       "AFSLocateNameEntry Decrement2 count on %wZ DE %p Ccb %p Cnt %d\n",
                                       &pDirEntry->NameInformation.FileName,
                                       pDirEntry,
                                       NULL,
-                                      lCount);
+                                      lCount));
 
                         ASSERT( lCount >= 0);
 
                         pDirEntry = pCurrentVolume->DirectoryCB;
 
+                        pCurrentObject = pDirEntry->ObjectInformation;
+
                         //
                         // Reference the new dir entry
                         //
 
                         lCount = InterlockedIncrement( &pDirEntry->DirOpenReferenceCount);
 
-                        AFSDbgLogMsg( AFS_SUBSYSTEM_DIRENTRY_REF_COUNTING,
+                        AFSDbgTrace(( AFS_SUBSYSTEM_DIRENTRY_REF_COUNTING,
                                       AFS_TRACE_LEVEL_VERBOSE,
                                       "AFSLocateNameEntry Increment2 count on %wZ DE %p Ccb %p Cnt %d\n",
                                       &pDirEntry->NameInformation.FileName,
                                       pDirEntry,
                                       NULL,
-                                      lCount);
+                                      lCount));
 
                         //
                         // Reset the name array
@@ -812,7 +922,7 @@ AFSLocateNameEntry( IN GUID *AuthGroup,
 
                         lLinkCount = pNameArray->LinkCount;
 
-                        AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
+                        AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING,
                                       AFS_TRACE_LEVEL_VERBOSE,
                                       "AFSLocateNameEntry (FO: %p) Resetting name array for %wZ FID %08lX-%08lX-%08lX-%08lX\n",
                                       FileObject,
@@ -820,14 +930,28 @@ AFSLocateNameEntry( IN GUID *AuthGroup,
                                       pCurrentObject->FileId.Cell,
                                       pCurrentObject->FileId.Volume,
                                       pCurrentObject->FileId.Vnode,
-                                      pCurrentObject->FileId.Unique);
+                                      pCurrentObject->FileId.Unique));
 
                         AFSResetNameArray( pNameArray,
                                            pDirEntry);
 
                         pNameArray->LinkCount = lLinkCount;
 
-                        pParentDirEntry = NULL;
+                        if ( pParentDirEntry)
+                        {
+
+                            lCount = InterlockedDecrement( &pParentDirEntry->DirOpenReferenceCount);
+
+                            AFSDbgTrace(( AFS_SUBSYSTEM_DIRENTRY_REF_COUNTING,
+                                          AFS_TRACE_LEVEL_VERBOSE,
+                                          "AFSLocateNameEntry Decrement count on %wZ DE %p Ccb %p Cnt %d\n",
+                                          &pParentDirEntry->NameInformation.FileName,
+                                          pParentDirEntry,
+                                          NULL,
+                                          lCount));
+
+                            pParentDirEntry = NULL;
+                        }
                     }
 
                     //
@@ -855,18 +979,26 @@ AFSLocateNameEntry( IN GUID *AuthGroup,
                         // Pass back the directory entries
                         //
 
-                        *ParentDirectoryCB = pParentDirEntry;
+                        *OutParentDirectoryCB = pParentDirEntry;
 
-                        *DirectoryCB = pDirEntry;
+                        pParentDirEntry = NULL;
+
+                        *OutDirectoryCB = pDirEntry;
 
-                        *VolumeCB = pCurrentVolume;
+                        pDirEntry = NULL;
+
+                        *OutVolumeCB = pCurrentVolume;
+
+                        *OutVolumeReferenceReason = VolumeReferenceReason;
+
+                        bReleaseCurrentVolume = FALSE;
 
                         *RootPathName = uniFullPathName;
 
                         try_return( ntStatus);
                     }
 
-                    AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
+                    AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING,
                                   AFS_TRACE_LEVEL_VERBOSE,
                                   "AFSLocateNameEntry (FO: %p) Building MP target for parent %wZ FID %08lX-%08lX-%08lX-%08lX\n",
                                   FileObject,
@@ -874,7 +1006,7 @@ AFSLocateNameEntry( IN GUID *AuthGroup,
                                   pCurrentObject->FileId.Cell,
                                   pCurrentObject->FileId.Volume,
                                   pCurrentObject->FileId.Vnode,
-                                  pCurrentObject->FileId.Unique);
+                                  pCurrentObject->FileId.Unique));
 
                     //
                     // Go retrieve the target entry for this node
@@ -883,24 +1015,14 @@ AFSLocateNameEntry( IN GUID *AuthGroup,
                     // Also decrement the ref count on the volume
                     //
 
-                    ASSERT( pCurrentVolume->VolumeReferenceCount > 1);
-
-                    lCount = InterlockedDecrement( &pCurrentVolume->VolumeReferenceCount);
-
-                    AFSDbgLogMsg( AFS_SUBSYSTEM_VOLUME_REF_COUNTING,
-                                  AFS_TRACE_LEVEL_VERBOSE,
-                                  "AFSLocateNameEntry Decrement2 count on volume %p Cnt %d\n",
-                                  pCurrentVolume,
-                                  lCount);
-
                     ntStatus = AFSBuildMountPointTarget( AuthGroup,
                                                          pDirEntry,
-                                                         &pCurrentVolume);
+                                                         &pTargetVolume);
 
                     if( !NT_SUCCESS( ntStatus))
                     {
 
-                        AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
+                        AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING,
                                       AFS_TRACE_LEVEL_ERROR,
                                       "AFSLocateNameEntry (FO: %p) Failed to build MP target for parent %wZ FID %08lX-%08lX-%08lX-%08lX Status %08lX\n",
                                       FileObject,
@@ -909,18 +1031,30 @@ AFSLocateNameEntry( IN GUID *AuthGroup,
                                       pCurrentObject->FileId.Volume,
                                       pCurrentObject->FileId.Vnode,
                                       pCurrentObject->FileId.Unique,
-                                      ntStatus);
-
-                        //
-                        // We already decremented the current volume above
-                        //
-
-                        bReleaseCurrentVolume = FALSE;
+                                      ntStatus));
 
                         try_return( ntStatus);
                     }
 
-                    ASSERT( pCurrentVolume->VolumeReferenceCount > 1);
+                    ASSERT( pCurrentVolume->VolumeReferenceCount > 0);
+
+                    lCount = AFSVolumeDecrement( pCurrentVolume,
+                                                 VolumeReferenceReason);
+
+                    AFSDbgTrace(( AFS_SUBSYSTEM_VOLUME_REF_COUNTING,
+                                  AFS_TRACE_LEVEL_VERBOSE,
+                                  "AFSLocateNameEntry Decrement2 count on volume %p Reason %u Cnt %d\n",
+                                  pCurrentVolume,
+                                  VolumeReferenceReason,
+                                  lCount));
+
+                    pCurrentVolume = pTargetVolume;
+
+                    pTargetVolume = NULL;
+
+                    ASSERT( pCurrentVolume->VolumeReferenceCount > 0);
+
+                    VolumeReferenceReason = AFS_VOLUME_REFERENCE_MOUNTPT;
 
                     //
                     // We want to restart processing here on the new parent ...
@@ -929,27 +1063,29 @@ AFSLocateNameEntry( IN GUID *AuthGroup,
 
                     lCount = InterlockedDecrement( &pDirEntry->DirOpenReferenceCount);
 
-                    AFSDbgLogMsg( AFS_SUBSYSTEM_DIRENTRY_REF_COUNTING,
+                    AFSDbgTrace(( AFS_SUBSYSTEM_DIRENTRY_REF_COUNTING,
                                   AFS_TRACE_LEVEL_VERBOSE,
                                   "AFSLocateNameEntry Decrement3 count on %wZ DE %p Ccb %p Cnt %d\n",
                                   &pDirEntry->NameInformation.FileName,
                                   pDirEntry,
                                   NULL,
-                                  lCount);
+                                  lCount));
 
                     ASSERT( lCount >= 0);
 
                     pDirEntry = pCurrentVolume->DirectoryCB;
 
+                    pCurrentObject = pDirEntry->ObjectInformation;
+
                     lCount = InterlockedIncrement( &pDirEntry->DirOpenReferenceCount);
 
-                    AFSDbgLogMsg( AFS_SUBSYSTEM_DIRENTRY_REF_COUNTING,
+                    AFSDbgTrace(( AFS_SUBSYSTEM_DIRENTRY_REF_COUNTING,
                                   AFS_TRACE_LEVEL_VERBOSE,
                                   "AFSLocateNameEntry Increment3 count on %wZ DE %p Ccb %p Cnt %d\n",
                                   &pDirEntry->NameInformation.FileName,
                                   pDirEntry,
                                   NULL,
-                                  lCount);
+                                  lCount));
 
                     //
                     // The name array stores both the mount point and the target.
@@ -959,7 +1095,21 @@ AFSLocateNameEntry( IN GUID *AuthGroup,
                     AFSInsertNextElement( pNameArray,
                                           pDirEntry);
 
-                    pParentDirEntry = NULL;
+                    if ( pParentDirEntry)
+                    {
+
+                        lCount = InterlockedDecrement( &pParentDirEntry->DirOpenReferenceCount);
+
+                        AFSDbgTrace(( AFS_SUBSYSTEM_DIRENTRY_REF_COUNTING,
+                                      AFS_TRACE_LEVEL_VERBOSE,
+                                      "AFSLocateNameEntry Decrement count on %wZ DE %p Ccb %p Cnt %d\n",
+                                      &pParentDirEntry->NameInformation.FileName,
+                                      pParentDirEntry,
+                                      NULL,
+                                      lCount));
+
+                        pParentDirEntry = NULL;
+                    }
 
                     //
                     // Increment our link count
@@ -973,18 +1123,27 @@ AFSLocateNameEntry( IN GUID *AuthGroup,
                 case AFS_FILE_TYPE_DFSLINK:
                 {
 
-                    if( BooleanFlagOn( Flags, AFS_LOCATE_FLAGS_NO_DFS_LINK_EVAL))
+                   if( BooleanFlagOn( Flags, AFS_LOCATE_FLAGS_NO_DFS_LINK_EVAL) &&
+                       uniRemainingPath.Length == 0)
                     {
 
                         //
                         // Pass back the directory entries
                         //
 
-                        *ParentDirectoryCB = pParentDirEntry;
+                        *OutParentDirectoryCB = pParentDirEntry;
+
+                        pParentDirEntry = NULL;
+
+                        *OutDirectoryCB = pDirEntry;
+
+                        pDirEntry = NULL;
+
+                        *OutVolumeCB = pCurrentVolume;
 
-                        *DirectoryCB = pDirEntry;
+                        *OutVolumeReferenceReason = VolumeReferenceReason;
 
-                        *VolumeCB = pCurrentVolume;
+                        bReleaseCurrentVolume = FALSE;
 
                         *RootPathName = uniFullPathName;
 
@@ -996,13 +1155,15 @@ AFSLocateNameEntry( IN GUID *AuthGroup,
                     // system for it to reevaluate it
                     //
 
-                    if( FileObject != NULL)
+                    if( FileObject != NULL ||
+                       TargetName != NULL)
                     {
 
                         ntStatus = AFSProcessDFSLink( pDirEntry,
                                                       FileObject,
                                                       &uniRemainingPath,
-                                                      AuthGroup);
+                                                      AuthGroup,
+                                                     TargetName);
                     }
                     else
                     {
@@ -1019,7 +1180,7 @@ AFSLocateNameEntry( IN GUID *AuthGroup,
                         ntStatus != STATUS_REPARSE)
                     {
 
-                        AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
+                        AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING,
                                       AFS_TRACE_LEVEL_ERROR,
                                       "AFSLocateNameEntry (FO: %p) Failed to process DFSLink parent %wZ FID %08lX-%08lX-%08lX-%08lX Status %08lX\n",
                                       FileObject,
@@ -1028,7 +1189,7 @@ AFSLocateNameEntry( IN GUID *AuthGroup,
                                       pCurrentObject->FileId.Volume,
                                       pCurrentObject->FileId.Vnode,
                                       pCurrentObject->FileId.Unique,
-                                      ntStatus);
+                                      ntStatus));
                     }
 
                     try_return( ntStatus);
@@ -1052,10 +1213,11 @@ AFSLocateNameEntry( IN GUID *AuthGroup,
             //
 
             if( pCurrentObject->FileType == AFS_FILE_TYPE_DIRECTORY &&
-                !BooleanFlagOn( pCurrentObject->Flags, AFS_OBJECT_FLAGS_DIRECTORY_ENUMERATED))
+                !BooleanFlagOn( pCurrentObject->Flags, AFS_OBJECT_FLAGS_DIRECTORY_ENUMERATED) &&
+                uniPathName.Length > 0)
             {
 
-                AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
+                AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING,
                               AFS_TRACE_LEVEL_VERBOSE,
                               "AFSLocateNameEntry (FO: %p) Enumerating parent %wZ FID %08lX-%08lX-%08lX-%08lX\n",
                               FileObject,
@@ -1063,7 +1225,7 @@ AFSLocateNameEntry( IN GUID *AuthGroup,
                               pCurrentObject->FileId.Cell,
                               pCurrentObject->FileId.Volume,
                               pCurrentObject->FileId.Vnode,
-                              pCurrentObject->FileId.Unique);
+                              pCurrentObject->FileId.Unique));
 
                 AFSAcquireExcl( pCurrentObject->Specific.Directory.DirectoryNodeHdr.TreeLock,
                                 TRUE);
@@ -1080,7 +1242,7 @@ AFSLocateNameEntry( IN GUID *AuthGroup,
 
                         AFSReleaseResource( pCurrentObject->Specific.Directory.DirectoryNodeHdr.TreeLock);
 
-                        AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
+                        AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING,
                                       AFS_TRACE_LEVEL_ERROR,
                                       "AFSLocateNameEntry (FO: %p) Failed to enumerate parent %wZ FID %08lX-%08lX-%08lX-%08lX Status %08lX\n",
                                       FileObject,
@@ -1089,12 +1251,10 @@ AFSLocateNameEntry( IN GUID *AuthGroup,
                                       pCurrentObject->FileId.Volume,
                                       pCurrentObject->FileId.Vnode,
                                       pCurrentObject->FileId.Unique,
-                                      ntStatus);
+                                      ntStatus));
 
                         try_return( ntStatus);
                     }
-
-                    SetFlag( pDirEntry->ObjectInformation->Flags, AFS_OBJECT_FLAGS_DIRECTORY_ENUMERATED);
                 }
 
                 AFSReleaseResource( pCurrentObject->Specific.Directory.DirectoryNodeHdr.TreeLock);
@@ -1105,7 +1265,7 @@ AFSLocateNameEntry( IN GUID *AuthGroup,
                 if( uniPathName.Length > 0)
                 {
 
-                    AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
+                    AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING,
                                   AFS_TRACE_LEVEL_ERROR,
                                   "AFSLocateNameEntry (FO: %p) Encountered file node %wZ FID %08lX-%08lX-%08lX-%08lX in path processing\n",
                                   FileObject,
@@ -1113,7 +1273,7 @@ AFSLocateNameEntry( IN GUID *AuthGroup,
                                   pCurrentObject->FileId.Cell,
                                   pCurrentObject->FileId.Volume,
                                   pCurrentObject->FileId.Vnode,
-                                  pCurrentObject->FileId.Unique);
+                                  pCurrentObject->FileId.Unique));
 
                     // The proper error code to return would be STATUS_OBJECT_PATH_INVALID because
                     // one of the components of the path is not a directory.  However, returning
@@ -1127,7 +1287,7 @@ AFSLocateNameEntry( IN GUID *AuthGroup,
                 else
                 {
 
-                    AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
+                    AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING,
                                   AFS_TRACE_LEVEL_VERBOSE,
                                   "AFSLocateNameEntry (FO: %p) Returning file %wZ FID %08lX-%08lX-%08lX-%08lX\n",
                                   FileObject,
@@ -1135,17 +1295,25 @@ AFSLocateNameEntry( IN GUID *AuthGroup,
                                   pCurrentObject->FileId.Cell,
                                   pCurrentObject->FileId.Volume,
                                   pCurrentObject->FileId.Vnode,
-                                  pCurrentObject->FileId.Unique);
+                                  pCurrentObject->FileId.Unique));
 
                     //
                     // Pass back the directory entries
                     //
 
-                    *ParentDirectoryCB = pParentDirEntry;
+                    *OutParentDirectoryCB = pParentDirEntry;
+
+                    pParentDirEntry = NULL;
+
+                    *OutDirectoryCB = pDirEntry;
+
+                    pDirEntry = NULL;
+
+                    *OutVolumeCB = pCurrentVolume;
 
-                    *DirectoryCB = pDirEntry;
+                    *OutVolumeReferenceReason = VolumeReferenceReason;
 
-                    *VolumeCB = pCurrentVolume;
+                    bReleaseCurrentVolume = FALSE;
 
                     *RootPathName = uniFullPathName;
                 }
@@ -1160,7 +1328,7 @@ AFSLocateNameEntry( IN GUID *AuthGroup,
             if( uniPathName.Length == 0)
             {
 
-                AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
+                AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING,
                               AFS_TRACE_LEVEL_VERBOSE,
                               "AFSLocateNameEntry (FO: %p) Completed processing returning %wZ FID %08lX-%08lX-%08lX-%08lX\n",
                               FileObject,
@@ -1168,17 +1336,25 @@ AFSLocateNameEntry( IN GUID *AuthGroup,
                               pCurrentObject->FileId.Cell,
                               pCurrentObject->FileId.Volume,
                               pCurrentObject->FileId.Vnode,
-                              pCurrentObject->FileId.Unique);
+                              pCurrentObject->FileId.Unique));
 
                 //
                 // Pass back the directory entries
                 //
 
-                *ParentDirectoryCB = pParentDirEntry;
+                *OutParentDirectoryCB = pParentDirEntry;
 
-                *DirectoryCB = pDirEntry;
+                pParentDirEntry = NULL;
 
-                *VolumeCB = pCurrentVolume;
+                *OutDirectoryCB = pDirEntry;
+
+                pDirEntry = NULL;
+
+                *OutVolumeCB = pCurrentVolume;
+
+                *OutVolumeReferenceReason = VolumeReferenceReason;
+
+                bReleaseCurrentVolume = FALSE;
 
                 *RootPathName = uniFullPathName;
 
@@ -1231,7 +1407,7 @@ AFSLocateNameEntry( IN GUID *AuthGroup,
                                          TRUE) == 0)
             {
 
-                AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
+                AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING,
                               AFS_TRACE_LEVEL_VERBOSE,
                               "AFSLocateNameEntry (FO: %p) Backing up entry from %wZ FID %08lX-%08lX-%08lX-%08lX\n",
                               FileObject,
@@ -1239,20 +1415,20 @@ AFSLocateNameEntry( IN GUID *AuthGroup,
                               pCurrentObject->FileId.Cell,
                               pCurrentObject->FileId.Volume,
                               pCurrentObject->FileId.Vnode,
-                              pCurrentObject->FileId.Unique);
+                              pCurrentObject->FileId.Unique));
 
                 //
                 // Need to back up one entry in the name array
                 //
                 lCount = InterlockedDecrement( &pDirEntry->DirOpenReferenceCount);
 
-                AFSDbgLogMsg( AFS_SUBSYSTEM_DIRENTRY_REF_COUNTING,
+                AFSDbgTrace(( AFS_SUBSYSTEM_DIRENTRY_REF_COUNTING,
                               AFS_TRACE_LEVEL_VERBOSE,
                               "AFSLocateNameEntry Decrement4 count on %wZ DE %p Ccb %p Cnt %d\n",
                               &pDirEntry->NameInformation.FileName,
                               pDirEntry,
                               NULL,
-                              lCount);
+                              lCount));
 
                 ASSERT( lCount >= 0);
 
@@ -1261,34 +1437,89 @@ AFSLocateNameEntry( IN GUID *AuthGroup,
                 if( pDirEntry == NULL)
                 {
 
-                    AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
+                    AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING,
                                   AFS_TRACE_LEVEL_ERROR,
-                                  "AFSLocateNameEntry AFSBackupEntry failed\n");
+                                  "AFSLocateNameEntry AFSBackupEntry failed\n"));
 
                     try_return(ntStatus = STATUS_OBJECT_PATH_INVALID);
                 }
 
+                pCurrentObject = pDirEntry->ObjectInformation;
+
                 lCount = InterlockedIncrement( &pDirEntry->DirOpenReferenceCount);
 
-                AFSDbgLogMsg( AFS_SUBSYSTEM_DIRENTRY_REF_COUNTING,
+                AFSDbgTrace(( AFS_SUBSYSTEM_DIRENTRY_REF_COUNTING,
                               AFS_TRACE_LEVEL_VERBOSE,
                               "AFSLocateNameEntry Increment4 count on %wZ DE %p Ccb %p Cnt %d\n",
                               &pDirEntry->NameInformation.FileName,
                               pDirEntry,
                               NULL,
-                              lCount);
+                              lCount));
 
-                if( BooleanFlagOn( pDirEntry->ObjectInformation->Flags, AFS_OBJECT_ROOT_VOLUME))
+                if ( pParentDirEntry)
                 {
 
+                    lCount = InterlockedDecrement( &pParentDirEntry->DirOpenReferenceCount);
+
+                    AFSDbgTrace(( AFS_SUBSYSTEM_DIRENTRY_REF_COUNTING,
+                                  AFS_TRACE_LEVEL_VERBOSE,
+                                  "AFSLocateNameEntry Decrement count on %wZ DE %p Ccb %p Cnt %d\n",
+                                  &pParentDirEntry->NameInformation.FileName,
+                                  pParentDirEntry,
+                                  NULL,
+                                  lCount));
+
                     pParentDirEntry = NULL;
                 }
-                else
+
+                if( !BooleanFlagOn( pDirEntry->ObjectInformation->Flags, AFS_OBJECT_ROOT_VOLUME))
                 {
 
                     pParentDirEntry = AFSGetParentEntry( pNameArray);
 
                     ASSERT( pParentDirEntry != pDirEntry);
+
+                    if ( pParentDirEntry)
+                    {
+
+                        lCount = InterlockedIncrement( &pParentDirEntry->DirOpenReferenceCount);
+
+                        AFSDbgTrace(( AFS_SUBSYSTEM_DIRENTRY_REF_COUNTING,
+                                      AFS_TRACE_LEVEL_VERBOSE,
+                                      "AFSLocateNameEntry Increment count on %wZ DE %p Ccb %p Cnt %d\n",
+                                      &pParentDirEntry->NameInformation.FileName,
+                                      pParentDirEntry,
+                                      NULL,
+                                      lCount));
+                    }
+                }
+
+                if ( pDirEntry->ObjectInformation->VolumeCB != pCurrentVolume)
+                {
+
+                    lCount = AFSVolumeDecrement( pCurrentVolume,
+                                                 VolumeReferenceReason);
+
+                    AFSDbgTrace(( AFS_SUBSYSTEM_VOLUME_REF_COUNTING,
+                                  AFS_TRACE_LEVEL_VERBOSE,
+                                  "AFSLocateNameEntry Decrement count on volume %p Reason %u Cnt %d\n",
+                                  pCurrentVolume,
+                                  VolumeReferenceReason,
+                                  lCount));
+
+                    pCurrentVolume = pDirEntry->ObjectInformation->VolumeCB;
+
+                    VolumeReferenceReason = AFS_VOLUME_REFERENCE_LOCATE_NAME;
+
+                    lCount = AFSVolumeIncrement( pCurrentVolume,
+                                                 VolumeReferenceReason);
+
+                    AFSDbgTrace(( AFS_SUBSYSTEM_VOLUME_REF_COUNTING,
+                                  AFS_TRACE_LEVEL_VERBOSE,
+                                  "AFSLocateNameEntry Increment count on volume %p Reason %u Cnt %d\n",
+                                  pCurrentVolume,
+                                  VolumeReferenceReason,
+                                  lCount));
                 }
 
                 uniPathName = uniRemainingPath;
@@ -1300,10 +1531,26 @@ AFSLocateNameEntry( IN GUID *AuthGroup,
             // Update our pointers
             //
 
+            if ( pParentDirEntry)
+            {
+
+                lCount = InterlockedDecrement( &pParentDirEntry->DirOpenReferenceCount);
+
+                AFSDbgTrace(( AFS_SUBSYSTEM_DIRENTRY_REF_COUNTING,
+                              AFS_TRACE_LEVEL_VERBOSE,
+                              "AFSLocateNameEntry Decrement count on %wZ DE %p Ccb %p Cnt %d\n",
+                              &pParentDirEntry->NameInformation.FileName,
+                              pParentDirEntry,
+                              NULL,
+                              lCount));
+            }
+
             pParentDirEntry = pDirEntry;
 
             pDirEntry = NULL;
 
+            pCurrentObject = NULL;
+
             uniSearchName = uniComponentName;
 
             while( pDirEntry == NULL)
@@ -1321,12 +1568,12 @@ AFSLocateNameEntry( IN GUID *AuthGroup,
                                              NULL))
                 {
 
-                    AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
+                    AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING,
                                   AFS_TRACE_LEVEL_VERBOSE_2,
                                   "AFSLocateNameEntry (FO: %p) Processing @SYS substitution for %wZ Index %08lX\n",
                                   FileObject,
                                   &uniComponentName,
-                                  ulSubstituteIndex);
+                                  ulSubstituteIndex));
 
                     ntStatus = AFSSubstituteSysName( &uniComponentName,
                                                      &uniSearchName,
@@ -1335,13 +1582,13 @@ AFSLocateNameEntry( IN GUID *AuthGroup,
                     if ( NT_SUCCESS( ntStatus))
                     {
 
-                        AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
+                        AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING,
                                       AFS_TRACE_LEVEL_VERBOSE_2,
                                       "AFSLocateNameEntry (FO: %p) Located substitution %wZ for %wZ Index %08lX\n",
                                       FileObject,
                                       &uniSearchName,
                                       &uniComponentName,
-                                      ulSubstituteIndex);
+                                      ulSubstituteIndex));
 
                         //
                         // Go reparse the name again
@@ -1356,13 +1603,13 @@ AFSLocateNameEntry( IN GUID *AuthGroup,
                     else
                     {
 
-                        AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
+                        AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING,
                                       AFS_TRACE_LEVEL_ERROR,
                                       "AFSLocateNameEntry (FO: %p) Failed to locate substitute string for %wZ Index %08lX Status %08lX\n",
                                       FileObject,
                                       &uniComponentName,
                                       ulSubstituteIndex,
-                                      ntStatus);
+                                      ntStatus));
 
                         if( ntStatus == STATUS_OBJECT_NAME_NOT_FOUND)
                         {
@@ -1371,11 +1618,17 @@ AFSLocateNameEntry( IN GUID *AuthGroup,
                             // Pass back the directory entries
                             //
 
-                            *ParentDirectoryCB = pParentDirEntry;
+                            *OutParentDirectoryCB = pParentDirEntry;
+
+                            pParentDirEntry = NULL;
 
-                            *DirectoryCB = NULL;
+                            *OutDirectoryCB = NULL;
 
-                            *VolumeCB = pCurrentVolume;
+                            *OutVolumeCB = pCurrentVolume;
+
+                            *OutVolumeReferenceReason = VolumeReferenceReason;
+
+                            bReleaseCurrentVolume = FALSE;
 
                             if( ComponentName != NULL)
                             {
@@ -1397,11 +1650,11 @@ AFSLocateNameEntry( IN GUID *AuthGroup,
                 // Generate the CRC on the node and perform a case sensitive lookup
                 //
 
-                AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
+                AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING,
                               AFS_TRACE_LEVEL_VERBOSE_2,
                               "AFSLocateNameEntry (FO: %p) Searching for entry %wZ case sensitive\n",
                               FileObject,
-                              &uniSearchName);
+                              &uniSearchName));
 
                 ulCRC = AFSGenerateCRC( &uniSearchName,
                                         FALSE);
@@ -1420,11 +1673,11 @@ AFSLocateNameEntry( IN GUID *AuthGroup,
                     // Missed so perform a case insensitive lookup
                     //
 
-                    AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
+                    AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING,
                                   AFS_TRACE_LEVEL_VERBOSE_2,
                                   "AFSLocateNameEntry (FO: %p) Searching for entry %wZ case insensitive\n",
                                   FileObject,
-                                  &uniSearchName);
+                                  &uniSearchName));
 
                     ulCRC = AFSGenerateCRC( &uniSearchName,
                                             TRUE);
@@ -1447,11 +1700,11 @@ AFSLocateNameEntry( IN GUID *AuthGroup,
                                                     NULL))
                         {
 
-                            AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
+                            AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING,
                                           AFS_TRACE_LEVEL_VERBOSE_2,
                                           "AFSLocateNameEntry (FO: %p) Searching for entry %wZ short name\n",
                                           FileObject,
-                                          &uniSearchName);
+                                          &uniSearchName));
 
                             AFSLocateShortNameDirEntry( pParentDirEntry->ObjectInformation->Specific.Directory.ShortNameTree,
                                                         ulCRC,
@@ -1499,35 +1752,57 @@ AFSLocateNameEntry( IN GUID *AuthGroup,
                                 continue;       // while( pDirEntry == NULL)
                             }
 
+                            //
+                            // Node name not found so get out
+                            //
+
+                            AFSReleaseResource( pParentDirEntry->ObjectInformation->Specific.Directory.DirectoryNodeHdr.TreeLock);
+
                             if( uniRemainingPath.Length > 0)
                             {
 
                                 ntStatus = STATUS_OBJECT_PATH_NOT_FOUND;
+
+                                AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING,
+                                              AFS_TRACE_LEVEL_VERBOSE,
+                                              "AFSLocateNameEntry (FO: %p) Returning path not found for %wZ in Parent FID %08lX-%08lX-%08lX-%08lX\n",
+                                              FileObject,
+                                              &uniSearchName,
+                                              pParentDirEntry->ObjectInformation->FileId.Cell,
+                                              pParentDirEntry->ObjectInformation->FileId.Volume,
+                                              pParentDirEntry->ObjectInformation->FileId.Vnode,
+                                              pParentDirEntry->ObjectInformation->FileId.Unique));
                             }
                             else
                             {
 
                                 ntStatus = STATUS_OBJECT_NAME_NOT_FOUND;
 
-                                AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
+                                AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING,
                                               AFS_TRACE_LEVEL_VERBOSE,
-                                              "AFSLocateNameEntry (FO: %p) Returning name not found for %wZ FID %08lX-%08lX-%08lX-%08lX\n",
+                                              "AFSLocateNameEntry (FO: %p) Returning name not found for %wZ in Parent FID %08lX-%08lX-%08lX-%08lX\n",
                                               FileObject,
                                               &uniSearchName,
-                                              pCurrentObject->FileId.Cell,
-                                              pCurrentObject->FileId.Volume,
-                                              pCurrentObject->FileId.Vnode,
-                                              pCurrentObject->FileId.Unique);
+                                              pParentDirEntry->ObjectInformation->FileId.Cell,
+                                              pParentDirEntry->ObjectInformation->FileId.Volume,
+                                              pParentDirEntry->ObjectInformation->FileId.Vnode,
+                                              pParentDirEntry->ObjectInformation->FileId.Unique));
 
                                 //
                                 // Pass back the directory entries
                                 //
 
-                                *ParentDirectoryCB = pParentDirEntry;
+                                *OutParentDirectoryCB = pParentDirEntry;
+
+                                pParentDirEntry = NULL;
+
+                                *OutDirectoryCB = NULL;
 
-                                *DirectoryCB = NULL;
+                                *OutVolumeCB = pCurrentVolume;
 
-                                *VolumeCB = pCurrentVolume;
+                                *OutVolumeReferenceReason = VolumeReferenceReason;
+
+                                bReleaseCurrentVolume = FALSE;
 
                                 if( ComponentName != NULL)
                                 {
@@ -1538,13 +1813,7 @@ AFSLocateNameEntry( IN GUID *AuthGroup,
                                 *RootPathName = uniFullPathName;
                             }
 
-                            AFSReleaseResource( pParentDirEntry->ObjectInformation->Specific.Directory.DirectoryNodeHdr.TreeLock);
-
-                            //
-                            // Node name not found so get out
-                            //
-
-                            try_return( ntStatus);  // while( pDirEntry == NULL)
+                            try_return( ntStatus);
                         }
                     }
                     else
@@ -1555,6 +1824,8 @@ AFSLocateNameEntry( IN GUID *AuthGroup,
                         // Is more than one link entry for this node then fail the lookup request
                         //
 
+                        pCurrentObject = pDirEntry->ObjectInformation;
+
                         if( !BooleanFlagOn( pDirEntry->Flags, AFS_DIR_ENTRY_CASE_INSENSTIVE_LIST_HEAD) ||
                             pDirEntry->CaseInsensitiveList.fLink != NULL)
                         {
@@ -1565,13 +1836,13 @@ AFSLocateNameEntry( IN GUID *AuthGroup,
 
                             lCount = InterlockedIncrement( &pDirEntry->DirOpenReferenceCount);
 
-                            AFSDbgLogMsg( AFS_SUBSYSTEM_DIRENTRY_REF_COUNTING,
+                            AFSDbgTrace(( AFS_SUBSYSTEM_DIRENTRY_REF_COUNTING,
                                           AFS_TRACE_LEVEL_VERBOSE,
                                           "AFSLocateNameEntry Increment5 count on %wZ DE %p Ccb %p Cnt %d\n",
                                           &pDirEntry->NameInformation.FileName,
                                           pDirEntry,
                                           NULL,
-                                          lCount);
+                                          lCount));
 
                             AFSReleaseResource( pParentDirEntry->ObjectInformation->Specific.Directory.DirectoryNodeHdr.TreeLock);
 
@@ -1588,13 +1859,15 @@ AFSLocateNameEntry( IN GUID *AuthGroup,
                     // revalidate the parent and search again.
                     //
 
+                    pCurrentObject = pDirEntry->ObjectInformation;
+
                     if( BooleanFlagOn( pDirEntry->ObjectInformation->Flags, AFS_OBJECT_FLAGS_DELETED) &&
                         BooleanFlagOn( pParentDirEntry->ObjectInformation->Flags, AFS_OBJECT_FLAGS_VERIFY))
                     {
 
                         AFSReleaseResource( pParentDirEntry->ObjectInformation->Specific.Directory.DirectoryNodeHdr.TreeLock);
 
-                        AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
+                        AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING,
                                       AFS_TRACE_LEVEL_VERBOSE,
                                       "AFSLocateNameEntry (FO: %p) Verifying(2) parent %wZ FID %08lX-%08lX-%08lX-%08lX\n",
                                       FileObject,
@@ -1602,7 +1875,7 @@ AFSLocateNameEntry( IN GUID *AuthGroup,
                                       pParentDirEntry->ObjectInformation->FileId.Cell,
                                       pParentDirEntry->ObjectInformation->FileId.Volume,
                                       pParentDirEntry->ObjectInformation->FileId.Vnode,
-                                      pParentDirEntry->ObjectInformation->FileId.Unique);
+                                      pParentDirEntry->ObjectInformation->FileId.Unique));
 
                         //
                         // Directory TreeLock should be exclusively held
@@ -1612,14 +1885,15 @@ AFSLocateNameEntry( IN GUID *AuthGroup,
                                         TRUE);
 
                         ntStatus = AFSVerifyEntry( AuthGroup,
-                                                   pParentDirEntry);
+                                                  pParentDirEntry,
+                                                  FALSE);
 
                         AFSReleaseResource( pParentDirEntry->ObjectInformation->Specific.Directory.DirectoryNodeHdr.TreeLock);
 
                         if( !NT_SUCCESS( ntStatus))
                         {
 
-                            AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
+                            AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING,
                                           AFS_TRACE_LEVEL_ERROR,
                                           "AFSLocateNameEntry (FO: %p) Failed to verify(2) parent %wZ FID %08lX-%08lX-%08lX-%08lX Status %08lX\n",
                                           FileObject,
@@ -1628,21 +1902,23 @@ AFSLocateNameEntry( IN GUID *AuthGroup,
                                           pParentDirEntry->ObjectInformation->FileId.Volume,
                                           pParentDirEntry->ObjectInformation->FileId.Vnode,
                                           pParentDirEntry->ObjectInformation->FileId.Unique,
-                                          ntStatus);
+                                          ntStatus));
 
                             try_return( ntStatus);
                         }
 
-                        AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
+                        AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING,
                                       AFS_TRACE_LEVEL_VERBOSE,
                                       "AFSLocateNameEntry (FO: %p) Reprocessing component %wZ in parent %wZ\n",
                                       FileObject,
                                       &uniSearchName,
-                                      &pParentDirEntry->NameInformation.FileName);
+                                      &pParentDirEntry->NameInformation.FileName));
 
 
                         pDirEntry = NULL;
 
+                        pCurrentObject = NULL;
+
                         continue;
                     }
 
@@ -1652,13 +1928,13 @@ AFSLocateNameEntry( IN GUID *AuthGroup,
 
                     lCount = InterlockedIncrement( &pDirEntry->DirOpenReferenceCount);
 
-                    AFSDbgLogMsg( AFS_SUBSYSTEM_DIRENTRY_REF_COUNTING,
+                    AFSDbgTrace(( AFS_SUBSYSTEM_DIRENTRY_REF_COUNTING,
                                   AFS_TRACE_LEVEL_VERBOSE,
-                                  "AFSLocateNameEntry Increment5 count on %wZ DE %p Ccb %p Cnt %d\n",
+                                  "AFSLocateNameEntry Increment6 count on %wZ DE %p Ccb %p Cnt %d\n",
                                   &pDirEntry->NameInformation.FileName,
                                   pDirEntry,
                                   NULL,
-                                  lCount);
+                                  lCount));
                 }
 
                 AFSReleaseResource( pParentDirEntry->ObjectInformation->Specific.Directory.DirectoryNodeHdr.TreeLock);
@@ -1669,149 +1945,180 @@ AFSLocateNameEntry( IN GUID *AuthGroup,
             // If we have a dirEntry for this component, perform some basic validation on it
             //
 
-            if( pDirEntry != NULL &&
-                BooleanFlagOn( pDirEntry->ObjectInformation->Flags, AFS_OBJECT_FLAGS_DELETED))
+            if( pDirEntry != NULL)
             {
 
                 pCurrentObject = pDirEntry->ObjectInformation;
 
-                AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
-                              AFS_TRACE_LEVEL_ERROR,
-                              "AFSLocateNameEntry (FO: %p) Deleted entry %wZ FID %08lX-%08lX-%08lX-%08lX\n",
-                              FileObject,
-                              &pDirEntry->NameInformation.FileName,
-                              pCurrentObject->FileId.Cell,
-                              pCurrentObject->FileId.Volume,
-                              pCurrentObject->FileId.Vnode,
-                              pCurrentObject->FileId.Unique);
-
-                //
-                // This entry was deleted through the invalidation call back so perform cleanup
-                // on the entry
-                //
+                if (BooleanFlagOn( pDirEntry->ObjectInformation->Flags, AFS_OBJECT_FLAGS_DELETED))
+                {
 
-                pParentObjectInfo = pCurrentObject->ParentObjectInformation;
+                    AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING,
+                                  AFS_TRACE_LEVEL_ERROR,
+                                  "AFSLocateNameEntry (FO: %p) Deleted entry %wZ FID %08lX-%08lX-%08lX-%08lX\n",
+                                  FileObject,
+                                  &pDirEntry->NameInformation.FileName,
+                                  pCurrentObject->FileId.Cell,
+                                  pCurrentObject->FileId.Volume,
+                                  pCurrentObject->FileId.Vnode,
+                                  pCurrentObject->FileId.Unique));
 
-                ASSERT( pParentObjectInfo != NULL);
+                    //
+                    // This entry was deleted through the invalidation call back so perform cleanup
+                    // on the entry
+                    //
 
-                AFSAcquireExcl( pParentObjectInfo->Specific.Directory.DirectoryNodeHdr.TreeLock,
-                                TRUE);
+                    if( BooleanFlagOn( pCurrentObject->Flags, AFS_OBJECT_FLAGS_PARENT_FID))
+                    {
 
-                AFSAcquireExcl( pCurrentObject->VolumeCB->ObjectInfoTree.TreeLock,
-                                TRUE);
+                        pParentObjectInfo = AFSFindObjectInfo( pCurrentObject->VolumeCB,
+                                                               &pCurrentObject->ParentFileId,
+                                                               FALSE);
+                    }
 
-                lCount = InterlockedDecrement( &pDirEntry->DirOpenReferenceCount);
+                    ASSERT( pParentObjectInfo != NULL);
 
-                AFSDbgLogMsg( AFS_SUBSYSTEM_DIRENTRY_REF_COUNTING,
-                              AFS_TRACE_LEVEL_VERBOSE,
-                              "AFSLocateNameEntry Decrement count on %wZ DE %p Ccb %p Cnt %d\n",
-                              &pDirEntry->NameInformation.FileName,
-                              pDirEntry,
-                              NULL,
-                              lCount);
+                    AFSAcquireExcl( pParentObjectInfo->Specific.Directory.DirectoryNodeHdr.TreeLock,
+                                    TRUE);
 
-                ASSERT( lCount >= 0);
+                    AFSAcquireExcl( pCurrentObject->VolumeCB->ObjectInfoTree.TreeLock,
+                                    TRUE);
 
-                if( lCount <= 0)
-                {
+                    lCount = InterlockedDecrement( &pDirEntry->DirOpenReferenceCount);
 
-                    AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING|AFS_SUBSYSTEM_CLEANUP_PROCESSING,
+                    AFSDbgTrace(( AFS_SUBSYSTEM_DIRENTRY_REF_COUNTING,
                                   AFS_TRACE_LEVEL_VERBOSE,
-                                  "AFSLocateNameEntry Deleting dir entry %p (%p) for %wZ\n",
+                                  "AFSLocateNameEntry Decrement count on %wZ DE %p Ccb %p Cnt %d\n",
+                                  &pDirEntry->NameInformation.FileName,
                                   pDirEntry,
-                                  pCurrentObject,
-                                  &pDirEntry->NameInformation.FileName);
+                                  NULL,
+                                  lCount));
 
-                    //
-                    // Remove and delete the directory entry from the parent list
-                    //
+                    ASSERT( lCount >= 0);
 
-                    AFSDeleteDirEntry( pParentObjectInfo,
-                                       pDirEntry);
+                    if( lCount == 0 &&
+                        pDirEntry->NameArrayReferenceCount <= 0)
+                    {
 
-                    AFSAcquireShared( &pCurrentObject->NonPagedInfo->ObjectInfoLock,
-                                      TRUE);
+                        AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING|AFS_SUBSYSTEM_CLEANUP_PROCESSING,
+                                      AFS_TRACE_LEVEL_VERBOSE,
+                                      "AFSLocateNameEntry Deleting dir entry %p (%p) for %wZ\n",
+                                      pDirEntry,
+                                      pCurrentObject,
+                                      &pDirEntry->NameInformation.FileName));
 
-                    if( pCurrentObject->ObjectReferenceCount <= 0)
-                    {
+                        //
+                        // Remove and delete the directory entry from the parent list
+                        //
 
-                        if( BooleanFlagOn( pCurrentObject->Flags, AFS_OBJECT_INSERTED_HASH_TREE))
+                        AFSDeleteDirEntry( pParentObjectInfo,
+                                           &pDirEntry);
+
+                        AFSAcquireShared( &pCurrentObject->NonPagedInfo->ObjectInfoLock,
+                                          TRUE);
+
+                        if( pCurrentObject->ObjectReferenceCount <= 0)
                         {
 
-                            AFSDbgLogMsg( AFS_SUBSYSTEM_CLEANUP_PROCESSING,
-                                          AFS_TRACE_LEVEL_VERBOSE,
-                                          "AFSLocateNameEntry Removing object %p from volume tree\n",
-                                          pCurrentObject);
+                            if( BooleanFlagOn( pCurrentObject->Flags, AFS_OBJECT_INSERTED_HASH_TREE))
+                            {
 
-                            AFSRemoveHashEntry( &pCurrentObject->VolumeCB->ObjectInfoTree.TreeHead,
-                                                &pCurrentObject->TreeEntry);
+                                AFSDbgTrace(( AFS_SUBSYSTEM_CLEANUP_PROCESSING,
+                                              AFS_TRACE_LEVEL_VERBOSE,
+                                              "AFSLocateNameEntry Removing object %p from volume tree\n",
+                                              pCurrentObject));
 
-                            ClearFlag( pCurrentObject->Flags, AFS_OBJECT_INSERTED_HASH_TREE);
+                                AFSRemoveHashEntry( &pCurrentObject->VolumeCB->ObjectInfoTree.TreeHead,
+                                                    &pCurrentObject->TreeEntry);
+
+                                ClearFlag( pCurrentObject->Flags, AFS_OBJECT_INSERTED_HASH_TREE);
+                            }
                         }
+
+                        AFSReleaseResource( &pCurrentObject->NonPagedInfo->ObjectInfoLock);
                     }
+                    else
+                    {
 
-                    AFSReleaseResource( &pCurrentObject->NonPagedInfo->ObjectInfoLock);
-                }
-                else
-                {
+                        AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING,
+                                      AFS_TRACE_LEVEL_VERBOSE,
+                                      "AFSLocateNameEntry Setting DELETE flag in dir entry %p for %wZ\n",
+                                      pDirEntry,
+                                      &pDirEntry->NameInformation.FileName));
 
-                    AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
-                                  AFS_TRACE_LEVEL_VERBOSE,
-                                  "AFSLocateNameEntry Setting DELETE flag in dir entry %p for %wZ\n",
-                                  pDirEntry,
-                                  &pDirEntry->NameInformation.FileName);
+                        SetFlag( pDirEntry->Flags, AFS_DIR_ENTRY_DELETED);
 
-                    SetFlag( pDirEntry->Flags, AFS_DIR_ENTRY_DELETED);
+                        AFSRemoveNameEntry( pParentObjectInfo,
+                                            pDirEntry);
+                    }
 
-                    AFSRemoveNameEntry( pParentObjectInfo,
-                                        pDirEntry);
-                }
+                    AFSReleaseResource( pParentObjectInfo->Specific.Directory.DirectoryNodeHdr.TreeLock);
 
-                AFSReleaseResource( pParentObjectInfo->Specific.Directory.DirectoryNodeHdr.TreeLock);
+                    AFSReleaseResource( pCurrentObject->VolumeCB->ObjectInfoTree.TreeLock);
 
-                AFSReleaseResource( pCurrentObject->VolumeCB->ObjectInfoTree.TreeLock);
+                    //
+                    // We deleted the dir entry so check if there is any remaining portion
+                    // of the name to process.
+                    //
 
-                //
-                // We deleted the dir entry so check if there is any remaining portion
-                // of the name to process.
-                //
+                    if( uniRemainingPath.Length > 0)
+                    {
 
-                if( uniRemainingPath.Length > 0)
-                {
-                    ntStatus = STATUS_OBJECT_PATH_NOT_FOUND;
-                }
-                else
-                {
+                        ntStatus = STATUS_OBJECT_PATH_NOT_FOUND;
 
-                    ntStatus = STATUS_OBJECT_NAME_NOT_FOUND;
+                        AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING,
+                                      AFS_TRACE_LEVEL_VERBOSE,
+                                      "AFSLocateNameEntry (FO: %p) Returning path not found(2) for %wZ in Parent FID %08lX-%08lX-%08lX-%08lX\n",
+                                      FileObject,
+                                      &uniComponentName,
+                                      pParentObjectInfo->FileId.Cell,
+                                      pParentObjectInfo->FileId.Volume,
+                                      pParentObjectInfo->FileId.Vnode,
+                                      pParentObjectInfo->FileId.Unique));
 
-                    AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
-                                  AFS_TRACE_LEVEL_VERBOSE,
-                                  "AFSLocateNameEntry (FO: %p) Returning name not found(2) for %wZ FID %08lX-%08lX-%08lX-%08lX\n",
-                                  FileObject,
-                                  &uniComponentName,
-                                  pCurrentObject->FileId.Cell,
-                                  pCurrentObject->FileId.Volume,
-                                  pCurrentObject->FileId.Vnode,
-                                  pCurrentObject->FileId.Unique);
+                        AFSReleaseObjectInfo( &pParentObjectInfo);
+                    }
+                    else
+                    {
 
-                    //
-                    // Pass back the directory entries
-                    //
+                        ntStatus = STATUS_OBJECT_NAME_NOT_FOUND;
 
-                    *ParentDirectoryCB = pParentDirEntry;
+                        AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING,
+                                      AFS_TRACE_LEVEL_VERBOSE,
+                                      "AFSLocateNameEntry (FO: %p) Returning name not found(2) for %wZ in Parent FID %08lX-%08lX-%08lX-%08lX\n",
+                                      FileObject,
+                                      &uniComponentName,
+                                      pParentObjectInfo->FileId.Cell,
+                                      pParentObjectInfo->FileId.Volume,
+                                      pParentObjectInfo->FileId.Vnode,
+                                      pParentObjectInfo->FileId.Unique));
 
-                    *DirectoryCB = NULL;
+                        AFSReleaseObjectInfo( &pParentObjectInfo);
 
-                    *VolumeCB = pCurrentVolume;
+                        //
+                        // Pass back the directory entries
+                        //
 
-                    if( ComponentName != NULL)
-                    {
+                        *OutParentDirectoryCB = pParentDirEntry;
 
-                        *ComponentName = uniComponentName;
-                    }
+                        pParentDirEntry = NULL;
 
-                    *RootPathName = uniFullPathName;
+                        *OutDirectoryCB = NULL;
+
+                        *OutVolumeCB = pCurrentVolume;
+
+                        *OutVolumeReferenceReason = VolumeReferenceReason;
+
+                        bReleaseCurrentVolume = FALSE;
+
+                        if( ComponentName != NULL)
+                        {
+
+                            *ComponentName = uniComponentName;
+                        }
+
+                        *RootPathName = uniFullPathName;
+                    }
                 }
             }
 
@@ -1822,22 +2129,6 @@ AFSLocateNameEntry( IN GUID *AuthGroup,
             }
 
             //
-            // Decrement the previous parent
-            //
-
-            lCount = InterlockedDecrement( &pParentDirEntry->DirOpenReferenceCount);
-
-            AFSDbgLogMsg( AFS_SUBSYSTEM_DIRENTRY_REF_COUNTING,
-                          AFS_TRACE_LEVEL_VERBOSE,
-                          "AFSLocateNameEntry Decrement5 count on Parent %wZ DE %p Ccb %p Cnt %d\n",
-                          &pParentDirEntry->NameInformation.FileName,
-                          pParentDirEntry,
-                          NULL,
-                          lCount);
-
-            ASSERT( lCount >= 0);
-
-            //
             // If we ended up substituting a name in the component then update
             // the full path and update the pointers
             //
@@ -1847,13 +2138,13 @@ AFSLocateNameEntry( IN GUID *AuthGroup,
 
                 BOOLEAN bRelativeOpen = FALSE;
 
-                AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
+                AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING,
                               AFS_TRACE_LEVEL_VERBOSE_2,
                               "AFSLocateNameEntry (FO: %p) Substituting %wZ into %wZ Index %08lX\n",
                               FileObject,
                               &uniSearchName,
                               &uniComponentName,
-                              ulSubstituteIndex);
+                              ulSubstituteIndex));
 
                 if( FileObject != NULL &&
                     FileObject->RelatedFileObject != NULL)
@@ -1873,20 +2164,20 @@ AFSLocateNameEntry( IN GUID *AuthGroup,
                                                     &uniSearchName,
                                                     &uniRemainingPath,
                                                     bRelativeOpen ||
-                                                            bAllocatedSymLinkBuffer ||
-                                                            bSubstitutedName);
+                                                    bAllocatedSymLinkBuffer ||
+                                                    bSubstitutedName);
 
                 if( !NT_SUCCESS( ntStatus))
                 {
 
-                    AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
+                    AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING,
                                   AFS_TRACE_LEVEL_ERROR,
                                   "AFSLocateNameEntry (FO: %p) Failure to substitute %wZ into %wZ Index %08lX Status %08lX\n",
                                   FileObject,
                                   &uniSearchName,
                                   &uniComponentName,
                                   ulSubstituteIndex,
-                                  ntStatus);
+                                  ntStatus));
 
                     try_return( ntStatus);
                 }
@@ -1921,7 +2212,7 @@ AFSLocateNameEntry( IN GUID *AuthGroup,
                 if( !NT_SUCCESS( ntStatus))
                 {
 
-                    AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
+                    AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING,
                                   AFS_TRACE_LEVEL_ERROR,
                                   "AFSLocateNameEntry (FO: %p) Failed to evaluate possible DFS Link %wZ FID %08lX-%08lX-%08lX-%08lX Status %08lX\n",
                                   FileObject,
@@ -1930,7 +2221,7 @@ AFSLocateNameEntry( IN GUID *AuthGroup,
                                   pCurrentObject->FileId.Volume,
                                   pCurrentObject->FileId.Vnode,
                                   pCurrentObject->FileId.Unique,
-                                  ntStatus);
+                                  ntStatus));
 
                     try_return( ntStatus);
                 }
@@ -1940,7 +2231,7 @@ AFSLocateNameEntry( IN GUID *AuthGroup,
             // Update the name array
             //
 
-            AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
+            AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING,
                           AFS_TRACE_LEVEL_VERBOSE,
                           "AFSLocateNameEntry (FO: %p) Inserting name array entry %wZ FID %08lX-%08lX-%08lX-%08lX\n",
                           FileObject,
@@ -1948,7 +2239,7 @@ AFSLocateNameEntry( IN GUID *AuthGroup,
                           pCurrentObject->FileId.Cell,
                           pCurrentObject->FileId.Volume,
                           pCurrentObject->FileId.Vnode,
-                          pCurrentObject->FileId.Unique);
+                          pCurrentObject->FileId.Unique));
 
             ntStatus = AFSInsertNextElement( pNameArray,
                                              pDirEntry);
@@ -1962,95 +2253,99 @@ AFSLocateNameEntry( IN GUID *AuthGroup,
 
 try_exit:
 
-        AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
+        AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING,
                       AFS_TRACE_LEVEL_VERBOSE,
                       "AFSLocateNameEntry (FO: %p) Completed processing %wZ Status %08lX\n",
                       FileObject,
                       RootPathName,
-                      ntStatus);
+                      ntStatus));
 
         if( ( !NT_SUCCESS( ntStatus) &&
               ntStatus != STATUS_OBJECT_NAME_NOT_FOUND) ||
             ntStatus == STATUS_REPARSE)
         {
-
-            if( pDirEntry != NULL)
+            if( RootPathName->Buffer != uniFullPathName.Buffer)
             {
 
-                lCount = InterlockedDecrement( &pDirEntry->DirOpenReferenceCount);
+                AFSExFreePoolWithTag( uniFullPathName.Buffer, 0);
+            }
+        }
+        else
+        {
+
+            if( *OutParentDirectoryCB != NULL)
+            {
 
-                AFSDbgLogMsg( AFS_SUBSYSTEM_DIRENTRY_REF_COUNTING,
+                AFSDbgTrace(( AFS_SUBSYSTEM_DIRENTRY_REF_COUNTING,
                               AFS_TRACE_LEVEL_VERBOSE,
-                              "AFSLocateNameEntry Decrement6 count on %wZ DE %p Ccb %p Cnt %d\n",
-                              &pDirEntry->NameInformation.FileName,
-                              pDirEntry,
+                              "AFSLocateNameEntry Count on Parent %wZ DE %p Ccb %p Cnt %d\n",
+                              &(*OutParentDirectoryCB)->NameInformation.FileName,
+                              *OutParentDirectoryCB,
                               NULL,
-                              lCount);
-
-                ASSERT( lCount >= 0);
+                              (*OutParentDirectoryCB)->DirOpenReferenceCount));
             }
-            else if( pParentDirEntry != NULL)
-            {
 
-                lCount = InterlockedDecrement( &pParentDirEntry->DirOpenReferenceCount);
+            if( *OutDirectoryCB != NULL)
+            {
 
-                AFSDbgLogMsg( AFS_SUBSYSTEM_DIRENTRY_REF_COUNTING,
+                AFSDbgTrace(( AFS_SUBSYSTEM_DIRENTRY_REF_COUNTING,
                               AFS_TRACE_LEVEL_VERBOSE,
-                              "AFSLocateNameEntry Decrement7 count on %wZ DE %p Ccb %p Cnt %d\n",
-                              &pParentDirEntry->NameInformation.FileName,
-                              pParentDirEntry,
+                              "AFSLocateNameEntry Count on %wZ DE %p Ccb %p Cnt %d\n",
+                              &(*OutDirectoryCB)->NameInformation.FileName,
+                              *OutDirectoryCB,
                               NULL,
-                              lCount);
-
-                ASSERT( lCount >= 0);
+                              (*OutDirectoryCB)->DirOpenReferenceCount));
             }
+        }
 
-            if( bReleaseCurrentVolume)
-            {
+        if( pDirEntry != NULL)
+        {
 
-                ASSERT( pCurrentVolume->VolumeReferenceCount > 1);
+            lCount = InterlockedDecrement( &pDirEntry->DirOpenReferenceCount);
 
-                lCount = InterlockedDecrement( &pCurrentVolume->VolumeReferenceCount);
+            AFSDbgTrace(( AFS_SUBSYSTEM_DIRENTRY_REF_COUNTING,
+                          AFS_TRACE_LEVEL_VERBOSE,
+                          "AFSLocateNameEntry Decrement6 count on %wZ DE %p Ccb %p Cnt %d\n",
+                          &pDirEntry->NameInformation.FileName,
+                          pDirEntry,
+                          NULL,
+                          lCount));
 
-                AFSDbgLogMsg( AFS_SUBSYSTEM_VOLUME_REF_COUNTING,
-                              AFS_TRACE_LEVEL_VERBOSE,
-                              "AFSLocateNameEntry Decrement3 count on volume %p Cnt %d\n",
-                              pCurrentVolume,
-                              lCount);
-            }
+            ASSERT( lCount >= 0);
+        }
 
-            if( RootPathName->Buffer != uniFullPathName.Buffer)
-            {
+        if( pParentDirEntry != NULL)
+        {
 
-                AFSExFreePoolWithTag( uniFullPathName.Buffer, 0);
-            }
+            lCount = InterlockedDecrement( &pParentDirEntry->DirOpenReferenceCount);
+
+            AFSDbgTrace(( AFS_SUBSYSTEM_DIRENTRY_REF_COUNTING,
+                          AFS_TRACE_LEVEL_VERBOSE,
+                          "AFSLocateNameEntry Decrement7 count on %wZ DE %p Ccb %p Cnt %d\n",
+                          &pParentDirEntry->NameInformation.FileName,
+                          pParentDirEntry,
+                          NULL,
+                          lCount));
+
+            ASSERT( lCount >= 0);
         }
-        else
+
+        if( bReleaseCurrentVolume)
         {
 
-            if( *ParentDirectoryCB != NULL)
-            {
+            ASSERT( pCurrentVolume->VolumeReferenceCount > 0);
 
-                AFSDbgLogMsg( AFS_SUBSYSTEM_DIRENTRY_REF_COUNTING,
-                              AFS_TRACE_LEVEL_VERBOSE,
-                              "AFSLocateNameEntry Count on Parent %wZ DE %p Ccb %p Cnt %d\n",
-                              &(*ParentDirectoryCB)->NameInformation.FileName,
-                              *ParentDirectoryCB,
-                              NULL,
-                              (*ParentDirectoryCB)->DirOpenReferenceCount);
-            }
+            lCount = AFSVolumeDecrement( pCurrentVolume,
+                                         VolumeReferenceReason);
 
-            if( *DirectoryCB != NULL)
-            {
+            AFSDbgTrace(( AFS_SUBSYSTEM_VOLUME_REF_COUNTING,
+                          AFS_TRACE_LEVEL_VERBOSE,
+                          "AFSLocateNameEntry Decrement7 count on volume %p Reason %u Cnt %d\n",
+                          pCurrentVolume,
+                          VolumeReferenceReason,
+                          lCount));
 
-                AFSDbgLogMsg( AFS_SUBSYSTEM_DIRENTRY_REF_COUNTING,
-                              AFS_TRACE_LEVEL_VERBOSE,
-                              "AFSLocateNameEntry Count on %wZ DE %p Ccb %p Cnt %d\n",
-                              &(*DirectoryCB)->NameInformation.FileName,
-                              *DirectoryCB,
-                              NULL,
-                              (*DirectoryCB)->DirOpenReferenceCount);
-            }
+            bReleaseCurrentVolume = FALSE;
         }
 
         if( bSubstituteName &&
@@ -2083,7 +2378,7 @@ AFSCreateDirEntry( IN GUID            *AuthGroup,
     __Enter
     {
 
-        AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
+        AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING,
                       AFS_TRACE_LEVEL_VERBOSE_2,
                       "AFSCreateDirEntry Creating dir entry in parent %wZ FID %08lX-%08lX-%08lX-%08lX Component %wZ Attribs %08lX\n",
                       &ParentDirCB->NameInformation.FileName,
@@ -2092,7 +2387,7 @@ AFSCreateDirEntry( IN GUID            *AuthGroup,
                       ParentObjectInfo->FileId.Vnode,
                       ParentObjectInfo->FileId.Unique,
                       ComponentName,
-                      Attributes);
+                      Attributes));
 
         //
         // OK, before inserting the node into the parent tree, issue
@@ -2123,7 +2418,7 @@ AFSCreateDirEntry( IN GUID            *AuthGroup,
         if( !NT_SUCCESS( ntStatus))
         {
 
-            AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
+            AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING,
                           AFS_TRACE_LEVEL_ERROR,
                           "AFSCreateDirEntry Failed to create dir entry in parent %wZ FID %08lX-%08lX-%08lX-%08lX Component %wZ Attribs %08lX Status %08lX\n",
                           &ParentDirCB->NameInformation.FileName,
@@ -2133,7 +2428,7 @@ AFSCreateDirEntry( IN GUID            *AuthGroup,
                           ParentObjectInfo->FileId.Unique,
                           ComponentName,
                           Attributes,
-                          ntStatus);
+                          ntStatus));
 
             try_return( ntStatus);
         }
@@ -2153,22 +2448,23 @@ AFSCreateDirEntry( IN GUID            *AuthGroup,
         if( BooleanFlagOn( ParentObjectInfo->Flags, AFS_OBJECT_FLAGS_VERIFY))
         {
 
-            AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
+            AFSDbgTrace(( 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);
+                          ParentObjectInfo->FileId.Unique));
 
             ntStatus = AFSVerifyEntry( AuthGroup,
-                                       ParentDirCB);
+                                      ParentDirCB,
+                                      FALSE);
 
             if( !NT_SUCCESS( ntStatus))
             {
 
-                AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
+                AFSDbgTrace(( 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,
@@ -2176,7 +2472,7 @@ AFSCreateDirEntry( IN GUID            *AuthGroup,
                               ParentObjectInfo->FileId.Volume,
                               ParentObjectInfo->FileId.Vnode,
                               ParentObjectInfo->FileId.Unique,
-                              ntStatus);
+                              ntStatus));
 
                 AFSReleaseResource( ParentObjectInfo->Specific.Directory.DirectoryNodeHdr.TreeLock);
 
@@ -2203,24 +2499,24 @@ AFSCreateDirEntry( IN GUID            *AuthGroup,
 
                     lCount = InterlockedDecrement( &pDirNode->DirOpenReferenceCount);
 
-                    AFSDbgLogMsg( AFS_SUBSYSTEM_DIRENTRY_REF_COUNTING,
+                    AFSDbgTrace(( AFS_SUBSYSTEM_DIRENTRY_REF_COUNTING,
                                   AFS_TRACE_LEVEL_VERBOSE,
                                   "AFSCreateDirEntry Decrement count on %wZ DE %p Cnt %d\n",
                                   &pDirNode->NameInformation.FileName,
                                   pDirNode,
-                                  lCount);
+                                  lCount));
 
                     AFSDeleteDirEntry( ParentObjectInfo,
-                                       pDirNode);
+                                       &pDirNode);
 
                     lCount = InterlockedIncrement( &pExistingDirNode->DirOpenReferenceCount);
 
-                    AFSDbgLogMsg( AFS_SUBSYSTEM_DIRENTRY_REF_COUNTING,
+                    AFSDbgTrace(( AFS_SUBSYSTEM_DIRENTRY_REF_COUNTING,
                                   AFS_TRACE_LEVEL_VERBOSE,
                                   "AFSCreateDirEntry Increment count on %wZ DE %p Cnt %d\n",
                                   &pExistingDirNode->NameInformation.FileName,
                                   pExistingDirNode,
-                                  lCount);
+                                  lCount));
 
                     *DirEntry = pExistingDirNode;
                 }
@@ -2236,10 +2532,11 @@ AFSCreateDirEntry( IN GUID            *AuthGroup,
                 // Need to tear down this entry and rebuild it below
                 //
 
-                if( pExistingDirNode->DirOpenReferenceCount <= 0)
+                if( pExistingDirNode->DirOpenReferenceCount <= 0 &&
+                    pExistingDirNode->NameArrayReferenceCount <= 0)
                 {
 
-                    AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
+                    AFSDbgTrace(( 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,
@@ -2251,17 +2548,17 @@ AFSCreateDirEntry( IN GUID            *AuthGroup,
                                   pDirNode->ObjectInformation->FileId.Cell,
                                   pDirNode->ObjectInformation->FileId.Volume,
                                   pDirNode->ObjectInformation->FileId.Vnode,
-                                  pDirNode->ObjectInformation->FileId.Unique);
+                                  pDirNode->ObjectInformation->FileId.Unique));
 
                     AFSDeleteDirEntry( ParentObjectInfo,
-                                       pExistingDirNode);
+                                       &pExistingDirNode);
                 }
                 else
                 {
 
                     SetFlag( pExistingDirNode->Flags, AFS_DIR_ENTRY_DELETED);
 
-                    AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
+                    AFSDbgTrace(( 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,
@@ -2273,7 +2570,7 @@ AFSCreateDirEntry( IN GUID            *AuthGroup,
                                   pDirNode->ObjectInformation->FileId.Cell,
                                   pDirNode->ObjectInformation->FileId.Volume,
                                   pDirNode->ObjectInformation->FileId.Vnode,
-                                  pDirNode->ObjectInformation->FileId.Unique);
+                                  pDirNode->ObjectInformation->FileId.Unique));
 
                     AFSRemoveNameEntry( ParentObjectInfo,
                                         pExistingDirNode);
@@ -2281,7 +2578,7 @@ AFSCreateDirEntry( IN GUID            *AuthGroup,
             }
         }
 
-        AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
+        AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING,
                       AFS_TRACE_LEVEL_VERBOSE_2,
                       "AFSCreateDirEntry Inserting dir entry in parent %wZ FID %08lX-%08lX-%08lX-%08lX Component %wZ\n",
                       &ParentDirCB->NameInformation.FileName,
@@ -2289,7 +2586,7 @@ AFSCreateDirEntry( IN GUID            *AuthGroup,
                       ParentObjectInfo->FileId.Volume,
                       ParentObjectInfo->FileId.Vnode,
                       ParentObjectInfo->FileId.Unique,
-                      ComponentName);
+                      ComponentName));
 
         //
         // Insert the directory node
@@ -2332,11 +2629,11 @@ AFSInsertDirectoryNode( IN AFSObjectInfoCB *ParentObjectInfo,
         // Insert the node into the directory node tree
         //
 
-        AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
+        AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING,
                       AFS_TRACE_LEVEL_VERBOSE,
                       "AFSInsertDirectoryNode Insert DE %p for %wZ Clearing NOT_IN flag\n",
                       DirEntry,
-                      &DirEntry->NameInformation.FileName);
+                      &DirEntry->NameInformation.FileName));
 
         ClearFlag( DirEntry->Flags, AFS_DIR_ENTRY_NOT_IN_PARENT_TREE);
 
@@ -2345,11 +2642,11 @@ AFSInsertDirectoryNode( IN AFSObjectInfoCB *ParentObjectInfo,
 
             ParentObjectInfo->Specific.Directory.DirectoryNodeHdr.CaseSensitiveTreeHead = DirEntry;
 
-            AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
+            AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING,
                           AFS_TRACE_LEVEL_VERBOSE,
                           "AFSInsertDirectoryNode Insert DE %p to head of case sensitive tree for %wZ\n",
                           DirEntry,
-                          &DirEntry->NameInformation.FileName);
+                          &DirEntry->NameInformation.FileName));
         }
         else
         {
@@ -2357,11 +2654,11 @@ AFSInsertDirectoryNode( IN AFSObjectInfoCB *ParentObjectInfo,
             AFSInsertCaseSensitiveDirEntry( ParentObjectInfo->Specific.Directory.DirectoryNodeHdr.CaseSensitiveTreeHead,
                                             DirEntry);
 
-            AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
+            AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING,
                           AFS_TRACE_LEVEL_VERBOSE,
                           "AFSInsertDirectoryNode Insert DE %p to case sensitive tree for %wZ\n",
                           DirEntry,
-                          &DirEntry->NameInformation.FileName);
+                          &DirEntry->NameInformation.FileName));
         }
 
         if( ParentObjectInfo->Specific.Directory.DirectoryNodeHdr.CaseInsensitiveTreeHead == NULL)
@@ -2371,11 +2668,11 @@ AFSInsertDirectoryNode( IN AFSObjectInfoCB *ParentObjectInfo,
 
             SetFlag( DirEntry->Flags, AFS_DIR_ENTRY_CASE_INSENSTIVE_LIST_HEAD);
 
-            AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
+            AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING,
                           AFS_TRACE_LEVEL_VERBOSE,
                           "AFSInsertDirectoryNode Insert DE %p to head of case insensitive tree for %wZ\n",
                           DirEntry,
-                          &DirEntry->NameInformation.FileName);
+                          &DirEntry->NameInformation.FileName));
         }
         else
         {
@@ -2383,11 +2680,11 @@ AFSInsertDirectoryNode( IN AFSObjectInfoCB *ParentObjectInfo,
             AFSInsertCaseInsensitiveDirEntry( ParentObjectInfo->Specific.Directory.DirectoryNodeHdr.CaseInsensitiveTreeHead,
                                               DirEntry);
 
-            AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
+            AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING,
                           AFS_TRACE_LEVEL_VERBOSE,
                           "AFSInsertDirectoryNode Insert DE %p to case insensitive tree for %wZ\n",
                           DirEntry,
-                          &DirEntry->NameInformation.FileName);
+                          &DirEntry->NameInformation.FileName));
         }
 
         //
@@ -2402,11 +2699,11 @@ AFSInsertDirectoryNode( IN AFSObjectInfoCB *ParentObjectInfo,
 
                 ParentObjectInfo->Specific.Directory.ShortNameTree = DirEntry;
 
-                AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
+                AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING,
                               AFS_TRACE_LEVEL_VERBOSE,
                               "AFSInsertDirectoryNode Insert DE %p to head of shortname tree for %wZ\n",
                               DirEntry,
-                              &DirEntry->NameInformation.FileName);
+                              &DirEntry->NameInformation.FileName));
 
                 SetFlag( DirEntry->Flags, AFS_DIR_ENTRY_INSERTED_SHORT_NAME);
             }
@@ -2416,21 +2713,21 @@ AFSInsertDirectoryNode( IN AFSObjectInfoCB *ParentObjectInfo,
                 if( !NT_SUCCESS( AFSInsertShortNameDirEntry( ParentObjectInfo->Specific.Directory.ShortNameTree,
                                                              DirEntry)))
                 {
-                    AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
+                    AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING,
                                   AFS_TRACE_LEVEL_VERBOSE,
                                   "AFSInsertDirectoryNode Failed to insert DE %p to shortname tree for %wZ\n",
                                   DirEntry,
-                                  &DirEntry->NameInformation.FileName);
+                                  &DirEntry->NameInformation.FileName));
                 }
                 else
                 {
                     SetFlag( DirEntry->Flags, AFS_DIR_ENTRY_INSERTED_SHORT_NAME);
 
-                    AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
+                    AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING,
                                   AFS_TRACE_LEVEL_VERBOSE,
                                   "AFSInsertDirectoryNode Insert DE %p to shortname tree for %wZ\n",
                                   DirEntry,
-                                  &DirEntry->NameInformation.FileName);
+                                  &DirEntry->NameInformation.FileName));
                 }
             }
         }
@@ -2442,7 +2739,7 @@ AFSInsertDirectoryNode( IN AFSObjectInfoCB *ParentObjectInfo,
             // And insert the node into the directory list
             //
 
-            AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
+            AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING,
                           AFS_TRACE_LEVEL_VERBOSE,
                           "AFSInsertDirectoryNode Inserting entry %p %wZ FID %08lX-%08lX-%08lX-%08lX\n",
                           DirEntry,
@@ -2450,7 +2747,7 @@ AFSInsertDirectoryNode( IN AFSObjectInfoCB *ParentObjectInfo,
                           DirEntry->ObjectInformation->FileId.Cell,
                           DirEntry->ObjectInformation->FileId.Volume,
                           DirEntry->ObjectInformation->FileId.Vnode,
-                          DirEntry->ObjectInformation->FileId.Unique);
+                          DirEntry->ObjectInformation->FileId.Unique));
 
             if( ParentObjectInfo->Specific.Directory.DirectoryNodeListHead == NULL)
             {
@@ -2471,7 +2768,7 @@ AFSInsertDirectoryNode( IN AFSObjectInfoCB *ParentObjectInfo,
 
             lCount = InterlockedIncrement( &ParentObjectInfo->Specific.Directory.DirectoryNodeCount);
 
-            AFSDbgLogMsg( AFS_SUBSYSTEM_DIR_NODE_COUNT,
+            AFSDbgTrace(( 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,
@@ -2479,91 +2776,113 @@ AFSInsertDirectoryNode( IN AFSObjectInfoCB *ParentObjectInfo,
                           ParentObjectInfo->FileId.Cell,
                           ParentObjectInfo->FileId.Volume,
                           ParentObjectInfo->FileId.Vnode,
-                          ParentObjectInfo->FileId.Unique);
+                          ParentObjectInfo->FileId.Unique));
         }
     }
 
     return;
 }
 
-NTSTATUS
+void
 AFSDeleteDirEntry( IN AFSObjectInfoCB *ParentObjectInfo,
-                   IN AFSDirectoryCB *DirEntry)
+                   IN AFSDirectoryCB **ppDirEntry)
 {
 
-    NTSTATUS ntStatus = STATUS_SUCCESS;
     LONG lCount;
+    AFSDirectoryCB *pDirEntry;
 
     __Enter
     {
 
-        AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING | AFS_SUBSYSTEM_DIRENTRY_REF_COUNTING,
+        pDirEntry = (AFSDirectoryCB *) InterlockedCompareExchangePointer( (PVOID *)ppDirEntry,
+                                                                          NULL,
+                                                                          *ppDirEntry);
+
+        if ( pDirEntry == NULL)
+        {
+
+            try_return( NOTHING);
+        }
+
+        AFSDbgTrace(( AFS_SUBSYSTEM_CLEANUP_PROCESSING | AFS_SUBSYSTEM_DIRENTRY_REF_COUNTING,
                       AFS_TRACE_LEVEL_VERBOSE,
-                      "AFSDeleteDirEntry Deleting dir entry in parent %08lX Entry %p %wZ FID %08lX-%08lX-%08lX-%08lX RefCount %d\n",
+                     "AFSDeleteDirEntry Deleting dir entry in parent %p Entry %p object %p %wZ RefCount %d\n",
                       ParentObjectInfo,
-                      DirEntry,
-                      &DirEntry->NameInformation.FileName,
-                      DirEntry->ObjectInformation->FileId.Cell,
-                      DirEntry->ObjectInformation->FileId.Volume,
-                      DirEntry->ObjectInformation->FileId.Vnode,
-                      DirEntry->ObjectInformation->FileId.Unique,
-                      DirEntry->DirOpenReferenceCount);
+                      pDirEntry,
+                      pDirEntry->ObjectInformation,
+                      &pDirEntry->NameInformation.FileName,
+                      pDirEntry->DirOpenReferenceCount));
 
-        ASSERT( DirEntry->DirOpenReferenceCount == 0);
+        ASSERT( pDirEntry->DirOpenReferenceCount == 0);
 
         AFSRemoveDirNodeFromParent( ParentObjectInfo,
-                                    DirEntry,
+                                    pDirEntry,
                                     TRUE);
 
         //
         // Free up the name buffer if it was reallocated
         //
 
-        if( BooleanFlagOn( DirEntry->Flags, AFS_DIR_RELEASE_NAME_BUFFER))
+        if( BooleanFlagOn( pDirEntry->Flags, AFS_DIR_RELEASE_NAME_BUFFER))
         {
 
-            AFSExFreePoolWithTag( DirEntry->NameInformation.FileName.Buffer, 0);
+            AFSExFreePoolWithTag( pDirEntry->NameInformation.FileName.Buffer, 0);
         }
 
-        if( BooleanFlagOn( DirEntry->Flags, AFS_DIR_RELEASE_TARGET_NAME_BUFFER))
+        if( BooleanFlagOn( pDirEntry->Flags, AFS_DIR_RELEASE_TARGET_NAME_BUFFER))
         {
 
-            AFSExFreePoolWithTag( DirEntry->NameInformation.TargetName.Buffer, 0);
+            AFSExFreePoolWithTag( pDirEntry->NameInformation.TargetName.Buffer, 0);
         }
 
-        //
-        // Dereference the object for this dir entry
-        //
+        if ( pDirEntry->ObjectInformation != NULL)
+        {
+
+            if( BooleanFlagOn( pDirEntry->Flags, AFS_DIR_ENTRY_DELETED) &&
+                pDirEntry->ObjectInformation->Links == 0)
+            {
 
-        ASSERT( DirEntry->ObjectInformation->ObjectReferenceCount > 0);
+                SetFlag( pDirEntry->ObjectInformation->Flags, AFS_OBJECT_FLAGS_DELETED);
+            }
 
-        lCount = AFSObjectInfoDecrement( DirEntry->ObjectInformation);
+            //
+            // Dereference the object for this dir entry
+            //
 
-        AFSDbgLogMsg( AFS_SUBSYSTEM_OBJECT_REF_COUNTING,
-                      AFS_TRACE_LEVEL_VERBOSE,
-                      "AFSDeleteDirEntry Decrement count on object %p Cnt %d\n",
-                      DirEntry->ObjectInformation,
-                      lCount);
+            AFSAcquireShared( pDirEntry->ObjectInformation->VolumeCB->ObjectInfoTree.TreeLock,
+                              TRUE);
 
-        if( BooleanFlagOn( DirEntry->Flags, AFS_DIR_ENTRY_DELETED) &&
-            DirEntry->ObjectInformation->Links == 0)
-        {
+            lCount = AFSObjectInfoDecrement( pDirEntry->ObjectInformation,
+                                             AFS_OBJECT_REFERENCE_DIRENTRY);
+
+            AFSDbgTrace(( AFS_SUBSYSTEM_OBJECT_REF_COUNTING,
+                          AFS_TRACE_LEVEL_VERBOSE,
+                         "AFSDeleteDirEntry Decrement count on object %p Cnt %d\n",
+                          pDirEntry->ObjectInformation,
+                          lCount));
 
-            SetFlag( DirEntry->ObjectInformation->Flags, AFS_OBJECT_FLAGS_DELETED);
+            AFSReleaseResource( pDirEntry->ObjectInformation->VolumeCB->ObjectInfoTree.TreeLock);
         }
 
-        ExDeleteResourceLite( &DirEntry->NonPaged->Lock);
+        ExDeleteResourceLite( &pDirEntry->NonPaged->Lock);
 
-        AFSExFreePoolWithTag( DirEntry->NonPaged, AFS_DIR_ENTRY_NP_TAG);
+        AFSExFreePoolWithTag( pDirEntry->NonPaged, AFS_DIR_ENTRY_NP_TAG);
 
         //
         // Free up the dir entry
         //
 
-        AFSExFreePoolWithTag( DirEntry, AFS_DIR_ENTRY_TAG);
-    }
+        AFSDbgTrace(( AFS_SUBSYSTEM_DIRENTRY_ALLOCATION,
+                      AFS_TRACE_LEVEL_VERBOSE,
+                     "AFSDeleteDirEntry AFS_DIR_ENTRY_TAG deallocating %p\n",
+                      pDirEntry));
 
-    return ntStatus;
+        AFSExFreePoolWithTag( pDirEntry, AFS_DIR_ENTRY_TAG);
+
+try_exit:
+
+        NOTHING;
+    }
 }
 
 NTSTATUS
@@ -2581,25 +2900,39 @@ AFSRemoveDirNodeFromParent( IN AFSObjectInfoCB *ParentObjectInfo,
 
         ASSERT( ExIsResourceAcquiredExclusiveLite( ParentObjectInfo->Specific.Directory.DirectoryNodeHdr.TreeLock));
 
-        AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
-                      AFS_TRACE_LEVEL_VERBOSE,
-                      "AFSRemoveDirNodeFromParent Removing DirEntry %p %wZ FID %08lX-%08lX-%08lX-%08lX from Parent %p\n",
-                      DirEntry,
-                      &DirEntry->NameInformation.FileName,
-                      DirEntry->ObjectInformation->FileId.Cell,
-                      DirEntry->ObjectInformation->FileId.Volume,
-                      DirEntry->ObjectInformation->FileId.Vnode,
-                      DirEntry->ObjectInformation->FileId.Unique,
-                      ParentObjectInfo);
+        if ( DirEntry->ObjectInformation != NULL)
+        {
+
+            AFSDbgTrace(( AFS_SUBSYSTEM_CLEANUP_PROCESSING,
+                          AFS_TRACE_LEVEL_VERBOSE,
+                          "AFSRemoveDirNodeFromParent Removing DirEntry %p %wZ FID %08lX-%08lX-%08lX-%08lX from Parent %p\n",
+                          DirEntry,
+                          &DirEntry->NameInformation.FileName,
+                          DirEntry->ObjectInformation->FileId.Cell,
+                          DirEntry->ObjectInformation->FileId.Volume,
+                          DirEntry->ObjectInformation->FileId.Vnode,
+                          DirEntry->ObjectInformation->FileId.Unique,
+                          ParentObjectInfo));
+        }
+        else
+        {
+
+            AFSDbgTrace(( AFS_SUBSYSTEM_CLEANUP_PROCESSING,
+                          AFS_TRACE_LEVEL_VERBOSE,
+                          "AFSRemoveDirNodeFromParent Removing DirEntry %p %wZ from Parent %p\n",
+                          DirEntry,
+                          &DirEntry->NameInformation.FileName,
+                          ParentObjectInfo));
+        }
 
         if( !BooleanFlagOn( DirEntry->Flags, AFS_DIR_ENTRY_NOT_IN_PARENT_TREE))
         {
 
-            AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
+            AFSDbgTrace(( AFS_SUBSYSTEM_CLEANUP_PROCESSING,
                           AFS_TRACE_LEVEL_VERBOSE,
                           "AFSRemoveDirNodeFromParent Removing DirEntry %p name %wZ\n",
                           DirEntry,
-                          &DirEntry->NameInformation.FileName);
+                          &DirEntry->NameInformation.FileName));
 
             AFSRemoveNameEntry( ParentObjectInfo,
                                 DirEntry);
@@ -2607,11 +2940,11 @@ AFSRemoveDirNodeFromParent( IN AFSObjectInfoCB *ParentObjectInfo,
         else
         {
 
-            AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
+            AFSDbgTrace(( AFS_SUBSYSTEM_CLEANUP_PROCESSING,
                           AFS_TRACE_LEVEL_VERBOSE,
                           "AFSRemoveDirNodeFromParent DE %p for %wZ NOT removing entry due to flag set\n",
                           DirEntry,
-                          &DirEntry->NameInformation.FileName);
+                          &DirEntry->NameInformation.FileName));
 
         }
 
@@ -2651,7 +2984,7 @@ AFSRemoveDirNodeFromParent( IN AFSObjectInfoCB *ParentObjectInfo,
 
             ClearFlag( DirEntry->Flags, AFS_DIR_ENTRY_INSERTED_ENUM_LIST);
 
-            AFSDbgLogMsg( AFS_SUBSYSTEM_DIR_NODE_COUNT,
+            AFSDbgTrace(( AFS_SUBSYSTEM_DIR_NODE_COUNT,
                           AFS_TRACE_LEVEL_VERBOSE,
                           "AFSRemoveDirNodeFromParent Removing entry %wZ Dec Count %d to parent FID %08lX-%08lX-%08lX-%08lX\n",
                           &DirEntry->NameInformation.FileName,
@@ -2659,7 +2992,7 @@ AFSRemoveDirNodeFromParent( IN AFSObjectInfoCB *ParentObjectInfo,
                           ParentObjectInfo->FileId.Cell,
                           ParentObjectInfo->FileId.Volume,
                           ParentObjectInfo->FileId.Vnode,
-                          ParentObjectInfo->FileId.Unique);
+                          ParentObjectInfo->FileId.Unique));
 
             DirEntry->ListEntry.fLink = NULL;
             DirEntry->ListEntry.bLink = NULL;
@@ -2747,369 +3080,453 @@ AFSFixupTargetName( IN OUT PUNICODE_STRING FileName,
     return ntStatus;
 }
 
-NTSTATUS
-AFSParseName( IN PIRP Irp,
-              IN GUID *AuthGroup,
-              OUT PUNICODE_STRING FileName,
-              OUT PUNICODE_STRING ParsedFileName,
-              OUT PUNICODE_STRING RootFileName,
-              OUT ULONG *ParseFlags,
-              OUT AFSVolumeCB   **VolumeCB,
-              OUT AFSDirectoryCB **ParentDirectoryCB,
-              OUT AFSNameArrayHdr **NameArray)
+static NTSTATUS
+AFSParseRelatedName( IN PIRP Irp,
+                    IN GUID *AuthGroup,
+                    OUT PUNICODE_STRING FileName,
+                    OUT PUNICODE_STRING ParsedFileName,
+                    OUT PUNICODE_STRING RootFileName,
+                    OUT ULONG *ParseFlags,
+                    OUT AFSVolumeCB   **VolumeCB,
+                    OUT AFSDirectoryCB **ParentDirectoryCB,
+                    OUT AFSNameArrayHdr **NameArray)
 {
-
     NTSTATUS            ntStatus = STATUS_SUCCESS;
     PIO_STACK_LOCATION  pIrpSp = IoGetCurrentIrpStackLocation( Irp);
     AFSDeviceExt       *pDeviceExt = (AFSDeviceExt *)AFSRDRDeviceObject->DeviceExtension;
-    UNICODE_STRING      uniFullName, uniComponentName, uniRemainingPath;
-    ULONG               ulCRC = 0;
-    AFSDirectoryCB     *pDirEntry = NULL;
-    USHORT              usIndex = 0, usDriveIndex = 0;
     AFSCcb             *pRelatedCcb = NULL;
-    AFSNameArrayHdr    *pNameArray = NULL, *pRelatedNameArray = NULL;
+    AFSFcb             *pRelatedFcb = NULL;
+    AFSNameArrayHdr    *pRelatedNameArray = NULL;
+    UNICODE_STRING      uniFullName;
+    AFSDirectoryCB     *pDirEntry = NULL;
+    AFSNameArrayHdr    *pNameArray = NULL;
     USHORT              usComponentIndex = 0;
     USHORT              usComponentLength = 0;
     AFSVolumeCB        *pVolumeCB = NULL;
-    AFSFcb             *pRelatedFcb = NULL;
-    BOOLEAN             bReleaseTreeLock = FALSE;
-    BOOLEAN             bIsAllShare = FALSE;
-    LONG                lCount;
+     LONG                lCount;
 
-    __Enter
-    {
+     __Enter
+     {
 
-        //
-        // Indicate we are opening a root ...
-        //
+        pRelatedFcb = (AFSFcb *)pIrpSp->FileObject->RelatedFileObject->FsContext;
 
-        *ParseFlags = AFS_PARSE_FLAG_ROOT_ACCESS;
+        pRelatedCcb = (AFSCcb *)pIrpSp->FileObject->RelatedFileObject->FsContext2;
 
-        *ParentDirectoryCB = NULL;
+        pRelatedNameArray = pRelatedCcb->NameArray;
 
-        if( pIrpSp->FileObject->RelatedFileObject != NULL)
-        {
+        uniFullName = pIrpSp->FileObject->FileName;
 
-            pRelatedFcb = (AFSFcb *)pIrpSp->FileObject->RelatedFileObject->FsContext;
+        ASSERT( pRelatedFcb != NULL);
 
-            pRelatedCcb = (AFSCcb *)pIrpSp->FileObject->RelatedFileObject->FsContext2;
+        //
+        // On error, FileName indicates the path on which the failure occurred.
+        //
 
-            pRelatedNameArray = pRelatedCcb->NameArray;
+        *FileName = pRelatedCcb->FullFileName;
 
-            uniFullName = pIrpSp->FileObject->FileName;
+        //
+        // No wild cards in the name
+        //
 
-            ASSERT( pRelatedFcb != NULL);
+        AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING,
+                      AFS_TRACE_LEVEL_VERBOSE_2,
+                      "AFSParseRelatedName (%p) %wZ FID %08lX-%08lX-%08lX-%08lX %wZ\n",
+                      Irp,
+                      &pRelatedCcb->DirectoryCB->NameInformation.FileName,
+                      pRelatedFcb->ObjectInformation->FileId.Cell,
+                      pRelatedFcb->ObjectInformation->FileId.Volume,
+                      pRelatedFcb->ObjectInformation->FileId.Vnode,
+                      pRelatedFcb->ObjectInformation->FileId.Unique,
+                      &pRelatedCcb->FullFileName));
 
-            //
-            // No wild cards in the name
-            //
+        if( FsRtlDoesNameContainWildCards( &pRelatedCcb->FullFileName))
+        {
 
-            AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
-                          AFS_TRACE_LEVEL_VERBOSE_2,
-                          "AFSParseName (%p) Relative open for %wZ FID %08lX-%08lX-%08lX-%08lX component %wZ\n",
-                          Irp,
-                          &pRelatedCcb->DirectoryCB->NameInformation.FileName,
-                          pRelatedCcb->DirectoryCB->ObjectInformation->FileId.Cell,
-                          pRelatedCcb->DirectoryCB->ObjectInformation->FileId.Volume,
-                          pRelatedCcb->DirectoryCB->ObjectInformation->FileId.Vnode,
-                          pRelatedCcb->DirectoryCB->ObjectInformation->FileId.Unique,
-                          &uniFullName);
-
-            if( FsRtlDoesNameContainWildCards( &uniFullName))
-            {
+            AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING,
+                          AFS_TRACE_LEVEL_ERROR,
+                          "AFSParseNameRelated (%p) Component %wZ contains wild cards\n",
+                          Irp,
+                          &pRelatedCcb->FullFileName));
 
-                AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
-                              AFS_TRACE_LEVEL_ERROR,
-                              "AFSParseName (%p) Component %wZ contains wild cards\n",
-                              Irp,
-                              &uniFullName);
+            try_return( ntStatus = STATUS_OBJECT_NAME_INVALID);
+        }
 
-                try_return( ntStatus = STATUS_OBJECT_NAME_INVALID);
-            }
+        pVolumeCB = pRelatedFcb->ObjectInformation->VolumeCB;
 
-            pVolumeCB = pRelatedFcb->ObjectInformation->VolumeCB;
+        pDirEntry = pRelatedCcb->DirectoryCB;
 
-            pDirEntry = pRelatedCcb->DirectoryCB;
+        //
+        // Grab the root node while checking state
+        //
 
-            *FileName = pIrpSp->FileObject->FileName;
+        AFSAcquireShared( pVolumeCB->VolumeLock,
+                          TRUE);
 
-            //
-            // Grab the root node while checking state
-            //
+        if( BooleanFlagOn( pVolumeCB->ObjectInformation.Flags, AFS_OBJECT_FLAGS_OBJECT_INVALID) ||
+            BooleanFlagOn( pVolumeCB->Flags, AFS_VOLUME_FLAGS_OFFLINE))
+        {
 
-            AFSAcquireShared( pVolumeCB->VolumeLock,
-                              TRUE);
+            //
+            // The volume has been taken off line so fail the access
+            //
 
-            if( BooleanFlagOn( pVolumeCB->ObjectInformation.Flags, AFS_OBJECT_FLAGS_OBJECT_INVALID) ||
-                BooleanFlagOn( pVolumeCB->Flags, AFS_VOLUME_FLAGS_OFFLINE))
-            {
+            AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING,
+                          AFS_TRACE_LEVEL_ERROR,
+                          "AFSParseNameRelated (%p) Volume %08lX:%08lX OFFLINE/INVALID\n",
+                          Irp,
+                          pVolumeCB->ObjectInformation.FileId.Cell,
+                          pVolumeCB->ObjectInformation.FileId.Volume));
 
-                //
-                // The volume has been taken off line so fail the access
-                //
+            AFSReleaseResource( pVolumeCB->VolumeLock);
 
-                AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
-                              AFS_TRACE_LEVEL_ERROR,
-                              "AFSParseName (%p) Volume %08lX:%08lX OFFLINE/INVALID\n",
-                              Irp,
-                              pVolumeCB->ObjectInformation.FileId.Cell,
-                              pVolumeCB->ObjectInformation.FileId.Volume);
+            try_return( ntStatus = STATUS_DEVICE_NOT_READY);
+        }
 
-                AFSReleaseResource( pVolumeCB->VolumeLock);
+        if( BooleanFlagOn( pVolumeCB->ObjectInformation.Flags, AFS_OBJECT_FLAGS_VERIFY))
+        {
 
-                try_return( ntStatus = STATUS_DEVICE_NOT_READY);
-            }
+            AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING,
+                          AFS_TRACE_LEVEL_VERBOSE,
+                          "AFSParseNameRelated (%p) Verifying root of volume %08lX:%08lX\n",
+                          Irp,
+                          pVolumeCB->ObjectInformation.FileId.Cell,
+                          pVolumeCB->ObjectInformation.FileId.Volume));
 
-            if( BooleanFlagOn( pVolumeCB->ObjectInformation.Flags, AFS_OBJECT_FLAGS_VERIFY))
-            {
+            ntStatus = AFSVerifyVolume( (ULONGLONG)PsGetCurrentProcessId(),
+                                        pVolumeCB);
 
-                AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
-                              AFS_TRACE_LEVEL_VERBOSE,
-                              "AFSParseName (%p) Verifying root of volume %08lX:%08lX\n",
-                              Irp,
-                              pVolumeCB->ObjectInformation.FileId.Cell,
-                              pVolumeCB->ObjectInformation.FileId.Volume);
+            if( !NT_SUCCESS( ntStatus))
+            {
 
-                ntStatus = AFSVerifyVolume( (ULONGLONG)PsGetCurrentProcessId(),
-                                            pVolumeCB);
+                AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING,
+                              AFS_TRACE_LEVEL_ERROR,
+                              "AFSParseNameRelated (%p) Failed verification of root Status %08lX\n",
+                              Irp,
+                              ntStatus));
 
-                if( !NT_SUCCESS( ntStatus))
-                {
+                AFSReleaseResource( pVolumeCB->VolumeLock);
 
-                    AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
-                                  AFS_TRACE_LEVEL_ERROR,
-                                  "AFSParseName (%p) Failed verification of root Status %08lX\n",
-                                  Irp,
-                                  ntStatus);
+                try_return( ntStatus);
+            }
+        }
 
-                    AFSReleaseResource( pVolumeCB->VolumeLock);
+        AFSReleaseResource( pVolumeCB->VolumeLock);
 
-                    try_return( ntStatus);
-                }
-            }
+        if( BooleanFlagOn( pDirEntry->ObjectInformation->Flags, AFS_OBJECT_FLAGS_VERIFY))
+        {
 
-            AFSReleaseResource( pVolumeCB->VolumeLock);
+            AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING,
+                          AFS_TRACE_LEVEL_VERBOSE,
+                          "AFSParseNameRelated (%p) Verifying parent %wZ FID %08lX-%08lX-%08lX-%08lX\n",
+                          Irp,
+                          &pDirEntry->NameInformation.FileName,
+                          pDirEntry->ObjectInformation->FileId.Cell,
+                          pDirEntry->ObjectInformation->FileId.Volume,
+                          pDirEntry->ObjectInformation->FileId.Vnode,
+                          pDirEntry->ObjectInformation->FileId.Unique));
 
-            if( BooleanFlagOn( pDirEntry->ObjectInformation->Flags, AFS_OBJECT_FLAGS_VERIFY))
-            {
+            //
+            // Directory TreeLock should be exclusively held
+            //
 
-                AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
-                              AFS_TRACE_LEVEL_VERBOSE,
-                              "AFSParseName (%p) Verifying parent %wZ FID %08lX-%08lX-%08lX-%08lX\n",
-                              Irp,
-                              &pDirEntry->NameInformation.FileName,
-                              pDirEntry->ObjectInformation->FileId.Cell,
-                              pDirEntry->ObjectInformation->FileId.Volume,
-                              pDirEntry->ObjectInformation->FileId.Vnode,
-                              pDirEntry->ObjectInformation->FileId.Unique);
+            AFSAcquireExcl( pDirEntry->ObjectInformation->Specific.Directory.DirectoryNodeHdr.TreeLock,
+                            TRUE);
 
-                //
-                // Directory TreeLock should be exclusively held
-                //
+            ntStatus = AFSVerifyEntry( AuthGroup,
+                                       pDirEntry,
+                                       FALSE);
 
-                AFSAcquireExcl( pDirEntry->ObjectInformation->Specific.Directory.DirectoryNodeHdr.TreeLock,
-                                TRUE);
+            AFSReleaseResource( pDirEntry->ObjectInformation->Specific.Directory.DirectoryNodeHdr.TreeLock);
 
-                ntStatus = AFSVerifyEntry( AuthGroup,
-                                           pDirEntry);
+            if( !NT_SUCCESS( ntStatus))
+            {
 
-                AFSReleaseResource( pDirEntry->ObjectInformation->Specific.Directory.DirectoryNodeHdr.TreeLock);
+                AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING,
+                              AFS_TRACE_LEVEL_VERBOSE,
+                              "AFSParseNameRelated (%p) Failed verification of parent %wZ FID %08lX-%08lX-%08lX-%08lX Status %08lX\n",
+                              Irp,
+                              &pDirEntry->NameInformation.FileName,
+                              pDirEntry->ObjectInformation->FileId.Cell,
+                              pDirEntry->ObjectInformation->FileId.Volume,
+                              pDirEntry->ObjectInformation->FileId.Vnode,
+                              pDirEntry->ObjectInformation->FileId.Unique,
+                              ntStatus));
 
-                if( !NT_SUCCESS( ntStatus))
-                {
+                try_return( ntStatus);
+            }
+        }
 
-                    AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
-                                  AFS_TRACE_LEVEL_VERBOSE,
-                                  "AFSParseName (%p) Failed verification of parent %wZ FID %08lX-%08lX-%08lX-%08lX Status %08lX\n",
-                                  Irp,
-                                  &pDirEntry->NameInformation.FileName,
-                                  pDirEntry->ObjectInformation->FileId.Cell,
-                                  pDirEntry->ObjectInformation->FileId.Volume,
-                                  pDirEntry->ObjectInformation->FileId.Vnode,
-                                  pDirEntry->ObjectInformation->FileId.Unique,
-                                  ntStatus);
+        //
+        // Create our full path name buffer
+        //
 
-                    try_return( ntStatus);
-                }
-            }
+        uniFullName.MaximumLength = pRelatedCcb->FullFileName.Length
+            + sizeof( WCHAR) + pIrpSp->FileObject->FileName.Length
+            + sizeof( WCHAR);
 
-            //
-            // Create our full path name buffer
-            //
+        uniFullName.Length = 0;
 
-            uniFullName.MaximumLength = pRelatedCcb->FullFileName.Length +
-                                                    sizeof( WCHAR) +
-                                                    pIrpSp->FileObject->FileName.Length +
-                                                    sizeof( WCHAR);
+        uniFullName.Buffer = (WCHAR *)AFSExAllocatePoolWithTag( PagedPool,
+                                                                uniFullName.MaximumLength,
+                                                                AFS_NAME_BUFFER_THREE_TAG);
 
-            uniFullName.Length = 0;
+        if( uniFullName.Buffer == NULL)
+        {
 
-            uniFullName.Buffer = (WCHAR *)AFSExAllocatePoolWithTag( PagedPool,
-                                                                    uniFullName.MaximumLength,
-                                                                    AFS_NAME_BUFFER_THREE_TAG);
+            AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING,
+                          AFS_TRACE_LEVEL_ERROR,
+                          "AFSParseNameRelated (%p) Failed to allocate full name buffer\n",
+                          Irp));
 
-            if( uniFullName.Buffer == NULL)
-            {
+            try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
+        }
 
-                AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
-                              AFS_TRACE_LEVEL_ERROR,
-                              "AFSParseName (%p) Failed to allocate full name buffer\n",
-                              Irp);
+        SetFlag( *ParseFlags, AFS_PARSE_FLAG_FREE_FILE_BUFFER);
 
-                try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
-            }
+        RtlZeroMemory( uniFullName.Buffer,
+                       uniFullName.MaximumLength);
 
-            RtlZeroMemory( uniFullName.Buffer,
-                           uniFullName.MaximumLength);
+        RtlCopyMemory( uniFullName.Buffer,
+                       pRelatedCcb->FullFileName.Buffer,
+                       pRelatedCcb->FullFileName.Length);
 
-            RtlCopyMemory( uniFullName.Buffer,
-                           pRelatedCcb->FullFileName.Buffer,
-                           pRelatedCcb->FullFileName.Length);
+        uniFullName.Length = pRelatedCcb->FullFileName.Length;
 
-            uniFullName.Length = pRelatedCcb->FullFileName.Length;
+        usComponentIndex = (USHORT)(uniFullName.Length/sizeof( WCHAR));
 
-            usComponentIndex = (USHORT)(uniFullName.Length/sizeof( WCHAR));
+        usComponentLength = pIrpSp->FileObject->FileName.Length;
 
-            usComponentLength = pIrpSp->FileObject->FileName.Length;
+        if( uniFullName.Buffer[ (uniFullName.Length/sizeof( WCHAR)) - 1] != L'\\' &&
+            pIrpSp->FileObject->FileName.Length > 0 &&
+            pIrpSp->FileObject->FileName.Buffer[ 0] != L'\\' &&
+            pIrpSp->FileObject->FileName.Buffer[ 0] != L':')
+        {
 
-            if( uniFullName.Buffer[ (uniFullName.Length/sizeof( WCHAR)) - 1] != L'\\' &&
-                pIrpSp->FileObject->FileName.Length > 0 &&
-                pIrpSp->FileObject->FileName.Buffer[ 0] != L'\\' &&
-                pIrpSp->FileObject->FileName.Buffer[ 0] != L':')
-            {
+            uniFullName.Buffer[ (uniFullName.Length/sizeof( WCHAR))] = L'\\';
 
-                uniFullName.Buffer[ (uniFullName.Length/sizeof( WCHAR))] = L'\\';
+            uniFullName.Length += sizeof( WCHAR);
 
-                uniFullName.Length += sizeof( WCHAR);
+            usComponentLength += sizeof( WCHAR);
+        }
 
-                usComponentLength += sizeof( WCHAR);
-            }
+        if( pIrpSp->FileObject->FileName.Length > 0)
+        {
 
-            if( pIrpSp->FileObject->FileName.Length > 0)
-            {
+            RtlCopyMemory( &uniFullName.Buffer[ uniFullName.Length/sizeof( WCHAR)],
+                           pIrpSp->FileObject->FileName.Buffer,
+                           pIrpSp->FileObject->FileName.Length);
 
-                RtlCopyMemory( &uniFullName.Buffer[ uniFullName.Length/sizeof( WCHAR)],
-                               pIrpSp->FileObject->FileName.Buffer,
-                               pIrpSp->FileObject->FileName.Length);
+            uniFullName.Length += pIrpSp->FileObject->FileName.Length;
+        }
 
-                uniFullName.Length += pIrpSp->FileObject->FileName.Length;
-            }
+        *RootFileName = uniFullName;
 
-            *RootFileName = uniFullName;
+        //
+        // We populate up to the current parent
+        //
 
-            //
-            // We populate up to the current parent
-            //
+        if( pRelatedNameArray == NULL)
+        {
 
-            if( pRelatedNameArray == NULL)
-            {
+            //
+            // Init and populate our name array
+            //
 
-                //
-                // Init and populate our name array
-                //
+            pNameArray = AFSInitNameArray( NULL,
+                                           0);
 
-                pNameArray = AFSInitNameArray( NULL,
-                                               0);
+            if( pNameArray == NULL)
+            {
 
-                if( pNameArray == NULL)
-                {
+                AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING,
+                              AFS_TRACE_LEVEL_VERBOSE,
+                              "AFSParseNameRelated (%p) Failed to initialize name array\n",
+                              Irp));
 
-                    AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
-                                  AFS_TRACE_LEVEL_VERBOSE,
-                                  "AFSParseName (%p) Failed to initialize name array\n",
-                                  Irp);
+                AFSExFreePoolWithTag( uniFullName.Buffer, 0);
 
-                    AFSExFreePoolWithTag( uniFullName.Buffer, 0);
+                ClearFlag( *ParseFlags, AFS_PARSE_FLAG_FREE_FILE_BUFFER);
 
-                    try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
-                }
+                try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
+            }
 
-                ntStatus = AFSPopulateNameArray( pNameArray,
-                                                 NULL,
-                                                 pRelatedCcb->DirectoryCB);
-            }
-            else
-            {
+            ntStatus = AFSPopulateNameArray( pNameArray,
+                                             NULL,
+                                             pRelatedCcb->DirectoryCB);
+        }
+        else
+        {
 
-                //
-                // Init and populate our name array
-                //
+            //
+            // Init and populate our name array
+            //
 
-                pNameArray = AFSInitNameArray( NULL,
-                                               pRelatedNameArray->MaxElementCount);
+            pNameArray = AFSInitNameArray( NULL,
+                                           pRelatedNameArray->MaxElementCount);
 
-                if( pNameArray == NULL)
-                {
+            if( pNameArray == NULL)
+            {
 
-                    AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
-                                  AFS_TRACE_LEVEL_VERBOSE,
-                                  "AFSParseName (%p) Failed to initialize name array\n",
-                                  Irp);
+                AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING,
+                              AFS_TRACE_LEVEL_VERBOSE,
+                              "AFSParseNameRelated (%p) Failed to initialize name array\n",
+                              Irp));
 
-                    AFSExFreePoolWithTag( uniFullName.Buffer, 0);
+                AFSExFreePoolWithTag( uniFullName.Buffer, 0);
 
-                    try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
-                }
+                ClearFlag( *ParseFlags, AFS_PARSE_FLAG_FREE_FILE_BUFFER);
 
-                ntStatus = AFSPopulateNameArrayFromRelatedArray( pNameArray,
-                                                                 pRelatedNameArray,
-                                                                 pRelatedCcb->DirectoryCB);
-            }
+                try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
+            }
 
-            if( !NT_SUCCESS( ntStatus))
-            {
+            ntStatus = AFSPopulateNameArrayFromRelatedArray( pNameArray,
+                                                             pRelatedNameArray,
+                                                             pRelatedCcb->DirectoryCB);
+        }
 
-                AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
-                              AFS_TRACE_LEVEL_VERBOSE,
-                              "AFSParseName (%p) Failed to populate name array\n",
-                              Irp);
+        if( !NT_SUCCESS( ntStatus))
+        {
 
-                AFSExFreePoolWithTag( uniFullName.Buffer, 0);
+            AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING,
+                          AFS_TRACE_LEVEL_VERBOSE,
+                          "AFSParseNameRelated (%p) Failed to populate name array\n",
+                          Irp));
 
-                try_return( ntStatus);
-            }
+            AFSExFreePoolWithTag( uniFullName.Buffer, 0);
 
-            ParsedFileName->Length = usComponentLength;
-            ParsedFileName->MaximumLength = uniFullName.MaximumLength;
+            ClearFlag( *ParseFlags, AFS_PARSE_FLAG_FREE_FILE_BUFFER);
 
-            ParsedFileName->Buffer = &uniFullName.Buffer[ usComponentIndex];
+            try_return( ntStatus);
+        }
 
-            //
-            // Indicate to caller that RootFileName must be freed
-            //
+        ParsedFileName->Length = usComponentLength;
 
-            SetFlag( *ParseFlags, AFS_PARSE_FLAG_FREE_FILE_BUFFER);
+        ParsedFileName->MaximumLength = uniFullName.MaximumLength;
 
-            *NameArray = pNameArray;
+        ParsedFileName->Buffer = &uniFullName.Buffer[ usComponentIndex];
 
-            //
-            // Increment our volume reference count
-            //
+        *NameArray = pNameArray;
 
-            lCount = InterlockedIncrement( &pVolumeCB->VolumeReferenceCount);
+        //
+        // Increment our volume reference count
+        //
 
-            AFSDbgLogMsg( AFS_SUBSYSTEM_VOLUME_REF_COUNTING,
-                          AFS_TRACE_LEVEL_VERBOSE,
-                          "AFSParseName Increment count on volume %p Cnt %d\n",
-                          pVolumeCB,
-                          lCount);
+        lCount = AFSVolumeIncrement( pVolumeCB,
+                                     AFS_VOLUME_REFERENCE_PARSE_NAME);
 
-            *VolumeCB = pVolumeCB;
+        AFSDbgTrace(( AFS_SUBSYSTEM_VOLUME_REF_COUNTING,
+                      AFS_TRACE_LEVEL_VERBOSE,
+                      "AFSParseNameRelated Increment count on volume %p Cnt %d\n",
+                      pVolumeCB,
+                      lCount));
 
-            *ParentDirectoryCB = pDirEntry;
+        *VolumeCB = pVolumeCB;
 
-            AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
-                          AFS_TRACE_LEVEL_VERBOSE_2,
-                          "AFSParseName (%p) Returning full name %wZ\n",
-                          Irp,
-                          &uniFullName);
+        *ParentDirectoryCB = pDirEntry;
 
-            try_return( ntStatus);
+        AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING,
+                      AFS_TRACE_LEVEL_VERBOSE_2,
+                      "AFSParseNameRelated (%p) Returning full name %wZ\n",
+                      Irp,
+                      &uniFullName));
+
+        try_return( ntStatus);
+
+try_exit:
+
+        if( NT_SUCCESS( ntStatus))
+        {
+
+            if( *ParentDirectoryCB != NULL)
+            {
+
+                lCount = InterlockedIncrement( &(*ParentDirectoryCB)->DirOpenReferenceCount);
+
+                AFSDbgTrace(( AFS_SUBSYSTEM_DIRENTRY_REF_COUNTING,
+                              AFS_TRACE_LEVEL_VERBOSE,
+                              "AFSParseRelatedName Increment1 count on %wZ DE %p Ccb %p Cnt %d\n",
+                              &(*ParentDirectoryCB)->NameInformation.FileName,
+                              (*ParentDirectoryCB),
+                              NULL,
+                              lCount));
+            }
+        }
+
+        if( *VolumeCB != NULL)
+        {
+            ASSERT( (*VolumeCB)->VolumeReferenceCount > 0);
+        }
+
+        if( ntStatus != STATUS_SUCCESS)
+        {
+
+            if( pNameArray != NULL)
+            {
+
+                AFSFreeNameArray( pNameArray);
+            }
+        }
+     }
+
+    return ntStatus;
+}
+
+NTSTATUS
+AFSParseName( IN PIRP Irp,
+             IN GUID *AuthGroup,
+             OUT PUNICODE_STRING FileName,
+             OUT PUNICODE_STRING ParsedFileName,
+             OUT PUNICODE_STRING RootFileName,
+             OUT ULONG *ParseFlags,
+             OUT AFSVolumeCB   **VolumeCB,
+             OUT AFSDirectoryCB **ParentDirectoryCB,
+             OUT AFSNameArrayHdr **NameArray)
+{
+
+    NTSTATUS            ntStatus = STATUS_SUCCESS;
+    PIO_STACK_LOCATION  pIrpSp = IoGetCurrentIrpStackLocation( Irp);
+    AFSDeviceExt       *pDeviceExt = (AFSDeviceExt *)AFSRDRDeviceObject->DeviceExtension;
+    UNICODE_STRING      uniFullName, uniComponentName, uniRemainingPath;
+    ULONG               ulCRC = 0;
+    AFSDirectoryCB     *pDirEntry = NULL;
+    USHORT              usIndex = 0, usDriveIndex = 0;
+    AFSNameArrayHdr    *pNameArray = NULL;
+    USHORT              usComponentIndex = 0;
+    USHORT              usComponentLength = 0;
+    AFSVolumeCB        *pVolumeCB = NULL;
+    BOOLEAN             bReleaseTreeLock = FALSE;
+    BOOLEAN             bIsAllShare = FALSE;
+    LONG                lCount;
+
+    __Enter
+    {
+
+       if( pIrpSp->FileObject->RelatedFileObject != NULL)
+       {
+
+           return AFSParseRelatedName( Irp, AuthGroup, FileName,
+                                       ParsedFileName, RootFileName,
+                                       ParseFlags, VolumeCB,
+                                       ParentDirectoryCB, NameArray);
         }
 
-        //
-        // No wild cards in the name
-        //
+       //
+       // Indicate we are opening a root ...
+       //
+
+       *ParseFlags = AFS_PARSE_FLAG_ROOT_ACCESS;
+
+       *ParentDirectoryCB = NULL;
+
+       //
+       // On error, FileName indicates the path on which the failure occurred
+       //
+
+       *FileName = pIrpSp->FileObject->FileName;
+
+       //
+       // No wild cards in the name
+       //
 
         uniFullName = pIrpSp->FileObject->FileName;
 
@@ -3117,11 +3534,11 @@ AFSParseName( IN PIRP Irp,
             uniFullName.Length < AFSServerName.Length)
         {
 
-            AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
+            AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING,
                           AFS_TRACE_LEVEL_ERROR,
                           "AFSParseName (%p) Name %wZ contains wild cards or too short\n",
                           Irp,
-                          &uniFullName);
+                          &uniFullName));
 
             try_return( ntStatus = STATUS_OBJECT_NAME_INVALID);
         }
@@ -3190,11 +3607,11 @@ AFSParseName( IN PIRP Irp,
                                          TRUE) != 0)
             {
 
-                AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
+                AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING,
                               AFS_TRACE_LEVEL_ERROR,
                               "AFSParseName (%p) Name %wZ does not have server name\n",
                               Irp,
-                              &pIrpSp->FileObject->FileName);
+                              &pIrpSp->FileObject->FileName));
 
                 try_return( ntStatus = STATUS_BAD_NETWORK_NAME);
             }
@@ -3207,11 +3624,11 @@ AFSParseName( IN PIRP Irp,
                 !AFSIsDriveMapped( pIrpSp->FileObject->FileName.Buffer[ usDriveIndex]))
             {
 
-                AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
+                AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING,
                               AFS_TRACE_LEVEL_ERROR,
                               "AFSParseName (%p) Name %wZ contains invalid drive mapping\n",
                               Irp,
-                              &pIrpSp->FileObject->FileName);
+                              &pIrpSp->FileObject->FileName));
 
                 try_return( ntStatus = STATUS_BAD_NETWORK_NAME);
             }
@@ -3220,20 +3637,20 @@ AFSParseName( IN PIRP Irp,
         if( FsRtlDoesNameContainWildCards( &uniFullName))
         {
 
-            AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
+            AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING,
                           AFS_TRACE_LEVEL_ERROR,
                           "AFSParseName (%p) Component %wZ contains wild cards\n",
                           Irp,
-                          &uniFullName);
+                          &uniFullName));
 
             try_return( ntStatus = STATUS_OBJECT_NAME_INVALID);
         }
 
-        AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
+        AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING,
                       AFS_TRACE_LEVEL_VERBOSE_2,
                       "AFSParseName (%p) Processing full name %wZ\n",
                       Irp,
-                      &uniFullName);
+                      &uniFullName));
 
         if( uniFullName.Length > 0 &&
             uniFullName.Buffer[ (uniFullName.Length/sizeof( WCHAR)) - 1] == L'\\')
@@ -3257,12 +3674,12 @@ AFSParseName( IN PIRP Irp,
             // The volume has been taken off line so fail the access
             //
 
-            AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
+            AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING,
                           AFS_TRACE_LEVEL_ERROR,
                           "AFSParseName (%p) Volume %08lX:%08lX OFFLINE/INVALID\n",
                           Irp,
                           AFSGlobalRoot->ObjectInformation.FileId.Cell,
-                          AFSGlobalRoot->ObjectInformation.FileId.Volume);
+                          AFSGlobalRoot->ObjectInformation.FileId.Volume));
 
             AFSReleaseResource( AFSGlobalRoot->VolumeLock);
 
@@ -3272,12 +3689,12 @@ AFSParseName( IN PIRP Irp,
         if( BooleanFlagOn( AFSGlobalRoot->ObjectInformation.Flags, AFS_OBJECT_FLAGS_VERIFY))
         {
 
-            AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
+            AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING,
                           AFS_TRACE_LEVEL_VERBOSE,
                           "AFSParseName (%p) Verifying root of volume %08lX:%08lX\n",
                           Irp,
                           AFSGlobalRoot->ObjectInformation.FileId.Cell,
-                          AFSGlobalRoot->ObjectInformation.FileId.Volume);
+                          AFSGlobalRoot->ObjectInformation.FileId.Volume));
 
             ntStatus = AFSVerifyVolume( (ULONGLONG)PsGetCurrentProcessId(),
                                         AFSGlobalRoot);
@@ -3285,11 +3702,11 @@ AFSParseName( IN PIRP Irp,
             if( !NT_SUCCESS( ntStatus))
             {
 
-                AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
+                AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING,
                               AFS_TRACE_LEVEL_ERROR,
                               "AFSParseName (%p) Failed verification of root Status %08lX\n",
                               Irp,
-                              ntStatus);
+                              ntStatus));
 
                 AFSReleaseResource( AFSGlobalRoot->VolumeLock);
 
@@ -3302,23 +3719,23 @@ AFSParseName( IN PIRP Irp,
         if( !BooleanFlagOn( AFSGlobalRoot->ObjectInformation.Flags, AFS_OBJECT_FLAGS_DIRECTORY_ENUMERATED))
         {
 
-            AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
+            AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING,
                           AFS_TRACE_LEVEL_VERBOSE,
                           "AFSParseName (%p) Enumerating global root of volume %08lX:%08lX\n",
                           Irp,
                           AFSGlobalRoot->ObjectInformation.FileId.Cell,
-                          AFSGlobalRoot->ObjectInformation.FileId.Volume);
+                          AFSGlobalRoot->ObjectInformation.FileId.Volume));
 
             ntStatus = AFSEnumerateGlobalRoot( AuthGroup);
 
             if( !NT_SUCCESS( ntStatus))
             {
 
-                AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
+                AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING,
                               AFS_TRACE_LEVEL_ERROR,
                               "AFSParseName (%p) Failed enumeraiton of root Status %08lX\n",
                               Irp,
-                              ntStatus);
+                              ntStatus));
 
                 try_return( ntStatus);
             }
@@ -3333,20 +3750,20 @@ AFSParseName( IN PIRP Irp,
               uniRemainingPath.Buffer[ 0] == L'\\'))
         {
 
-            AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
+            AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING,
                           AFS_TRACE_LEVEL_VERBOSE_2,
                           "AFSParseName (%p) Returning global root access\n",
-                          Irp);
+                          Irp));
 
             lCount = InterlockedIncrement( &AFSGlobalRoot->DirectoryCB->DirOpenReferenceCount);
 
-            AFSDbgLogMsg( AFS_SUBSYSTEM_DIRENTRY_REF_COUNTING,
+            AFSDbgTrace(( AFS_SUBSYSTEM_DIRENTRY_REF_COUNTING,
                           AFS_TRACE_LEVEL_VERBOSE,
                           "AFSParseName Increment2 count on %wZ DE %p Ccb %p Cnt %d\n",
                           &AFSGlobalRoot->DirectoryCB->NameInformation.FileName,
                           AFSGlobalRoot->DirectoryCB,
                           NULL,
-                          lCount);
+                          lCount));
 
             *VolumeCB = NULL;
 
@@ -3381,11 +3798,11 @@ AFSParseName( IN PIRP Irp,
         if( FsRtlDoesNameContainWildCards( &uniFullName))
         {
 
-            AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
+            AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING,
                           AFS_TRACE_LEVEL_ERROR,
                           "AFSParseName (%p) Component %wZ contains wild cards\n",
                           Irp,
-                          &uniComponentName);
+                          &uniComponentName));
 
             try_return( ntStatus = STATUS_OBJECT_NAME_INVALID);
         }
@@ -3412,20 +3829,20 @@ AFSParseName( IN PIRP Irp,
                   uniRemainingPath.Buffer[ 0] == L'\\'))
             {
 
-                AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
+                AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING,
                               AFS_TRACE_LEVEL_VERBOSE_2,
                               "AFSParseName (%p) Returning global root access\n",
-                              Irp);
+                              Irp));
 
                 lCount = InterlockedIncrement( &AFSGlobalRoot->DirectoryCB->DirOpenReferenceCount);
 
-                AFSDbgLogMsg( AFS_SUBSYSTEM_DIRENTRY_REF_COUNTING,
+                AFSDbgTrace(( AFS_SUBSYSTEM_DIRENTRY_REF_COUNTING,
                               AFS_TRACE_LEVEL_VERBOSE,
                               "AFSParseName Increment3 count on %wZ DE %p Ccb %p Cnt %d\n",
                               &AFSGlobalRoot->DirectoryCB->NameInformation.FileName,
                               AFSGlobalRoot->DirectoryCB,
                               NULL,
-                              lCount);
+                              lCount));
 
                 *VolumeCB = NULL;
 
@@ -3455,20 +3872,20 @@ AFSParseName( IN PIRP Irp,
                                          TRUE) == 0)
             {
 
-                AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
+                AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING,
                               AFS_TRACE_LEVEL_VERBOSE_2,
                               "AFSParseName (%p) Returning root PIOCtl access\n",
-                              Irp);
+                              Irp));
 
                 lCount = InterlockedIncrement( &AFSGlobalRoot->DirectoryCB->DirOpenReferenceCount);
 
-                AFSDbgLogMsg( AFS_SUBSYSTEM_DIRENTRY_REF_COUNTING,
+                AFSDbgTrace(( AFS_SUBSYSTEM_DIRENTRY_REF_COUNTING,
                               AFS_TRACE_LEVEL_VERBOSE,
                               "AFSParseName Increment4 count on %wZ DE %p Ccb %p Cnt %d\n",
                               &AFSGlobalRoot->DirectoryCB->NameInformation.FileName,
                               AFSGlobalRoot->DirectoryCB,
                               NULL,
-                              lCount);
+                              lCount));
 
                 ClearFlag( *ParseFlags, AFS_PARSE_FLAG_ROOT_ACCESS);
 
@@ -3483,11 +3900,11 @@ AFSParseName( IN PIRP Irp,
                                                            &uniRemainingPath)) != NULL)
         {
 
-            AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
+            AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING,
                           AFS_TRACE_LEVEL_VERBOSE_2,
                           "AFSParseName (%p) Returning root share name %wZ access\n",
                           Irp,
-                          &uniComponentName);
+                          &uniComponentName));
 
             //
             // Add in the full share name to pass back
@@ -3594,6 +4011,13 @@ AFSParseName( IN PIRP Irp,
                              ntStatus == STATUS_OBJECT_PATH_NOT_FOUND)
                         {
 
+                            AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING,
+                                          AFS_TRACE_LEVEL_VERBOSE,
+                                          "AFSParseName (%p) AFSCheckCellName %wZ returned path not found; ntStatus %08X\n",
+                                          Irp,
+                                          &uniComponentName,
+                                          STATUS_OBJECT_NAME_NOT_FOUND));
+
                             ntStatus = STATUS_OBJECT_NAME_NOT_FOUND;
                         }
 
@@ -3633,10 +4057,10 @@ AFSParseName( IN PIRP Irp,
             if( pNameArray == NULL)
             {
 
-                AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
+                AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING,
                               AFS_TRACE_LEVEL_VERBOSE,
                               "AFSParseName (%p) Failed to initialize name array\n",
-                              Irp);
+                              Irp));
 
                 try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
             }
@@ -3647,10 +4071,10 @@ AFSParseName( IN PIRP Irp,
             if ( ntStatus)
             {
 
-                AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
+                AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING,
                               AFS_TRACE_LEVEL_VERBOSE,
                               "AFSParseName (%p) Failed to insert name array element\n",
-                              Irp);
+                              Irp));
 
                 try_return( ntStatus);
             }
@@ -3711,10 +4135,10 @@ AFSParseName( IN PIRP Irp,
             if( pNameArray == NULL)
             {
 
-                AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
+                AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING,
                               AFS_TRACE_LEVEL_VERBOSE,
                               "AFSParseName (%p) Failed to initialize name array\n",
-                              Irp);
+                              Irp));
 
                 try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
             }
@@ -3785,13 +4209,14 @@ AFSParseName( IN PIRP Irp,
         // Increment our reference on the volume
         //
 
-        lCount = InterlockedIncrement( &pVolumeCB->VolumeReferenceCount);
+        lCount = AFSVolumeIncrement( pVolumeCB,
+                                     AFS_VOLUME_REFERENCE_PARSE_NAME);
 
-        AFSDbgLogMsg( AFS_SUBSYSTEM_VOLUME_REF_COUNTING,
+        AFSDbgTrace(( AFS_SUBSYSTEM_VOLUME_REF_COUNTING,
                       AFS_TRACE_LEVEL_VERBOSE,
                       "AFSParseName Increment2 count on global volume %p Cnt %d\n",
                       pVolumeCB,
-                      lCount);
+                      lCount));
 
 try_exit:
 
@@ -3803,19 +4228,19 @@ try_exit:
 
                 lCount = InterlockedIncrement( &(*ParentDirectoryCB)->DirOpenReferenceCount);
 
-                AFSDbgLogMsg( AFS_SUBSYSTEM_DIRENTRY_REF_COUNTING,
+                AFSDbgTrace(( AFS_SUBSYSTEM_DIRENTRY_REF_COUNTING,
                               AFS_TRACE_LEVEL_VERBOSE,
                               "AFSParseName Increment1 count on %wZ DE %p Ccb %p Cnt %d\n",
                               &(*ParentDirectoryCB)->NameInformation.FileName,
                               (*ParentDirectoryCB),
                               NULL,
-                              lCount);
+                              lCount));
             }
         }
 
         if( *VolumeCB != NULL)
         {
-            ASSERT( (*VolumeCB)->VolumeReferenceCount > 1);
+            ASSERT( (*VolumeCB)->VolumeReferenceCount > 0);
         }
 
         if( ntStatus != STATUS_SUCCESS)
@@ -3905,12 +4330,13 @@ AFSCheckCellName( IN GUID *AuthGroup,
         ntStatus = AFSEvaluateTargetByName( AuthGroup,
                                             &AFSGlobalRoot->ObjectInformation,
                                             CellName,
+                                            0,
                                             &pDirEnumEntry);
 
         if( !NT_SUCCESS( ntStatus))
         {
 
-            AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
+            AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING,
                           AFS_TRACE_LEVEL_WARNING,
                           "AFSCheckCellName entry %wZ does not exist parent FID %08lX-%08lX-%08lX-%08lX Status %08lX\n",
                           CellName,
@@ -3918,7 +4344,7 @@ AFSCheckCellName( IN GUID *AuthGroup,
                           AFSGlobalRoot->ObjectInformation.FileId.Volume,
                           AFSGlobalRoot->ObjectInformation.FileId.Vnode,
                           AFSGlobalRoot->ObjectInformation.FileId.Unique,
-                          ntStatus);
+                          ntStatus));
 
             try_return( ntStatus);
         }
@@ -3949,6 +4375,10 @@ AFSCheckCellName( IN GUID *AuthGroup,
                                            &pDirEnumEntry->FileId,
                                            &pVolumeCB);
 
+            //
+            // On success returns with a volume reference count held
+            //
+
             if( !NT_SUCCESS( ntStatus))
             {
                 try_return( ntStatus);
@@ -3958,21 +4388,22 @@ AFSCheckCellName( IN GUID *AuthGroup,
 
             lCount = InterlockedIncrement( &pVolumeCB->DirectoryCB->DirOpenReferenceCount);
 
-            AFSDbgLogMsg( AFS_SUBSYSTEM_DIRENTRY_REF_COUNTING,
+            AFSDbgTrace(( AFS_SUBSYSTEM_DIRENTRY_REF_COUNTING,
                           AFS_TRACE_LEVEL_VERBOSE,
                           "AFSCheckCellName Increment1 count on %wZ DE %p Ccb %p Cnt %d\n",
                           &pVolumeCB->DirectoryCB->NameInformation.FileName,
                           pVolumeCB->DirectoryCB,
                           NULL,
-                          lCount);
+                          lCount));
 
-            lCount = InterlockedDecrement( &pVolumeCB->VolumeReferenceCount);
+            lCount = AFSVolumeDecrement( pVolumeCB,
+                                         AFS_VOLUME_REFERENCE_BUILD_ROOT);
 
-            AFSDbgLogMsg( AFS_SUBSYSTEM_VOLUME_REF_COUNTING,
+            AFSDbgTrace(( AFS_SUBSYSTEM_VOLUME_REF_COUNTING,
                           AFS_TRACE_LEVEL_VERBOSE,
-                          "AFSCheckCellName Increment count on volume %p Cnt %d\n",
+                          "AFSCheckCellName Decrement count on volume %p Cnt %d\n",
                           pVolumeCB,
-                          lCount);
+                          lCount));
         }
         else
         {
@@ -4027,7 +4458,7 @@ AFSCheckCellName( IN GUID *AuthGroup,
                 {
 
                     AFSDeleteDirEntry( &AFSGlobalRoot->ObjectInformation,
-                                       pDirNode);
+                                       &pDirNode);
 
                     AFSReleaseResource( AFSGlobalRoot->ObjectInformation.Specific.Directory.DirectoryNodeHdr.TreeLock);
 
@@ -4070,7 +4501,7 @@ AFSCheckCellName( IN GUID *AuthGroup,
 
             lCount = InterlockedIncrement( &AFSGlobalRoot->ObjectInformation.Specific.Directory.DirectoryNodeCount);
 
-            AFSDbgLogMsg( AFS_SUBSYSTEM_DIR_NODE_COUNT,
+            AFSDbgTrace(( 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,
@@ -4078,17 +4509,17 @@ AFSCheckCellName( IN GUID *AuthGroup,
                           AFSGlobalRoot->ObjectInformation.FileId.Cell,
                           AFSGlobalRoot->ObjectInformation.FileId.Volume,
                           AFSGlobalRoot->ObjectInformation.FileId.Vnode,
-                          AFSGlobalRoot->ObjectInformation.FileId.Unique);
+                          AFSGlobalRoot->ObjectInformation.FileId.Unique));
 
             lCount = InterlockedIncrement( &pDirNode->DirOpenReferenceCount);
 
-            AFSDbgLogMsg( AFS_SUBSYSTEM_DIRENTRY_REF_COUNTING,
+            AFSDbgTrace(( AFS_SUBSYSTEM_DIRENTRY_REF_COUNTING,
                           AFS_TRACE_LEVEL_VERBOSE,
                           "AFSCheckCellName Increment2 count on %wZ DE %p Ccb %p Cnt %d\n",
                           &pDirNode->NameInformation.FileName,
                           pDirNode,
                           NULL,
-                          lCount);
+                          lCount));
 
             AFSReleaseResource( AFSGlobalRoot->ObjectInformation.Specific.Directory.DirectoryNodeHdr.TreeLock);
 
@@ -4133,14 +4564,14 @@ AFSBuildMountPointTarget( IN GUID *AuthGroup,
         // Loop on each entry, building the chain until we encounter the final target
         //
 
-        AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
+        AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING,
                       AFS_TRACE_LEVEL_VERBOSE_2,
                       "AFSBuildMountPointTarget Building target directory for %wZ FID %08lX-%08lX-%08lX-%08lX\n",
                       &DirectoryCB->NameInformation.FileName,
                       DirectoryCB->ObjectInformation->FileId.Cell,
                       DirectoryCB->ObjectInformation->FileId.Volume,
                       DirectoryCB->ObjectInformation->FileId.Vnode,
-                      DirectoryCB->ObjectInformation->FileId.Unique);
+                      DirectoryCB->ObjectInformation->FileId.Unique));
 
         //
         // Do we need to evaluate the node?
@@ -4154,14 +4585,14 @@ AFSBuildMountPointTarget( IN GUID *AuthGroup,
             // Go evaluate the current target to get the target fid
             //
 
-            AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
+            AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING,
                           AFS_TRACE_LEVEL_VERBOSE_2,
                           "AFSBuildMountPointTarget Evaluating target %wZ FID %08lX-%08lX-%08lX-%08lX\n",
                               &DirectoryCB->NameInformation.FileName,
                               DirectoryCB->ObjectInformation->FileId.Cell,
                               DirectoryCB->ObjectInformation->FileId.Volume,
                               DirectoryCB->ObjectInformation->FileId.Vnode,
-                              DirectoryCB->ObjectInformation->FileId.Unique);
+                              DirectoryCB->ObjectInformation->FileId.Unique));
 
             ntStatus = AFSEvaluateTargetByID( DirectoryCB->ObjectInformation,
                                               AuthGroup,
@@ -4171,11 +4602,12 @@ AFSBuildMountPointTarget( IN GUID *AuthGroup,
             if( !NT_SUCCESS( ntStatus))
             {
 
-                AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
+                AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING,
                               AFS_TRACE_LEVEL_ERROR,
                               "AFSBuildMountPointTarget Failed to evaluate target %wZ Status %08lX\n",
                               &DirectoryCB->NameInformation.FileName,
-                              ntStatus);
+                              ntStatus));
+
                 try_return( ntStatus);
             }
 
@@ -4183,14 +4615,14 @@ AFSBuildMountPointTarget( IN GUID *AuthGroup,
                 pDirEntry->TargetFileId.Unique == 0)
             {
 
-                AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
+                AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING,
                               AFS_TRACE_LEVEL_ERROR,
                               "AFSBuildMountPointTarget Target %wZ FID %08lX-%08lX-%08lX-%08lX service returned zero FID\n",
                               &DirectoryCB->NameInformation.FileName,
                               DirectoryCB->ObjectInformation->FileId.Cell,
                               DirectoryCB->ObjectInformation->FileId.Volume,
                               DirectoryCB->ObjectInformation->FileId.Vnode,
-                              DirectoryCB->ObjectInformation->FileId.Unique);
+                              DirectoryCB->ObjectInformation->FileId.Unique));
 
                 try_return( ntStatus = STATUS_REPARSE_POINT_NOT_RESOLVED);
             }
@@ -4225,19 +4657,19 @@ AFSBuildMountPointTarget( IN GUID *AuthGroup,
 
         ullIndex = AFSCreateHighIndex( &stTargetFileID);
 
-        AFSDbgLogMsg( AFS_SUBSYSTEM_LOCK_PROCESSING,
+        AFSDbgTrace(( AFS_SUBSYSTEM_LOCK_PROCESSING,
                       AFS_TRACE_LEVEL_VERBOSE,
                       "AFSBuildMountPointTarget Acquiring RDR VolumeTreeLock lock %p EXCL %08lX\n",
                       &pDevExt->Specific.RDR.VolumeTreeLock,
-                      PsGetCurrentThread());
+                      PsGetCurrentThread()));
 
         AFSAcquireShared( &pDevExt->Specific.RDR.VolumeTreeLock,
                           TRUE);
 
-        AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
+        AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING,
                       AFS_TRACE_LEVEL_VERBOSE_2,
                       "AFSBuildMountPointTarget Locating volume for target %I64X\n",
-                      ullIndex);
+                      ullIndex));
 
         ntStatus = AFSLocateHashEntry( pDevExt->Specific.RDR.VolumeTree.TreeHead,
                                        ullIndex,
@@ -4261,17 +4693,18 @@ AFSBuildMountPointTarget( IN GUID *AuthGroup,
             // Go init the root of the volume
             //
 
-            AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
+            AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING,
                           AFS_TRACE_LEVEL_VERBOSE_2,
                           "AFSBuildMountPointTarget Initializing root for %wZ FID %08lX-%08lX-%08lX-%08lX\n",
                           &DirectoryCB->NameInformation.FileName,
                           DirectoryCB->ObjectInformation->FileId.Cell,
                           DirectoryCB->ObjectInformation->FileId.Volume,
                           DirectoryCB->ObjectInformation->FileId.Vnode,
-                          DirectoryCB->ObjectInformation->FileId.Unique);
+                          DirectoryCB->ObjectInformation->FileId.Unique));
 
             ntStatus = AFSInitVolume( AuthGroup,
                                       &stTargetFileID,
+                                      AFS_VOLUME_REFERENCE_MOUNTPT,
                                       &pVolumeCB);
 
             if( !NT_SUCCESS( ntStatus))
@@ -4296,13 +4729,14 @@ AFSBuildMountPointTarget( IN GUID *AuthGroup,
             // obtain one to match
             //
 
-            lCount = InterlockedIncrement( &pVolumeCB->VolumeReferenceCount);
+            lCount = AFSVolumeIncrement( pVolumeCB,
+                                         AFS_VOLUME_REFERENCE_MOUNTPT);
 
-            AFSDbgLogMsg( AFS_SUBSYSTEM_VOLUME_REF_COUNTING,
+            AFSDbgTrace(( AFS_SUBSYSTEM_VOLUME_REF_COUNTING,
                           AFS_TRACE_LEVEL_VERBOSE,
                           "AFSBuildMountPointTarget Increment count on volume %p Cnt %d\n",
                           pVolumeCB,
-                          lCount);
+                          lCount));
 
             AFSReleaseResource( &pDevExt->Specific.RDR.VolumeTreeLock);
         }
@@ -4329,13 +4763,14 @@ AFSBuildMountPointTarget( IN GUID *AuthGroup,
             if( !NT_SUCCESS( ntStatus))
             {
 
-                lCount = InterlockedDecrement( &pVolumeCB->VolumeReferenceCount);
+                lCount = AFSVolumeDecrement( pVolumeCB,
+                                             AFS_VOLUME_REFERENCE_MOUNTPT);
 
-                AFSDbgLogMsg( AFS_SUBSYSTEM_VOLUME_REF_COUNTING,
+                AFSDbgTrace(( AFS_SUBSYSTEM_VOLUME_REF_COUNTING,
                               AFS_TRACE_LEVEL_VERBOSE,
                               "AFSBuildMountPoint Decrement count on volume %p Cnt %d\n",
                               pVolumeCB,
-                              lCount);
+                              lCount));
 
                 AFSReleaseResource( pVolumeCB->VolumeLock);
 
@@ -4355,14 +4790,14 @@ AFSBuildMountPointTarget( IN GUID *AuthGroup,
             AFSReleaseResource( pVolumeCB->VolumeLock);
         }
 
-        AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
+        AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING,
                       AFS_TRACE_LEVEL_VERBOSE_2,
                       "AFSBuildMountPointTarget Evaluated target of %wZ FID %08lX-%08lX-%08lX-%08lX as root volume\n",
                       &pVolumeCB->DirectoryCB->NameInformation.FileName,
                       pVolumeCB->ObjectInformation.FileId.Cell,
                       pVolumeCB->ObjectInformation.FileId.Volume,
                       pVolumeCB->ObjectInformation.FileId.Vnode,
-                      pVolumeCB->ObjectInformation.FileId.Unique);
+                      pVolumeCB->ObjectInformation.FileId.Unique));
 
         *TargetVolumeCB = pVolumeCB;
 
@@ -4394,29 +4829,29 @@ AFSBuildRootVolume( IN GUID *AuthGroup,
     __Enter
     {
 
-        AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
+        AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING,
                       AFS_TRACE_LEVEL_VERBOSE_2,
                       "AFSBuildRootVolume Building target volume for FID %08lX-%08lX-%08lX-%08lX\n",
                       FileId->Cell,
                       FileId->Volume,
                       FileId->Vnode,
-                      FileId->Unique);
+                      FileId->Unique));
 
         ullIndex = AFSCreateHighIndex( FileId);
 
-        AFSDbgLogMsg( AFS_SUBSYSTEM_LOCK_PROCESSING,
+        AFSDbgTrace(( AFS_SUBSYSTEM_LOCK_PROCESSING,
                       AFS_TRACE_LEVEL_VERBOSE,
                       "AFSBuildRootVolume Acquiring RDR VolumeTreeLock lock %p EXCL %08lX\n",
                       &pDevExt->Specific.RDR.VolumeTreeLock,
-                      PsGetCurrentThread());
+                      PsGetCurrentThread()));
 
         AFSAcquireShared( &pDevExt->Specific.RDR.VolumeTreeLock,
                           TRUE);
 
-        AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
+        AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING,
                       AFS_TRACE_LEVEL_VERBOSE_2,
                       "AFSBuildRootVolume Locating volume for target %I64X\n",
-                      ullIndex);
+                      ullIndex));
 
         ntStatus = AFSLocateHashEntry( pDevExt->Specific.RDR.VolumeTree.TreeHead,
                                        ullIndex,
@@ -4440,16 +4875,17 @@ AFSBuildRootVolume( IN GUID *AuthGroup,
             // Go init the root of the volume
             //
 
-            AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
+            AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING,
                          AFS_TRACE_LEVEL_VERBOSE_2,
                           "AFSBuildRootVolume Initializing root for FID %08lX-%08lX-%08lX-%08lX\n",
                           FileId->Cell,
                           FileId->Volume,
                           FileId->Vnode,
-                          FileId->Unique);
+                          FileId->Unique));
 
             ntStatus = AFSInitVolume( AuthGroup,
                                       FileId,
+                                      AFS_VOLUME_REFERENCE_BUILD_ROOT,
                                       &pVolumeCB);
 
             if( !NT_SUCCESS( ntStatus))
@@ -4474,13 +4910,14 @@ AFSBuildRootVolume( IN GUID *AuthGroup,
             // obtain one to match
             //
 
-            lCount = InterlockedIncrement( &pVolumeCB->VolumeReferenceCount);
+            lCount = AFSVolumeIncrement( pVolumeCB,
+                                         AFS_VOLUME_REFERENCE_BUILD_ROOT);
 
-            AFSDbgLogMsg( AFS_SUBSYSTEM_VOLUME_REF_COUNTING,
+            AFSDbgTrace(( AFS_SUBSYSTEM_VOLUME_REF_COUNTING,
                           AFS_TRACE_LEVEL_VERBOSE,
                           "AFSBuildRootVolume Increment count on volume %p Cnt %d\n",
                           pVolumeCB,
-                          lCount);
+                          lCount));
 
             AFSReleaseResource( &pDevExt->Specific.RDR.VolumeTreeLock);
         }
@@ -4508,13 +4945,14 @@ AFSBuildRootVolume( IN GUID *AuthGroup,
             if( !NT_SUCCESS( ntStatus))
             {
 
-                lCount = InterlockedDecrement( &pVolumeCB->VolumeReferenceCount);
+                lCount = AFSVolumeDecrement( pVolumeCB,
+                                             AFS_VOLUME_REFERENCE_BUILD_ROOT);
 
-                AFSDbgLogMsg( AFS_SUBSYSTEM_VOLUME_REF_COUNTING,
+                AFSDbgTrace(( AFS_SUBSYSTEM_VOLUME_REF_COUNTING,
                               AFS_TRACE_LEVEL_VERBOSE,
                               "AFSBuildRootVolume Decrement count on volume %p Cnt %d\n",
                               pVolumeCB,
-                              lCount);
+                              lCount));
 
                 AFSReleaseResource( pVolumeCB->VolumeLock);
 
@@ -4534,14 +4972,14 @@ AFSBuildRootVolume( IN GUID *AuthGroup,
             AFSReleaseResource( pVolumeCB->VolumeLock);
         }
 
-        AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
+        AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING,
                       AFS_TRACE_LEVEL_VERBOSE_2,
                       "AFSBuildRootVolume Evaluated target of %wZ FID %08lX-%08lX-%08lX-%08lX as root volume\n",
                       &pVolumeCB->DirectoryCB->NameInformation.FileName,
                       pVolumeCB->ObjectInformation.FileId.Cell,
                       pVolumeCB->ObjectInformation.FileId.Volume,
                       pVolumeCB->ObjectInformation.FileId.Vnode,
-                      pVolumeCB->ObjectInformation.FileId.Unique);
+                      pVolumeCB->ObjectInformation.FileId.Unique));
 
         *TargetVolumeCB = pVolumeCB;
 
@@ -4557,7 +4995,8 @@ NTSTATUS
 AFSProcessDFSLink( IN AFSDirectoryCB *DirEntry,
                    IN PFILE_OBJECT FileObject,
                    IN UNICODE_STRING *RemainingPath,
-                   IN GUID *AuthGroup)
+                   IN GUID *AuthGroup,
+                  OUT PUNICODE_STRING TargetName)
 {
 
     NTSTATUS ntStatus = STATUS_INVALID_DEVICE_REQUEST;
@@ -4569,7 +5008,14 @@ AFSProcessDFSLink( IN AFSDirectoryCB *DirEntry,
     __Enter
     {
 
-        //
+       if ( FileObject != NULL && TargetName != NULL ||
+            FileObject == NULL && TargetName == NULL)
+       {
+
+           try_return( ntStatus = STATUS_INVALID_PARAMETER);
+       }
+
+       //
         // Build up the name to reparse
         //
 
@@ -4598,7 +5044,7 @@ AFSProcessDFSLink( IN AFSDirectoryCB *DirEntry,
                 pDirEntry->TargetNameLength == 0)
             {
 
-                AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
+                AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING,
                               AFS_TRACE_LEVEL_ERROR,
                               "AFSProcessDFSLink EvaluateTargetByID failed for Fcb %wZ FID %08lX-%08lX-%08lX-%08lX Status %08lX\n",
                               &DirEntry->NameInformation.FileName,
@@ -4606,7 +5052,7 @@ AFSProcessDFSLink( IN AFSDirectoryCB *DirEntry,
                               DirEntry->ObjectInformation->FileId.Volume,
                               DirEntry->ObjectInformation->FileId.Vnode,
                               DirEntry->ObjectInformation->FileId.Unique,
-                              ntStatus);
+                              ntStatus));
 
                 if( NT_SUCCESS( ntStatus))
                 {
@@ -4632,7 +5078,7 @@ AFSProcessDFSLink( IN AFSDirectoryCB *DirEntry,
             if( !NT_SUCCESS( ntStatus))
             {
 
-                AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
+                AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING,
                               AFS_TRACE_LEVEL_ERROR,
                               "AFSProcessDFSLink UpdateTargetName failed for Fcb %wZ FID %08lX-%08lX-%08lX-%08lX Status %08lX\n",
                               &DirEntry->NameInformation.FileName,
@@ -4640,7 +5086,7 @@ AFSProcessDFSLink( IN AFSDirectoryCB *DirEntry,
                               DirEntry->ObjectInformation->FileId.Volume,
                               DirEntry->ObjectInformation->FileId.Vnode,
                               DirEntry->ObjectInformation->FileId.Unique,
-                              ntStatus);
+                              ntStatus));
 
                 AFSReleaseResource( &DirEntry->NonPaged->Lock);
 
@@ -4668,8 +5114,8 @@ AFSProcessDFSLink( IN AFSDirectoryCB *DirEntry,
         }
 
         //
-        // Allocate the reparse buffer
-        //
+       // Allocate the reparse buffer (from FS because might be returned in FileObject)
+       //
 
         uniReparseName.Buffer = (WCHAR *)AFSExAllocatePoolWithTag( PagedPool,
                                                                    uniReparseName.MaximumLength,
@@ -4678,7 +5124,7 @@ AFSProcessDFSLink( IN AFSDirectoryCB *DirEntry,
         if( uniReparseName.Buffer == NULL)
         {
 
-            AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
+            AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING,
                           AFS_TRACE_LEVEL_ERROR,
                           "AFSProcessDFSLink uniReparseName.Buffer == NULL Fcb %wZ FID %08lX-%08lX-%08lX-%08lX Status %08lX\n",
                           &DirEntry->NameInformation.FileName,
@@ -4686,7 +5132,7 @@ AFSProcessDFSLink( IN AFSDirectoryCB *DirEntry,
                           DirEntry->ObjectInformation->FileId.Volume,
                           DirEntry->ObjectInformation->FileId.Vnode,
                           DirEntry->ObjectInformation->FileId.Unique,
-                          STATUS_INSUFFICIENT_RESOURCES);
+                          STATUS_INSUFFICIENT_RESOURCES));
 
             AFSReleaseResource( &DirEntry->NonPaged->Lock);
 
@@ -4753,19 +5199,31 @@ AFSProcessDFSLink( IN AFSDirectoryCB *DirEntry,
             uniReparseName.Length += RemainingPath->Length;
         }
 
-        //
-        // Update the name in the file object
-        //
-
-        if( FileObject->FileName.Buffer != NULL)
+       if( FileObject != NULL)
         {
+           //
+           // Update the name in the file object
+           //
+
+           if( FileObject->FileName.Buffer != NULL)
+           {
+
+               //
+               // original FileObject buffer was not allocated by AFS
+               //
+
+               ExFreePoolWithTag( FileObject->FileName.Buffer, 0);
+           }
 
-            AFSExFreePoolWithTag( FileObject->FileName.Buffer, 0);
+           FileObject->FileName = uniReparseName;
         }
+       else
+       {
 
-        FileObject->FileName = uniReparseName;
+           *TargetName = uniReparseName;
+       }
 
-        AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
+        AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING,
                       AFS_TRACE_LEVEL_VERBOSE,
                       "AFSProcessDFSLink Reparsing access to Fcb %wZ FID %08lX-%08lX-%08lX-%08lX to %wZ\n",
                       &DirEntry->NameInformation.FileName,
@@ -4773,7 +5231,7 @@ AFSProcessDFSLink( IN AFSDirectoryCB *DirEntry,
                       DirEntry->ObjectInformation->FileId.Volume,
                       DirEntry->ObjectInformation->FileId.Vnode,
                       DirEntry->ObjectInformation->FileId.Unique,
-                      &uniReparseName);
+                      &uniReparseName));
 
         //
         // Return status reparse ...
@@ -4792,3 +5250,111 @@ try_exit:
 
     return ntStatus;
 }
+
+NTSTATUS
+AFSGetFullFileName( IN AFSFcb *Fcb,
+                   IN AFSCcb *Ccb,
+                   OUT ULONG *FileNameLength,
+                   OUT WCHAR *FileName,
+                   IN OUT LONG *RemainingLength)
+{
+
+    NTSTATUS    ntStatus = STATUS_SUCCESS;
+    ULONG       ulCopyLength = 0;
+    ULONG       cchCopied = 0;
+    BOOLEAN     bAddTrailingSlash = FALSE;
+    USHORT      usFullNameLength = 0;
+
+    __Enter
+    {
+
+       //
+       // Add a trailing slash for anything which is of the form \server\share
+       //
+
+       if( ( Fcb->ObjectInformation->FileType == AFS_FILE_TYPE_DIRECTORY ||
+             Fcb->ObjectInformation->FileType == AFS_FILE_TYPE_MOUNTPOINT) &&
+           Ccb->FullFileName.Length > sizeof( WCHAR) &&
+           Ccb->FullFileName.Buffer[ (Ccb->FullFileName.Length/sizeof( WCHAR)) - 1] != L'\\' &&
+           AFSIsShareName( &Ccb->FullFileName))
+       {
+           bAddTrailingSlash = TRUE;
+       }
+
+       usFullNameLength = sizeof( WCHAR) +
+                                   AFSServerName.Length +
+                                   Ccb->FullFileName.Length;
+
+       if( bAddTrailingSlash)
+       {
+           usFullNameLength += sizeof( WCHAR);
+       }
+
+       if( *RemainingLength >= (LONG)usFullNameLength)
+       {
+           ulCopyLength = (LONG)usFullNameLength;
+       }
+       else
+       {
+
+           ulCopyLength = *RemainingLength;
+
+           ntStatus = STATUS_BUFFER_OVERFLOW;
+       }
+
+       *FileNameLength = (ULONG)usFullNameLength;
+
+       if( ulCopyLength > 0)
+       {
+
+           FileName[ 0] = L'\\';
+           ulCopyLength -= sizeof( WCHAR);
+
+           *RemainingLength -= sizeof( WCHAR);
+           cchCopied += 1;
+
+           if( ulCopyLength >= AFSServerName.Length)
+           {
+
+               RtlCopyMemory( &FileName[ 1],
+                              AFSServerName.Buffer,
+                              AFSServerName.Length);
+
+               ulCopyLength -= AFSServerName.Length;
+               *RemainingLength -= AFSServerName.Length;
+               cchCopied += AFSServerName.Length/sizeof( WCHAR);
+
+               if( ulCopyLength >= Ccb->FullFileName.Length)
+               {
+
+                   RtlCopyMemory( &FileName[ cchCopied],
+                                  Ccb->FullFileName.Buffer,
+                                  Ccb->FullFileName.Length);
+
+                   ulCopyLength -= Ccb->FullFileName.Length;
+                   *RemainingLength -= Ccb->FullFileName.Length;
+                   cchCopied += Ccb->FullFileName.Length/sizeof( WCHAR);
+
+                   if( ulCopyLength > 0 &&
+                       bAddTrailingSlash)
+                   {
+                       FileName[ cchCopied] = L'\\';
+
+                       *RemainingLength -= sizeof( WCHAR);
+                   }
+               }
+               else
+               {
+
+                   RtlCopyMemory( &FileName[ cchCopied],
+                                  Ccb->FullFileName.Buffer,
+                                  ulCopyLength);
+
+                   *RemainingLength -= ulCopyLength;
+               }
+           }
+       }
+    }
+
+    return ntStatus;
+}