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
{
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;
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);
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());
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());
AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
AFS_TRACE_LEVEL_ERROR,
- "AFSQueryDirectory (%08lX) Unknown FileInformationClass %u\n",
+ "AFSQueryDirectory (%p) Unknown FileInformationClass %u\n",
Irp,
FileInformationClass);
{
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))
{
- 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;
}
}
// We don't worry about entries while enumerating the directory
//
- AFSValidateEntry( pDirEntry,
- &pCcb->AuthGroup,
- 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,
- &pCcb->AuthGroup,
- &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--;
- lCount = 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);
- lCount = InterlockedDecrement( &pDirEntry->OpenReferenceCount);
-
try_return( ntStatus = STATUS_INVALID_INFO_CLASS);
-
- break;
}
}
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
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());
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",
ObjectInfo->FileId.Volume,
ObjectInfo->FileId.Vnode,
ObjectInfo->FileId.Unique);
-
- lCount = InterlockedIncrement( &pDirEntry->OpenReferenceCount);
}
else
{
try_exit:
+ 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);
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;
}
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;
}
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
{