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)
{
--- /dev/null
+/*
+ * 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;
+}