Windows: Move Name Array functions to new file
authorJeffrey Altman <jaltman@your-file-system.com>
Sat, 30 Mar 2013 23:54:11 +0000 (19:54 -0400)
committerJeffrey Altman <jaltman@your-file-system.com>
Fri, 5 Apr 2013 17:12:58 +0000 (10:12 -0700)
In an effort to reduce some of the clutter in AFSGeneric.cpp,
move the Name Array functions to AFSNameArray.cpp.

Change-Id: I97c9c5c67229851cbe937a603a93a2db97d6c12c
Reviewed-on: http://gerrit.openafs.org/9696
Reviewed-by: Peter Scott <pscott@kerneldrivers.com>
Tested-by: BuildBot <buildbot@rampaginggeek.com>
Reviewed-by: Jeffrey Altman <jaltman@your-file-system.com>
Tested-by: Jeffrey Altman <jaltman@your-file-system.com>

src/WINNT/afsrdr/kernel/lib/AFSGeneric.cpp
src/WINNT/afsrdr/kernel/lib/AFSNameArray.cpp [new file with mode: 0644]
src/WINNT/afsrdr/kernel/lib/Include/AFSCommon.h
src/WINNT/afsrdr/kernel/lib/sources

index f5bb20c..ce9fffc 100644 (file)
@@ -5068,755 +5068,6 @@ try_exit:
     return ntStatus;
 }
 
-AFSNameArrayHdr *
-AFSInitNameArray( IN AFSDirectoryCB *DirectoryCB,
-                  IN ULONG InitialElementCount)
-{
-
-    AFSNameArrayHdr *pNameArray = NULL;
-    AFSNameArrayCB *pCurrentElement = NULL;
-    AFSDeviceExt *pDevExt = (AFSDeviceExt *) AFSRDRDeviceObject->DeviceExtension;
-    LONG lCount;
-
-    __Enter
-    {
-
-        if( InitialElementCount == 0)
-        {
-
-            InitialElementCount = pDevExt->Specific.RDR.NameArrayLength;
-        }
-
-        pNameArray = (AFSNameArrayHdr *)AFSExAllocatePoolWithTag( PagedPool,
-                                                                  sizeof( AFSNameArrayHdr) +
-                                                                    (InitialElementCount * sizeof( AFSNameArrayCB)),
-                                                                  AFS_NAME_ARRAY_TAG);
-
-        if( pNameArray == NULL)
-        {
-
-            AFSDbgTrace(( AFS_SUBSYSTEM_NAME_ARRAY_PROCESSING,
-                          AFS_TRACE_LEVEL_ERROR,
-                          "AFSInitNameArray Failed to allocate name array\n"));
-
-            try_return( pNameArray);
-        }
-
-        RtlZeroMemory( pNameArray,
-                       sizeof( AFSNameArrayHdr) +
-                          (InitialElementCount * sizeof( AFSNameArrayCB)));
-
-        pNameArray->MaxElementCount = InitialElementCount;
-
-        if( DirectoryCB != NULL)
-        {
-
-            pCurrentElement = &pNameArray->ElementArray[ 0];
-
-            pNameArray->CurrentEntry = pCurrentElement;
-
-            pNameArray->Count = 1;
-
-            pNameArray->LinkCount = 0;
-
-            lCount = InterlockedIncrement( &DirectoryCB->NameArrayReferenceCount);
-
-            AFSDbgTrace(( AFS_SUBSYSTEM_NAME_ARRAY_REF_COUNTING,
-                          AFS_TRACE_LEVEL_VERBOSE,
-                          "AFSInitNameArray [NA:%p] Increment count on %wZ DE %p Cnt %d\n",
-                          pNameArray,
-                          &DirectoryCB->NameInformation.FileName,
-                          DirectoryCB,
-                          lCount));
-
-            pCurrentElement->DirectoryCB = DirectoryCB;
-
-            pCurrentElement->Component = DirectoryCB->NameInformation.FileName;
-
-            pCurrentElement->FileId = DirectoryCB->ObjectInformation->FileId;
-
-            if( pCurrentElement->FileId.Vnode == 1)
-            {
-
-                SetFlag( pCurrentElement->Flags, AFS_NAME_ARRAY_FLAG_ROOT_ELEMENT);
-            }
-
-            AFSDbgTrace(( AFS_SUBSYSTEM_NAME_ARRAY_PROCESSING,
-                          AFS_TRACE_LEVEL_VERBOSE,
-                          "AFSInitNameArray [NA:%p] Element[0] DE %p FID %08lX-%08lX-%08lX-%08lX %wZ Type %d\n",
-                          pNameArray,
-                          pCurrentElement->DirectoryCB,
-                          pCurrentElement->FileId.Cell,
-                          pCurrentElement->FileId.Volume,
-                          pCurrentElement->FileId.Vnode,
-                          pCurrentElement->FileId.Unique,
-                          &pCurrentElement->DirectoryCB->NameInformation.FileName,
-                          pCurrentElement->DirectoryCB->ObjectInformation->FileType));
-        }
-
-try_exit:
-
-        NOTHING;
-    }
-
-    return pNameArray;
-}
-
-NTSTATUS
-AFSPopulateNameArray( IN AFSNameArrayHdr *NameArray,
-                      IN UNICODE_STRING *Path,
-                      IN AFSDirectoryCB *DirectoryCB)
-{
-
-    NTSTATUS ntStatus = STATUS_SUCCESS;
-    AFSNameArrayCB *pCurrentElement = NULL;
-    LONG lCount;
-
-    __Enter
-    {
-
-        AFSDbgTrace(( AFS_SUBSYSTEM_NAME_ARRAY_PROCESSING,
-                      AFS_TRACE_LEVEL_VERBOSE,
-                      "AFSPopulateNameArray [NA:%p] passed Path %wZ DE %p FID %08lX-%08lX-%08lX-%08lX %wZ Type %d\n",
-                      NameArray,
-                      &Path,
-                      DirectoryCB,
-                      DirectoryCB->ObjectInformation->FileId.Cell,
-                      DirectoryCB->ObjectInformation->FileId.Volume,
-                      DirectoryCB->ObjectInformation->FileId.Vnode,
-                      DirectoryCB->ObjectInformation->FileId.Unique,
-                      &DirectoryCB->NameInformation.FileName,
-                      DirectoryCB->ObjectInformation->FileType));
-
-        //
-        // Init some info in the header
-        //
-
-        pCurrentElement = &NameArray->ElementArray[ 0];
-
-        NameArray->CurrentEntry = pCurrentElement;
-
-        //
-        // The first entry points at the root
-        //
-
-        pCurrentElement->DirectoryCB = DirectoryCB->ObjectInformation->VolumeCB->DirectoryCB;
-
-        lCount = InterlockedIncrement( &pCurrentElement->DirectoryCB->NameArrayReferenceCount);
-
-        AFSDbgTrace(( AFS_SUBSYSTEM_NAME_ARRAY_REF_COUNTING,
-                      AFS_TRACE_LEVEL_VERBOSE,
-                      "AFSPopulateNameArray [NA:%p] Increment count on volume %wZ DE %p Cnt %d\n",
-                      NameArray,
-                      &pCurrentElement->DirectoryCB->NameInformation.FileName,
-                      pCurrentElement->DirectoryCB,
-                      lCount));
-
-        pCurrentElement->Component = DirectoryCB->ObjectInformation->VolumeCB->DirectoryCB->NameInformation.FileName;
-
-        pCurrentElement->FileId = DirectoryCB->ObjectInformation->VolumeCB->ObjectInformation.FileId;
-
-        pCurrentElement->Flags = 0;
-
-        if( pCurrentElement->FileId.Vnode == 1)
-        {
-
-            SetFlag( pCurrentElement->Flags, AFS_NAME_ARRAY_FLAG_ROOT_ELEMENT);
-        }
-
-        NameArray->Count = 1;
-
-        NameArray->LinkCount = 0;
-
-        AFSDbgTrace(( AFS_SUBSYSTEM_NAME_ARRAY_PROCESSING,
-                      AFS_TRACE_LEVEL_VERBOSE,
-                      "AFSPopulateNameArray [NA:%p] Element[0] DE %p FID %08lX-%08lX-%08lX-%08lX %wZ Type %d\n",
-                      NameArray,
-                      pCurrentElement->DirectoryCB,
-                      pCurrentElement->FileId.Cell,
-                      pCurrentElement->FileId.Volume,
-                      pCurrentElement->FileId.Vnode,
-                      pCurrentElement->FileId.Unique,
-                      &pCurrentElement->DirectoryCB->NameInformation.FileName,
-                      pCurrentElement->DirectoryCB->ObjectInformation->FileType));
-
-        //
-        // If the root is the parent then we are done ...
-        //
-
-        if( &DirectoryCB->ObjectInformation->VolumeCB->ObjectInformation == DirectoryCB->ObjectInformation)
-        {
-            try_return( ntStatus);
-        }
-
-try_exit:
-
-        NOTHING;
-    }
-
-    return ntStatus;
-}
-
-NTSTATUS
-AFSPopulateNameArrayFromRelatedArray( IN AFSNameArrayHdr *NameArray,
-                                      IN AFSNameArrayHdr *RelatedNameArray,
-                                      IN AFSDirectoryCB *DirectoryCB)
-{
-
-    NTSTATUS ntStatus = STATUS_SUCCESS;
-    AFSNameArrayCB *pCurrentElement = NULL, *pCurrentRelatedElement = NULL;
-    LONG lCount;
-
-    __Enter
-    {
-
-        if ( DirectoryCB)
-        {
-
-            AFSDbgTrace(( AFS_SUBSYSTEM_NAME_ARRAY_PROCESSING,
-                          AFS_TRACE_LEVEL_VERBOSE,
-                          "AFSPopulateNameArray [NA:%p] passed RelatedNameArray %p DE %p FID %08lX-%08lX-%08lX-%08lX %wZ Type %d\n",
-                          NameArray,
-                          RelatedNameArray,
-                          DirectoryCB,
-                          DirectoryCB->ObjectInformation->FileId.Cell,
-                          DirectoryCB->ObjectInformation->FileId.Volume,
-                          DirectoryCB->ObjectInformation->FileId.Vnode,
-                          DirectoryCB->ObjectInformation->FileId.Unique,
-                          &DirectoryCB->NameInformation.FileName,
-                          DirectoryCB->ObjectInformation->FileType));
-        }
-        else
-        {
-
-            AFSDbgTrace(( AFS_SUBSYSTEM_NAME_ARRAY_PROCESSING,
-                          AFS_TRACE_LEVEL_VERBOSE,
-                          "AFSPopulateNameArray [NA:%p] passed RelatedNameArray %p DE NULL\n",
-                          NameArray,
-                          RelatedNameArray));
-        }
-
-        //
-        // Init some info in the header
-        //
-
-        pCurrentElement = &NameArray->ElementArray[ 0];
-
-        pCurrentRelatedElement = &RelatedNameArray->ElementArray[ 0];
-
-        NameArray->Count = 0;
-
-        NameArray->LinkCount = RelatedNameArray->LinkCount;
-
-        //
-        // Populate the name array with the data from the related array
-        //
-
-        while( TRUE)
-        {
-
-            pCurrentElement->DirectoryCB = pCurrentRelatedElement->DirectoryCB;
-
-            pCurrentElement->Component = pCurrentRelatedElement->DirectoryCB->NameInformation.FileName;
-
-            pCurrentElement->FileId    = pCurrentElement->DirectoryCB->ObjectInformation->FileId;
-
-            pCurrentElement->Flags = 0;
-
-            if( pCurrentElement->FileId.Vnode == 1)
-            {
-
-                SetFlag( pCurrentElement->Flags, AFS_NAME_ARRAY_FLAG_ROOT_ELEMENT);
-            }
-
-            lCount = InterlockedIncrement( &pCurrentElement->DirectoryCB->NameArrayReferenceCount);
-
-            AFSDbgTrace(( AFS_SUBSYSTEM_NAME_ARRAY_REF_COUNTING,
-                          AFS_TRACE_LEVEL_VERBOSE,
-                          "AFSPopulateNameArrayFromRelatedArray [NA:%p] Increment count on %wZ DE %p Cnt %d\n",
-                          NameArray,
-                          &pCurrentElement->DirectoryCB->NameInformation.FileName,
-                          pCurrentElement->DirectoryCB,
-                          lCount));
-
-            lCount = InterlockedIncrement( &NameArray->Count);
-
-            AFSDbgTrace(( AFS_SUBSYSTEM_NAME_ARRAY_PROCESSING,
-                          AFS_TRACE_LEVEL_VERBOSE,
-                          "AFSPopulateNameArrayFromRelatedArray [NA:%p] Element[%d] DE %p FID %08lX-%08lX-%08lX-%08lX %wZ Type %d\n",
-                          NameArray,
-                          lCount - 1,
-                          pCurrentElement->DirectoryCB,
-                          pCurrentElement->FileId.Cell,
-                          pCurrentElement->FileId.Volume,
-                          pCurrentElement->FileId.Vnode,
-                          pCurrentElement->FileId.Unique,
-                          &pCurrentElement->DirectoryCB->NameInformation.FileName,
-                          pCurrentElement->DirectoryCB->ObjectInformation->FileType));
-
-            if( pCurrentElement->DirectoryCB == DirectoryCB ||
-                NameArray->Count == RelatedNameArray->Count)
-            {
-
-                //
-                // Done ...
-                //
-
-                break;
-            }
-
-            pCurrentElement++;
-
-            pCurrentRelatedElement++;
-        }
-
-        NameArray->CurrentEntry = NameArray->Count > 0 ? pCurrentElement : NULL;
-    }
-
-    return ntStatus;
-}
-
-NTSTATUS
-AFSFreeNameArray( IN AFSNameArrayHdr *NameArray)
-{
-
-    NTSTATUS ntStatus = STATUS_SUCCESS;
-    AFSNameArrayCB *pCurrentElement = NULL;
-    LONG lCount, lElement;
-
-    __Enter
-    {
-
-        AFSDbgTrace(( AFS_SUBSYSTEM_NAME_ARRAY_PROCESSING,
-                      AFS_TRACE_LEVEL_VERBOSE,
-                      "AFSFreeNameArray [NA:%p]\n",
-                      NameArray));
-
-        for ( lElement = 0; lElement < NameArray->Count; lElement++)
-        {
-
-            pCurrentElement = &NameArray->ElementArray[ lElement];
-
-            lCount = InterlockedDecrement( &pCurrentElement->DirectoryCB->NameArrayReferenceCount);
-
-            AFSDbgTrace(( AFS_SUBSYSTEM_NAME_ARRAY_REF_COUNTING,
-                          AFS_TRACE_LEVEL_VERBOSE,
-                          "AFSFreeNameArray [NA:%p] Decrement count on %wZ DE %p Cnt %d\n",
-                          NameArray,
-                          &pCurrentElement->DirectoryCB->NameInformation.FileName,
-                          pCurrentElement->DirectoryCB,
-                          lCount));
-
-            ASSERT( lCount >= 0);
-        }
-
-        AFSExFreePoolWithTag( NameArray, AFS_NAME_ARRAY_TAG);
-    }
-
-    return ntStatus;
-}
-
-NTSTATUS
-AFSInsertNextElement( IN AFSNameArrayHdr *NameArray,
-                      IN AFSDirectoryCB *DirectoryCB)
-{
-
-    NTSTATUS ntStatus = STATUS_SUCCESS;
-    AFSNameArrayCB *pCurrentElement = NULL;
-    LONG lCount;
-
-    __Enter
-    {
-
-        AFSDbgTrace(( AFS_SUBSYSTEM_NAME_ARRAY_PROCESSING,
-                      AFS_TRACE_LEVEL_VERBOSE,
-                      "AFSInsertNextElement [NA:%p] passed DE %p FID %08lX-%08lX-%08lX-%08lX %wZ Type %d\n",
-                      NameArray,
-                      DirectoryCB,
-                      DirectoryCB->ObjectInformation->FileId.Cell,
-                      DirectoryCB->ObjectInformation->FileId.Volume,
-                      DirectoryCB->ObjectInformation->FileId.Vnode,
-                      DirectoryCB->ObjectInformation->FileId.Unique,
-                      &DirectoryCB->NameInformation.FileName,
-                      DirectoryCB->ObjectInformation->FileType));
-
-        if( NameArray->Count == (LONG) NameArray->MaxElementCount)
-        {
-
-            AFSDbgTrace(( AFS_SUBSYSTEM_NAME_ARRAY_PROCESSING,
-                          AFS_TRACE_LEVEL_ERROR,
-                          "AFSInsertNextElement [NA:%p] Name has reached Maximum Size\n",
-                          NameArray));
-
-            try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
-        }
-
-        for ( lCount = 0; lCount < NameArray->Count; lCount++)
-        {
-
-            if ( AFSIsEqualFID( &NameArray->ElementArray[ lCount].FileId,
-                                &DirectoryCB->ObjectInformation->FileId) )
-            {
-
-                AFSDbgTrace(( AFS_SUBSYSTEM_NAME_ARRAY_PROCESSING,
-                              AFS_TRACE_LEVEL_WARNING,
-                              "AFSInsertNextElement [NA:%p] DE %p recursion Status %08X\n",
-                              NameArray,
-                              DirectoryCB,
-                              STATUS_ACCESS_DENIED));
-
-                try_return( ntStatus = STATUS_ACCESS_DENIED);
-            }
-        }
-
-        if( NameArray->Count > 0)
-        {
-
-            NameArray->CurrentEntry++;
-        }
-        else
-        {
-            NameArray->CurrentEntry = &NameArray->ElementArray[ 0];
-        }
-
-        pCurrentElement = NameArray->CurrentEntry;
-
-        lCount = InterlockedIncrement( &NameArray->Count);
-
-        lCount = InterlockedIncrement( &DirectoryCB->NameArrayReferenceCount);
-
-        AFSDbgTrace(( AFS_SUBSYSTEM_NAME_ARRAY_REF_COUNTING,
-                      AFS_TRACE_LEVEL_VERBOSE,
-                      "AFSInsertNextElement [NA:%p] Increment count on %wZ DE %p Cnt %d\n",
-                      NameArray,
-                      &DirectoryCB->NameInformation.FileName,
-                      DirectoryCB,
-                      lCount));
-
-        ASSERT( lCount > 0);
-
-        pCurrentElement->DirectoryCB = DirectoryCB;
-
-        pCurrentElement->Component = DirectoryCB->NameInformation.FileName;
-
-        pCurrentElement->FileId = DirectoryCB->ObjectInformation->FileId;
-
-        pCurrentElement->Flags = 0;
-
-        if( pCurrentElement->FileId.Vnode == 1)
-        {
-
-            SetFlag( pCurrentElement->Flags, AFS_NAME_ARRAY_FLAG_ROOT_ELEMENT);
-        }
-
-        AFSDbgTrace(( AFS_SUBSYSTEM_NAME_ARRAY_PROCESSING,
-                      AFS_TRACE_LEVEL_VERBOSE,
-                      "AFSInsertNextElement [NA:%p] Element[%d] DE %p FID %08lX-%08lX-%08lX-%08lX %wZ Type %d\n",
-                      NameArray,
-                      NameArray->Count - 1,
-                      pCurrentElement->DirectoryCB,
-                      pCurrentElement->FileId.Cell,
-                      pCurrentElement->FileId.Volume,
-                      pCurrentElement->FileId.Vnode,
-                      pCurrentElement->FileId.Unique,
-                      &pCurrentElement->DirectoryCB->NameInformation.FileName,
-                      pCurrentElement->DirectoryCB->ObjectInformation->FileType));
-
-try_exit:
-
-        NOTHING;
-    }
-
-    return ntStatus;
-}
-
-AFSDirectoryCB *
-AFSBackupEntry( IN AFSNameArrayHdr *NameArray)
-{
-
-    AFSDirectoryCB *pDirectoryCB = NULL;
-    AFSNameArrayCB *pCurrentElement = NULL;
-    BOOLEAN         bVolumeRoot = FALSE;
-    LONG lCount;
-
-    __Enter
-    {
-
-        AFSDbgTrace(( AFS_SUBSYSTEM_NAME_ARRAY_PROCESSING,
-                      AFS_TRACE_LEVEL_VERBOSE,
-                      "AFSBackupEntry [NA:%p]\n",
-                      NameArray));
-
-        if( NameArray->Count == 0)
-        {
-
-            AFSDbgTrace(( AFS_SUBSYSTEM_NAME_ARRAY_PROCESSING,
-                          AFS_TRACE_LEVEL_ERROR,
-                          "AFSBackupEntry [NA:%p] No more entries\n",
-                          NameArray));
-
-            try_return( pCurrentElement);
-        }
-
-        lCount = InterlockedDecrement( &NameArray->CurrentEntry->DirectoryCB->NameArrayReferenceCount);
-
-        AFSDbgTrace(( AFS_SUBSYSTEM_NAME_ARRAY_REF_COUNTING,
-                      AFS_TRACE_LEVEL_VERBOSE,
-                      "AFSBackupEntry [NA:%p] Decrement count on %wZ DE %p Cnt %d\n",
-                      NameArray,
-                      &NameArray->CurrentEntry->DirectoryCB->NameInformation.FileName,
-                      NameArray->CurrentEntry->DirectoryCB,
-                      lCount));
-
-        ASSERT( lCount >= 0);
-
-        NameArray->CurrentEntry->DirectoryCB = NULL;
-
-        lCount = InterlockedDecrement( &NameArray->Count);
-
-        if( lCount == 0)
-        {
-            NameArray->CurrentEntry = NULL;
-
-            AFSDbgTrace(( AFS_SUBSYSTEM_NAME_ARRAY_PROCESSING,
-                          AFS_TRACE_LEVEL_ERROR,
-                          "AFSBackupEntry [NA:%p] No more entries\n",
-                          NameArray));
-        }
-        else
-        {
-
-            bVolumeRoot = BooleanFlagOn( NameArray->CurrentEntry->Flags, AFS_NAME_ARRAY_FLAG_ROOT_ELEMENT);
-
-            NameArray->CurrentEntry--;
-
-            pCurrentElement = NameArray->CurrentEntry;
-
-            pDirectoryCB = pCurrentElement->DirectoryCB;
-
-            AFSDbgTrace(( AFS_SUBSYSTEM_NAME_ARRAY_PROCESSING,
-                          AFS_TRACE_LEVEL_VERBOSE,
-                          "AFSBackupEntry [NA:%p] Returning Element[%d] DE %p FID %08lX-%08lX-%08lX-%08lX %wZ Type %d\n",
-                          NameArray,
-                          NameArray->Count - 1,
-                          pCurrentElement->DirectoryCB,
-                          pCurrentElement->FileId.Cell,
-                          pCurrentElement->FileId.Volume,
-                          pCurrentElement->FileId.Vnode,
-                          pCurrentElement->FileId.Unique,
-                          &pCurrentElement->DirectoryCB->NameInformation.FileName,
-                          pCurrentElement->DirectoryCB->ObjectInformation->FileType));
-
-            //
-            // If the entry we are removing is a volume root,
-            // we must remove the mount point entry as well.
-            // If the NameArray was constructed by checking the
-            // share name via the service, the name array can
-            // contain two volume roots in sequence without a
-            // mount point separating them.
-            //
-
-            if ( bVolumeRoot &&
-                 !BooleanFlagOn( NameArray->CurrentEntry->Flags, AFS_NAME_ARRAY_FLAG_ROOT_ELEMENT))
-            {
-
-                pDirectoryCB = AFSBackupEntry( NameArray);
-            }
-        }
-
-
-try_exit:
-
-        NOTHING;
-    }
-
-    return pDirectoryCB;
-}
-
-AFSDirectoryCB *
-AFSGetParentEntry( IN AFSNameArrayHdr *NameArray)
-{
-
-    AFSDirectoryCB *pDirEntry = NULL;
-    AFSNameArrayCB *pElement = NULL;
-
-    __Enter
-    {
-
-        AFSDbgTrace(( AFS_SUBSYSTEM_NAME_ARRAY_PROCESSING,
-                      AFS_TRACE_LEVEL_VERBOSE,
-                      "AFSGetParentEntry [NA:%p]\n",
-                      NameArray));
-
-        if( NameArray->Count == 0 ||
-            NameArray->Count == 1)
-        {
-
-            AFSDbgTrace(( AFS_SUBSYSTEM_NAME_ARRAY_PROCESSING,
-                          AFS_TRACE_LEVEL_ERROR,
-                          "AFSGetParentEntry [NA:%p] No more entries\n",
-                          NameArray));
-
-            try_return( pDirEntry = NULL);
-        }
-
-        pElement = &NameArray->ElementArray[ NameArray->Count - 2];
-
-        pDirEntry = pElement->DirectoryCB;
-
-        AFSDbgTrace(( AFS_SUBSYSTEM_NAME_ARRAY_PROCESSING,
-                      AFS_TRACE_LEVEL_VERBOSE,
-                      "AFSGetParentEntry [NA:%p] Returning Element[%d] DE %p FID %08lX-%08lX-%08lX-%08lX %wZ Type %d\n",
-                      NameArray,
-                      NameArray->Count - 2,
-                      pElement->DirectoryCB,
-                      pElement->FileId.Cell,
-                      pElement->FileId.Volume,
-                      pElement->FileId.Vnode,
-                      pElement->FileId.Unique,
-                      &pElement->DirectoryCB->NameInformation.FileName,
-                      pElement->DirectoryCB->ObjectInformation->FileType));
-
-try_exit:
-
-        NOTHING;
-    }
-
-    return pDirEntry;
-}
-
-void
-AFSResetNameArray( IN AFSNameArrayHdr *NameArray,
-                   IN AFSDirectoryCB *DirectoryCB)
-{
-
-    AFSNameArrayCB *pCurrentElement = NULL;
-    AFSDeviceExt *pDevExt = (AFSDeviceExt *) AFSRDRDeviceObject->DeviceExtension;
-    LONG lCount, lElement;
-
-    __Enter
-    {
-
-        AFSDbgTrace(( AFS_SUBSYSTEM_NAME_ARRAY_PROCESSING,
-                      AFS_TRACE_LEVEL_VERBOSE,
-                      "AFSResetNameArray [NA:%p] passed DE %p FID %08lX-%08lX-%08lX-%08lX %wZ Type %d\n",
-                      NameArray,
-                      DirectoryCB,
-                      DirectoryCB->ObjectInformation->FileId.Cell,
-                      DirectoryCB->ObjectInformation->FileId.Volume,
-                      DirectoryCB->ObjectInformation->FileId.Vnode,
-                      DirectoryCB->ObjectInformation->FileId.Unique,
-                      &DirectoryCB->NameInformation.FileName,
-                      DirectoryCB->ObjectInformation->FileType));
-
-        //
-        // Dereference previous name array contents
-        //
-
-        for ( lElement = 0; lElement < NameArray->Count; lElement++)
-        {
-
-            pCurrentElement = &NameArray->ElementArray[ lElement];
-
-            lCount = InterlockedDecrement( &pCurrentElement->DirectoryCB->NameArrayReferenceCount);
-
-            AFSDbgTrace(( AFS_SUBSYSTEM_NAME_ARRAY_REF_COUNTING,
-                          AFS_TRACE_LEVEL_VERBOSE,
-                          "AFSResetNameArray [NA:%p] Decrement count on %wZ DE %p Cnt %d\n",
-                          NameArray,
-                          &pCurrentElement->DirectoryCB->NameInformation.FileName,
-                          pCurrentElement->DirectoryCB,
-                          lCount));
-
-            ASSERT( lCount >= 0);
-        }
-
-        RtlZeroMemory( NameArray,
-                       sizeof( AFSNameArrayHdr) +
-                          ((pDevExt->Specific.RDR.NameArrayLength - 1) * sizeof( AFSNameArrayCB)));
-
-        NameArray->MaxElementCount = pDevExt->Specific.RDR.NameArrayLength;
-
-        if( DirectoryCB != NULL)
-        {
-
-            pCurrentElement = &NameArray->ElementArray[ 0];
-
-            NameArray->CurrentEntry = pCurrentElement;
-
-            NameArray->Count = 1;
-
-            NameArray->LinkCount = 0;
-
-            lCount = InterlockedIncrement( &DirectoryCB->NameArrayReferenceCount);
-
-            AFSDbgTrace(( AFS_SUBSYSTEM_NAME_ARRAY_REF_COUNTING,
-                          AFS_TRACE_LEVEL_VERBOSE,
-                          "AFSResetNameArray [NA:%p] Increment count on %wZ DE %p Cnt %d\n",
-                          NameArray,
-                          &DirectoryCB->NameInformation.FileName,
-                          DirectoryCB,
-                          lCount));
-
-            pCurrentElement->DirectoryCB = DirectoryCB;
-
-            pCurrentElement->Component = DirectoryCB->NameInformation.FileName;
-
-            pCurrentElement->FileId = DirectoryCB->ObjectInformation->FileId;
-
-            pCurrentElement->Flags  = 0;
-
-            if( pCurrentElement->FileId.Vnode == 1)
-            {
-
-                SetFlag( pCurrentElement->Flags, AFS_NAME_ARRAY_FLAG_ROOT_ELEMENT);
-            }
-
-            AFSDbgTrace(( AFS_SUBSYSTEM_NAME_ARRAY_PROCESSING,
-                          AFS_TRACE_LEVEL_VERBOSE,
-                          "AFSResetNameArray [NA:%p] Element[0] DE %p FID %08lX-%08lX-%08lX-%08lX %wZ Type %d\n",
-                          NameArray,
-                          pCurrentElement->DirectoryCB,
-                          pCurrentElement->FileId.Cell,
-                          pCurrentElement->FileId.Volume,
-                          pCurrentElement->FileId.Vnode,
-                          pCurrentElement->FileId.Unique,
-                          &pCurrentElement->DirectoryCB->NameInformation.FileName,
-                          pCurrentElement->DirectoryCB->ObjectInformation->FileType));
-        }
-    }
-
-    return;
-}
-
-void
-AFSDumpNameArray( IN AFSNameArrayHdr *NameArray)
-{
-
-    AFSNameArrayCB *pCurrentElement = NULL;
-
-    pCurrentElement = &NameArray->ElementArray[ 0];
-
-    AFSPrint("AFSDumpNameArray Start (%d)\n", NameArray->Count);
-
-    while( pCurrentElement->DirectoryCB != NULL)
-    {
-
-        AFSPrint("FID %08lX-%08lX-%08lX-%08lX %wZ\n",
-                  pCurrentElement->FileId.Cell,
-                  pCurrentElement->FileId.Volume,
-                  pCurrentElement->FileId.Vnode,
-                  pCurrentElement->FileId.Unique,
-                  &pCurrentElement->DirectoryCB->NameInformation.FileName);
-
-        pCurrentElement++;
-    }
-
-    AFSPrint("AFSDumpNameArray End\n\n");
-
-    return;
-}
-
 void
 AFSSetEnumerationEvent( IN AFSFcb *Fcb)
 {
diff --git a/src/WINNT/afsrdr/kernel/lib/AFSNameArray.cpp b/src/WINNT/afsrdr/kernel/lib/AFSNameArray.cpp
new file mode 100644 (file)
index 0000000..560805e
--- /dev/null
@@ -0,0 +1,786 @@
+/*
+ * Copyright (c) 2008, 2009, 2010, 2011 Kernel Drivers, LLC.
+ * Copyright (c) 2009, 2010, 2011, 2012, 2013 Your File System, Inc.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * - Redistributions of source code must retain the above copyright notice,
+ *   this list of conditions and the following disclaimer.
+ * - Redistributions in binary form must reproduce the above copyright
+ *   notice, this list of conditions and the following disclaimer in the
+ *   documentation and/or other materials provided with the distribution.
+ * - Neither the names of Kernel Drivers, LLC and Your File System, Inc.
+ *   nor the names of their contributors may be used to endorse or promote
+ *   products derived from this software without specific prior written
+ *   permission from Kernel Drivers, LLC and Your File System, Inc.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+ * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
+ * PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
+ * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+ * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+//
+// File: AFSNameArray.cpp
+//
+
+#include "AFSCommon.h"
+
+AFSNameArrayHdr *
+AFSInitNameArray( IN AFSDirectoryCB *DirectoryCB,
+                  IN ULONG InitialElementCount)
+{
+
+    AFSNameArrayHdr *pNameArray = NULL;
+    AFSNameArrayCB *pCurrentElement = NULL;
+    AFSDeviceExt *pDevExt = (AFSDeviceExt *) AFSRDRDeviceObject->DeviceExtension;
+    LONG lCount;
+
+    __Enter
+    {
+
+        if( InitialElementCount == 0)
+        {
+
+            InitialElementCount = pDevExt->Specific.RDR.NameArrayLength;
+        }
+
+        pNameArray = (AFSNameArrayHdr *)AFSExAllocatePoolWithTag( PagedPool,
+                                                                  sizeof( AFSNameArrayHdr) +
+                                                                    (InitialElementCount * sizeof( AFSNameArrayCB)),
+                                                                  AFS_NAME_ARRAY_TAG);
+
+        if( pNameArray == NULL)
+        {
+
+            AFSDbgTrace(( AFS_SUBSYSTEM_NAME_ARRAY_PROCESSING,
+                          AFS_TRACE_LEVEL_ERROR,
+                          "AFSInitNameArray Failed to allocate name array\n"));
+
+            try_return( pNameArray);
+        }
+
+        RtlZeroMemory( pNameArray,
+                       sizeof( AFSNameArrayHdr) +
+                          (InitialElementCount * sizeof( AFSNameArrayCB)));
+
+        pNameArray->MaxElementCount = InitialElementCount;
+
+        if( DirectoryCB != NULL)
+        {
+
+            pCurrentElement = &pNameArray->ElementArray[ 0];
+
+            pNameArray->CurrentEntry = pCurrentElement;
+
+            pNameArray->Count = 1;
+
+            pNameArray->LinkCount = 0;
+
+            lCount = InterlockedIncrement( &DirectoryCB->NameArrayReferenceCount);
+
+            AFSDbgTrace(( AFS_SUBSYSTEM_NAME_ARRAY_REF_COUNTING,
+                          AFS_TRACE_LEVEL_VERBOSE,
+                          "AFSInitNameArray [NA:%p] Increment count on %wZ DE %p Cnt %d\n",
+                          pNameArray,
+                          &DirectoryCB->NameInformation.FileName,
+                          DirectoryCB,
+                          lCount));
+
+            pCurrentElement->DirectoryCB = DirectoryCB;
+
+            pCurrentElement->Component = DirectoryCB->NameInformation.FileName;
+
+            pCurrentElement->FileId = DirectoryCB->ObjectInformation->FileId;
+
+            if( pCurrentElement->FileId.Vnode == 1)
+            {
+
+                SetFlag( pCurrentElement->Flags, AFS_NAME_ARRAY_FLAG_ROOT_ELEMENT);
+            }
+
+            AFSDbgTrace(( AFS_SUBSYSTEM_NAME_ARRAY_PROCESSING,
+                          AFS_TRACE_LEVEL_VERBOSE,
+                          "AFSInitNameArray [NA:%p] Element[0] DE %p FID %08lX-%08lX-%08lX-%08lX %wZ Type %d\n",
+                          pNameArray,
+                          pCurrentElement->DirectoryCB,
+                          pCurrentElement->FileId.Cell,
+                          pCurrentElement->FileId.Volume,
+                          pCurrentElement->FileId.Vnode,
+                          pCurrentElement->FileId.Unique,
+                          &pCurrentElement->DirectoryCB->NameInformation.FileName,
+                          pCurrentElement->DirectoryCB->ObjectInformation->FileType));
+        }
+
+try_exit:
+
+        NOTHING;
+    }
+
+    return pNameArray;
+}
+
+NTSTATUS
+AFSPopulateNameArray( IN AFSNameArrayHdr *NameArray,
+                      IN UNICODE_STRING *Path,
+                      IN AFSDirectoryCB *DirectoryCB)
+{
+
+    NTSTATUS ntStatus = STATUS_SUCCESS;
+    AFSNameArrayCB *pCurrentElement = NULL;
+    LONG lCount;
+
+    __Enter
+    {
+
+        AFSDbgTrace(( AFS_SUBSYSTEM_NAME_ARRAY_PROCESSING,
+                      AFS_TRACE_LEVEL_VERBOSE,
+                      "AFSPopulateNameArray [NA:%p] passed Path %wZ DE %p FID %08lX-%08lX-%08lX-%08lX %wZ Type %d\n",
+                      NameArray,
+                      &Path,
+                      DirectoryCB,
+                      DirectoryCB->ObjectInformation->FileId.Cell,
+                      DirectoryCB->ObjectInformation->FileId.Volume,
+                      DirectoryCB->ObjectInformation->FileId.Vnode,
+                      DirectoryCB->ObjectInformation->FileId.Unique,
+                      &DirectoryCB->NameInformation.FileName,
+                      DirectoryCB->ObjectInformation->FileType));
+
+        //
+        // Init some info in the header
+        //
+
+        pCurrentElement = &NameArray->ElementArray[ 0];
+
+        NameArray->CurrentEntry = pCurrentElement;
+
+        //
+        // The first entry points at the root
+        //
+
+        pCurrentElement->DirectoryCB = DirectoryCB->ObjectInformation->VolumeCB->DirectoryCB;
+
+        lCount = InterlockedIncrement( &pCurrentElement->DirectoryCB->NameArrayReferenceCount);
+
+        AFSDbgTrace(( AFS_SUBSYSTEM_NAME_ARRAY_REF_COUNTING,
+                      AFS_TRACE_LEVEL_VERBOSE,
+                      "AFSPopulateNameArray [NA:%p] Increment count on volume %wZ DE %p Cnt %d\n",
+                      NameArray,
+                      &pCurrentElement->DirectoryCB->NameInformation.FileName,
+                      pCurrentElement->DirectoryCB,
+                      lCount));
+
+        pCurrentElement->Component = DirectoryCB->ObjectInformation->VolumeCB->DirectoryCB->NameInformation.FileName;
+
+        pCurrentElement->FileId = DirectoryCB->ObjectInformation->VolumeCB->ObjectInformation.FileId;
+
+        pCurrentElement->Flags = 0;
+
+        if( pCurrentElement->FileId.Vnode == 1)
+        {
+
+            SetFlag( pCurrentElement->Flags, AFS_NAME_ARRAY_FLAG_ROOT_ELEMENT);
+        }
+
+        NameArray->Count = 1;
+
+        NameArray->LinkCount = 0;
+
+        AFSDbgTrace(( AFS_SUBSYSTEM_NAME_ARRAY_PROCESSING,
+                      AFS_TRACE_LEVEL_VERBOSE,
+                      "AFSPopulateNameArray [NA:%p] Element[0] DE %p FID %08lX-%08lX-%08lX-%08lX %wZ Type %d\n",
+                      NameArray,
+                      pCurrentElement->DirectoryCB,
+                      pCurrentElement->FileId.Cell,
+                      pCurrentElement->FileId.Volume,
+                      pCurrentElement->FileId.Vnode,
+                      pCurrentElement->FileId.Unique,
+                      &pCurrentElement->DirectoryCB->NameInformation.FileName,
+                      pCurrentElement->DirectoryCB->ObjectInformation->FileType));
+
+        //
+        // If the root is the parent then we are done ...
+        //
+
+        if( &DirectoryCB->ObjectInformation->VolumeCB->ObjectInformation == DirectoryCB->ObjectInformation)
+        {
+            try_return( ntStatus);
+        }
+
+try_exit:
+
+        NOTHING;
+    }
+
+    return ntStatus;
+}
+
+NTSTATUS
+AFSPopulateNameArrayFromRelatedArray( IN AFSNameArrayHdr *NameArray,
+                                      IN AFSNameArrayHdr *RelatedNameArray,
+                                      IN AFSDirectoryCB *DirectoryCB)
+{
+
+    NTSTATUS ntStatus = STATUS_SUCCESS;
+    AFSNameArrayCB *pCurrentElement = NULL, *pCurrentRelatedElement = NULL;
+    LONG lCount;
+
+    __Enter
+    {
+
+        if ( DirectoryCB)
+        {
+
+            AFSDbgTrace(( AFS_SUBSYSTEM_NAME_ARRAY_PROCESSING,
+                          AFS_TRACE_LEVEL_VERBOSE,
+                          "AFSPopulateNameArray [NA:%p] passed RelatedNameArray %p DE %p FID %08lX-%08lX-%08lX-%08lX %wZ Type %d\n",
+                          NameArray,
+                          RelatedNameArray,
+                          DirectoryCB,
+                          DirectoryCB->ObjectInformation->FileId.Cell,
+                          DirectoryCB->ObjectInformation->FileId.Volume,
+                          DirectoryCB->ObjectInformation->FileId.Vnode,
+                          DirectoryCB->ObjectInformation->FileId.Unique,
+                          &DirectoryCB->NameInformation.FileName,
+                          DirectoryCB->ObjectInformation->FileType));
+        }
+        else
+        {
+
+            AFSDbgTrace(( AFS_SUBSYSTEM_NAME_ARRAY_PROCESSING,
+                          AFS_TRACE_LEVEL_VERBOSE,
+                          "AFSPopulateNameArray [NA:%p] passed RelatedNameArray %p DE NULL\n",
+                          NameArray,
+                          RelatedNameArray));
+        }
+
+        //
+        // Init some info in the header
+        //
+
+        pCurrentElement = &NameArray->ElementArray[ 0];
+
+        pCurrentRelatedElement = &RelatedNameArray->ElementArray[ 0];
+
+        NameArray->Count = 0;
+
+        NameArray->LinkCount = RelatedNameArray->LinkCount;
+
+        //
+        // Populate the name array with the data from the related array
+        //
+
+        while( TRUE)
+        {
+
+            pCurrentElement->DirectoryCB = pCurrentRelatedElement->DirectoryCB;
+
+            pCurrentElement->Component = pCurrentRelatedElement->DirectoryCB->NameInformation.FileName;
+
+            pCurrentElement->FileId    = pCurrentElement->DirectoryCB->ObjectInformation->FileId;
+
+            pCurrentElement->Flags = 0;
+
+            if( pCurrentElement->FileId.Vnode == 1)
+            {
+
+                SetFlag( pCurrentElement->Flags, AFS_NAME_ARRAY_FLAG_ROOT_ELEMENT);
+            }
+
+            lCount = InterlockedIncrement( &pCurrentElement->DirectoryCB->NameArrayReferenceCount);
+
+            AFSDbgTrace(( AFS_SUBSYSTEM_NAME_ARRAY_REF_COUNTING,
+                          AFS_TRACE_LEVEL_VERBOSE,
+                          "AFSPopulateNameArrayFromRelatedArray [NA:%p] Increment count on %wZ DE %p Cnt %d\n",
+                          NameArray,
+                          &pCurrentElement->DirectoryCB->NameInformation.FileName,
+                          pCurrentElement->DirectoryCB,
+                          lCount));
+
+            lCount = InterlockedIncrement( &NameArray->Count);
+
+            AFSDbgTrace(( AFS_SUBSYSTEM_NAME_ARRAY_PROCESSING,
+                          AFS_TRACE_LEVEL_VERBOSE,
+                          "AFSPopulateNameArrayFromRelatedArray [NA:%p] Element[%d] DE %p FID %08lX-%08lX-%08lX-%08lX %wZ Type %d\n",
+                          NameArray,
+                          lCount - 1,
+                          pCurrentElement->DirectoryCB,
+                          pCurrentElement->FileId.Cell,
+                          pCurrentElement->FileId.Volume,
+                          pCurrentElement->FileId.Vnode,
+                          pCurrentElement->FileId.Unique,
+                          &pCurrentElement->DirectoryCB->NameInformation.FileName,
+                          pCurrentElement->DirectoryCB->ObjectInformation->FileType));
+
+            if( pCurrentElement->DirectoryCB == DirectoryCB ||
+                NameArray->Count == RelatedNameArray->Count)
+            {
+
+                //
+                // Done ...
+                //
+
+                break;
+            }
+
+            pCurrentElement++;
+
+            pCurrentRelatedElement++;
+        }
+
+        NameArray->CurrentEntry = NameArray->Count > 0 ? pCurrentElement : NULL;
+    }
+
+    return ntStatus;
+}
+
+NTSTATUS
+AFSFreeNameArray( IN AFSNameArrayHdr *NameArray)
+{
+
+    NTSTATUS ntStatus = STATUS_SUCCESS;
+    AFSNameArrayCB *pCurrentElement = NULL;
+    LONG lCount, lElement;
+
+    __Enter
+    {
+
+        AFSDbgTrace(( AFS_SUBSYSTEM_NAME_ARRAY_PROCESSING,
+                      AFS_TRACE_LEVEL_VERBOSE,
+                      "AFSFreeNameArray [NA:%p]\n",
+                      NameArray));
+
+        for ( lElement = 0; lElement < NameArray->Count; lElement++)
+        {
+
+            pCurrentElement = &NameArray->ElementArray[ lElement];
+
+            lCount = InterlockedDecrement( &pCurrentElement->DirectoryCB->NameArrayReferenceCount);
+
+            AFSDbgTrace(( AFS_SUBSYSTEM_NAME_ARRAY_REF_COUNTING,
+                          AFS_TRACE_LEVEL_VERBOSE,
+                          "AFSFreeNameArray [NA:%p] Decrement count on %wZ DE %p Cnt %d\n",
+                          NameArray,
+                          &pCurrentElement->DirectoryCB->NameInformation.FileName,
+                          pCurrentElement->DirectoryCB,
+                          lCount));
+
+            ASSERT( lCount >= 0);
+        }
+
+        AFSExFreePoolWithTag( NameArray, AFS_NAME_ARRAY_TAG);
+    }
+
+    return ntStatus;
+}
+
+NTSTATUS
+AFSInsertNextElement( IN AFSNameArrayHdr *NameArray,
+                      IN AFSDirectoryCB *DirectoryCB)
+{
+
+    NTSTATUS ntStatus = STATUS_SUCCESS;
+    AFSNameArrayCB *pCurrentElement = NULL;
+    LONG lCount;
+
+    __Enter
+    {
+
+        AFSDbgTrace(( AFS_SUBSYSTEM_NAME_ARRAY_PROCESSING,
+                      AFS_TRACE_LEVEL_VERBOSE,
+                      "AFSInsertNextElement [NA:%p] passed DE %p FID %08lX-%08lX-%08lX-%08lX %wZ Type %d\n",
+                      NameArray,
+                      DirectoryCB,
+                      DirectoryCB->ObjectInformation->FileId.Cell,
+                      DirectoryCB->ObjectInformation->FileId.Volume,
+                      DirectoryCB->ObjectInformation->FileId.Vnode,
+                      DirectoryCB->ObjectInformation->FileId.Unique,
+                      &DirectoryCB->NameInformation.FileName,
+                      DirectoryCB->ObjectInformation->FileType));
+
+        if( NameArray->Count == (LONG) NameArray->MaxElementCount)
+        {
+
+            AFSDbgTrace(( AFS_SUBSYSTEM_NAME_ARRAY_PROCESSING,
+                          AFS_TRACE_LEVEL_ERROR,
+                          "AFSInsertNextElement [NA:%p] Name has reached Maximum Size\n",
+                          NameArray));
+
+            try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
+        }
+
+        for ( lCount = 0; lCount < NameArray->Count; lCount++)
+        {
+
+            if ( AFSIsEqualFID( &NameArray->ElementArray[ lCount].FileId,
+                                &DirectoryCB->ObjectInformation->FileId) )
+            {
+
+                AFSDbgTrace(( AFS_SUBSYSTEM_NAME_ARRAY_PROCESSING,
+                              AFS_TRACE_LEVEL_WARNING,
+                              "AFSInsertNextElement [NA:%p] DE %p recursion Status %08X\n",
+                              NameArray,
+                              DirectoryCB,
+                              STATUS_ACCESS_DENIED));
+
+                try_return( ntStatus = STATUS_ACCESS_DENIED);
+            }
+        }
+
+        if( NameArray->Count > 0)
+        {
+
+            NameArray->CurrentEntry++;
+        }
+        else
+        {
+            NameArray->CurrentEntry = &NameArray->ElementArray[ 0];
+        }
+
+        pCurrentElement = NameArray->CurrentEntry;
+
+        lCount = InterlockedIncrement( &NameArray->Count);
+
+        lCount = InterlockedIncrement( &DirectoryCB->NameArrayReferenceCount);
+
+        AFSDbgTrace(( AFS_SUBSYSTEM_NAME_ARRAY_REF_COUNTING,
+                      AFS_TRACE_LEVEL_VERBOSE,
+                      "AFSInsertNextElement [NA:%p] Increment count on %wZ DE %p Cnt %d\n",
+                      NameArray,
+                      &DirectoryCB->NameInformation.FileName,
+                      DirectoryCB,
+                      lCount));
+
+        ASSERT( lCount > 0);
+
+        pCurrentElement->DirectoryCB = DirectoryCB;
+
+        pCurrentElement->Component = DirectoryCB->NameInformation.FileName;
+
+        pCurrentElement->FileId = DirectoryCB->ObjectInformation->FileId;
+
+        pCurrentElement->Flags = 0;
+
+        if( pCurrentElement->FileId.Vnode == 1)
+        {
+
+            SetFlag( pCurrentElement->Flags, AFS_NAME_ARRAY_FLAG_ROOT_ELEMENT);
+        }
+
+        AFSDbgTrace(( AFS_SUBSYSTEM_NAME_ARRAY_PROCESSING,
+                      AFS_TRACE_LEVEL_VERBOSE,
+                      "AFSInsertNextElement [NA:%p] Element[%d] DE %p FID %08lX-%08lX-%08lX-%08lX %wZ Type %d\n",
+                      NameArray,
+                      NameArray->Count - 1,
+                      pCurrentElement->DirectoryCB,
+                      pCurrentElement->FileId.Cell,
+                      pCurrentElement->FileId.Volume,
+                      pCurrentElement->FileId.Vnode,
+                      pCurrentElement->FileId.Unique,
+                      &pCurrentElement->DirectoryCB->NameInformation.FileName,
+                      pCurrentElement->DirectoryCB->ObjectInformation->FileType));
+
+try_exit:
+
+        NOTHING;
+    }
+
+    return ntStatus;
+}
+
+AFSDirectoryCB *
+AFSBackupEntry( IN AFSNameArrayHdr *NameArray)
+{
+
+    AFSDirectoryCB *pDirectoryCB = NULL;
+    AFSNameArrayCB *pCurrentElement = NULL;
+    BOOLEAN         bVolumeRoot = FALSE;
+    LONG lCount;
+
+    __Enter
+    {
+
+        AFSDbgTrace(( AFS_SUBSYSTEM_NAME_ARRAY_PROCESSING,
+                      AFS_TRACE_LEVEL_VERBOSE,
+                      "AFSBackupEntry [NA:%p]\n",
+                      NameArray));
+
+        if( NameArray->Count == 0)
+        {
+
+            AFSDbgTrace(( AFS_SUBSYSTEM_NAME_ARRAY_PROCESSING,
+                          AFS_TRACE_LEVEL_ERROR,
+                          "AFSBackupEntry [NA:%p] No more entries\n",
+                          NameArray));
+
+            try_return( pCurrentElement);
+        }
+
+        lCount = InterlockedDecrement( &NameArray->CurrentEntry->DirectoryCB->NameArrayReferenceCount);
+
+        AFSDbgTrace(( AFS_SUBSYSTEM_NAME_ARRAY_REF_COUNTING,
+                      AFS_TRACE_LEVEL_VERBOSE,
+                      "AFSBackupEntry [NA:%p] Decrement count on %wZ DE %p Cnt %d\n",
+                      NameArray,
+                      &NameArray->CurrentEntry->DirectoryCB->NameInformation.FileName,
+                      NameArray->CurrentEntry->DirectoryCB,
+                      lCount));
+
+        ASSERT( lCount >= 0);
+
+        NameArray->CurrentEntry->DirectoryCB = NULL;
+
+        lCount = InterlockedDecrement( &NameArray->Count);
+
+        if( lCount == 0)
+        {
+            NameArray->CurrentEntry = NULL;
+
+            AFSDbgTrace(( AFS_SUBSYSTEM_NAME_ARRAY_PROCESSING,
+                          AFS_TRACE_LEVEL_ERROR,
+                          "AFSBackupEntry [NA:%p] No more entries\n",
+                          NameArray));
+        }
+        else
+        {
+
+            bVolumeRoot = BooleanFlagOn( NameArray->CurrentEntry->Flags, AFS_NAME_ARRAY_FLAG_ROOT_ELEMENT);
+
+            NameArray->CurrentEntry--;
+
+            pCurrentElement = NameArray->CurrentEntry;
+
+            pDirectoryCB = pCurrentElement->DirectoryCB;
+
+            AFSDbgTrace(( AFS_SUBSYSTEM_NAME_ARRAY_PROCESSING,
+                          AFS_TRACE_LEVEL_VERBOSE,
+                          "AFSBackupEntry [NA:%p] Returning Element[%d] DE %p FID %08lX-%08lX-%08lX-%08lX %wZ Type %d\n",
+                          NameArray,
+                          NameArray->Count - 1,
+                          pCurrentElement->DirectoryCB,
+                          pCurrentElement->FileId.Cell,
+                          pCurrentElement->FileId.Volume,
+                          pCurrentElement->FileId.Vnode,
+                          pCurrentElement->FileId.Unique,
+                          &pCurrentElement->DirectoryCB->NameInformation.FileName,
+                          pCurrentElement->DirectoryCB->ObjectInformation->FileType));
+
+            //
+            // If the entry we are removing is a volume root,
+            // we must remove the mount point entry as well.
+            // If the NameArray was constructed by checking the
+            // share name via the service, the name array can
+            // contain two volume roots in sequence without a
+            // mount point separating them.
+            //
+
+            if ( bVolumeRoot &&
+                 !BooleanFlagOn( NameArray->CurrentEntry->Flags, AFS_NAME_ARRAY_FLAG_ROOT_ELEMENT))
+            {
+
+                pDirectoryCB = AFSBackupEntry( NameArray);
+            }
+        }
+
+
+try_exit:
+
+        NOTHING;
+    }
+
+    return pDirectoryCB;
+}
+
+AFSDirectoryCB *
+AFSGetParentEntry( IN AFSNameArrayHdr *NameArray)
+{
+
+    AFSDirectoryCB *pDirEntry = NULL;
+    AFSNameArrayCB *pElement = NULL;
+
+    __Enter
+    {
+
+        AFSDbgTrace(( AFS_SUBSYSTEM_NAME_ARRAY_PROCESSING,
+                      AFS_TRACE_LEVEL_VERBOSE,
+                      "AFSGetParentEntry [NA:%p]\n",
+                      NameArray));
+
+        if( NameArray->Count == 0 ||
+            NameArray->Count == 1)
+        {
+
+            AFSDbgTrace(( AFS_SUBSYSTEM_NAME_ARRAY_PROCESSING,
+                          AFS_TRACE_LEVEL_ERROR,
+                          "AFSGetParentEntry [NA:%p] No more entries\n",
+                          NameArray));
+
+            try_return( pDirEntry = NULL);
+        }
+
+        pElement = &NameArray->ElementArray[ NameArray->Count - 2];
+
+        pDirEntry = pElement->DirectoryCB;
+
+        AFSDbgTrace(( AFS_SUBSYSTEM_NAME_ARRAY_PROCESSING,
+                      AFS_TRACE_LEVEL_VERBOSE,
+                      "AFSGetParentEntry [NA:%p] Returning Element[%d] DE %p FID %08lX-%08lX-%08lX-%08lX %wZ Type %d\n",
+                      NameArray,
+                      NameArray->Count - 2,
+                      pElement->DirectoryCB,
+                      pElement->FileId.Cell,
+                      pElement->FileId.Volume,
+                      pElement->FileId.Vnode,
+                      pElement->FileId.Unique,
+                      &pElement->DirectoryCB->NameInformation.FileName,
+                      pElement->DirectoryCB->ObjectInformation->FileType));
+
+try_exit:
+
+        NOTHING;
+    }
+
+    return pDirEntry;
+}
+
+void
+AFSResetNameArray( IN AFSNameArrayHdr *NameArray,
+                   IN AFSDirectoryCB *DirectoryCB)
+{
+
+    AFSNameArrayCB *pCurrentElement = NULL;
+    AFSDeviceExt *pDevExt = (AFSDeviceExt *) AFSRDRDeviceObject->DeviceExtension;
+    LONG lCount, lElement;
+
+    __Enter
+    {
+
+        AFSDbgTrace(( AFS_SUBSYSTEM_NAME_ARRAY_PROCESSING,
+                      AFS_TRACE_LEVEL_VERBOSE,
+                      "AFSResetNameArray [NA:%p] passed DE %p FID %08lX-%08lX-%08lX-%08lX %wZ Type %d\n",
+                      NameArray,
+                      DirectoryCB,
+                      DirectoryCB->ObjectInformation->FileId.Cell,
+                      DirectoryCB->ObjectInformation->FileId.Volume,
+                      DirectoryCB->ObjectInformation->FileId.Vnode,
+                      DirectoryCB->ObjectInformation->FileId.Unique,
+                      &DirectoryCB->NameInformation.FileName,
+                      DirectoryCB->ObjectInformation->FileType));
+
+        //
+        // Dereference previous name array contents
+        //
+
+        for ( lElement = 0; lElement < NameArray->Count; lElement++)
+        {
+
+            pCurrentElement = &NameArray->ElementArray[ lElement];
+
+            lCount = InterlockedDecrement( &pCurrentElement->DirectoryCB->NameArrayReferenceCount);
+
+            AFSDbgTrace(( AFS_SUBSYSTEM_NAME_ARRAY_REF_COUNTING,
+                          AFS_TRACE_LEVEL_VERBOSE,
+                          "AFSResetNameArray [NA:%p] Decrement count on %wZ DE %p Cnt %d\n",
+                          NameArray,
+                          &pCurrentElement->DirectoryCB->NameInformation.FileName,
+                          pCurrentElement->DirectoryCB,
+                          lCount));
+
+            ASSERT( lCount >= 0);
+        }
+
+        RtlZeroMemory( NameArray,
+                       sizeof( AFSNameArrayHdr) +
+                          ((pDevExt->Specific.RDR.NameArrayLength - 1) * sizeof( AFSNameArrayCB)));
+
+        NameArray->MaxElementCount = pDevExt->Specific.RDR.NameArrayLength;
+
+        if( DirectoryCB != NULL)
+        {
+
+            pCurrentElement = &NameArray->ElementArray[ 0];
+
+            NameArray->CurrentEntry = pCurrentElement;
+
+            NameArray->Count = 1;
+
+            NameArray->LinkCount = 0;
+
+            lCount = InterlockedIncrement( &DirectoryCB->NameArrayReferenceCount);
+
+            AFSDbgTrace(( AFS_SUBSYSTEM_NAME_ARRAY_REF_COUNTING,
+                          AFS_TRACE_LEVEL_VERBOSE,
+                          "AFSResetNameArray [NA:%p] Increment count on %wZ DE %p Cnt %d\n",
+                          NameArray,
+                          &DirectoryCB->NameInformation.FileName,
+                          DirectoryCB,
+                          lCount));
+
+            pCurrentElement->DirectoryCB = DirectoryCB;
+
+            pCurrentElement->Component = DirectoryCB->NameInformation.FileName;
+
+            pCurrentElement->FileId = DirectoryCB->ObjectInformation->FileId;
+
+            pCurrentElement->Flags  = 0;
+
+            if( pCurrentElement->FileId.Vnode == 1)
+            {
+
+                SetFlag( pCurrentElement->Flags, AFS_NAME_ARRAY_FLAG_ROOT_ELEMENT);
+            }
+
+            AFSDbgTrace(( AFS_SUBSYSTEM_NAME_ARRAY_PROCESSING,
+                          AFS_TRACE_LEVEL_VERBOSE,
+                          "AFSResetNameArray [NA:%p] Element[0] DE %p FID %08lX-%08lX-%08lX-%08lX %wZ Type %d\n",
+                          NameArray,
+                          pCurrentElement->DirectoryCB,
+                          pCurrentElement->FileId.Cell,
+                          pCurrentElement->FileId.Volume,
+                          pCurrentElement->FileId.Vnode,
+                          pCurrentElement->FileId.Unique,
+                          &pCurrentElement->DirectoryCB->NameInformation.FileName,
+                          pCurrentElement->DirectoryCB->ObjectInformation->FileType));
+        }
+    }
+
+    return;
+}
+
+void
+AFSDumpNameArray( IN AFSNameArrayHdr *NameArray)
+{
+
+    AFSNameArrayCB *pCurrentElement = NULL;
+
+    pCurrentElement = &NameArray->ElementArray[ 0];
+
+    AFSPrint("AFSDumpNameArray Start (%d)\n", NameArray->Count);
+
+    while( pCurrentElement->DirectoryCB != NULL)
+    {
+
+        AFSPrint("FID %08lX-%08lX-%08lX-%08lX %wZ\n",
+                  pCurrentElement->FileId.Cell,
+                  pCurrentElement->FileId.Volume,
+                  pCurrentElement->FileId.Vnode,
+                  pCurrentElement->FileId.Unique,
+                  &pCurrentElement->DirectoryCB->NameInformation.FileName);
+
+        pCurrentElement++;
+    }
+
+    AFSPrint("AFSDumpNameArray End\n\n");
+
+    return;
+}
index fdbdc2f..f2b44f8 100644 (file)
@@ -1294,40 +1294,6 @@ AFSUpdateTargetName( IN OUT UNICODE_STRING *TargetName,
                      IN WCHAR *NameBuffer,
                      IN USHORT NameLength);
 
-AFSNameArrayHdr *
-AFSInitNameArray( IN AFSDirectoryCB *DirectoryCB,
-                  IN ULONG InitialElementCount);
-
-NTSTATUS
-AFSPopulateNameArray( IN AFSNameArrayHdr *NameArray,
-                      IN UNICODE_STRING *Path,
-                      IN AFSDirectoryCB *DirectoryCB);
-
-NTSTATUS
-AFSPopulateNameArrayFromRelatedArray( IN AFSNameArrayHdr *NameArray,
-                                      IN AFSNameArrayHdr *RelatedNameArray,
-                                      IN AFSDirectoryCB *DirectoryCB);
-
-NTSTATUS
-AFSFreeNameArray( IN AFSNameArrayHdr *NameArray);
-
-NTSTATUS
-AFSInsertNextElement( IN AFSNameArrayHdr *NameArray,
-                      IN AFSDirectoryCB *DirEntry);
-
-AFSDirectoryCB *
-AFSBackupEntry( IN AFSNameArrayHdr *NameArray);
-
-AFSDirectoryCB *
-AFSGetParentEntry( IN AFSNameArrayHdr *NameArray);
-
-void
-AFSResetNameArray( IN AFSNameArrayHdr *NameArray,
-                   IN AFSDirectoryCB *DirEntry);
-
-void
-AFSDumpNameArray( IN IN AFSNameArrayHdr *NameArray);
-
 void
 AFSSetEnumerationEvent( IN AFSFcb *Fcb);
 
@@ -1475,6 +1441,44 @@ AFSPerformObjectInvalidate( IN AFSObjectInfoCB *ObjectInfo,
                             IN ULONG InvalidateReason);
 
 //
+// AFSNameArray.cpp Prototypes
+//
+
+AFSNameArrayHdr *
+AFSInitNameArray( IN AFSDirectoryCB *DirectoryCB,
+                  IN ULONG InitialElementCount);
+
+NTSTATUS
+AFSPopulateNameArray( IN AFSNameArrayHdr *NameArray,
+                      IN UNICODE_STRING *Path,
+                      IN AFSDirectoryCB *DirectoryCB);
+
+NTSTATUS
+AFSPopulateNameArrayFromRelatedArray( IN AFSNameArrayHdr *NameArray,
+                                      IN AFSNameArrayHdr *RelatedNameArray,
+                                      IN AFSDirectoryCB *DirectoryCB);
+
+NTSTATUS
+AFSFreeNameArray( IN AFSNameArrayHdr *NameArray);
+
+NTSTATUS
+AFSInsertNextElement( IN AFSNameArrayHdr *NameArray,
+                      IN AFSDirectoryCB *DirEntry);
+
+AFSDirectoryCB *
+AFSBackupEntry( IN AFSNameArrayHdr *NameArray);
+
+AFSDirectoryCB *
+AFSGetParentEntry( IN AFSNameArrayHdr *NameArray);
+
+void
+AFSResetNameArray( IN AFSNameArrayHdr *NameArray,
+                   IN AFSDirectoryCB *DirEntry);
+
+void
+AFSDumpNameArray( IN IN AFSNameArrayHdr *NameArray);
+
+//
 // AFSWorker.cpp Prototypes
 //
 
index af67ae7..3028f6e 100644 (file)
@@ -30,6 +30,7 @@ SOURCES= AFSInit.cpp \
          AFSIoSupport.cpp \
         AFSLockControl.cpp \
         AFSMD5Support.cpp \
+         AFSNameArray.cpp \
         AFSNameSupport.cpp \
         AFSNetworkProviderSupport.cpp \
         AFSQuota.cpp \