Windows: DirOpenReferenceCount reorganizing completed
[openafs.git] / src / WINNT / afsrdr / kernel / lib / AFSDirControl.cpp
index cf7ec7b..b6bb2ef 100644 (file)
@@ -54,11 +54,9 @@ NTSTATUS
 AFSDirControl( IN PDEVICE_OBJECT LibDeviceObject,
                IN PIRP Irp)
 {
-
+    UNREFERENCED_PARAMETER(LibDeviceObject);
     NTSTATUS ntStatus = STATUS_SUCCESS;
-    ULONG ulRequestType = 0;
     IO_STACK_LOCATION *pIrpSp = IoGetCurrentIrpStackLocation( Irp);
-    AFSFcb *pFcb = NULL;
 
     __try
     {
@@ -89,12 +87,14 @@ AFSDirControl( IN PDEVICE_OBJECT LibDeviceObject,
                 break;
         }
     }
-    __except( AFSExceptionFilter( GetExceptionCode(), GetExceptionInformation()) )
+    __except( AFSExceptionFilter( __FUNCTION__, GetExceptionCode(), GetExceptionInformation()) )
     {
 
         AFSDbgLogMsg( 0,
                       0,
                       "EXCEPTION - AFSDirControl\n");
+
+        AFSDumpTraceFilesFnc();
     }
 
     if( ntStatus != STATUS_PENDING)
@@ -118,21 +118,18 @@ AFSQueryDirectory( IN PIRP Irp)
     AFSFcb *pFcb = NULL;
     AFSCcb *pCcb = NULL;
     BOOLEAN bInitialQuery = FALSE;
-    ULONG ulIndex;
     PUCHAR pBuffer;
     ULONG ulUserBufferLength;
     PUNICODE_STRING puniArgFileName = NULL;
     UNICODE_STRING uniTmpMaskName;
-    UNICODE_STRING uniDirUniBuf;
     WCHAR wchMaskBuffer[ 4];
     FILE_INFORMATION_CLASS FileInformationClass;
-    ULONG ulFileIndex, ulDOSFileIndex;
+    ULONG ulFileIndex;
     BOOLEAN bRestartScan;
     BOOLEAN bReturnSingleEntry;
     BOOLEAN bIndexSpecified;
     ULONG ulNextEntry = 0;
     ULONG ulLastEntry = 0;
-    BOOLEAN bDoCase;
     PFILE_DIRECTORY_INFORMATION pDirInfo;
     PFILE_FULL_DIR_INFORMATION pFullDirInfo;
     PFILE_BOTH_DIR_INFORMATION pBothDirInfo;
@@ -141,11 +138,11 @@ AFSQueryDirectory( IN PIRP Irp)
     ULONG ulBytesConverted;
     AFSDirectoryCB *pDirEntry = NULL;
     BOOLEAN bReleaseMain = FALSE;
-    ULONG ulTargetFileType = AFS_FILE_TYPE_UNKNOWN;
+    BOOLEAN bReleaseFcb = FALSE;
     AFSFileInfoCB       stFileInfo;
-    BOOLEAN         bUseFileInfo = TRUE;
     AFSObjectInfoCB *pObjectInfo = NULL;
     ULONG ulAdditionalAttributes = 0;
+    LONG lCount;
 
     __Enter
     {
@@ -161,7 +158,7 @@ AFSQueryDirectory( IN PIRP Irp)
 
             AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
                           AFS_TRACE_LEVEL_ERROR,
-                          "AFSQueryDirectory Attempted access (%08lX) when pFcb == NULL\n",
+                          "AFSQueryDirectory Attempted access (%p) when pFcb == NULL\n",
                           Irp);
 
             try_return( ntStatus = STATUS_INVALID_DEVICE_REQUEST);
@@ -174,7 +171,7 @@ AFSQueryDirectory( IN PIRP Irp)
 
             AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
                           AFS_TRACE_LEVEL_ERROR,
-                          "AFSQueryDirectory Attempted access (%08lX) to non-directory Fcb %08lX NodeType %u\n",
+                          "AFSQueryDirectory Attempted access (%p) to non-directory Fcb %p NodeType %u\n",
                           Irp,
                           pFcb,
                           pFcb->Header.NodeTypeCode);
@@ -202,7 +199,7 @@ AFSQueryDirectory( IN PIRP Irp)
         bReturnSingleEntry = BooleanFlagOn( pIrpSp->Flags, SL_RETURN_SINGLE_ENTRY);
         bIndexSpecified    = BooleanFlagOn( pIrpSp->Flags, SL_INDEX_SPECIFIED);
 
-        bInitialQuery = (BOOLEAN)( !BooleanFlagOn( pCcb->Flags, CCB_FLAGS_DIRECTORY_QUERY_MAPPED));
+        bInitialQuery = (BOOLEAN)( !BooleanFlagOn( pCcb->Flags, CCB_FLAG_DIRECTORY_QUERY_MAPPED));
 
         if( bInitialQuery)
         {
@@ -214,34 +211,14 @@ AFSQueryDirectory( IN PIRP Irp)
 
             AFSDbgLogMsg( AFS_SUBSYSTEM_LOCK_PROCESSING,
                           AFS_TRACE_LEVEL_VERBOSE,
-                          "AFSQueryDirectory Acquiring Dcb lock %08lX EXCL %08lX\n",
+                          "AFSQueryDirectory Acquiring Dcb lock %p EXCL %08lX\n",
                           &pFcb->NPFcb->Resource,
                           PsGetCurrentThread());
 
             AFSAcquireExcl( &pFcb->NPFcb->Resource,
                             TRUE);
 
-            //
-            // Tell the service to prime the cache of the directory content
-            //
-
-            ntStatus = AFSEnumerateDirectoryNoResponse( &pFcb->AuthGroup,
-                                                        &pFcb->ObjectInformation->FileId);
-
-            if( !NT_SUCCESS( ntStatus))
-            {
-
-                AFSReleaseResource( &pFcb->NPFcb->Resource);
-
-                AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
-                              AFS_TRACE_LEVEL_ERROR,
-                              "AFSQueryDirectory Enumerate directory failure for parent %wZ Mask %wZ Status %08lX\n",
-                              &pCcb->DirectoryCB->NameInformation.FileName,
-                              &pCcb->MaskName,
-                              ntStatus);
-
-                try_return( ntStatus);
-            }
+            bReleaseFcb = TRUE;
         }
         else
         {
@@ -253,12 +230,14 @@ AFSQueryDirectory( IN PIRP Irp)
 
             AFSDbgLogMsg( AFS_SUBSYSTEM_LOCK_PROCESSING,
                           AFS_TRACE_LEVEL_VERBOSE,
-                          "AFSQueryDirectory Acquiring Dcb lock %08lX SHARED %08lX\n",
+                          "AFSQueryDirectory Acquiring Dcb lock %p SHARED %08lX\n",
                           &pFcb->NPFcb->Resource,
                           PsGetCurrentThread());
 
             AFSAcquireShared( &pFcb->NPFcb->Resource,
                               TRUE);
+
+            bReleaseFcb = TRUE;
         }
 
         //
@@ -287,7 +266,7 @@ AFSQueryDirectory( IN PIRP Irp)
                           pFcb->ObjectInformation->FileId.Vnode,
                           pFcb->ObjectInformation->FileId.Unique);
 
-            ntStatus = AFSVerifyEntry( &pFcb->AuthGroup,
+            ntStatus = AFSVerifyEntry( &pCcb->AuthGroup,
                                        pCcb->DirectoryCB);
 
             if( !NT_SUCCESS( ntStatus))
@@ -310,10 +289,15 @@ AFSQueryDirectory( IN PIRP Irp)
             // Perform a new snapshot of the directory
             //
 
+            AFSAcquireExcl( &pCcb->NPCcb->CcbLock,
+                            TRUE);
+
             ntStatus = AFSSnapshotDirectory( pFcb,
                                              pCcb,
                                              FALSE);
 
+            AFSReleaseResource( &pCcb->NPCcb->CcbLock);
+
             if( !NT_SUCCESS( ntStatus))
             {
 
@@ -336,6 +320,8 @@ AFSQueryDirectory( IN PIRP Irp)
 
         AFSReleaseResource( &pFcb->NPFcb->Resource);
 
+        bReleaseFcb = FALSE;
+
         //
         // Start processing the data
         //
@@ -349,6 +335,9 @@ AFSQueryDirectory( IN PIRP Irp)
             try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
         }
 
+        AFSAcquireExcl( &pCcb->NPCcb->CcbLock,
+                        TRUE);
+
         // Check if initial on this map
         if( bInitialQuery)
         {
@@ -360,6 +349,8 @@ AFSQueryDirectory( IN PIRP Irp)
             if( !NT_SUCCESS( ntStatus))
             {
 
+                AFSReleaseResource( &pCcb->NPCcb->CcbLock);
+
                 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
                               AFS_TRACE_LEVEL_ERROR,
                               "AFSQueryDirectory Snapshot directory failure for parent %wZ Mask %wZ Status %08lX\n",
@@ -370,7 +361,7 @@ AFSQueryDirectory( IN PIRP Irp)
                 try_return( ntStatus);
             }
 
-            SetFlag( pCcb->Flags, CCB_FLAGS_DIRECTORY_QUERY_MAPPED);
+            SetFlag( pCcb->Flags, CCB_FLAG_DIRECTORY_QUERY_MAPPED);
 
             ClearFlag( pCcb->Flags, CCB_FLAG_DIR_OF_DIRS_ONLY);
 
@@ -474,6 +465,8 @@ AFSQueryDirectory( IN PIRP Irp)
                     if( pFcb->ObjectInformation->Specific.Directory.PIOCtlDirectoryCB == NULL)
                     {
 
+                        AFSReleaseResource( &pCcb->NPCcb->CcbLock);
+
                         AFSReleaseResource( pFcb->ObjectInformation->Specific.Directory.DirectoryNodeHdr.TreeLock);
 
                         bReleaseMain = FALSE;
@@ -508,6 +501,9 @@ AFSQueryDirectory( IN PIRP Irp)
                         bReleaseMain = TRUE;
 
                         AFSReleaseResource( &pFcb->NPFcb->Resource);
+
+                        AFSAcquireExcl( &pCcb->NPCcb->CcbLock,
+                                        TRUE);
                     }
                 }
 
@@ -550,6 +546,12 @@ AFSQueryDirectory( IN PIRP Irp)
             }
         }
 
+        AFSReleaseResource( &pCcb->NPCcb->CcbLock);
+
+        AFSReleaseResource( pFcb->ObjectInformation->Specific.Directory.DirectoryNodeHdr.TreeLock);
+
+        bReleaseMain = FALSE;
+
         switch( FileInformationClass)
         {
 
@@ -595,22 +597,42 @@ AFSQueryDirectory( IN PIRP Irp)
 
                 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
                               AFS_TRACE_LEVEL_ERROR,
-                              "AFSQueryDirectory (%08lX) Unknown FileInformationClass %u\n",
+                              "AFSQueryDirectory (%p) Unknown FileInformationClass %u\n",
                               Irp,
                               FileInformationClass);
 
                 try_return( ntStatus = STATUS_INVALID_INFO_CLASS);
         }
 
-        AFSReleaseResource( pFcb->ObjectInformation->Specific.Directory.DirectoryNodeHdr.TreeLock);
-
-        bReleaseMain = FALSE;
-
         while( TRUE)
         {
 
             ULONG ulBytesRemainingInBuffer;
-            int rc;
+
+            //
+            // Drop the DirOpenReferenceCount held during a prior
+            // execution of the loop
+            //
+
+            if ( pDirEntry != NULL)
+            {
+
+                lCount = InterlockedDecrement( &pDirEntry->DirOpenReferenceCount);
+
+                AFSDbgLogMsg( AFS_SUBSYSTEM_DIRENTRY_REF_COUNTING,
+                              AFS_TRACE_LEVEL_VERBOSE,
+                              "AFSQueryDirectory Decrement count on %wZ DE %p Ccb %p Cnt %d\n",
+                              &pDirEntry->NameInformation.FileName,
+                              pDirEntry,
+                              pCcb,
+                              lCount);
+
+                ASSERT( lCount >= 0);
+
+                pDirEntry = NULL;
+            }
+
+            ulAdditionalAttributes = 0;
 
             //
             //  If the user had requested only a single match and we have
@@ -623,6 +645,10 @@ AFSQueryDirectory( IN PIRP Irp)
                 try_return( ntStatus);
             }
 
+            //
+            // On Success, pDirEntry has a held DirOpenReferenceCount
+            //
+
             pDirEntry = AFSLocateNextDirEntry( pFcb->ObjectInformation,
                                                pCcb);
 
@@ -655,8 +681,6 @@ AFSQueryDirectory( IN PIRP Irp)
                      BooleanFlagOn( pDirEntry->Flags, AFS_DIR_ENTRY_DELETED))
             {
 
-                InterlockedDecrement( &pDirEntry->OpenReferenceCount);
-
                 continue;
             }
 
@@ -679,8 +703,6 @@ AFSQueryDirectory( IN PIRP Irp)
                     if( !FlagOn( pObjectInfo->FileAttributes, FILE_ATTRIBUTE_DIRECTORY))
                     {
 
-                        InterlockedDecrement( &pDirEntry->OpenReferenceCount);
-
                         continue;
                     }
                 }
@@ -700,8 +722,6 @@ AFSQueryDirectory( IN PIRP Irp)
                                                       NULL))
                         {
 
-                            InterlockedDecrement( &pDirEntry->OpenReferenceCount);
-
                             continue;
                         }
                     }
@@ -722,8 +742,6 @@ AFSQueryDirectory( IN PIRP Irp)
                                                          TRUE))
                             {
 
-                                InterlockedDecrement( &pDirEntry->OpenReferenceCount);
-
                                 continue;
                             }
                         }
@@ -736,42 +754,27 @@ AFSQueryDirectory( IN PIRP Irp)
             // We don't worry about entries while enumerating the directory
             //
 
-            AFSValidateEntry( pDirEntry,
-                              &pFcb->AuthGroup,
-                              FALSE,
-                              FALSE);
-
-            pObjectInfo = pDirEntry->ObjectInformation;
-
-            bUseFileInfo = FALSE;
-
-            ulAdditionalAttributes = 0;
-
-            if( pObjectInfo->FileType == AFS_FILE_TYPE_SYMLINK)
+            if ( BooleanFlagOn( pDirEntry->ObjectInformation->Flags, AFS_OBJECT_FLAGS_VERIFY))
             {
 
-                //
-                // Go grab the file information for this entry
-                // No worries on failures since we will just display
-                // pseudo information
-                //
-
-                RtlZeroMemory( &stFileInfo,
-                               sizeof( AFSFileInfoCB));
-
-                if( NT_SUCCESS( AFSRetrieveFileAttributes( pCcb->DirectoryCB,
-                                                           pDirEntry,
-                                                           &pCcb->FullFileName,
-                                                           pCcb->NameArray,
-                                                           &stFileInfo)))
+                ntStatus = AFSValidateEntry( pDirEntry,
+                                             &pCcb->AuthGroup,
+                                             FALSE,
+                                             FALSE);
+                if ( NT_SUCCESS( ntStatus))
                 {
 
-                    ulAdditionalAttributes = FILE_ATTRIBUTE_REPARSE_POINT;
+                    ClearFlag( pDirEntry->ObjectInformation->Flags, AFS_OBJECT_FLAGS_VERIFY);
+                }
+                else
+                {
 
-                    bUseFileInfo = TRUE;
+                    ntStatus = STATUS_SUCCESS;
                 }
             }
 
+            pObjectInfo = pDirEntry->ObjectInformation;
+
             //  Here are the rules concerning filling up the buffer:
             //
             //  1.  The Io system guarantees that there will always be
@@ -799,11 +802,77 @@ AFSQueryDirectory( IN PIRP Irp)
 
                 pCcb->CurrentDirIndex--;
 
-                InterlockedDecrement( &pDirEntry->OpenReferenceCount);
-
                 try_return( ntStatus = STATUS_SUCCESS);
             }
 
+
+            //
+            // For Symlinks and Mount Points the reparse point attribute
+            // must be associated with the directory entry.  In addition,
+            // for Symlinks it must be determined if the target object is
+            // a directory or not.  If so, the directory attribute must be
+            // specified.  Mount points always refer to directories and
+            // must have the directory attribute set.
+            //
+
+            switch( pObjectInfo->FileType)
+            {
+
+            case AFS_FILE_TYPE_MOUNTPOINT:
+            case AFS_FILE_TYPE_DFSLINK:
+            {
+
+                ulAdditionalAttributes = FILE_ATTRIBUTE_DIRECTORY | FILE_ATTRIBUTE_REPARSE_POINT;
+
+                break;
+            }
+
+            case AFS_FILE_TYPE_SYMLINK:
+            {
+
+                //
+                // Go grab the file information for this entry
+                // No worries on failures since we will just display
+                // pseudo information
+                //
+
+                RtlZeroMemory( &stFileInfo,
+                               sizeof( AFSFileInfoCB));
+
+                if( NT_SUCCESS( AFSRetrieveFileAttributes( pCcb->DirectoryCB,
+                                                           pDirEntry,
+                                                           &pCcb->FullFileName,
+                                                           pCcb->NameArray,
+                                                           &pCcb->AuthGroup,
+                                                           &stFileInfo)))
+                {
+
+                    if ( stFileInfo.FileAttributes & FILE_ATTRIBUTE_DIRECTORY)
+                    {
+
+                        ulAdditionalAttributes = FILE_ATTRIBUTE_DIRECTORY;
+                    }
+                }
+
+                ulAdditionalAttributes |= FILE_ATTRIBUTE_REPARSE_POINT;
+
+                break;
+            }
+            }
+
+            //
+            // Check if the name begins with a . and we are hiding them
+            //
+
+            if( !BooleanFlagOn( pDirEntry->Flags, AFS_DIR_ENTRY_FAKE) &&
+                pDirEntry->NameInformation.FileName.Buffer[ 0] == L'.' &&
+                BooleanFlagOn( pDeviceExt->DeviceFlags, AFS_DEVICE_FLAG_HIDE_DOT_NAMES))
+            {
+
+                ulAdditionalAttributes |= FILE_ATTRIBUTE_HIDDEN;
+            }
+
+
             AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
                           AFS_TRACE_LEVEL_VERBOSE,
                           "AFSQueryDirectory Insert into parent %wZ Entry %wZ\n",
@@ -842,20 +911,7 @@ AFSQueryDirectory( IN PIRP Irp)
                 {
                     pDirInfo = (PFILE_DIRECTORY_INFORMATION)&pBuffer[ ulNextEntry];
 
-                    if( bUseFileInfo)
-                    {
-
-                        pDirInfo->CreationTime = stFileInfo.CreationTime;
-                        pDirInfo->LastWriteTime = stFileInfo.LastWriteTime;
-                        pDirInfo->LastAccessTime = stFileInfo.LastAccessTime;
-                        pDirInfo->ChangeTime = stFileInfo.ChangeTime;
-
-                        pDirInfo->EndOfFile = stFileInfo.EndOfFile;
-                        pDirInfo->AllocationSize = stFileInfo.AllocationSize;
-
-                        pDirInfo->FileAttributes = stFileInfo.FileAttributes | ulAdditionalAttributes;
-                    }
-                    else if( BooleanFlagOn( pDirEntry->Flags, AFS_DIR_ENTRY_FAKE))
+                    if( BooleanFlagOn( pDirEntry->Flags, AFS_DIR_ENTRY_FAKE))
                     {
 
                         pDirInfo->CreationTime = pFcb->ObjectInformation->CreationTime;
@@ -886,19 +942,16 @@ AFSQueryDirectory( IN PIRP Irp)
                         pDirInfo->EndOfFile = pObjectInfo->EndOfFile;
                         pDirInfo->AllocationSize = pObjectInfo->AllocationSize;
 
-                        pDirInfo->FileAttributes = pObjectInfo->FileAttributes | ulAdditionalAttributes;
-                    }
-
-                    //
-                    // Check if the name begins with a . and we are hiding them
-                    //
+                        if ( ulAdditionalAttributes && pObjectInfo->FileAttributes == FILE_ATTRIBUTE_NORMAL)
+                        {
 
-                    if( !BooleanFlagOn( pDirEntry->Flags, AFS_DIR_ENTRY_FAKE) &&
-                        pDirEntry->NameInformation.FileName.Buffer[ 0] == L'.' &&
-                        BooleanFlagOn( pDeviceExt->DeviceFlags, AFS_DEVICE_FLAG_HIDE_DOT_NAMES))
-                    {
+                            pDirInfo->FileAttributes = ulAdditionalAttributes;
+                        }
+                        else
+                        {
 
-                        pDirInfo->FileAttributes |= FILE_ATTRIBUTE_HIDDEN;
+                            pDirInfo->FileAttributes = pObjectInfo->FileAttributes | ulAdditionalAttributes;
+                        }
                     }
 
                     pDirInfo->FileIndex = pDirEntry->FileIndex;
@@ -915,19 +968,16 @@ AFSQueryDirectory( IN PIRP Irp)
 
                     break;
                 }
+
                 default:
                 {
                     AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
                                   AFS_TRACE_LEVEL_ERROR,
-                                  "AFSQueryDirectory (%08lX) Unknown FileInformationClass %u\n",
+                                  "AFSQueryDirectory (%p) Unknown FileInformationClass %u\n",
                                   Irp,
                                   FileInformationClass);
 
-                    InterlockedDecrement( &pDirEntry->OpenReferenceCount);
-
                     try_return( ntStatus = STATUS_INVALID_INFO_CLASS);
-
-                    break;
                 }
             }
 
@@ -951,13 +1001,9 @@ AFSQueryDirectory( IN PIRP Irp)
             if( ulBytesConverted < pDirEntry->NameInformation.FileName.Length)
             {
 
-                InterlockedDecrement( &pDirEntry->OpenReferenceCount);
-
                 try_return( ntStatus = STATUS_BUFFER_OVERFLOW);
             }
 
-            InterlockedDecrement( &pDirEntry->OpenReferenceCount);
-
             dStatus = STATUS_SUCCESS;
 
             //  Set ourselves up for the next iteration
@@ -967,12 +1013,34 @@ AFSQueryDirectory( IN PIRP Irp)
 
 try_exit:
 
+        if ( pDirEntry != NULL)
+        {
+
+            lCount = InterlockedDecrement( &pDirEntry->DirOpenReferenceCount);
+
+            AFSDbgLogMsg( AFS_SUBSYSTEM_DIRENTRY_REF_COUNTING,
+                          AFS_TRACE_LEVEL_VERBOSE,
+                          "AFSQueryDirectory Decrement8 count on %wZ DE %p Ccb %p Cnt %d\n",
+                          &pDirEntry->NameInformation.FileName,
+                          pDirEntry,
+                          pCcb,
+                          lCount);
+
+            ASSERT( lCount >= 0);
+        }
+
         if( bReleaseMain)
         {
 
             AFSReleaseResource( pFcb->ObjectInformation->Specific.Directory.DirectoryNodeHdr.TreeLock);
         }
 
+        if ( bReleaseFcb)
+        {
+
+            AFSReleaseResource( &pFcb->NPFcb->Resource);
+        }
+
         if( pFcb != NULL)
         {
 
@@ -1009,7 +1077,7 @@ AFSNotifyChangeDirectory( IN PIRP Irp)
 
             AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
                           AFS_TRACE_LEVEL_ERROR,
-                          "AFSNotifyChangeDirectory Attempted access (%08lX) when pFcb == NULL\n",
+                          "AFSNotifyChangeDirectory Attempted access (%p) when pFcb == NULL\n",
                           Irp);
 
             try_return( ntStatus = STATUS_INVALID_DEVICE_REQUEST);
@@ -1035,7 +1103,7 @@ AFSNotifyChangeDirectory( IN PIRP Irp)
 
         AFSDbgLogMsg( AFS_SUBSYSTEM_LOCK_PROCESSING,
                       AFS_TRACE_LEVEL_VERBOSE,
-                      "AFSNotifyChangeDirectory Acquiring Dcb lock %08lX EXCL %08lX\n",
+                      "AFSNotifyChangeDirectory Acquiring Dcb lock %p EXCL %08lX\n",
                       &pFcb->NPFcb->Resource,
                       PsGetCurrentThread());
 
@@ -1095,10 +1163,17 @@ AFSLocateNextDirEntry( IN AFSObjectInfoCB *ObjectInfo,
     AFSSnapshotHdr *pSnapshotHdr = NULL;
     AFSSnapshotEntry *pSnapshotEntry = NULL;
     ULONG ulCount = 0;
+    LONG lCount;
 
     __Enter
     {
 
+        AFSAcquireShared( ObjectInfo->Specific.Directory.DirectoryNodeHdr.TreeLock,
+                          TRUE);
+
+        AFSAcquireExcl( &Ccb->NPCcb->CcbLock,
+                        TRUE);
+
         //
         // Is this a PIOCtl query
         //
@@ -1190,9 +1265,6 @@ AFSLocateNextDirEntry( IN AFSObjectInfoCB *ObjectInfo,
             // Get to a valid entry
             //
 
-            AFSAcquireShared( ObjectInfo->Specific.Directory.DirectoryNodeHdr.TreeLock,
-                              TRUE);
-
             while( ulCount < pSnapshotHdr->EntryCount)
             {
 
@@ -1229,8 +1301,6 @@ AFSLocateNextDirEntry( IN AFSObjectInfoCB *ObjectInfo,
                                       ObjectInfo->FileId.Volume,
                                       ObjectInfo->FileId.Vnode,
                                       ObjectInfo->FileId.Unique);
-
-                        InterlockedIncrement( &pDirEntry->OpenReferenceCount);
                     }
                     else
                     {
@@ -1263,13 +1333,29 @@ AFSLocateNextDirEntry( IN AFSObjectInfoCB *ObjectInfo,
 
                 Ccb->CurrentDirIndex++;
             }
-
-            AFSReleaseResource( ObjectInfo->Specific.Directory.DirectoryNodeHdr.TreeLock);
         }
 
 try_exit:
 
-        NOTHING;
+        if( pDirEntry != NULL)
+        {
+
+            lCount = InterlockedIncrement( &pDirEntry->DirOpenReferenceCount);
+
+            AFSDbgLogMsg( AFS_SUBSYSTEM_DIRENTRY_REF_COUNTING,
+                          AFS_TRACE_LEVEL_VERBOSE,
+                          "AFSLocateNextDirEntry Increment count on %wZ DE %p Ccb %p Cnt %d\n",
+                          &pDirEntry->NameInformation.FileName,
+                          pDirEntry,
+                          Ccb,
+                          lCount);
+
+            ASSERT( lCount >= 0);
+        }
+
+        AFSReleaseResource( &Ccb->NPCcb->CcbLock);
+
+        AFSReleaseResource( ObjectInfo->Specific.Directory.DirectoryNodeHdr.TreeLock);
     }
 
     return pDirEntry;
@@ -1290,6 +1376,9 @@ AFSLocateDirEntryByIndex( IN AFSObjectInfoCB *ObjectInfo,
     __Enter
     {
 
+        AFSAcquireExcl( &Ccb->NPCcb->CcbLock,
+                        TRUE);
+
         Ccb->CurrentDirIndex = DirIndex;
 
         if( DirIndex == (ULONG)AFS_DIR_ENTRY_DOT_INDEX)
@@ -1361,7 +1450,7 @@ AFSLocateDirEntryByIndex( IN AFSObjectInfoCB *ObjectInfo,
 
 try_exit:
 
-        NOTHING;
+        AFSReleaseResource( &Ccb->NPCcb->CcbLock);
     }
 
     return pDirEntry;
@@ -1410,7 +1499,7 @@ AFSSnapshotDirectory( IN AFSFcb *Fcb,
             if( Ccb->DirectorySnapshot != NULL)
             {
 
-                AFSExFreePool( Ccb->DirectorySnapshot);
+                AFSExFreePoolWithTag( Ccb->DirectorySnapshot, AFS_DIR_SNAPSHOT_TAG);
 
                 Ccb->DirectorySnapshot = NULL;
             }
@@ -1498,7 +1587,7 @@ AFSSnapshotDirectory( IN AFSFcb *Fcb,
         if( Ccb->DirectorySnapshot != NULL)
         {
 
-            AFSExFreePool( Ccb->DirectorySnapshot);
+            AFSExFreePoolWithTag( Ccb->DirectorySnapshot, AFS_DIR_SNAPSHOT_TAG);
 
             Ccb->DirectorySnapshot = NULL;
         }
@@ -1528,6 +1617,9 @@ AFSFsRtlNotifyFullChangeDirectory( IN AFSObjectInfoCB *ObjectInfo,
     __Enter
     {
 
+        AFSAcquireExcl( &Ccb->NPCcb->CcbLock,
+                        TRUE);
+
         //
         // Build a dir name based on the FID of the file
         //
@@ -1577,7 +1669,7 @@ AFSFsRtlNotifyFullChangeDirectory( IN AFSObjectInfoCB *ObjectInfo,
 
         AFSDbgLogMsg( AFS_SUBSYSTEM_DIR_NOTIF_PROCESSING,
                       AFS_TRACE_LEVEL_VERBOSE,
-                      "AFSFsRtlNotifyFullChangeDirectory Registering notification on %wZ Irp %08lX Filter %08lX Tree %02lX\n",
+                      "AFSFsRtlNotifyFullChangeDirectory Registering notification on %wZ Irp %p Filter %08lX Tree %02lX\n",
                       &Ccb->NotifyMask,
                       NotifyIrp,
                       CompletionFilter,
@@ -1603,11 +1695,13 @@ try_exit:
             if( Ccb->NotifyMask.Buffer != NULL)
             {
 
-                AFSExFreePool( Ccb->NotifyMask.Buffer);
+                AFSExFreePoolWithTag( Ccb->NotifyMask.Buffer, AFS_GENERIC_MEMORY_7_TAG);
 
                 Ccb->NotifyMask.Buffer = NULL;
             }
         }
+
+        AFSReleaseResource( &Ccb->NPCcb->CcbLock);
     }
 
     return ntStatus;
@@ -1722,7 +1816,7 @@ try_exit:
         if( uniName.Buffer != NULL)
         {
 
-            AFSExFreePool( uniName.Buffer);
+            AFSExFreePoolWithTag( uniName.Buffer, AFS_GENERIC_MEMORY_8_TAG);
         }
     }
 
@@ -1737,10 +1831,9 @@ BOOLEAN
 AFSNotifyReportChangeCallback( IN void *NotifyContext,
                                IN void *FilterContext)
 {
-
+    UNREFERENCED_PARAMETER(NotifyContext);
+    UNREFERENCED_PARAMETER(FilterContext);
     BOOLEAN bReturn = TRUE;
-    AFSCcb *pDirCcb = (AFSCcb *)NotifyContext;
-    AFSCcb *pNotifyCcb = (AFSCcb *)FilterContext;
 
     __Enter
     {