break;
}
}
- __except( AFSExceptionFilter( GetExceptionCode(), GetExceptionInformation()) )
+ __except( AFSExceptionFilter( __FUNCTION__, GetExceptionCode(), GetExceptionInformation()) )
{
AFSDbgLogMsg( 0,
0,
"EXCEPTION - AFSDirControl\n");
+
+ AFSDumpTraceFilesFnc();
}
if( ntStatus != STATUS_PENDING)
ULONG ulBytesConverted;
AFSDirectoryCB *pDirEntry = NULL;
BOOLEAN bReleaseMain = FALSE;
+ BOOLEAN bReleaseFcb = FALSE;
ULONG ulTargetFileType = AFS_FILE_TYPE_UNKNOWN;
AFSFileInfoCB stFileInfo;
BOOLEAN bUseFileInfo = TRUE;
AFSObjectInfoCB *pObjectInfo = NULL;
ULONG ulAdditionalAttributes = 0;
+ LONG lCount;
__Enter
{
bReturnSingleEntry = BooleanFlagOn( pIrpSp->Flags, SL_RETURN_SINGLE_ENTRY);
bIndexSpecified = BooleanFlagOn( pIrpSp->Flags, SL_INDEX_SPECIFIED);
- bInitialQuery = (BOOLEAN)( !BooleanFlagOn( pCcb->Flags, CCB_FLAGS_DIRECTORY_QUERY_MAPPED));
+ bInitialQuery = (BOOLEAN)( !BooleanFlagOn( pCcb->Flags, CCB_FLAG_DIRECTORY_QUERY_MAPPED));
if( bInitialQuery)
{
AFSAcquireExcl( &pFcb->NPFcb->Resource,
TRUE);
- //
- // Tell the service to prime the cache of the directory content
- //
-
- ntStatus = AFSEnumerateDirectoryNoResponse( &pFcb->AuthGroup,
- &pFcb->ObjectInformation->FileId);
-
- if( !NT_SUCCESS( ntStatus))
- {
-
- AFSReleaseResource( &pFcb->NPFcb->Resource);
-
- AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
- AFS_TRACE_LEVEL_ERROR,
- "AFSQueryDirectory Enumerate directory failure for parent %wZ Mask %wZ Status %08lX\n",
- &pCcb->DirectoryCB->NameInformation.FileName,
- &pCcb->MaskName,
- ntStatus);
-
- try_return( ntStatus);
- }
+ bReleaseFcb = TRUE;
}
else
{
AFSAcquireShared( &pFcb->NPFcb->Resource,
TRUE);
+
+ bReleaseFcb = TRUE;
}
//
- // Grab the directory node hdr tree lock shared while parsing the directory
+ // Grab the directory node hdr tree lock while parsing the directory
// contents
//
- AFSAcquireShared( pFcb->ObjectInformation->Specific.Directory.DirectoryNodeHdr.TreeLock,
- TRUE);
+ AFSAcquireExcl( pFcb->ObjectInformation->Specific.Directory.DirectoryNodeHdr.TreeLock,
+ TRUE);
bReleaseMain = TRUE;
//
+ // Before attempting to insert the new entry, check if we need to validate the parent
+ //
+
+ if( BooleanFlagOn( pFcb->ObjectInformation->Flags, AFS_OBJECT_FLAGS_VERIFY))
+ {
+
+ AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
+ AFS_TRACE_LEVEL_VERBOSE,
+ "AFSQueryDirectory Verifying parent %wZ FID %08lX-%08lX-%08lX-%08lX\n",
+ &pCcb->DirectoryCB->NameInformation.FileName,
+ pFcb->ObjectInformation->FileId.Cell,
+ pFcb->ObjectInformation->FileId.Volume,
+ pFcb->ObjectInformation->FileId.Vnode,
+ pFcb->ObjectInformation->FileId.Unique);
+
+ ntStatus = AFSVerifyEntry( &pCcb->AuthGroup,
+ pCcb->DirectoryCB);
+
+ if( !NT_SUCCESS( ntStatus))
+ {
+
+ AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
+ AFS_TRACE_LEVEL_ERROR,
+ "AFSQueryDirectory Failed to verify parent %wZ FID %08lX-%08lX-%08lX-%08lX Status %08lX\n",
+ &pCcb->DirectoryCB->NameInformation.FileName,
+ pFcb->ObjectInformation->FileId.Cell,
+ pFcb->ObjectInformation->FileId.Volume,
+ pFcb->ObjectInformation->FileId.Vnode,
+ pFcb->ObjectInformation->FileId.Unique,
+ ntStatus);
+
+ try_return( ntStatus);
+ }
+
+ //
+ // Perform a new snapshot of the directory
+ //
+
+ ntStatus = AFSSnapshotDirectory( pFcb,
+ pCcb,
+ FALSE);
+
+ if( !NT_SUCCESS( ntStatus))
+ {
+
+ AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
+ AFS_TRACE_LEVEL_ERROR,
+ "AFSQueryDirectory Snapshot directory failure for parent %wZ Mask %wZ Status %08lX\n",
+ &pCcb->DirectoryCB->NameInformation.FileName,
+ &pCcb->MaskName,
+ ntStatus);
+
+ try_return( ntStatus);
+ }
+ }
+
+ AFSConvertToShared( pFcb->ObjectInformation->Specific.Directory.DirectoryNodeHdr.TreeLock);
+
+ //
// We can now safely drop the lock on the node
//
AFSReleaseResource( &pFcb->NPFcb->Resource);
+ bReleaseFcb = FALSE;
+
//
// Start processing the data
//
{
ntStatus = AFSSnapshotDirectory( pFcb,
- pCcb);
+ pCcb,
+ TRUE);
if( !NT_SUCCESS( ntStatus))
{
try_return( ntStatus);
}
- SetFlag( pCcb->Flags, CCB_FLAGS_DIRECTORY_QUERY_MAPPED);
+ SetFlag( pCcb->Flags, CCB_FLAG_DIRECTORY_QUERY_MAPPED);
ClearFlag( pCcb->Flags, CCB_FLAG_DIR_OF_DIRS_ONLY);
FileInformationClass);
try_return( ntStatus = STATUS_INVALID_INFO_CLASS);
- }
+ }
AFSReleaseResource( pFcb->ObjectInformation->Specific.Directory.DirectoryNodeHdr.TreeLock);
BooleanFlagOn( pDirEntry->Flags, AFS_DIR_ENTRY_DELETED))
{
+ lCount = InterlockedDecrement( &pDirEntry->OpenReferenceCount);
+
continue;
}
if( !FlagOn( pObjectInfo->FileAttributes, FILE_ATTRIBUTE_DIRECTORY))
{
+ lCount = InterlockedDecrement( &pDirEntry->OpenReferenceCount);
+
continue;
}
}
NULL))
{
+ lCount = InterlockedDecrement( &pDirEntry->OpenReferenceCount);
+
continue;
}
}
TRUE))
{
+ lCount = InterlockedDecrement( &pDirEntry->OpenReferenceCount);
+
continue;
}
}
//
AFSValidateEntry( pDirEntry,
- &pFcb->AuthGroup,
- FALSE,
+ &pCcb->AuthGroup,
FALSE);
pObjectInfo = pDirEntry->ObjectInformation;
pDirEntry,
&pCcb->FullFileName,
pCcb->NameArray,
+ &pCcb->AuthGroup,
&stFileInfo)))
{
+ ulAdditionalAttributes = FILE_ATTRIBUTE_REPARSE_POINT;
+
bUseFileInfo = TRUE;
}
}
pCcb->CurrentDirIndex--;
+ lCount = InterlockedDecrement( &pDirEntry->OpenReferenceCount);
+
try_return( ntStatus = STATUS_SUCCESS);
}
// Now fill the base parts of the structure that are applicable.
case FileIdBothDirectoryInformation:
case FileBothDirectoryInformation:
-
+ {
pBothDirInfo = (PFILE_BOTH_DIR_INFORMATION)&pBuffer[ ulNextEntry];
pBothDirInfo->ShortNameLength = (CHAR)pDirEntry->NameInformation.ShortNameLength;
&pDirEntry->NameInformation.ShortName[ 0],
pBothDirInfo->ShortNameLength);
}
+ }
case FileIdFullDirectoryInformation:
case FileFullDirectoryInformation:
-
+ {
pFullDirInfo = (PFILE_FULL_DIR_INFORMATION)&pBuffer[ ulNextEntry];
pFullDirInfo->EaSize = 0;
-
+ }
case FileDirectoryInformation:
-
+ {
pDirInfo = (PFILE_DIRECTORY_INFORMATION)&pBuffer[ ulNextEntry];
if( bUseFileInfo)
pDirInfo->EndOfFile = stFileInfo.EndOfFile;
pDirInfo->AllocationSize = stFileInfo.AllocationSize;
- pDirInfo->FileAttributes = stFileInfo.FileAttributes;
+ pDirInfo->FileAttributes = stFileInfo.FileAttributes | ulAdditionalAttributes;
}
else if( BooleanFlagOn( pDirEntry->Flags, AFS_DIR_ENTRY_FAKE))
{
pDirInfo->FileNameLength = pDirEntry->NameInformation.FileName.Length;
break;
+ }
case FileNamesInformation:
-
+ {
pNamesInfo = (PFILE_NAMES_INFORMATION)&pBuffer[ ulNextEntry];
pNamesInfo->FileIndex = pDirEntry->FileIndex;
pNamesInfo->FileNameLength = pDirEntry->NameInformation.FileName.Length;
break;
-
+ }
default:
-
+ {
AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
AFS_TRACE_LEVEL_ERROR,
"AFSQueryDirectory (%08lX) Unknown FileInformationClass %u\n",
Irp,
FileInformationClass);
+ lCount = InterlockedDecrement( &pDirEntry->OpenReferenceCount);
+
try_return( ntStatus = STATUS_INVALID_INFO_CLASS);
break;
+ }
}
ulBytesConverted = ulBytesRemainingInBuffer - ulBaseLength >= pDirEntry->NameInformation.FileName.Length ?
if( ulBytesConverted < pDirEntry->NameInformation.FileName.Length)
{
+ lCount = InterlockedDecrement( &pDirEntry->OpenReferenceCount);
+
try_return( ntStatus = STATUS_BUFFER_OVERFLOW);
}
+ lCount = InterlockedDecrement( &pDirEntry->OpenReferenceCount);
+
dStatus = STATUS_SUCCESS;
// Set ourselves up for the next iteration
AFSReleaseResource( pFcb->ObjectInformation->Specific.Directory.DirectoryNodeHdr.TreeLock);
}
+ if ( bReleaseFcb)
+ {
+
+ AFSReleaseResource( &pFcb->NPFcb->Resource);
+ }
+
if( pFcb != NULL)
{
AFSSnapshotHdr *pSnapshotHdr = NULL;
AFSSnapshotEntry *pSnapshotEntry = NULL;
ULONG ulCount = 0;
+ LONG lCount;
__Enter
{
pDirEntry = ObjectInfo->Specific.Directory.PIOCtlDirectoryCB;
+ if( pDirEntry != NULL)
+ {
+
+ lCount = InterlockedIncrement( &pDirEntry->OpenReferenceCount);
+ }
+
AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
AFS_TRACE_LEVEL_VERBOSE,
"AFSLocateNextDirEntry Returning PIOctl entry %wZ in parent FID %08lX-%08lX-%08lX-%08lX\n",
pDirEntry = AFSGlobalDotDirEntry;
+ if( pDirEntry != NULL)
+ {
+
+ lCount = InterlockedIncrement( &pDirEntry->OpenReferenceCount);
+ }
+
AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
AFS_TRACE_LEVEL_VERBOSE,
"AFSLocateNextDirEntry Returning1 snapshot entry %wZ in parent FID %08lX-%08lX-%08lX-%08lX\n",
pDirEntry = AFSGlobalDotDotDirEntry;
+ if( pDirEntry != NULL)
+ {
+
+ lCount = InterlockedIncrement( &pDirEntry->OpenReferenceCount);
+ }
+
AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
AFS_TRACE_LEVEL_VERBOSE,
"AFSLocateNextDirEntry Returning2 snapshot entry %wZ in parent FID %08lX-%08lX-%08lX-%08lX\n",
// Get to a valid entry
//
+ AFSAcquireShared( ObjectInfo->Specific.Directory.DirectoryNodeHdr.TreeLock,
+ TRUE);
+
while( ulCount < pSnapshotHdr->EntryCount)
{
ObjectInfo->FileId.Volume,
ObjectInfo->FileId.Vnode,
ObjectInfo->FileId.Unique);
+
+ lCount = InterlockedIncrement( &pDirEntry->OpenReferenceCount);
}
else
{
Ccb->CurrentDirIndex++;
}
+
+ AFSReleaseResource( ObjectInfo->Specific.Directory.DirectoryNodeHdr.TreeLock);
}
try_exit:
NTSTATUS
AFSSnapshotDirectory( IN AFSFcb *Fcb,
- IN AFSCcb *Ccb)
+ IN AFSCcb *Ccb,
+ IN BOOLEAN ResetIndex)
{
NTSTATUS ntStatus = STATUS_SUCCESS;
__Enter
{
- //
- // Set it up so we still get the . and .. entries for empty directories
- //
-
- if( BooleanFlagOn( Ccb->Flags, CCB_FLAG_RETURN_RELATIVE_ENTRIES))
+ if( ResetIndex)
{
- Ccb->CurrentDirIndex = AFS_DIR_ENTRY_INITIAL_DIR_INDEX;
- }
- else
- {
+ //
+ // Set it up so we still get the . and .. entries for empty directories
+ //
- Ccb->CurrentDirIndex = AFS_DIR_ENTRY_INITIAL_ROOT_INDEX;
+ if( BooleanFlagOn( Ccb->Flags, CCB_FLAG_RETURN_RELATIVE_ENTRIES))
+ {
+
+ Ccb->CurrentDirIndex = AFS_DIR_ENTRY_INITIAL_DIR_INDEX;
+ }
+ else
+ {
+
+ Ccb->CurrentDirIndex = AFS_DIR_ENTRY_INITIAL_ROOT_INDEX;
+ }
}
if( Fcb->ObjectInformation->Specific.Directory.DirectoryNodeCount == 0)