Windows: invalidate correct objects during dir verification
[openafs.git] / src / WINNT / afsrdr / kernel / lib / AFSCommSupport.cpp
index 74acdaa..1f684d0 100644 (file)
@@ -60,6 +60,8 @@ AFSEnumerateDirectory( IN GUID *AuthGroup,
     __Enter
     {
 
+        ASSERT( ExIsResourceAcquiredExclusiveLite( ObjectInfoCB->Specific.Directory.DirectoryNodeHdr.TreeLock));
+
         uniGUID.Length = 0;
         uniGUID.MaximumLength = 0;
         uniGUID.Buffer = NULL;
@@ -125,18 +127,31 @@ AFSEnumerateDirectory( IN GUID *AuthGroup,
         {
 
             //
-            // Go and retrieve the directory contents
+            // If the enumeration handle is -1 then we are done
             //
 
-            ntStatus = AFSProcessRequest( AFS_REQUEST_TYPE_DIR_ENUM,
-                                          ulRequestFlags,
-                                          AuthGroup,
-                                          NULL,
-                                          &ObjectInfoCB->FileId,
-                                          (void *)pDirQueryCB,
-                                          sizeof( AFSDirQueryCB),
-                                          pBuffer,
-                                          &ulResultLen);
+            if( ((ULONG)-1) == pDirQueryCB->EnumHandle )
+            {
+
+                ntStatus = STATUS_NO_MORE_ENTRIES;
+            }
+            else
+            {
+
+                //
+                // Go and retrieve the directory contents
+                //
+
+                ntStatus = AFSProcessRequest( AFS_REQUEST_TYPE_DIR_ENUM,
+                                              ulRequestFlags,
+                                              AuthGroup,
+                                              NULL,
+                                              &ObjectInfoCB->FileId,
+                                              (void *)pDirQueryCB,
+                                              sizeof( AFSDirQueryCB),
+                                              pBuffer,
+                                              &ulResultLen);
+            }
 
             if( ntStatus != STATUS_SUCCESS ||
                 ulResultLen == 0)
@@ -147,13 +162,56 @@ AFSEnumerateDirectory( IN GUID *AuthGroup,
                 {
 
                     ntStatus = STATUS_SUCCESS;
+
+                    pDirEnumResponse = (AFSDirEnumResp *)pBuffer;
+
+                    AFSAcquireExcl( ObjectInfoCB->Specific.Directory.DirectoryNodeHdr.TreeLock,
+                                    TRUE);
+
+                    AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
+                                  AFS_TRACE_LEVEL_VERBOSE,
+                                  "AFSEnumerateDirectory Directory Complete FID %08lX-%08lX-%08lX-%08lX Snapshot-DV %08lX:%08lX Current-DV %08lX:%08lX Status %08lX\n",
+                                  ObjectInfoCB->FileId.Cell,
+                                  ObjectInfoCB->FileId.Volume,
+                                  ObjectInfoCB->FileId.Vnode,
+                                  ObjectInfoCB->FileId.Unique,
+                                  pDirEnumResponse->SnapshotDataVersion.HighPart,
+                                  pDirEnumResponse->SnapshotDataVersion.LowPart,
+                                  pDirEnumResponse->CurrentDataVersion.HighPart,
+                                  pDirEnumResponse->CurrentDataVersion.LowPart,
+                                  ntStatus);
+
+                    ObjectInfoCB->DataVersion = pDirEnumResponse->SnapshotDataVersion;
+
+                    if ( pDirEnumResponse->SnapshotDataVersion.QuadPart != pDirEnumResponse->CurrentDataVersion.QuadPart )
+                    {
+
+                        SetFlag( ObjectInfoCB->Flags, AFS_OBJECT_FLAGS_VERIFY);
+
+                        ObjectInfoCB->DataVersion.QuadPart = (ULONGLONG)-1;
+
+                        AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
+                                      AFS_TRACE_LEVEL_VERBOSE,
+                                      "AFSEnumerateDirectory Force Verify due to DV change during enumeration FID %08lX-%08lX-%08lX-%08lX\n",
+                                      ObjectInfoCB->FileId.Cell,
+                                      ObjectInfoCB->FileId.Volume,
+                                      ObjectInfoCB->FileId.Vnode,
+                                      ObjectInfoCB->FileId.Unique);
+                    }
+
+                    AFSReleaseResource( ObjectInfoCB->Specific.Directory.DirectoryNodeHdr.TreeLock);
                 }
                 else
                 {
 
                     AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
-                                  AFS_TRACE_LEVEL_ERROR,
-                                  "AFSEnumerateDirectory Failed to enumerate directory Status %08lX\n",
+                                  AFS_TRACE_LEVEL_VERBOSE,
+                                  "AFSEnumerateDirectory Failed to enumerate directory FID %08lX-%08lX-%08lX-%08lX AuthGroup %wZ Status %08lX\n",
+                                  ObjectInfoCB->FileId.Cell,
+                                  ObjectInfoCB->FileId.Volume,
+                                  ObjectInfoCB->FileId.Vnode,
+                                  ObjectInfoCB->FileId.Unique,
+                                  &uniGUID,
                                   ntStatus);
                 }
 
@@ -164,6 +222,18 @@ AFSEnumerateDirectory( IN GUID *AuthGroup,
 
             pCurrentDirEntry = (AFSDirEnumEntry *)pDirEnumResponse->Entry;
 
+            AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
+                          AFS_TRACE_LEVEL_VERBOSE,
+                          "AFSEnumerateDirectory Enumerating FID %08lX-%08lX-%08lX-%08lX Snapshot-DV %08lX:%08lX Current-DV %08lX:%08lX\n",
+                          ObjectInfoCB->FileId.Cell,
+                          ObjectInfoCB->FileId.Volume,
+                          ObjectInfoCB->FileId.Vnode,
+                          ObjectInfoCB->FileId.Unique,
+                          pDirEnumResponse->SnapshotDataVersion.HighPart,
+                          pDirEnumResponse->SnapshotDataVersion.LowPart,
+                          pDirEnumResponse->CurrentDataVersion.HighPart,
+                          pDirEnumResponse->CurrentDataVersion.LowPart);
+
             //
             // Remove the leading header from the processed length
             //
@@ -200,25 +270,103 @@ AFSEnumerateDirectory( IN GUID *AuthGroup,
                 {
 
                     //
-                    // Duplicate entry, skip it
+                    // Check that the FIDs are the same
                     //
 
-                    ulEntryLength = QuadAlign( sizeof( AFSDirEnumEntry) +
-                                                    uniDirName.Length +
-                                                    uniTargetName.Length);
+                    if( AFSIsEqualFID( &pCurrentDirEntry->FileId,
+                                       &pDirNode->ObjectInformation->FileId))
+                    {
 
-                    pCurrentDirEntry = (AFSDirEnumEntry *)((char *)pCurrentDirEntry + ulEntryLength);
+                        //
+                        // Duplicate entry, skip it
+                        //
 
-                    if( ulResultLen >= ulEntryLength)
-                    {
-                        ulResultLen -= ulEntryLength;
+                        ulEntryLength = QuadAlign( sizeof( AFSDirEnumEntry) +
+                                                   uniDirName.Length +
+                                                   uniTargetName.Length);
+
+                        pCurrentDirEntry = (AFSDirEnumEntry *)((char *)pCurrentDirEntry + ulEntryLength);
+
+                        if( ulResultLen >= ulEntryLength)
+                        {
+                            ulResultLen -= ulEntryLength;
+                        }
+                        else
+                        {
+                            ulResultLen = 0;
+                        }
+
+                        //
+                        // Update the metadata for the entry
+                        //
+
+                        if( pDirNode->ObjectInformation->DataVersion.QuadPart != pCurrentDirEntry->DataVersion.QuadPart)
+                        {
+
+                            AFSInvalidateObject( &pDirNode->ObjectInformation,
++                                                 AFS_INVALIDATE_DATA_VERSION);
+                        }
+                        else
+                        {
+
+                            AFSUpdateMetaData( pDirNode,
+                                               pCurrentDirEntry);
+                        }
+
+                        continue;
                     }
                     else
                     {
-                        ulResultLen = 0;
-                    }
 
-                    continue;
+                        //
+                        // Need to tear down this entry and rebuild it below
+                        //
+
+                        if( pDirNode->OpenReferenceCount == 0)
+                        {
+
+                            AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
+                                          AFS_TRACE_LEVEL_VERBOSE,
+                                          "AFSEnumerateDirectory Different FIDs - Deleting DE %p for %wZ Old FID %08lX-%08lX-%08lX-%08lX New FID %08lX-%08lX-%08lX-%08lX\n",
+                                          pDirNode,
+                                          &pDirNode->NameInformation.FileName,
+                                          pDirNode->ObjectInformation->FileId.Cell,
+                                          pDirNode->ObjectInformation->FileId.Volume,
+                                          pDirNode->ObjectInformation->FileId.Vnode,
+                                          pDirNode->ObjectInformation->FileId.Unique,
+                                          pCurrentDirEntry->FileId.Cell,
+                                          pCurrentDirEntry->FileId.Volume,
+                                          pCurrentDirEntry->FileId.Vnode,
+                                          pCurrentDirEntry->FileId.Unique);
+
+                            AFSDeleteDirEntry( ObjectInfoCB,
+                                               pDirNode);
+                        }
+                        else
+                        {
+
+                            SetFlag( pDirNode->Flags, AFS_DIR_ENTRY_DELETED);
+
+                            AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
+                                          AFS_TRACE_LEVEL_VERBOSE,
+                                          "AFSEnumerateDirectory Different FIDs - Removing DE %p for %wZ Old FID %08lX-%08lX-%08lX-%08lX New FID %08lX-%08lX-%08lX-%08lX\n",
+                                          pDirNode,
+                                          &pDirNode->NameInformation.FileName,
+                                          pDirNode->ObjectInformation->FileId.Cell,
+                                          pDirNode->ObjectInformation->FileId.Volume,
+                                          pDirNode->ObjectInformation->FileId.Vnode,
+                                          pDirNode->ObjectInformation->FileId.Unique,
+                                          pCurrentDirEntry->FileId.Cell,
+                                          pCurrentDirEntry->FileId.Volume,
+                                          pCurrentDirEntry->FileId.Vnode,
+                                          pCurrentDirEntry->FileId.Unique);
+
+                            AFSRemoveNameEntry( ObjectInfoCB,
+                                                pDirNode);
+                        }
+
+                        pDirNode = NULL;
+                    }
                 }
 
                 pDirNode = AFSInitDirEntry( ObjectInfoCB,
@@ -235,13 +383,38 @@ AFSEnumerateDirectory( IN GUID *AuthGroup,
                     break;
                 }
 
+                AFSUpdateMetaData( pDirNode,
+                                   pCurrentDirEntry);
+
+                if( pDirNode->ObjectInformation->FileType == AFS_FILE_TYPE_DIRECTORY)
+                {
+
+                    AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
+                                  AFS_TRACE_LEVEL_VERBOSE,
+                                  "AFSEnumerateDirectory Setting VERIFY on entry %wZ for FID %08lX-%08lX-%08lX-%08lX\n",
+                                  &uniDirName,
+                                  pDirNode->ObjectInformation->FileId.Cell,
+                                  pDirNode->ObjectInformation->FileId.Volume,
+                                  pDirNode->ObjectInformation->FileId.Vnode,
+                                  pDirNode->ObjectInformation->FileId.Unique);
+
+                    AFSAcquireExcl( pDirNode->ObjectInformation->Specific.Directory.DirectoryNodeHdr.TreeLock,
+                                    TRUE);
+
+                    SetFlag( pDirNode->ObjectInformation->Flags, AFS_OBJECT_FLAGS_VERIFY);
+
+                    pDirNode->ObjectInformation->DataVersion.QuadPart = (ULONGLONG)-1;
+
+                    AFSReleaseResource( pDirNode->ObjectInformation->Specific.Directory.DirectoryNodeHdr.TreeLock);
+                }
+
                 //
                 // Set up the entry length
                 //
 
                 ulEntryLength = QuadAlign( sizeof( AFSDirEnumEntry) +
-                                                    pCurrentDirEntry->FileNameLength +
-                                                    pCurrentDirEntry->TargetNameLength);
+                                           pCurrentDirEntry->FileNameLength +
+                                           pCurrentDirEntry->TargetNameLength);
 
                 //
                 // Init the short name if we have one
@@ -263,33 +436,98 @@ AFSEnumerateDirectory( IN GUID *AuthGroup,
                     //
 
                     uniShortName.Length = pDirNode->NameInformation.ShortNameLength;
+                    uniShortName.MaximumLength = uniShortName.Length;
                     uniShortName.Buffer = pDirNode->NameInformation.ShortName;
 
-                    pDirNode->Type.Data.ShortNameTreeEntry.HashIndex = AFSGenerateCRC( &uniShortName,
-                                                                                       TRUE);
+                    if( !RtlIsNameLegalDOS8Dot3( &pDirNode->NameInformation.FileName,
+                                                 NULL,
+                                                 NULL))
+                    {
+
+                        pDirNode->Type.Data.ShortNameTreeEntry.HashIndex = AFSGenerateCRC( &uniShortName,
+                                                                                           TRUE);
+
+                        AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
+                                      AFS_TRACE_LEVEL_VERBOSE,
+                                      "AFSEnumerateDirectory Initialized short name %wZ for DE %p for %wZ FID %08lX-%08lX-%08lX-%08lX\n",
+                                      &uniShortName,
+                                      pDirNode,
+                                      &pDirNode->NameInformation.FileName,
+                                      pCurrentDirEntry->FileId.Cell,
+                                      pCurrentDirEntry->FileId.Volume,
+                                      pCurrentDirEntry->FileId.Vnode,
+                                      pCurrentDirEntry->FileId.Unique);
+                    }
+                    else
+                    {
+                        pDirNode->NameInformation.ShortNameLength = 0;
+
+                        RtlZeroMemory( pDirNode->NameInformation.ShortName,
+                                       (12 * sizeof( WCHAR)));
+                    }
                 }
 
                 //
                 // Insert the node into the name tree
                 //
 
-                ASSERT( ExIsResourceAcquiredExclusiveLite( ObjectInfoCB->Specific.Directory.DirectoryNodeHdr.TreeLock));
-
                 if( ObjectInfoCB->Specific.Directory.DirectoryNodeHdr.CaseSensitiveTreeHead == NULL)
                 {
 
                     ObjectInfoCB->Specific.Directory.DirectoryNodeHdr.CaseSensitiveTreeHead = pDirNode;
+
+                    AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
+                                  AFS_TRACE_LEVEL_VERBOSE,
+                                  "AFSEnumerateDirectory Insert DE %p to head of case sensitive tree for %wZ\n",
+                                  pDirNode,
+                                  &pDirNode->NameInformation.FileName);
                 }
                 else
                 {
 
-                    AFSInsertCaseSensitiveDirEntry( ObjectInfoCB->Specific.Directory.DirectoryNodeHdr.CaseSensitiveTreeHead,
-                                                    pDirNode);
+                    AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
+                                  AFS_TRACE_LEVEL_VERBOSE,
+                                  "AFSEnumerateDirectory Insert DE %p to case sensitive tree for %wZ\n",
+                                  pDirNode,
+                                  &pDirNode->NameInformation.FileName);
+
+                    if( !NT_SUCCESS( AFSInsertCaseSensitiveDirEntry( ObjectInfoCB->Specific.Directory.DirectoryNodeHdr.CaseSensitiveTreeHead,
+                                                                     pDirNode)))
+                    {
+
+                        //
+                        // Delete this dir entry and continue on
+                        //
+
+                        AFSDeleteDirEntry( ObjectInfoCB,
+                                           pDirNode);
+
+                        pCurrentDirEntry = (AFSDirEnumEntry *)((char *)pCurrentDirEntry + ulEntryLength);
+
+                        if( ulResultLen >= ulEntryLength)
+                        {
+                            ulResultLen -= ulEntryLength;
+                        }
+                        else
+                        {
+                            ulResultLen = 0;
+                        }
+
+                        continue;
+                    }
                 }
 
+                ClearFlag( pDirNode->Flags, AFS_DIR_ENTRY_NOT_IN_PARENT_TREE);
+
                 if( ObjectInfoCB->Specific.Directory.DirectoryNodeHdr.CaseInsensitiveTreeHead == NULL)
                 {
 
+                    AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
+                                  AFS_TRACE_LEVEL_VERBOSE,
+                                  "AFSEnumerateDirectory Insert DE %p to head of case insensitive tree for %wZ\n",
+                                  pDirNode,
+                                  &pDirNode->NameInformation.FileName);
+
                     ObjectInfoCB->Specific.Directory.DirectoryNodeHdr.CaseInsensitiveTreeHead = pDirNode;
 
                     SetFlag( pDirNode->Flags, AFS_DIR_ENTRY_CASE_INSENSTIVE_LIST_HEAD);
@@ -297,6 +535,12 @@ AFSEnumerateDirectory( IN GUID *AuthGroup,
                 else
                 {
 
+                    AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
+                                  AFS_TRACE_LEVEL_VERBOSE,
+                                  "AFSEnumerateDirectory Insert DE %p to case insensitive tree for %wZ\n",
+                                  pDirNode,
+                                  &pDirNode->NameInformation.FileName);
+
                     AFSInsertCaseInsensitiveDirEntry( ObjectInfoCB->Specific.Directory.DirectoryNodeHdr.CaseInsensitiveTreeHead,
                                                       pDirNode);
                 }
@@ -340,13 +584,30 @@ AFSEnumerateDirectory( IN GUID *AuthGroup,
                     if( ObjectInfoCB->Specific.Directory.ShortNameTree == NULL)
                     {
 
+                        AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
+                                      AFS_TRACE_LEVEL_VERBOSE,
+                                      "AFSEnumerateDirectory Insert DE %p to head of shortname tree for %wZ\n",
+                                      pDirNode,
+                                      &pDirNode->NameInformation.FileName);
+
                         ObjectInfoCB->Specific.Directory.ShortNameTree = pDirNode;
+
+                        SetFlag( pDirNode->Flags, AFS_DIR_ENTRY_INSERTED_SHORT_NAME);
                     }
                     else
                     {
 
-                        AFSInsertShortNameDirEntry( ObjectInfoCB->Specific.Directory.ShortNameTree,
-                                                    pDirNode);
+                        if( NT_SUCCESS( AFSInsertShortNameDirEntry( ObjectInfoCB->Specific.Directory.ShortNameTree,
+                                                                    pDirNode)))
+                        {
+                            SetFlag( pDirNode->Flags, AFS_DIR_ENTRY_INSERTED_SHORT_NAME);
+
+                            AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
+                                          AFS_TRACE_LEVEL_VERBOSE,
+                                          "AFSEnumerateDirectory Insert DE %p to shortname tree for %wZ\n",
+                                          pDirNode,
+                                          &pDirNode->NameInformation.FileName);
+                        }
                     }
                 }
 
@@ -379,16 +640,6 @@ AFSEnumerateDirectory( IN GUID *AuthGroup,
                           AFS_TRACE_LEVEL_VERBOSE,
                           "AFSEnumerateDirectory EnumHandle %08lX\n",
                           pDirQueryCB->EnumHandle);
-
-            //
-            // If the enumeration handle is -1 then we are done
-            //
-
-            if( ((ULONG)-1) == pDirQueryCB->EnumHandle )
-            {
-
-                break;
-            }
         }
 
 try_exit:
@@ -501,6 +752,8 @@ AFSVerifyDirectoryContent( IN AFSObjectInfoCB *ObjectInfoCB,
     __Enter
     {
 
+        ASSERT( ExIsResourceAcquiredExclusiveLite( ObjectInfoCB->Specific.Directory.DirectoryNodeHdr.TreeLock));
+
         uniGUID.Length = 0;
         uniGUID.MaximumLength = 0;
         uniGUID.Buffer = NULL;
@@ -560,18 +813,31 @@ AFSVerifyDirectoryContent( IN AFSObjectInfoCB *ObjectInfoCB,
         {
 
             //
-            // Go and retrieve the directory contents
+            // If the enumeration handle is -1 then we are done
             //
 
-            ntStatus = AFSProcessRequest( AFS_REQUEST_TYPE_DIR_ENUM,
-                                          ulRequestFlags,
-                                          AuthGroup,
-                                          NULL,
-                                          &ObjectInfoCB->FileId,
-                                          (void *)pDirQueryCB,
-                                          sizeof( AFSDirQueryCB),
-                                          pBuffer,
-                                          &ulResultLen);
+            if( ((ULONG)-1) == pDirQueryCB->EnumHandle )
+            {
+
+                ntStatus = STATUS_NO_MORE_ENTRIES;
+            }
+            else
+            {
+
+                //
+                // Go and retrieve the directory contents
+                //
+
+                ntStatus = AFSProcessRequest( AFS_REQUEST_TYPE_DIR_ENUM,
+                                              ulRequestFlags,
+                                              AuthGroup,
+                                              NULL,
+                                              &ObjectInfoCB->FileId,
+                                              (void *)pDirQueryCB,
+                                              sizeof( AFSDirQueryCB),
+                                              pBuffer,
+                                              &ulResultLen);
+            }
 
             if( ntStatus != STATUS_SUCCESS ||
                 ulResultLen == 0)
@@ -581,14 +847,60 @@ AFSVerifyDirectoryContent( IN AFSObjectInfoCB *ObjectInfoCB,
                     ntStatus == STATUS_NO_MORE_ENTRIES)
                 {
 
+                    pDirEnumResponse = (AFSDirEnumResp *)pBuffer;
+
+                    AFSAcquireExcl( ObjectInfoCB->Specific.Directory.DirectoryNodeHdr.TreeLock,
+                                    TRUE);
+
+                    AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
+                                  AFS_TRACE_LEVEL_VERBOSE,
+                                  "AFSVerifyDirectoryContent Directory Complete FID %08lX-%08lX-%08lX-%08lX Snapshot-DV %08lX:%08lX Current-DV %08lX:%08lX Status %08lX\n",
+                                  ObjectInfoCB->FileId.Cell,
+                                  ObjectInfoCB->FileId.Volume,
+                                  ObjectInfoCB->FileId.Vnode,
+                                  ObjectInfoCB->FileId.Unique,
+                                  pDirEnumResponse->SnapshotDataVersion.HighPart,
+                                  pDirEnumResponse->SnapshotDataVersion.LowPart,
+                                  pDirEnumResponse->CurrentDataVersion.HighPart,
+                                  pDirEnumResponse->CurrentDataVersion.LowPart,
+                                  ntStatus);
+
                     ntStatus = STATUS_SUCCESS;
+
+                    if ( pDirEnumResponse->SnapshotDataVersion.QuadPart != pDirEnumResponse->CurrentDataVersion.QuadPart )
+                    {
+
+                        SetFlag( ObjectInfoCB->Flags, AFS_OBJECT_FLAGS_VERIFY);
+
+                        ObjectInfoCB->DataVersion.QuadPart = (ULONGLONG)-1;
+
+                        AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
+                                      AFS_TRACE_LEVEL_VERBOSE,
+                                      "AFSVerifyDirectoryContent Force Verify due to DV change during enumeration FID %08lX-%08lX-%08lX-%08lX\n",
+                                      ObjectInfoCB->FileId.Cell,
+                                      ObjectInfoCB->FileId.Volume,
+                                      ObjectInfoCB->FileId.Vnode,
+                                      ObjectInfoCB->FileId.Unique);
+                    }
+                    else
+                    {
+
+                        ObjectInfoCB->DataVersion = pDirEnumResponse->SnapshotDataVersion;
+                    }
+
+                    AFSReleaseResource( ObjectInfoCB->Specific.Directory.DirectoryNodeHdr.TreeLock);
                 }
                 else
                 {
 
                     AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
                                   AFS_TRACE_LEVEL_ERROR,
-                                  "AFSVerifyDirectoryContent Failed to enumerate directory Status %08lX\n",
+                                  "AFSVerifyDirectoryContent Failed to enumerate directory FID %08lX-%08lX-%08lX-%08lX AuthGroup %wZ Status %08lX\n",
+                                  ObjectInfoCB->FileId.Cell,
+                                  ObjectInfoCB->FileId.Volume,
+                                  ObjectInfoCB->FileId.Vnode,
+                                  ObjectInfoCB->FileId.Unique,
+                                  &uniGUID,
                                   ntStatus);
                 }
 
@@ -599,6 +911,18 @@ AFSVerifyDirectoryContent( IN AFSObjectInfoCB *ObjectInfoCB,
 
             pCurrentDirEntry = (AFSDirEnumEntry *)pDirEnumResponse->Entry;
 
+            AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
+                          AFS_TRACE_LEVEL_VERBOSE,
+                          "AFSVerifyDirectoryContent EnumResponse FID %08lX-%08lX-%08lX-%08lX Snapshot-DV %08lX:%08lX Current-DV %08lX:%08lX\n",
+                          ObjectInfoCB->FileId.Cell,
+                          ObjectInfoCB->FileId.Volume,
+                          ObjectInfoCB->FileId.Vnode,
+                          ObjectInfoCB->FileId.Unique,
+                          pDirEnumResponse->SnapshotDataVersion.HighPart,
+                          pDirEnumResponse->SnapshotDataVersion.LowPart,
+                          pDirEnumResponse->CurrentDataVersion.HighPart,
+                          pDirEnumResponse->CurrentDataVersion.LowPart);
+
             //
             // Remove the leading header from the processed length
             //
@@ -627,8 +951,6 @@ AFSVerifyDirectoryContent( IN AFSObjectInfoCB *ObjectInfoCB,
                 ulCRC = AFSGenerateCRC( &uniDirName,
                                         FALSE);
 
-                ASSERT( ExIsResourceAcquiredExclusiveLite( ObjectInfoCB->Specific.Directory.DirectoryNodeHdr.TreeLock));
-
                 AFSLocateCaseSensitiveDirEntry( ObjectInfoCB->Specific.Directory.DirectoryNodeHdr.CaseSensitiveTreeHead,
                                                 ulCRC,
                                                 &pDirNode);
@@ -642,99 +964,139 @@ AFSVerifyDirectoryContent( IN AFSObjectInfoCB *ObjectInfoCB,
                                            pCurrentDirEntry->FileNameLength +
                                            pCurrentDirEntry->TargetNameLength);
 
-                if( pDirNode != NULL)
+                if( pDirNode &&
+                    AFSIsEqualFID( &pCurrentDirEntry->FileId,
+                                   &pDirNode->ObjectInformation->FileId))
                 {
 
                     //
-                    // Check that the FIDs are the same
+                    // Found matching directory entry by name and FileID
                     //
 
-                    if( AFSIsEqualFID( &pCurrentDirEntry->FileId,
-                                       &pDirNode->ObjectInformation->FileId))
-                    {
+                    AFSAcquireShared( ObjectInfoCB->VolumeCB->ObjectInfoTree.TreeLock,
+                                      TRUE);
 
-                        AFSAcquireShared( ObjectInfoCB->VolumeCB->ObjectInfoTree.TreeLock,
-                                          TRUE);
+                    ullIndex = AFSCreateLowIndex( &pCurrentDirEntry->FileId);
 
-                        ullIndex = AFSCreateLowIndex( &pCurrentDirEntry->FileId);
+                    ntStatus = AFSLocateHashEntry( ObjectInfoCB->VolumeCB->ObjectInfoTree.TreeHead,
+                                                   ullIndex,
+                                                   (AFSBTreeEntry **)&pObjectInfo);
 
-                        ntStatus = AFSLocateHashEntry( ObjectInfoCB->VolumeCB->ObjectInfoTree.TreeHead,
-                                                       ullIndex,
-                                                       (AFSBTreeEntry **)&pObjectInfo);
+                    AFSReleaseResource( ObjectInfoCB->VolumeCB->ObjectInfoTree.TreeLock);
 
-                        AFSReleaseResource( ObjectInfoCB->VolumeCB->ObjectInfoTree.TreeLock);
+                    if( NT_SUCCESS( ntStatus) &&
+                        pObjectInfo != NULL)
+                    {
 
-                        if( NT_SUCCESS( ntStatus) &&
-                            pObjectInfo != NULL)
-                        {
+                        //
+                        // Indicate this is a valid entry
+                        //
 
-                            //
-                            // Indicate this is a valid entry
-                            //
+                        SetFlag( pDirNode->Flags, AFS_DIR_ENTRY_VALID);
 
-                            SetFlag( pDirNode->Flags, AFS_DIR_ENTRY_VALID);
+                        if( pCurrentDirEntry->ShortNameLength > 0 &&
+                            pDirNode->NameInformation.ShortNameLength > 0)
+                        {
+                            AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
+                                          AFS_TRACE_LEVEL_VERBOSE,
+                                          "AFSVerifyDirectoryContent Verified entry %wZ (%wZ) parent FID %08lX-%08lX-%08lX-%08lX old short name %S New short name %S\n",
+                                          &uniDirName,
+                                          &pDirNode->NameInformation.FileName,
+                                          ObjectInfoCB->FileId.Cell,
+                                          ObjectInfoCB->FileId.Volume,
+                                          ObjectInfoCB->FileId.Vnode,
+                                          ObjectInfoCB->FileId.Unique,
+                                          pDirNode->NameInformation.ShortName,
+                                          pCurrentDirEntry->ShortName);
+                        }
+                        else if( pCurrentDirEntry->ShortNameLength == 0 &&
+                                 pDirNode->NameInformation.ShortNameLength > 0)
+                        {
 
                             AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
                                           AFS_TRACE_LEVEL_VERBOSE,
-                                          "AFSVerifyDirectoryContent Verified entry %wZ for parent FID %08lX-%08lX-%08lX-%08lX\n",
+                                          "AFSVerifyDirectoryContent Verified entry %wZ (%wZ) parent FID %08lX-%08lX-%08lX-%08lX old short name %S New short name NULL\n",
+                                          &uniDirName,
+                                          &pDirNode->NameInformation.FileName,
+                                          ObjectInfoCB->FileId.Cell,
+                                          ObjectInfoCB->FileId.Volume,
+                                          ObjectInfoCB->FileId.Vnode,
+                                          ObjectInfoCB->FileId.Unique,
+                                          pDirNode->NameInformation.ShortName);
+                        }
+                        else if( pCurrentDirEntry->ShortNameLength > 0 &&
+                                 pDirNode->NameInformation.ShortNameLength == 0)
+                        {
+                            AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
+                                          AFS_TRACE_LEVEL_VERBOSE,
+                                          "AFSVerifyDirectoryContent Verified entry %wZ (%wZ) parent FID %08lX-%08lX-%08lX-%08lX old short name NULL New short name %S\n",
                                           &uniDirName,
+                                          &pDirNode->NameInformation.FileName,
+                                          ObjectInfoCB->FileId.Cell,
+                                          ObjectInfoCB->FileId.Volume,
+                                          ObjectInfoCB->FileId.Vnode,
+                                          ObjectInfoCB->FileId.Unique,
+                                          pCurrentDirEntry->ShortName);
+                        }
+                        else
+                        {
+                            AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
+                                          AFS_TRACE_LEVEL_VERBOSE,
+                                          "AFSVerifyDirectoryContent Verified entry %wZ (%wZ) parent FID %08lX-%08lX-%08lX-%08lX old short name NULL New short name NULL\n",
+                                          &uniDirName,
+                                          &pDirNode->NameInformation.FileName,
                                           ObjectInfoCB->FileId.Cell,
                                           ObjectInfoCB->FileId.Volume,
                                           ObjectInfoCB->FileId.Vnode,
                                           ObjectInfoCB->FileId.Unique);
+                        }
 
+                        //
+                        // Update the metadata for the entry
+                        //
 
-                            //
-                            // Update the metadata for the entry
-                            //
-
-                            if( pObjectInfo->DataVersion.QuadPart == 0 ||
-                                pObjectInfo->DataVersion.QuadPart != pCurrentDirEntry->DataVersion.QuadPart)
-                            {
-
-                                AFSUpdateMetaData( pDirNode,
-                                                   pCurrentDirEntry);
-
-                                if( pObjectInfo->FileType == AFS_FILE_TYPE_DIRECTORY)
-                                {
-
-                                    AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
-                                                  AFS_TRACE_LEVEL_VERBOSE,
-                                                  "AFSVerifyDirectoryContent Setting VERIFY on entry %wZ for FID %08lX-%08lX-%08lX-%08lX\n",
-                                                  &uniDirName,
-                                                  ObjectInfoCB->FileId.Cell,
-                                                  ObjectInfoCB->FileId.Volume,
-                                                  ObjectInfoCB->FileId.Vnode,
-                                                  ObjectInfoCB->FileId.Unique);
+                        if( pObjectInfo->DataVersion.QuadPart != pCurrentDirEntry->DataVersion.QuadPart)
+                        {
 
-                                    SetFlag( pObjectInfo->Flags, AFS_OBJECT_FLAGS_VERIFY);
-                                    pObjectInfo->DataVersion.QuadPart = (ULONGLONG)-1;
-                                    pObjectInfo->Expiration.QuadPart = 0;
-                                }
-                            }
+                            AFSInvalidateObject( &pObjectInfo,
+                                                 AFS_INVALIDATE_DATA_VERSION);
+                        }
+                        else
+                        {
 
-                            //
-                            // Next dir entry
-                            //
+                            AFSUpdateMetaData( pDirNode,
+                                               pCurrentDirEntry);
+                        }
 
-                            pCurrentDirEntry = (AFSDirEnumEntry *)((char *)pCurrentDirEntry + ulEntryLength);
+                        //
+                        // Next dir entry
+                        //
 
-                            if( ulResultLen >= ulEntryLength)
-                            {
-                                ulResultLen -= ulEntryLength;
-                            }
-                            else
-                            {
-                                ulResultLen = 0;
-                            }
+                        pCurrentDirEntry = (AFSDirEnumEntry *)((char *)pCurrentDirEntry + ulEntryLength);
 
-                            continue;
+                        if( ulResultLen >= ulEntryLength)
+                        {
+                            ulResultLen -= ulEntryLength;
+                        }
+                        else
+                        {
+                            ulResultLen = 0;
                         }
+
+                        continue;
                     }
+                }
+                else if ( pDirNode)
+                {
+
+                    //
+                    // File name matches but FileID does not.
+                    //
 
                     AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
                                   AFS_TRACE_LEVEL_VERBOSE,
-                                  "AFSVerifyDirectoryContent Processing dir entry %wZ with different FID, same name in parent FID %08lX-%08lX-%08lX-%08lX\n",
+                                  "AFSVerifyDirectoryContent Processing dir entry %p %wZ with different FID, same name in parent FID %08lX-%08lX-%08lX-%08lX\n",
+                                  pDirNode,
                                   &pDirNode->NameInformation.FileName,
                                   ObjectInfoCB->FileId.Cell,
                                   ObjectInfoCB->FileId.Volume,
@@ -750,12 +1112,17 @@ AFSVerifyDirectoryContent( IN AFSObjectInfoCB *ObjectInfoCB,
 
                         AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
                                       AFS_TRACE_LEVEL_VERBOSE,
-                                      "AFSVerifyDirectoryContent Deleting dir entry %wZ from parent FID %08lX-%08lX-%08lX-%08lX\n",
+                                      "AFSVerifyDirectoryContent Different FIDs - Deleting DE %p for %wZ Old FID %08lX-%08lX-%08lX-%08lX New FID %08lX-%08lX-%08lX-%08lX\n",
+                                      pDirNode,
                                       &pDirNode->NameInformation.FileName,
-                                      ObjectInfoCB->FileId.Cell,
-                                      ObjectInfoCB->FileId.Volume,
-                                      ObjectInfoCB->FileId.Vnode,
-                                      ObjectInfoCB->FileId.Unique);
+                                      pDirNode->ObjectInformation->FileId.Cell,
+                                      pDirNode->ObjectInformation->FileId.Volume,
+                                      pDirNode->ObjectInformation->FileId.Vnode,
+                                      pDirNode->ObjectInformation->FileId.Unique,
+                                      pCurrentDirEntry->FileId.Cell,
+                                      pCurrentDirEntry->FileId.Volume,
+                                      pCurrentDirEntry->FileId.Vnode,
+                                      pCurrentDirEntry->FileId.Unique);
 
                         AFSDeleteDirEntry( ObjectInfoCB,
                                            pDirNode);
@@ -763,22 +1130,38 @@ AFSVerifyDirectoryContent( IN AFSObjectInfoCB *ObjectInfoCB,
                     else
                     {
 
+                        SetFlag( pDirNode->Flags, AFS_DIR_ENTRY_DELETED);
+
                         AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
-                                      AFS_TRACE_LEVEL_VERBOSE,
-                                      "AFSVerifyDirectoryContent Setting dir entry %p name %wZ DELETED in parent FID %08lX-%08lX-%08lX-%08lX\n",
+                                      AFS_TRACE_LEVEL_WARNING,
+                                      "AFSVerifyDirectoryContent Different FIDs - removing DE %p for %wZ Old FID %08lX-%08lX-%08lX-%08lX New FID %08lX-%08lX-%08lX-%08lX\n",
                                       pDirNode,
                                       &pDirNode->NameInformation.FileName,
-                                      ObjectInfoCB->FileId.Cell,
-                                      ObjectInfoCB->FileId.Volume,
-                                      ObjectInfoCB->FileId.Vnode,
-                                      ObjectInfoCB->FileId.Unique);
-
-                        SetFlag( pDirNode->Flags, AFS_DIR_ENTRY_DELETED);
+                                      pDirNode->ObjectInformation->FileId.Cell,
+                                      pDirNode->ObjectInformation->FileId.Volume,
+                                      pDirNode->ObjectInformation->FileId.Vnode,
+                                      pDirNode->ObjectInformation->FileId.Unique,
+                                      pCurrentDirEntry->FileId.Cell,
+                                      pCurrentDirEntry->FileId.Volume,
+                                      pCurrentDirEntry->FileId.Vnode,
+                                      pCurrentDirEntry->FileId.Unique);
 
                         AFSRemoveNameEntry( ObjectInfoCB,
                                             pDirNode);
                     }
                 }
+                else
+                {
+
+                    AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
+                                  AFS_TRACE_LEVEL_VERBOSE,
+                                  "AFSVerifyDirectoryContent New entry %wZ for parent FID %08lX-%08lX-%08lX-%08lX\n",
+                                  &uniDirName,
+                                  ObjectInfoCB->FileId.Cell,
+                                  ObjectInfoCB->FileId.Volume,
+                                  ObjectInfoCB->FileId.Vnode,
+                                  ObjectInfoCB->FileId.Unique);
+                }
 
                 pDirNode = AFSInitDirEntry( ObjectInfoCB,
                                             &uniDirName,
@@ -794,6 +1177,31 @@ AFSVerifyDirectoryContent( IN AFSObjectInfoCB *ObjectInfoCB,
                     break;
                 }
 
+                AFSUpdateMetaData( pDirNode,
+                                   pCurrentDirEntry);
+
+                if( pDirNode->ObjectInformation->FileType == AFS_FILE_TYPE_DIRECTORY)
+                {
+
+                    AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
+                                  AFS_TRACE_LEVEL_VERBOSE,
+                                  "AFSVerifyDirectoryContent Setting VERIFY on entry %wZ for FID %08lX-%08lX-%08lX-%08lX\n",
+                                  &uniDirName,
+                                  pDirNode->ObjectInformation->FileId.Cell,
+                                  pDirNode->ObjectInformation->FileId.Volume,
+                                  pDirNode->ObjectInformation->FileId.Vnode,
+                                  pDirNode->ObjectInformation->FileId.Unique);
+
+                    AFSAcquireExcl( pDirNode->ObjectInformation->Specific.Directory.DirectoryNodeHdr.TreeLock,
+                                    TRUE);
+
+                    SetFlag( pDirNode->ObjectInformation->Flags, AFS_OBJECT_FLAGS_VERIFY);
+
+                    pDirNode->ObjectInformation->DataVersion.QuadPart = (ULONGLONG)-1;
+
+                    AFSReleaseResource( pDirNode->ObjectInformation->Specific.Directory.DirectoryNodeHdr.TreeLock);
+                }
+
                 //
                 // Init the short name if we have one
                 //
@@ -814,10 +1222,48 @@ AFSVerifyDirectoryContent( IN AFSObjectInfoCB *ObjectInfoCB,
                     //
 
                     uniShortName.Length = pDirNode->NameInformation.ShortNameLength;
+                    uniShortName.MaximumLength = uniShortName.Length;
                     uniShortName.Buffer = pDirNode->NameInformation.ShortName;
 
-                    pDirNode->Type.Data.ShortNameTreeEntry.HashIndex = AFSGenerateCRC( &uniShortName,
-                                                                                       TRUE);
+                    if( !RtlIsNameLegalDOS8Dot3( &pDirNode->NameInformation.FileName,
+                                                 NULL,
+                                                 NULL))
+                    {
+
+                        pDirNode->Type.Data.ShortNameTreeEntry.HashIndex = AFSGenerateCRC( &uniShortName,
+                                                                                           TRUE);
+
+                        AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
+                                      AFS_TRACE_LEVEL_VERBOSE,
+                                      "AFSVerifyDirectoryContent Initialized short name %wZ for DE %p for %wZ FID %08lX-%08lX-%08lX-%08lX\n",
+                                      &uniShortName,
+                                      pDirNode,
+                                      &pDirNode->NameInformation.FileName,
+                                      pCurrentDirEntry->FileId.Cell,
+                                      pCurrentDirEntry->FileId.Volume,
+                                      pCurrentDirEntry->FileId.Vnode,
+                                      pCurrentDirEntry->FileId.Unique);
+                    }
+                    else
+                    {
+                        pDirNode->NameInformation.ShortNameLength = 0;
+
+                        RtlZeroMemory( pDirNode->NameInformation.ShortName,
+                                       (12 * sizeof( WCHAR)));
+                    }
+                }
+                else
+                {
+
+                    AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
+                                  AFS_TRACE_LEVEL_VERBOSE,
+                                  "AFSVerifyDirectoryContent NO short name for DE %p for %wZ FID %08lX-%08lX-%08lX-%08lX\n",
+                                  pDirNode,
+                                  &pDirNode->NameInformation.FileName,
+                                  pCurrentDirEntry->FileId.Cell,
+                                  pCurrentDirEntry->FileId.Volume,
+                                  pCurrentDirEntry->FileId.Vnode,
+                                  pCurrentDirEntry->FileId.Unique);
                 }
 
                 //
@@ -830,26 +1276,81 @@ AFSVerifyDirectoryContent( IN AFSObjectInfoCB *ObjectInfoCB,
                 {
 
                     ObjectInfoCB->Specific.Directory.DirectoryNodeHdr.CaseSensitiveTreeHead = pDirNode;
+
+                    AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
+                                  AFS_TRACE_LEVEL_VERBOSE,
+                                  "AFSVerifyDirectoryContent Insert DE %p to head of case sensitive tree for %wZ\n",
+                                  pDirNode,
+                                  &pDirNode->NameInformation.FileName);
                 }
                 else
                 {
 
-                    AFSInsertCaseSensitiveDirEntry( ObjectInfoCB->Specific.Directory.DirectoryNodeHdr.CaseSensitiveTreeHead,
-                                                    pDirNode);
+                    if( !NT_SUCCESS( AFSInsertCaseSensitiveDirEntry( ObjectInfoCB->Specific.Directory.DirectoryNodeHdr.CaseSensitiveTreeHead,
+                                                                     pDirNode)))
+                    {
+                        AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
+                                      AFS_TRACE_LEVEL_VERBOSE,
+                                      "AFSVerifyDirectoryContent Failed to insert DE %p to case sensitive tree for %wZ\n",
+                                      pDirNode,
+                                      &pDirNode->NameInformation.FileName);
+
+                        //
+                        // Delete this dir entry and continue on
+                        //
+
+                        AFSDeleteDirEntry( ObjectInfoCB,
+                                           pDirNode);
+
+                        pCurrentDirEntry = (AFSDirEnumEntry *)((char *)pCurrentDirEntry + ulEntryLength);
+
+                        if( ulResultLen >= ulEntryLength)
+                        {
+                            ulResultLen -= ulEntryLength;
+                        }
+                        else
+                        {
+                            ulResultLen = 0;
+                        }
+
+                        continue;
+                    }
+                    else
+                    {
+                        AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
+                                      AFS_TRACE_LEVEL_VERBOSE,
+                                      "AFSVerifyDirectoryContent Insert DE %p to case sensitive tree for %wZ\n",
+                                      pDirNode,
+                                      &pDirNode->NameInformation.FileName);
+                    }
                 }
 
+                ClearFlag( pDirNode->Flags, AFS_DIR_ENTRY_NOT_IN_PARENT_TREE);
+
                 if( ObjectInfoCB->Specific.Directory.DirectoryNodeHdr.CaseInsensitiveTreeHead == NULL)
                 {
 
                     ObjectInfoCB->Specific.Directory.DirectoryNodeHdr.CaseInsensitiveTreeHead = pDirNode;
 
                     SetFlag( pDirNode->Flags, AFS_DIR_ENTRY_CASE_INSENSTIVE_LIST_HEAD);
+
+                    AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
+                                  AFS_TRACE_LEVEL_VERBOSE,
+                                  "AFSVerifyDirectoryContent Insert DE %p to head of case insensitive tree for %wZ\n",
+                                  pDirNode,
+                                  &pDirNode->NameInformation.FileName);
                 }
                 else
                 {
 
                     AFSInsertCaseInsensitiveDirEntry( ObjectInfoCB->Specific.Directory.DirectoryNodeHdr.CaseInsensitiveTreeHead,
                                                       pDirNode);
+
+                    AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
+                                  AFS_TRACE_LEVEL_VERBOSE,
+                                  "AFSVerifyDirectoryContent Insert DE %p to case insensitive tree for %wZ\n",
+                                  pDirNode,
+                                  &pDirNode->NameInformation.FileName);
                 }
 
                 if( ObjectInfoCB->Specific.Directory.DirectoryNodeListHead == NULL)
@@ -892,15 +1393,43 @@ AFSVerifyDirectoryContent( IN AFSObjectInfoCB *ObjectInfoCB,
                     {
 
                         ObjectInfoCB->Specific.Directory.ShortNameTree = pDirNode;
+
+                        AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
+                                      AFS_TRACE_LEVEL_VERBOSE,
+                                      "AFSVerifyDirectoryContent Insert DE %p to head of shortname tree for %wZ\n",
+                                      pDirNode,
+                                      &pDirNode->NameInformation.FileName);
+
+                        SetFlag( pDirNode->Flags, AFS_DIR_ENTRY_INSERTED_SHORT_NAME);
                     }
                     else
                     {
 
-                        AFSInsertShortNameDirEntry( ObjectInfoCB->Specific.Directory.ShortNameTree,
-                                                    pDirNode);
+                        if( !NT_SUCCESS( AFSInsertShortNameDirEntry( ObjectInfoCB->Specific.Directory.ShortNameTree,
+                                                                     pDirNode)))
+                        {
+                            AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
+                                          AFS_TRACE_LEVEL_VERBOSE,
+                                          "AFSVerifyDirectoryContent Failed to insert DE %p (%08lX) to shortname tree for %wZ\n",
+                                          pDirNode,
+                                          pDirNode->Type.Data.ShortNameTreeEntry.HashIndex,
+                                          &pDirNode->NameInformation.FileName);
+                        }
+                        else
+                        {
+                            SetFlag( pDirNode->Flags, AFS_DIR_ENTRY_INSERTED_SHORT_NAME);
+
+                            AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
+                                          AFS_TRACE_LEVEL_VERBOSE,
+                                          "AFSVerifyDirectoryContent Insert DE %p to shortname tree for %wZ\n",
+                                          pDirNode,
+                                          &pDirNode->NameInformation.FileName);
+                        }
                     }
                 }
 
+                SetFlag( pDirNode->Flags, AFS_DIR_ENTRY_VALID);
+
                 //
                 // Next dir entry
                 //
@@ -925,16 +1454,6 @@ AFSVerifyDirectoryContent( IN AFSObjectInfoCB *ObjectInfoCB,
             //
 
             pDirQueryCB->EnumHandle = pDirEnumResponse->EnumHandle;
-
-            //
-            // If the enumeration handle is -1 then we are done
-            //
-
-            if( ((ULONG)-1) == pDirQueryCB->EnumHandle )
-            {
-
-                break;
-            }
         }
 
 try_exit:
@@ -1043,14 +1562,22 @@ AFSNotifyFileCreate( IN GUID            *AuthGroup,
         // The check is to ensure the DV has been modified
         //
 
-        if( liOldDataVersion.QuadPart != pResultCB->ParentDataVersion.QuadPart - 1 ||
-            liOldDataVersion.QuadPart != ParentObjectInfo->DataVersion.QuadPart)
+        AFSAcquireExcl( ParentObjectInfo->Specific.Directory.DirectoryNodeHdr.TreeLock,
+                        TRUE);
+
+        if( ParentObjectInfo->DataVersion.QuadPart != pResultCB->ParentDataVersion.QuadPart - 1)
         {
 
             AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
-                          AFS_TRACE_LEVEL_VERBOSE,
-                          "AFSNotifyFileCreate Raced with an invalidate call and a re-enumeration for entry %wZ\n",
-                          FileName);
+                          AFS_TRACE_LEVEL_WARNING,
+                          "AFSNotifyFileCreate Raced with an invalidate call and a re-enumeration for entry %wZ ParentFID %08lX-%08lX-%08lX-%08lX Version (%08lX:%08lX != %08lX:%08lX - 1)\n",
+                          FileName,
+                          ParentObjectInfo->FileId.Cell,
+                          ParentObjectInfo->FileId.Volume,
+                          ParentObjectInfo->FileId.Vnode,
+                          ParentObjectInfo->FileId.Unique,
+                          ParentObjectInfo->DataVersion.QuadPart,
+                          pResultCB->ParentDataVersion.QuadPart);
 
             //
             // We raced so go and lookup the directory entry in the parent
@@ -1059,26 +1586,105 @@ AFSNotifyFileCreate( IN GUID            *AuthGroup,
             ulCRC = AFSGenerateCRC( FileName,
                                     FALSE);
 
-            AFSAcquireShared( ParentObjectInfo->Specific.Directory.DirectoryNodeHdr.TreeLock,
-                              TRUE);
-
             AFSLocateCaseSensitiveDirEntry( ParentObjectInfo->Specific.Directory.DirectoryNodeHdr.CaseSensitiveTreeHead,
                                             ulCRC,
                                             &pDirNode);
 
-            AFSReleaseResource( ParentObjectInfo->Specific.Directory.DirectoryNodeHdr.TreeLock);
-
             if( pDirNode != NULL)
             {
 
                 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
                               AFS_TRACE_LEVEL_VERBOSE,
-                              "AFSNotifyFileCreate Located dir entry for file %wZ\n",
+                              "AFSNotifyFileCreate Located dir entry %p for file %wZ\n",
+                              pDirNode,
                               FileName);
 
-                *DirNode = pDirNode;
+                if ( AFSIsEqualFID( &pDirNode->ObjectInformation->FileId,
+                                    &pResultCB->DirEnum.FileId))
+                {
+
+                    InterlockedIncrement( &pDirNode->OpenReferenceCount);
+
+                    AFSDbgLogMsg( AFS_SUBSYSTEM_DIRENTRY_REF_COUNTING,
+                                  AFS_TRACE_LEVEL_VERBOSE,
+                                  "AFSNotifyFileCreate Increment count on %wZ DE %p Cnt %d\n",
+                                  &pDirNode->NameInformation.FileName,
+                                  pDirNode,
+                                  pDirNode->OpenReferenceCount);
+
+                    *DirNode = pDirNode;
+
+                    AFSReleaseResource( ParentObjectInfo->Specific.Directory.DirectoryNodeHdr.TreeLock);
+
+                    try_return( ntStatus = STATUS_REPARSE);
+                }
+                else
+                {
+
+                    //
+                    // We found an entry that matches the desired name but it is not the
+                    // same as the one that was created for us by the file server.
+                    //
+
+                    AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
+                                  AFS_TRACE_LEVEL_ERROR,
+                                  "AFSNotifyFileCreate Found matching name entry %wZ DE %p FID %08lX-%08lX-%08lX-%08lX != FID %08lX-%08lX-%08lX-%08lX\n",
+                                  FileName,
+                                  pDirNode,
+                                  pDirNode->ObjectInformation->FileId.Cell,
+                                  pDirNode->ObjectInformation->FileId.Volume,
+                                  pDirNode->ObjectInformation->FileId.Vnode,
+                                  pDirNode->ObjectInformation->FileId.Unique,
+                                  pResultCB->DirEnum.FileId.Cell,
+                                  pResultCB->DirEnum.FileId.Volume,
+                                  pResultCB->DirEnum.FileId.Vnode,
+                                  pResultCB->DirEnum.FileId.Unique);
+
+                    if( pDirNode->OpenReferenceCount == 0)
+                    {
+
+                        AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
+                                      AFS_TRACE_LEVEL_VERBOSE,
+                                      "AFSNotifyFileCreate Different FIDs - Deleting DE %p for %wZ Old FID %08lX-%08lX-%08lX-%08lX New FID %08lX-%08lX-%08lX-%08lX\n",
+                                      pDirNode,
+                                      &pDirNode->NameInformation.FileName,
+                                      pDirNode->ObjectInformation->FileId.Cell,
+                                      pDirNode->ObjectInformation->FileId.Volume,
+                                      pDirNode->ObjectInformation->FileId.Vnode,
+                                      pDirNode->ObjectInformation->FileId.Unique,
+                                      pResultCB->DirEnum.FileId.Cell,
+                                      pResultCB->DirEnum.FileId.Volume,
+                                      pResultCB->DirEnum.FileId.Vnode,
+                                      pResultCB->DirEnum.FileId.Unique);
+
+                        AFSDeleteDirEntry( ParentObjectInfo,
+                                           pDirNode);
+                    }
+                    else
+                    {
+
+                        SetFlag( pDirNode->Flags, AFS_DIR_ENTRY_DELETED);
+
+                        AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
+                                      AFS_TRACE_LEVEL_VERBOSE,
+                                      "AFSNotifyFileCreate Different FIDs - Removing DE %p for %wZ Old FID %08lX-%08lX-%08lX-%08lX New FID %08lX-%08lX-%08lX-%08lX\n",
+                                      pDirNode,
+                                      &pDirNode->NameInformation.FileName,
+                                      pDirNode->ObjectInformation->FileId.Cell,
+                                      pDirNode->ObjectInformation->FileId.Volume,
+                                      pDirNode->ObjectInformation->FileId.Vnode,
+                                      pDirNode->ObjectInformation->FileId.Unique,
+                                      pResultCB->DirEnum.FileId.Cell,
+                                      pResultCB->DirEnum.FileId.Volume,
+                                      pResultCB->DirEnum.FileId.Vnode,
+                                      pResultCB->DirEnum.FileId.Unique);
+
+                        AFSRemoveNameEntry( ParentObjectInfo,
+                                            pDirNode);
+                    }
 
-                try_return( ntStatus = STATUS_REPARSE);
+                    pDirNode = NULL;
+                }
             }
 
             //
@@ -1090,15 +1696,6 @@ AFSNotifyFileCreate( IN GUID            *AuthGroup,
 
             ParentObjectInfo->DataVersion.QuadPart = (ULONGLONG)-1;
         }
-        else
-        {
-
-            //
-            // Update the parent data version
-            //
-
-            ParentObjectInfo->DataVersion = pResultCB->ParentDataVersion;
-        }
 
         AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
                       AFS_TRACE_LEVEL_VERBOSE,
@@ -1124,6 +1721,12 @@ AFSNotifyFileCreate( IN GUID            *AuthGroup,
         if( pDirNode == NULL)
         {
 
+            SetFlag( ParentObjectInfo->Flags, AFS_OBJECT_FLAGS_VERIFY);
+
+            ParentObjectInfo->DataVersion.QuadPart = (ULONGLONG)-1;
+
+            AFSReleaseResource( ParentObjectInfo->Specific.Directory.DirectoryNodeHdr.TreeLock);
+
             try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
         }
 
@@ -1151,8 +1754,37 @@ AFSNotifyFileCreate( IN GUID            *AuthGroup,
 
             pDirNode->Type.Data.ShortNameTreeEntry.HashIndex = AFSGenerateCRC( &uniShortName,
                                                                                TRUE);
+
+            AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
+                          AFS_TRACE_LEVEL_VERBOSE,
+                          "AFSNotifyFileCreate Initialized short name %wZ for DE %p for %wZ\n",
+                          &uniShortName,
+                          pDirNode,
+                          &pDirNode->NameInformation.FileName);
+        }
+
+        if ( !BooleanFlagOn( ParentObjectInfo->Flags, AFS_OBJECT_FLAGS_VERIFY))
+        {
+
+            //
+            // Update the parent data version
+            //
+
+            ParentObjectInfo->DataVersion = pResultCB->ParentDataVersion;
+
+            AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
+                          AFS_TRACE_LEVEL_VERBOSE,
+                          "AFSNotifyFileCreate entry %wZ ParentFID %08lX-%08lX-%08lX-%08lX Version %08lX:%08lX\n",
+                          FileName,
+                          ParentObjectInfo->FileId.Cell,
+                          ParentObjectInfo->FileId.Volume,
+                          ParentObjectInfo->FileId.Vnode,
+                          ParentObjectInfo->FileId.Unique,
+                          ParentObjectInfo->DataVersion.QuadPart);
         }
 
+        AFSReleaseResource( ParentObjectInfo->Specific.Directory.DirectoryNodeHdr.TreeLock);
+
         //
         // Return the directory node
         //
@@ -1250,7 +1882,16 @@ AFSUpdateFileInformation( IN AFSFileID *ParentFid,
         // Update the data version
         //
 
-        ObjectInfo->DataVersion = pUpdateResultCB->DirEnum.DataVersion;
+        AFSAcquireExcl( ObjectInfo->Specific.Directory.DirectoryNodeHdr.TreeLock,
+                        TRUE);
+
+        if ( !BooleanFlagOn( ObjectInfo->Flags, AFS_OBJECT_FLAGS_VERIFY))
+        {
+
+            ObjectInfo->DataVersion = pUpdateResultCB->DirEnum.DataVersion;
+        }
+
+        AFSReleaseResource( ObjectInfo->Specific.Directory.DirectoryNodeHdr.TreeLock);
 
 try_exit:
 
@@ -1266,14 +1907,14 @@ try_exit:
 
 NTSTATUS
 AFSNotifyDelete( IN AFSDirectoryCB *DirectoryCB,
-                 IN BOOLEAN CheckOnly)
+                 IN GUID           *AuthGroup,
+                 IN BOOLEAN         CheckOnly)
 {
     NTSTATUS ntStatus = STATUS_SUCCESS;
     ULONG ulResultLen = 0;
     AFSFileDeleteCB stDelete;
     AFSFileDeleteResultCB stDeleteResult;
     ULONG ulRequestFlags = AFS_REQUEST_FLAG_SYNCHRONOUS;
-    GUID *pAuthGroup = NULL;
 
     __Enter
     {
@@ -1289,14 +1930,9 @@ AFSNotifyDelete( IN AFSDirectoryCB *DirectoryCB,
             ulRequestFlags |= AFS_REQUEST_FLAG_CHECK_ONLY;
         }
 
-        if( DirectoryCB->ObjectInformation->Fcb != NULL)
-        {
-            pAuthGroup = &DirectoryCB->ObjectInformation->Fcb->AuthGroup;
-        }
-
         ntStatus = AFSProcessRequest( AFS_REQUEST_TYPE_DELETE_FILE,
                                       ulRequestFlags,
-                                      pAuthGroup,
+                                      AuthGroup,
                                       &DirectoryCB->NameInformation.FileName,
                                       &DirectoryCB->ObjectInformation->FileId,
                                       &stDelete,
@@ -1309,21 +1945,29 @@ AFSNotifyDelete( IN AFSDirectoryCB *DirectoryCB,
 
             AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
                           AFS_TRACE_LEVEL_ERROR,
-                          "AFSNotifyDelete failed FID %08lX-%08lX-%08lX-%08lX Status %08lX\n",
-                          &DirectoryCB->ObjectInformation->FileId.Cell,
-                          &DirectoryCB->ObjectInformation->FileId.Volume,
-                          &DirectoryCB->ObjectInformation->FileId.Vnode,
-                          &DirectoryCB->ObjectInformation->FileId.Unique,
+                          "AFSNotifyDelete failed ParentFID %08lX-%08lX-%08lX-%08lX %wZ FID %08lX-%08lX-%08lX-%08lX Status %08lX\n",
+                          stDelete.ParentId.Cell,
+                          stDelete.ParentId.Volume,
+                          stDelete.ParentId.Vnode,
+                          stDelete.ParentId.Unique,
+                          &DirectoryCB->NameInformation.FileName,
+                          DirectoryCB->ObjectInformation->FileId.Cell,
+                          DirectoryCB->ObjectInformation->FileId.Volume,
+                          DirectoryCB->ObjectInformation->FileId.Vnode,
+                          DirectoryCB->ObjectInformation->FileId.Unique,
                           ntStatus);
 
             try_return( ntStatus);
         }
 
-        if( !CheckOnly)
+        AFSAcquireExcl( DirectoryCB->ObjectInformation->Specific.Directory.DirectoryNodeHdr.TreeLock,
+                        TRUE);
+
+        if( CheckOnly)
         {
 
             //
-            // Update the parent data version
+            // Validate the parent data version
             //
 
             if( DirectoryCB->ObjectInformation->ParentObjectInformation->DataVersion.QuadPart != stDeleteResult.ParentDataVersion.QuadPart)
@@ -1334,6 +1978,38 @@ AFSNotifyDelete( IN AFSDirectoryCB *DirectoryCB,
                 DirectoryCB->ObjectInformation->ParentObjectInformation->DataVersion.QuadPart = (ULONGLONG)-1;
             }
         }
+        else
+        {
+
+            //
+            // Update the parent data version
+            //
+
+            if( DirectoryCB->ObjectInformation->ParentObjectInformation->DataVersion.QuadPart != stDeleteResult.ParentDataVersion.QuadPart - 1)
+            {
+
+                SetFlag( DirectoryCB->ObjectInformation->ParentObjectInformation->Flags, AFS_OBJECT_FLAGS_VERIFY);
+
+                DirectoryCB->ObjectInformation->ParentObjectInformation->DataVersion.QuadPart = (ULONGLONG)-1;
+            }
+            else
+            {
+
+                //
+                // TODO -- The entry must be removed from the directory at which point the
+                // Directory data version number can be updated.  Until then we must force
+                // a verification.
+                //
+                // DirectoryCB->ObjectInformation->ParentObjectInformation->DataVersion.QuadPart = stDeleteResult.ParentDataVersion.QuadPart;
+                //
+
+                SetFlag( DirectoryCB->ObjectInformation->ParentObjectInformation->Flags, AFS_OBJECT_FLAGS_VERIFY);
+
+                DirectoryCB->ObjectInformation->ParentObjectInformation->DataVersion.QuadPart = (ULONGLONG)-1;
+            }
+        }
+
+        AFSReleaseResource( DirectoryCB->ObjectInformation->Specific.Directory.DirectoryNodeHdr.TreeLock);
 
 try_exit:
 
@@ -1345,6 +2021,7 @@ try_exit:
 
 NTSTATUS
 AFSNotifyRename( IN AFSObjectInfoCB *ObjectInfo,
+                 IN GUID            *AuthGroup,
                  IN AFSObjectInfoCB *ParentObjectInfo,
                  IN AFSObjectInfoCB *TargetParentObjectInfo,
                  IN AFSDirectoryCB *DirectoryCB,
@@ -1356,7 +2033,6 @@ AFSNotifyRename( IN AFSObjectInfoCB *ObjectInfo,
     AFSFileRenameCB *pRenameCB = NULL;
     AFSFileRenameResultCB *pRenameResultCB = NULL;
     ULONG ulResultLen = 0;
-    GUID *pAuthGroup = NULL;
 
     __Enter
     {
@@ -1388,11 +2064,6 @@ AFSNotifyRename( IN AFSObjectInfoCB *ObjectInfo,
                        TargetName->Buffer,
                        TargetName->Length);
 
-        if( ObjectInfo->Fcb != NULL)
-        {
-            pAuthGroup = &ObjectInfo->Fcb->AuthGroup;
-        }
-
         //
         // Use the same buffer for the result control block
         //
@@ -1403,7 +2074,7 @@ AFSNotifyRename( IN AFSObjectInfoCB *ObjectInfo,
 
         ntStatus = AFSProcessRequest( AFS_REQUEST_TYPE_RENAME_FILE,
                                       AFS_REQUEST_FLAG_SYNCHRONOUS,
-                                      pAuthGroup,
+                                      AuthGroup,
                                       &DirectoryCB->NameInformation.FileName,
                                       &ObjectInfo->FileId,
                                       pRenameCB,
@@ -1430,9 +2101,38 @@ AFSNotifyRename( IN AFSObjectInfoCB *ObjectInfo,
         // Update the information from the returned data
         //
 
-        ParentObjectInfo->DataVersion = pRenameResultCB->SourceParentDataVersion;
+        AFSAcquireExcl( ParentObjectInfo->Specific.Directory.DirectoryNodeHdr.TreeLock,
+                        TRUE);
+
+        if ( ParentObjectInfo->DataVersion.QuadPart == pRenameResultCB->SourceParentDataVersion.QuadPart - 1)
+        {
+
+            ParentObjectInfo->DataVersion = pRenameResultCB->SourceParentDataVersion;
+        }
+        else
+        {
+
+            SetFlag( ParentObjectInfo->Flags, AFS_OBJECT_FLAGS_VERIFY);
+
+            ParentObjectInfo->DataVersion.QuadPart = (ULONGLONG)-1;
+        }
+
+        if ( ParentObjectInfo != TargetParentObjectInfo)
+        {
+
+            if ( TargetParentObjectInfo->DataVersion.QuadPart == pRenameResultCB->TargetParentDataVersion.QuadPart - 1)
+            {
+
+                TargetParentObjectInfo->DataVersion = pRenameResultCB->TargetParentDataVersion;
+            }
+            else
+            {
+
+                SetFlag( TargetParentObjectInfo->Flags, AFS_OBJECT_FLAGS_VERIFY);
 
-        TargetParentObjectInfo->DataVersion = pRenameResultCB->TargetParentDataVersion;
+                TargetParentObjectInfo->DataVersion.QuadPart = (ULONGLONG)-1;
+            }
+        }
 
         //
         // Move over the short name
@@ -1443,14 +2143,61 @@ AFSNotifyRename( IN AFSObjectInfoCB *ObjectInfo,
         if( DirectoryCB->NameInformation.ShortNameLength > 0)
         {
 
+            UNICODE_STRING uniShortName;
+
+            uniShortName.Length = DirectoryCB->NameInformation.ShortNameLength;
+            uniShortName.MaximumLength = uniShortName.Length;
+            uniShortName.Buffer = DirectoryCB->NameInformation.ShortName;
+
+            AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
+                          AFS_TRACE_LEVEL_VERBOSE,
+                          "AFSNotifyRename Update old short name %wZ for DE %p for %wZ\n",
+                          &uniShortName,
+                          DirectoryCB,
+                          &DirectoryCB->NameInformation.FileName);
+
+            DirectoryCB->NameInformation.ShortNameLength = pRenameResultCB->DirEnum.ShortNameLength;
+
             RtlCopyMemory( DirectoryCB->NameInformation.ShortName,
                            pRenameResultCB->DirEnum.ShortName,
                            DirectoryCB->NameInformation.ShortNameLength);
+
+            uniShortName.Length = DirectoryCB->NameInformation.ShortNameLength;
+            uniShortName.MaximumLength = uniShortName.Length;
+            uniShortName.Buffer = DirectoryCB->NameInformation.ShortName;
+
+            AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
+                          AFS_TRACE_LEVEL_VERBOSE,
+                          "AFSNotifyRename Initialized short name %wZ for DE %p for %wZ\n",
+                          &uniShortName,
+                          DirectoryCB,
+                          &DirectoryCB->NameInformation.FileName);
+        }
+        else
+        {
+
+            UNICODE_STRING uniShortName;
+
+            uniShortName.Length = DirectoryCB->NameInformation.ShortNameLength;
+            uniShortName.MaximumLength = uniShortName.Length;
+            uniShortName.Buffer = DirectoryCB->NameInformation.ShortName;
+
+            AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
+                          AFS_TRACE_LEVEL_VERBOSE,
+                          "AFSNotifyRename Removing old short name %wZ for DE %p for %wZ\n",
+                          &uniShortName,
+                          DirectoryCB,
+                          &DirectoryCB->NameInformation.FileName);
+
+            DirectoryCB->NameInformation.ShortNameLength = 0;
+
+            DirectoryCB->Type.Data.ShortNameTreeEntry.HashIndex = 0;
         }
 
+        AFSReleaseResource( ParentObjectInfo->Specific.Directory.DirectoryNodeHdr.TreeLock);
+
         if( UpdatedFID != NULL)
         {
-
             *UpdatedFID = pRenameResultCB->DirEnum.FileId;
         }
 
@@ -1476,6 +2223,7 @@ AFSEvaluateTargetByID( IN AFSObjectInfoCB *ObjectInfo,
     NTSTATUS ntStatus = STATUS_SUCCESS;
     AFSEvalTargetCB stTargetID;
     ULONG ulResultBufferLength;
+    AFSFileEvalResultCB *pEvalResultCB = NULL;
     AFSDirEnumEntry *pDirEnumCB = NULL;
     ULONG ulRequestFlags = AFS_REQUEST_FLAG_SYNCHRONOUS;
 
@@ -1495,11 +2243,11 @@ AFSEvaluateTargetByID( IN AFSObjectInfoCB *ObjectInfo,
         // Allocate our response buffer
         //
 
-        pDirEnumCB = (AFSDirEnumEntry *)AFSExAllocatePoolWithTag( PagedPool,
-                                                                  PAGE_SIZE,
-                                                                  AFS_GENERIC_MEMORY_2_TAG);
+        pEvalResultCB = (AFSFileEvalResultCB *)AFSExAllocatePoolWithTag( PagedPool,
+                                                                         PAGE_SIZE,
+                                                                         AFS_GENERIC_MEMORY_30_TAG);
 
-        if( pDirEnumCB == NULL)
+        if( pEvalResultCB == NULL)
         {
 
             try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
@@ -1524,7 +2272,7 @@ AFSEvaluateTargetByID( IN AFSObjectInfoCB *ObjectInfo,
                                       &ObjectInfo->FileId,
                                       &stTargetID,
                                       sizeof( AFSEvalTargetCB),
-                                      pDirEnumCB,
+                                      pEvalResultCB,
                                       &ulResultBufferLength);
 
         if( ntStatus != STATUS_SUCCESS)
@@ -1535,13 +2283,20 @@ AFSEvaluateTargetByID( IN AFSObjectInfoCB *ObjectInfo,
             // verification
             //
 
-            if( ntStatus == STATUS_INVALID_HANDLE)
+            if( ntStatus == STATUS_OBJECT_PATH_INVALID)
             {
 
                 if( ObjectInfo->ParentObjectInformation != NULL)
                 {
 
+                    AFSAcquireExcl( ObjectInfo->ParentObjectInformation->Specific.Directory.DirectoryNodeHdr.TreeLock,
+                                    TRUE);
+
                     SetFlag( ObjectInfo->ParentObjectInformation->Flags, AFS_OBJECT_FLAGS_VERIFY);
+
+                    ObjectInfo->ParentObjectInformation->DataVersion.QuadPart = (ULONGLONG)-1;
+
+                    AFSReleaseResource( ObjectInfo->ParentObjectInformation->Specific.Directory.DirectoryNodeHdr.TreeLock);
                 }
             }
 
@@ -1549,22 +2304,57 @@ AFSEvaluateTargetByID( IN AFSObjectInfoCB *ObjectInfo,
         }
 
         //
+        // Validate the parent data version
+        //
+
+        if ( ObjectInfo->ParentObjectInformation != NULL)
+        {
+
+            AFSAcquireExcl( ObjectInfo->ParentObjectInformation->Specific.Directory.DirectoryNodeHdr.TreeLock,
+                            TRUE);
+
+            if ( ObjectInfo->ParentObjectInformation->DataVersion.QuadPart != pEvalResultCB->ParentDataVersion.QuadPart)
+            {
+
+                SetFlag( ObjectInfo->ParentObjectInformation->Flags, AFS_OBJECT_FLAGS_VERIFY);
+
+                ObjectInfo->ParentObjectInformation->DataVersion.QuadPart = (ULONGLONG)-1;
+            }
+
+            AFSReleaseResource( ObjectInfo->ParentObjectInformation->Specific.Directory.DirectoryNodeHdr.TreeLock);
+        }
+
+        //
         // Pass back the dir enum entry
         //
 
         if( DirEnumEntry != NULL)
         {
 
+            pDirEnumCB = (AFSDirEnumEntry *)AFSExAllocatePoolWithTag( PagedPool,
+                                                                      PAGE_SIZE,
+                                                                      AFS_GENERIC_MEMORY_2_TAG);
+
+            if( pDirEnumCB == NULL)
+            {
+
+                try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
+            }
+
+            RtlCopyMemory( pDirEnumCB, &pEvalResultCB->DirEnum,
+                           ulResultBufferLength - sizeof( AFSFileEvalResultCB) + sizeof( AFSDirEnumEntry));
+
             *DirEnumEntry = pDirEnumCB;
         }
-        else
+
+try_exit:
+
+        if( pEvalResultCB != NULL)
         {
 
-            AFSExFreePool( pDirEnumCB);
+            AFSExFreePool( pEvalResultCB);
         }
 
-try_exit:
-
         if( !NT_SUCCESS( ntStatus))
         {
 
@@ -1583,7 +2373,7 @@ try_exit:
 
 NTSTATUS
 AFSEvaluateTargetByName( IN GUID *AuthGroup,
-                         IN AFSFileID *ParentFileId,
+                         IN AFSObjectInfoCB *ParentObjectInfo,
                          IN PUNICODE_STRING SourceName,
                          OUT AFSDirEnumEntry **DirEnumEntry)
 {
@@ -1591,22 +2381,23 @@ AFSEvaluateTargetByName( IN GUID *AuthGroup,
     NTSTATUS ntStatus = STATUS_SUCCESS;
     AFSEvalTargetCB stTargetID;
     ULONG ulResultBufferLength;
+    AFSFileEvalResultCB *pEvalResultCB = NULL;
     AFSDirEnumEntry *pDirEnumCB = NULL;
 
     __Enter
     {
 
-        stTargetID.ParentId = *ParentFileId;
+        stTargetID.ParentId = ParentObjectInfo->FileId;
 
         //
         // Allocate our response buffer
         //
 
-        pDirEnumCB = (AFSDirEnumEntry *)AFSExAllocatePoolWithTag( PagedPool,
-                                                                  PAGE_SIZE,
-                                                                  AFS_GENERIC_MEMORY_3_TAG);
+        pEvalResultCB = (AFSFileEvalResultCB *)AFSExAllocatePoolWithTag( PagedPool,
+                                                                         PAGE_SIZE,
+                                                                         AFS_GENERIC_MEMORY_31_TAG);
 
-        if( pDirEnumCB == NULL)
+        if( pEvalResultCB == NULL)
         {
 
             try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
@@ -1625,32 +2416,76 @@ AFSEvaluateTargetByName( IN GUID *AuthGroup,
                                       NULL,
                                       &stTargetID,
                                       sizeof( AFSEvalTargetCB),
-                                      pDirEnumCB,
+                                      pEvalResultCB,
                                       &ulResultBufferLength);
 
         if( ntStatus != STATUS_SUCCESS)
         {
 
+            if( ntStatus == STATUS_OBJECT_PATH_INVALID)
+            {
+
+                AFSAcquireExcl( ParentObjectInfo->Specific.Directory.DirectoryNodeHdr.TreeLock,
+                                TRUE);
+
+                SetFlag( ParentObjectInfo->Flags, AFS_OBJECT_FLAGS_VERIFY);
+
+                ParentObjectInfo->DataVersion.QuadPart = (ULONGLONG)-1;
+
+                AFSReleaseResource( ParentObjectInfo->Specific.Directory.DirectoryNodeHdr.TreeLock);
+            }
+
             try_return( ntStatus);
         }
 
         //
+        // Validate the parent data version
+        //
+
+        AFSAcquireExcl( ParentObjectInfo->Specific.Directory.DirectoryNodeHdr.TreeLock,
+                        TRUE);
+
+        if ( ParentObjectInfo->DataVersion.QuadPart != pEvalResultCB->ParentDataVersion.QuadPart)
+        {
+
+            SetFlag( ParentObjectInfo->Flags, AFS_OBJECT_FLAGS_VERIFY);
+
+            ParentObjectInfo->DataVersion.QuadPart = (ULONGLONG)-1;
+        }
+
+        AFSReleaseResource( ParentObjectInfo->Specific.Directory.DirectoryNodeHdr.TreeLock);
+
+        //
         // Pass back the dir enum entry
         //
 
         if( DirEnumEntry != NULL)
         {
 
+            pDirEnumCB = (AFSDirEnumEntry *)AFSExAllocatePoolWithTag( PagedPool,
+                                                                      PAGE_SIZE,
+                                                                      AFS_GENERIC_MEMORY_3_TAG);
+
+            if( pDirEnumCB == NULL)
+            {
+
+                try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
+            }
+
+            RtlCopyMemory( pDirEnumCB, &pEvalResultCB->DirEnum,
+                           ulResultBufferLength - sizeof( AFSFileEvalResultCB) + sizeof( AFSDirEnumEntry));
+
             *DirEnumEntry = pDirEnumCB;
         }
-        else
+
+try_exit:
+
+        if( pEvalResultCB != NULL)
         {
 
-            AFSExFreePool( pDirEnumCB);
+            AFSExFreePool( pEvalResultCB);
         }
 
-try_exit:
-
         if( !NT_SUCCESS( ntStatus))
         {
 
@@ -1720,7 +2555,6 @@ AFSNotifyPipeTransceive( IN AFSCcb *Ccb,
     void *pInputSystemBuffer = NULL, *pOutputSystemBuffer = NULL;
     ULONG ulBufferLength = OutputLength;
     AFSPipeIORequestCB *pIoRequest = NULL;
-    GUID *pAuthGroup = NULL;
 
     __Enter
     {
@@ -1773,11 +2607,6 @@ AFSNotifyPipeTransceive( IN AFSCcb *Ccb,
             try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
         }
 
-        if( Ccb->DirectoryCB->ObjectInformation->Fcb != NULL)
-        {
-            pAuthGroup = &Ccb->DirectoryCB->ObjectInformation->Fcb->AuthGroup;
-        }
-
         //
         // Send the call to the service
         //
@@ -1786,7 +2615,7 @@ AFSNotifyPipeTransceive( IN AFSCcb *Ccb,
 
         ntStatus = AFSProcessRequest( AFS_REQUEST_TYPE_PIPE_TRANSCEIVE,
                                       AFS_REQUEST_FLAG_SYNCHRONOUS,
-                                      pAuthGroup,
+                                      &Ccb->AuthGroup,
                                       &Ccb->DirectoryCB->NameInformation.FileName,
                                       NULL,
                                       pIoRequest,
@@ -1850,7 +2679,6 @@ AFSNotifySetPipeInfo( IN AFSCcb *Ccb,
 
     NTSTATUS ntStatus = STATUS_SUCCESS;
     AFSPipeInfoRequestCB *pInfoRequest = NULL;
-    GUID *pAuthGroup = NULL;
 
     __Enter
     {
@@ -1881,18 +2709,13 @@ AFSNotifySetPipeInfo( IN AFSCcb *Ccb,
                        DataBuffer,
                        InputLength);
 
-        if( Ccb->DirectoryCB->ObjectInformation->Fcb != NULL)
-        {
-            pAuthGroup = &Ccb->DirectoryCB->ObjectInformation->Fcb->AuthGroup;
-        }
-
         //
         // Send the call to the service
         //
 
         ntStatus = AFSProcessRequest( AFS_REQUEST_TYPE_PIPE_SET_INFO,
                                       AFS_REQUEST_FLAG_SYNCHRONOUS,
-                                      pAuthGroup,
+                                      &Ccb->AuthGroup,
                                       &Ccb->DirectoryCB->NameInformation.FileName,
                                       NULL,
                                       pInfoRequest,
@@ -1935,7 +2758,6 @@ AFSNotifyQueryPipeInfo( IN AFSCcb *Ccb,
     NTSTATUS ntStatus = STATUS_SUCCESS;
     AFSPipeInfoRequestCB stInfoRequest;
     ULONG ulBytesProcessed = 0;
-    GUID *pAuthGroup = NULL;
 
     __Enter
     {
@@ -1953,18 +2775,13 @@ AFSNotifyQueryPipeInfo( IN AFSCcb *Ccb,
 
         ulBytesProcessed = OutputLength;
 
-        if( Ccb->DirectoryCB->ObjectInformation->Fcb != NULL)
-        {
-            pAuthGroup = &Ccb->DirectoryCB->ObjectInformation->Fcb->AuthGroup;
-        }
-
         //
         // Send the call to the service
         //
 
         ntStatus = AFSProcessRequest( AFS_REQUEST_TYPE_PIPE_QUERY_INFO,
                                       AFS_REQUEST_FLAG_SYNCHRONOUS,
-                                      pAuthGroup,
+                                      &Ccb->AuthGroup,
                                       &Ccb->DirectoryCB->NameInformation.FileName,
                                       NULL,
                                       &stInfoRequest,