AFSDirControl( IN PDEVICE_OBJECT LibDeviceObject,
IN PIRP Irp)
{
-
+ UNREFERENCED_PARAMETER(LibDeviceObject);
NTSTATUS ntStatus = STATUS_SUCCESS;
- ULONG ulRequestType = 0;
IO_STACK_LOCATION *pIrpSp = IoGetCurrentIrpStackLocation( Irp);
- AFSFcb *pFcb = NULL;
__try
{
break;
}
}
- __except( AFSExceptionFilter( GetExceptionCode(), GetExceptionInformation()) )
+ __except( AFSExceptionFilter( __FUNCTION__, GetExceptionCode(), GetExceptionInformation()) )
{
AFSDbgLogMsg( 0,
0,
"EXCEPTION - AFSDirControl\n");
+
+ AFSDumpTraceFilesFnc();
}
if( ntStatus != STATUS_PENDING)
AFSFcb *pFcb = NULL;
AFSCcb *pCcb = NULL;
BOOLEAN bInitialQuery = FALSE;
- ULONG ulIndex;
PUCHAR pBuffer;
ULONG ulUserBufferLength;
PUNICODE_STRING puniArgFileName = NULL;
UNICODE_STRING uniTmpMaskName;
- UNICODE_STRING uniDirUniBuf;
WCHAR wchMaskBuffer[ 4];
FILE_INFORMATION_CLASS FileInformationClass;
- ULONG ulFileIndex, ulDOSFileIndex;
+ ULONG ulFileIndex;
BOOLEAN bRestartScan;
BOOLEAN bReturnSingleEntry;
BOOLEAN bIndexSpecified;
ULONG ulNextEntry = 0;
ULONG ulLastEntry = 0;
- BOOLEAN bDoCase;
PFILE_DIRECTORY_INFORMATION pDirInfo;
PFILE_FULL_DIR_INFORMATION pFullDirInfo;
PFILE_BOTH_DIR_INFORMATION pBothDirInfo;
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
{
AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
AFS_TRACE_LEVEL_ERROR,
- "AFSQueryDirectory Attempted access (%08lX) when pFcb == NULL\n",
+ "AFSQueryDirectory Attempted access (%p) when pFcb == NULL\n",
Irp);
try_return( ntStatus = STATUS_INVALID_DEVICE_REQUEST);
AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
AFS_TRACE_LEVEL_ERROR,
- "AFSQueryDirectory Attempted access (%08lX) to non-directory Fcb %08lX NodeType %u\n",
+ "AFSQueryDirectory Attempted access (%p) to non-directory Fcb %p NodeType %u\n",
Irp,
pFcb,
pFcb->Header.NodeTypeCode);
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)
{
AFSDbgLogMsg( AFS_SUBSYSTEM_LOCK_PROCESSING,
AFS_TRACE_LEVEL_VERBOSE,
- "AFSQueryDirectory Acquiring Dcb lock %08lX EXCL %08lX\n",
+ "AFSQueryDirectory Acquiring Dcb lock %p EXCL %08lX\n",
&pFcb->NPFcb->Resource,
PsGetCurrentThread());
TRUE);
bReleaseFcb = TRUE;
-
- //
- // Tell the service to prime the cache of the directory content
- //
-
- ntStatus = AFSEnumerateDirectoryNoResponse( &pFcb->AuthGroup,
- &pFcb->ObjectInformation->FileId);
-
- if( !NT_SUCCESS( ntStatus))
- {
-
- 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);
- }
}
else
{
AFSDbgLogMsg( AFS_SUBSYSTEM_LOCK_PROCESSING,
AFS_TRACE_LEVEL_VERBOSE,
- "AFSQueryDirectory Acquiring Dcb lock %08lX SHARED %08lX\n",
+ "AFSQueryDirectory Acquiring Dcb lock %p SHARED %08lX\n",
&pFcb->NPFcb->Resource,
PsGetCurrentThread());
pFcb->ObjectInformation->FileId.Vnode,
pFcb->ObjectInformation->FileId.Unique);
- ntStatus = AFSVerifyEntry( &pFcb->AuthGroup,
+ ntStatus = AFSVerifyEntry( &pCcb->AuthGroup,
pCcb->DirectoryCB);
if( !NT_SUCCESS( ntStatus))
// Perform a new snapshot of the directory
//
+ AFSAcquireExcl( &pCcb->NPCcb->CcbLock,
+ TRUE);
+
ntStatus = AFSSnapshotDirectory( pFcb,
pCcb,
FALSE);
+ AFSReleaseResource( &pCcb->NPCcb->CcbLock);
+
if( !NT_SUCCESS( ntStatus))
{
try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
}
+ AFSAcquireExcl( &pCcb->NPCcb->CcbLock,
+ TRUE);
+
// Check if initial on this map
if( bInitialQuery)
{
if( !NT_SUCCESS( ntStatus))
{
+ AFSReleaseResource( &pCcb->NPCcb->CcbLock);
+
AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
AFS_TRACE_LEVEL_ERROR,
"AFSQueryDirectory Snapshot directory failure for parent %wZ Mask %wZ Status %08lX\n",
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);
if( pFcb->ObjectInformation->Specific.Directory.PIOCtlDirectoryCB == NULL)
{
+ AFSReleaseResource( &pCcb->NPCcb->CcbLock);
+
AFSReleaseResource( pFcb->ObjectInformation->Specific.Directory.DirectoryNodeHdr.TreeLock);
bReleaseMain = FALSE;
bReleaseMain = TRUE;
AFSReleaseResource( &pFcb->NPFcb->Resource);
+
+ AFSAcquireExcl( &pCcb->NPCcb->CcbLock,
+ TRUE);
}
}
}
}
+ AFSReleaseResource( &pCcb->NPCcb->CcbLock);
+
+ AFSReleaseResource( pFcb->ObjectInformation->Specific.Directory.DirectoryNodeHdr.TreeLock);
+
+ bReleaseMain = FALSE;
+
switch( FileInformationClass)
{
AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
AFS_TRACE_LEVEL_ERROR,
- "AFSQueryDirectory (%08lX) Unknown FileInformationClass %u\n",
+ "AFSQueryDirectory (%p) Unknown FileInformationClass %u\n",
Irp,
FileInformationClass);
try_return( ntStatus = STATUS_INVALID_INFO_CLASS);
}
- AFSReleaseResource( pFcb->ObjectInformation->Specific.Directory.DirectoryNodeHdr.TreeLock);
-
- bReleaseMain = FALSE;
-
while( TRUE)
{
ULONG ulBytesRemainingInBuffer;
- int rc;
+
+ //
+ // Drop the DirOpenReferenceCount held during a prior
+ // execution of the loop
+ //
+
+ if ( pDirEntry != NULL)
+ {
+
+ lCount = InterlockedDecrement( &pDirEntry->DirOpenReferenceCount);
+
+ AFSDbgLogMsg( AFS_SUBSYSTEM_DIRENTRY_REF_COUNTING,
+ AFS_TRACE_LEVEL_VERBOSE,
+ "AFSQueryDirectory Decrement count on %wZ DE %p Ccb %p Cnt %d\n",
+ &pDirEntry->NameInformation.FileName,
+ pDirEntry,
+ pCcb,
+ lCount);
+
+ ASSERT( lCount >= 0);
+
+ pDirEntry = NULL;
+ }
+
+ ulAdditionalAttributes = 0;
//
// If the user had requested only a single match and we have
try_return( ntStatus);
}
+ //
+ // On Success, pDirEntry has a held DirOpenReferenceCount
+ //
+
pDirEntry = AFSLocateNextDirEntry( pFcb->ObjectInformation,
pCcb);
BooleanFlagOn( pDirEntry->Flags, AFS_DIR_ENTRY_DELETED))
{
- InterlockedDecrement( &pDirEntry->OpenReferenceCount);
-
continue;
}
if( !FlagOn( pObjectInfo->FileAttributes, FILE_ATTRIBUTE_DIRECTORY))
{
- InterlockedDecrement( &pDirEntry->OpenReferenceCount);
-
continue;
}
}
NULL))
{
- InterlockedDecrement( &pDirEntry->OpenReferenceCount);
-
continue;
}
}
TRUE))
{
- InterlockedDecrement( &pDirEntry->OpenReferenceCount);
-
continue;
}
}
// We don't worry about entries while enumerating the directory
//
- AFSValidateEntry( pDirEntry,
- &pFcb->AuthGroup,
- FALSE,
- FALSE);
-
- pObjectInfo = pDirEntry->ObjectInformation;
-
- bUseFileInfo = FALSE;
-
- ulAdditionalAttributes = 0;
-
- if( pObjectInfo->FileType == AFS_FILE_TYPE_SYMLINK)
+ if ( BooleanFlagOn( pDirEntry->ObjectInformation->Flags, AFS_OBJECT_FLAGS_VERIFY))
{
- //
- // Go grab the file information for this entry
- // No worries on failures since we will just display
- // pseudo information
- //
-
- RtlZeroMemory( &stFileInfo,
- sizeof( AFSFileInfoCB));
-
- if( NT_SUCCESS( AFSRetrieveFileAttributes( pCcb->DirectoryCB,
- pDirEntry,
- &pCcb->FullFileName,
- pCcb->NameArray,
- &stFileInfo)))
+ ntStatus = AFSValidateEntry( pDirEntry,
+ &pCcb->AuthGroup,
+ FALSE,
+ FALSE);
+ if ( NT_SUCCESS( ntStatus))
{
- ulAdditionalAttributes = FILE_ATTRIBUTE_REPARSE_POINT;
+ ClearFlag( pDirEntry->ObjectInformation->Flags, AFS_OBJECT_FLAGS_VERIFY);
+ }
+ else
+ {
- bUseFileInfo = TRUE;
+ ntStatus = STATUS_SUCCESS;
}
}
+ pObjectInfo = pDirEntry->ObjectInformation;
+
// Here are the rules concerning filling up the buffer:
//
// 1. The Io system guarantees that there will always be
pCcb->CurrentDirIndex--;
- InterlockedDecrement( &pDirEntry->OpenReferenceCount);
-
try_return( ntStatus = STATUS_SUCCESS);
}
+
+ //
+ // For Symlinks and Mount Points the reparse point attribute
+ // must be associated with the directory entry. In addition,
+ // for Symlinks it must be determined if the target object is
+ // a directory or not. If so, the directory attribute must be
+ // specified. Mount points always refer to directories and
+ // must have the directory attribute set.
+ //
+
+ switch( pObjectInfo->FileType)
+ {
+
+ case AFS_FILE_TYPE_MOUNTPOINT:
+ case AFS_FILE_TYPE_DFSLINK:
+ {
+
+ ulAdditionalAttributes = FILE_ATTRIBUTE_DIRECTORY | FILE_ATTRIBUTE_REPARSE_POINT;
+
+ break;
+ }
+
+ case AFS_FILE_TYPE_SYMLINK:
+ {
+
+ //
+ // Go grab the file information for this entry
+ // No worries on failures since we will just display
+ // pseudo information
+ //
+
+ RtlZeroMemory( &stFileInfo,
+ sizeof( AFSFileInfoCB));
+
+ if( NT_SUCCESS( AFSRetrieveFileAttributes( pCcb->DirectoryCB,
+ pDirEntry,
+ &pCcb->FullFileName,
+ pCcb->NameArray,
+ &pCcb->AuthGroup,
+ &stFileInfo)))
+ {
+
+ if ( stFileInfo.FileAttributes & FILE_ATTRIBUTE_DIRECTORY)
+ {
+
+ ulAdditionalAttributes = FILE_ATTRIBUTE_DIRECTORY;
+ }
+ }
+
+ ulAdditionalAttributes |= FILE_ATTRIBUTE_REPARSE_POINT;
+
+ break;
+ }
+ }
+
+ //
+ // Check if the name begins with a . and we are hiding them
+ //
+
+ if( !BooleanFlagOn( pDirEntry->Flags, AFS_DIR_ENTRY_FAKE) &&
+ pDirEntry->NameInformation.FileName.Buffer[ 0] == L'.' &&
+ BooleanFlagOn( pDeviceExt->DeviceFlags, AFS_DEVICE_FLAG_HIDE_DOT_NAMES))
+ {
+
+ ulAdditionalAttributes |= FILE_ATTRIBUTE_HIDDEN;
+ }
+
+
AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
AFS_TRACE_LEVEL_VERBOSE,
"AFSQueryDirectory Insert into parent %wZ Entry %wZ\n",
{
pDirInfo = (PFILE_DIRECTORY_INFORMATION)&pBuffer[ ulNextEntry];
- if( bUseFileInfo)
- {
-
- pDirInfo->CreationTime = stFileInfo.CreationTime;
- pDirInfo->LastWriteTime = stFileInfo.LastWriteTime;
- pDirInfo->LastAccessTime = stFileInfo.LastAccessTime;
- pDirInfo->ChangeTime = stFileInfo.ChangeTime;
-
- pDirInfo->EndOfFile = stFileInfo.EndOfFile;
- pDirInfo->AllocationSize = stFileInfo.AllocationSize;
-
- pDirInfo->FileAttributes = stFileInfo.FileAttributes | ulAdditionalAttributes;
- }
- else if( BooleanFlagOn( pDirEntry->Flags, AFS_DIR_ENTRY_FAKE))
+ if( BooleanFlagOn( pDirEntry->Flags, AFS_DIR_ENTRY_FAKE))
{
pDirInfo->CreationTime = pFcb->ObjectInformation->CreationTime;
pDirInfo->EndOfFile = pObjectInfo->EndOfFile;
pDirInfo->AllocationSize = pObjectInfo->AllocationSize;
- pDirInfo->FileAttributes = pObjectInfo->FileAttributes | ulAdditionalAttributes;
- }
-
- //
- // Check if the name begins with a . and we are hiding them
- //
+ if ( ulAdditionalAttributes && pObjectInfo->FileAttributes == FILE_ATTRIBUTE_NORMAL)
+ {
- if( !BooleanFlagOn( pDirEntry->Flags, AFS_DIR_ENTRY_FAKE) &&
- pDirEntry->NameInformation.FileName.Buffer[ 0] == L'.' &&
- BooleanFlagOn( pDeviceExt->DeviceFlags, AFS_DEVICE_FLAG_HIDE_DOT_NAMES))
- {
+ pDirInfo->FileAttributes = ulAdditionalAttributes;
+ }
+ else
+ {
- pDirInfo->FileAttributes |= FILE_ATTRIBUTE_HIDDEN;
+ pDirInfo->FileAttributes = pObjectInfo->FileAttributes | ulAdditionalAttributes;
+ }
}
pDirInfo->FileIndex = pDirEntry->FileIndex;
break;
}
+
default:
{
AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
AFS_TRACE_LEVEL_ERROR,
- "AFSQueryDirectory (%08lX) Unknown FileInformationClass %u\n",
+ "AFSQueryDirectory (%p) Unknown FileInformationClass %u\n",
Irp,
FileInformationClass);
- InterlockedDecrement( &pDirEntry->OpenReferenceCount);
-
try_return( ntStatus = STATUS_INVALID_INFO_CLASS);
-
- break;
}
}
if( ulBytesConverted < pDirEntry->NameInformation.FileName.Length)
{
- InterlockedDecrement( &pDirEntry->OpenReferenceCount);
-
try_return( ntStatus = STATUS_BUFFER_OVERFLOW);
}
- InterlockedDecrement( &pDirEntry->OpenReferenceCount);
-
dStatus = STATUS_SUCCESS;
// Set ourselves up for the next iteration
try_exit:
+ if ( pDirEntry != NULL)
+ {
+
+ lCount = InterlockedDecrement( &pDirEntry->DirOpenReferenceCount);
+
+ AFSDbgLogMsg( AFS_SUBSYSTEM_DIRENTRY_REF_COUNTING,
+ AFS_TRACE_LEVEL_VERBOSE,
+ "AFSQueryDirectory Decrement8 count on %wZ DE %p Ccb %p Cnt %d\n",
+ &pDirEntry->NameInformation.FileName,
+ pDirEntry,
+ pCcb,
+ lCount);
+
+ ASSERT( lCount >= 0);
+ }
+
if( bReleaseMain)
{
AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
AFS_TRACE_LEVEL_ERROR,
- "AFSNotifyChangeDirectory Attempted access (%08lX) when pFcb == NULL\n",
+ "AFSNotifyChangeDirectory Attempted access (%p) when pFcb == NULL\n",
Irp);
try_return( ntStatus = STATUS_INVALID_DEVICE_REQUEST);
AFSDbgLogMsg( AFS_SUBSYSTEM_LOCK_PROCESSING,
AFS_TRACE_LEVEL_VERBOSE,
- "AFSNotifyChangeDirectory Acquiring Dcb lock %08lX EXCL %08lX\n",
+ "AFSNotifyChangeDirectory Acquiring Dcb lock %p EXCL %08lX\n",
&pFcb->NPFcb->Resource,
PsGetCurrentThread());
AFSSnapshotHdr *pSnapshotHdr = NULL;
AFSSnapshotEntry *pSnapshotEntry = NULL;
ULONG ulCount = 0;
+ LONG lCount;
__Enter
{
+ AFSAcquireShared( ObjectInfo->Specific.Directory.DirectoryNodeHdr.TreeLock,
+ TRUE);
+
+ AFSAcquireExcl( &Ccb->NPCcb->CcbLock,
+ TRUE);
+
//
// Is this a PIOCtl query
//
// 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);
-
- InterlockedIncrement( &pDirEntry->OpenReferenceCount);
}
else
{
Ccb->CurrentDirIndex++;
}
-
- AFSReleaseResource( ObjectInfo->Specific.Directory.DirectoryNodeHdr.TreeLock);
}
try_exit:
- NOTHING;
+ if( pDirEntry != NULL)
+ {
+
+ lCount = InterlockedIncrement( &pDirEntry->DirOpenReferenceCount);
+
+ AFSDbgLogMsg( AFS_SUBSYSTEM_DIRENTRY_REF_COUNTING,
+ AFS_TRACE_LEVEL_VERBOSE,
+ "AFSLocateNextDirEntry Increment count on %wZ DE %p Ccb %p Cnt %d\n",
+ &pDirEntry->NameInformation.FileName,
+ pDirEntry,
+ Ccb,
+ lCount);
+
+ ASSERT( lCount >= 0);
+ }
+
+ AFSReleaseResource( &Ccb->NPCcb->CcbLock);
+
+ AFSReleaseResource( ObjectInfo->Specific.Directory.DirectoryNodeHdr.TreeLock);
}
return pDirEntry;
__Enter
{
+ AFSAcquireExcl( &Ccb->NPCcb->CcbLock,
+ TRUE);
+
Ccb->CurrentDirIndex = DirIndex;
if( DirIndex == (ULONG)AFS_DIR_ENTRY_DOT_INDEX)
try_exit:
- NOTHING;
+ AFSReleaseResource( &Ccb->NPCcb->CcbLock);
}
return pDirEntry;
if( Ccb->DirectorySnapshot != NULL)
{
- AFSExFreePool( Ccb->DirectorySnapshot);
+ AFSExFreePoolWithTag( Ccb->DirectorySnapshot, AFS_DIR_SNAPSHOT_TAG);
Ccb->DirectorySnapshot = NULL;
}
if( Ccb->DirectorySnapshot != NULL)
{
- AFSExFreePool( Ccb->DirectorySnapshot);
+ AFSExFreePoolWithTag( Ccb->DirectorySnapshot, AFS_DIR_SNAPSHOT_TAG);
Ccb->DirectorySnapshot = NULL;
}
__Enter
{
+ AFSAcquireExcl( &Ccb->NPCcb->CcbLock,
+ TRUE);
+
//
// Build a dir name based on the FID of the file
//
AFSDbgLogMsg( AFS_SUBSYSTEM_DIR_NOTIF_PROCESSING,
AFS_TRACE_LEVEL_VERBOSE,
- "AFSFsRtlNotifyFullChangeDirectory Registering notification on %wZ Irp %08lX Filter %08lX Tree %02lX\n",
+ "AFSFsRtlNotifyFullChangeDirectory Registering notification on %wZ Irp %p Filter %08lX Tree %02lX\n",
&Ccb->NotifyMask,
NotifyIrp,
CompletionFilter,
if( Ccb->NotifyMask.Buffer != NULL)
{
- AFSExFreePool( Ccb->NotifyMask.Buffer);
+ AFSExFreePoolWithTag( Ccb->NotifyMask.Buffer, AFS_GENERIC_MEMORY_7_TAG);
Ccb->NotifyMask.Buffer = NULL;
}
}
+
+ AFSReleaseResource( &Ccb->NPCcb->CcbLock);
}
return ntStatus;
if( uniName.Buffer != NULL)
{
- AFSExFreePool( uniName.Buffer);
+ AFSExFreePoolWithTag( uniName.Buffer, AFS_GENERIC_MEMORY_8_TAG);
}
}
AFSNotifyReportChangeCallback( IN void *NotifyContext,
IN void *FilterContext)
{
-
+ UNREFERENCED_PARAMETER(NotifyContext);
+ UNREFERENCED_PARAMETER(FilterContext);
BOOLEAN bReturn = TRUE;
- AFSCcb *pDirCcb = (AFSCcb *)NotifyContext;
- AFSCcb *pNotifyCcb = (AFSCcb *)FilterContext;
__Enter
{