// The ObjectReferenceCount will be freed by AFSPerformObjectInvalidate
//
- lCount = AFSObjectInfoIncrement( pObjectInfo);
+ lCount = AFSObjectInfoIncrement( pObjectInfo,
+ AFS_OBJECT_REFERENCE_INVALIDATION);
+
+ AFSDbgLogMsg( AFS_SUBSYSTEM_OBJECT_REF_COUNTING,
+ AFS_TRACE_LEVEL_VERBOSE,
+ "AFSEnumerateDirectory calling AFSPerformObjectInvalidate Increment count on object %p Cnt %d\n",
+ pObjectInfo,
+ lCount);
AFSPerformObjectInvalidate( pObjectInfo,
AFS_INVALIDATE_DATA_VERSION);
// lock hierarchy.
//
- lCount = AFSObjectInfoIncrement( pObjectInfo);
+ lCount = AFSObjectInfoIncrement( pObjectInfo,
+ AFS_OBJECT_REFERENCE_INVALIDATION);
+
+ AFSDbgLogMsg( AFS_SUBSYSTEM_OBJECT_REF_COUNTING,
+ AFS_TRACE_LEVEL_VERBOSE,
+ "AFSVerifyDirectoryContent calling AFSQueueInvalidateObject Increment count on object %p Cnt %d\n",
+ pObjectInfo,
+ lCount);
if ( !NT_SUCCESS( AFSQueueInvalidateObject( pObjectInfo,
AFS_INVALIDATE_DATA_VERSION)))
{
- lCount = AFSObjectInfoDecrement( pObjectInfo);
+ lCount = AFSObjectInfoDecrement( pObjectInfo,
+ AFS_OBJECT_REFERENCE_INVALIDATION);
+
+ AFSDbgLogMsg( AFS_SUBSYSTEM_OBJECT_REF_COUNTING,
+ AFS_TRACE_LEVEL_VERBOSE,
+ "AFSVerifyDirectoryContent AFSQueueInvalidateObject failed Decrement count on object %p Cnt %d\n",
+ pObjectInfo,
+ lCount);
}
}
else
LONG lCount;
LARGE_INTEGER liOldDataVersion;
AFSDeviceExt *pDevExt = (AFSDeviceExt *) AFSRDRDeviceObject->DeviceExtension;
+ BOOLEAN bReleaseParentTreeLock = FALSE;
__Enter
{
+ *DirNode = NULL;
+
//
// Init the control block for the request
//
AFSAcquireExcl( ParentObjectInfo->Specific.Directory.DirectoryNodeHdr.TreeLock,
TRUE);
+ bReleaseParentTreeLock = TRUE;
+
if( ParentObjectInfo->DataVersion.QuadPart != pResultCB->ParentDataVersion.QuadPart - 1)
{
&pResultCB->DirEnum.FileId))
{
- lCount = InterlockedIncrement( &pDirNode->DirOpenReferenceCount);
-
- AFSDbgLogMsg( AFS_SUBSYSTEM_DIRENTRY_REF_COUNTING,
- AFS_TRACE_LEVEL_VERBOSE,
- "AFSNotifyFileCreate Increment count on %wZ DE %p Cnt %d\n",
- &pDirNode->NameInformation.FileName,
- pDirNode,
- lCount);
-
- ASSERT( lCount >= 0);
-
*DirNode = pDirNode;
- AFSReleaseResource( ParentObjectInfo->Specific.Directory.DirectoryNodeHdr.TreeLock);
-
try_return( ntStatus = STATUS_REPARSE);
}
else
ParentObjectInfo->DataVersion.QuadPart = (ULONGLONG)-1;
- AFSReleaseResource( ParentObjectInfo->Specific.Directory.DirectoryNodeHdr.TreeLock);
-
try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
}
ParentObjectInfo->DataVersion.QuadPart);
}
- AFSReleaseResource( ParentObjectInfo->Specific.Directory.DirectoryNodeHdr.TreeLock);
-
//
// Return the directory node
//
try_exit:
+ if ( *DirNode != NULL)
+ {
+
+ lCount = InterlockedIncrement( &(*DirNode)->DirOpenReferenceCount);
+
+ AFSDbgLogMsg( AFS_SUBSYSTEM_DIRENTRY_REF_COUNTING,
+ AFS_TRACE_LEVEL_VERBOSE,
+ "AFSNotifyFileCreate Increment count on %wZ DE %p Cnt %d\n",
+ &(*DirNode)->NameInformation.FileName,
+ *DirNode,
+ lCount);
+
+ ASSERT( lCount >= 0);
+ }
+
+ if ( bReleaseParentTreeLock)
+ {
+
+ AFSReleaseResource( ParentObjectInfo->Specific.Directory.DirectoryNodeHdr.TreeLock);
+ }
+
if( pResultCB != NULL)
{
AFSFileDeleteCB stDelete;
AFSFileDeleteResultCB stDeleteResult;
ULONG ulRequestFlags = AFS_REQUEST_FLAG_SYNCHRONOUS;
+ AFSObjectInfoCB *pObjectInfo = NULL;
+ AFSObjectInfoCB *pParentObjectInfo = NULL;
__Enter
{
- stDelete.ParentId = DirectoryCB->ObjectInformation->ParentObjectInformation->FileId;
+ pObjectInfo = DirectoryCB->ObjectInformation;
+
+ pParentObjectInfo = AFSFindObjectInfo( pObjectInfo->VolumeCB,
+ &pObjectInfo->ParentFileId);
+
+ stDelete.ParentId = pObjectInfo->ParentFileId;
stDelete.ProcessId = (ULONGLONG)PsGetCurrentProcessId();
ulRequestFlags,
AuthGroup,
&DirectoryCB->NameInformation.FileName,
- &DirectoryCB->ObjectInformation->FileId,
+ &pObjectInfo->FileId,
&stDelete,
sizeof( AFSFileDeleteCB),
&stDeleteResult,
stDelete.ParentId.Vnode,
stDelete.ParentId.Unique,
&DirectoryCB->NameInformation.FileName,
- DirectoryCB->ObjectInformation->FileId.Cell,
- DirectoryCB->ObjectInformation->FileId.Volume,
- DirectoryCB->ObjectInformation->FileId.Vnode,
- DirectoryCB->ObjectInformation->FileId.Unique,
+ pObjectInfo->FileId.Cell,
+ pObjectInfo->FileId.Volume,
+ pObjectInfo->FileId.Vnode,
+ pObjectInfo->FileId.Unique,
ntStatus);
try_return( ntStatus);
}
- AFSAcquireExcl( DirectoryCB->ObjectInformation->Specific.Directory.DirectoryNodeHdr.TreeLock,
+ AFSAcquireExcl( pObjectInfo->Specific.Directory.DirectoryNodeHdr.TreeLock,
TRUE);
if( CheckOnly)
// Validate the parent data version
//
- if( DirectoryCB->ObjectInformation->ParentObjectInformation->DataVersion.QuadPart != stDeleteResult.ParentDataVersion.QuadPart)
+ if( pParentObjectInfo->DataVersion.QuadPart != stDeleteResult.ParentDataVersion.QuadPart)
{
- SetFlag( DirectoryCB->ObjectInformation->ParentObjectInformation->Flags, AFS_OBJECT_FLAGS_VERIFY);
+ SetFlag( pParentObjectInfo->Flags, AFS_OBJECT_FLAGS_VERIFY);
- DirectoryCB->ObjectInformation->ParentObjectInformation->DataVersion.QuadPart = (ULONGLONG)-1;
+ pParentObjectInfo->DataVersion.QuadPart = (ULONGLONG)-1;
}
}
else
// Update the parent data version
//
- if( DirectoryCB->ObjectInformation->ParentObjectInformation->DataVersion.QuadPart != stDeleteResult.ParentDataVersion.QuadPart - 1)
+ if( pParentObjectInfo->DataVersion.QuadPart != stDeleteResult.ParentDataVersion.QuadPart - 1)
{
- SetFlag( DirectoryCB->ObjectInformation->ParentObjectInformation->Flags, AFS_OBJECT_FLAGS_VERIFY);
+ SetFlag( pParentObjectInfo->Flags, AFS_OBJECT_FLAGS_VERIFY);
- DirectoryCB->ObjectInformation->ParentObjectInformation->DataVersion.QuadPart = (ULONGLONG)-1;
+ pParentObjectInfo->DataVersion.QuadPart = (ULONGLONG)-1;
}
else
{
// Directory data version number can be updated. Until then we must force
// a verification.
//
- // DirectoryCB->ObjectInformation->ParentObjectInformation->DataVersion.QuadPart = stDeleteResult.ParentDataVersion.QuadPart;
+ // pParentObjectInfor->DataVersion.QuadPart = stDeleteResult.ParentDataVersion.QuadPart;
//
- SetFlag( DirectoryCB->ObjectInformation->ParentObjectInformation->Flags, AFS_OBJECT_FLAGS_VERIFY);
+ SetFlag( pParentObjectInfo->Flags, AFS_OBJECT_FLAGS_VERIFY);
- DirectoryCB->ObjectInformation->ParentObjectInformation->DataVersion.QuadPart = (ULONGLONG)-1;
+ pParentObjectInfo->DataVersion.QuadPart = (ULONGLONG)-1;
}
}
- AFSReleaseResource( DirectoryCB->ObjectInformation->Specific.Directory.DirectoryNodeHdr.TreeLock);
+ AFSReleaseResource( pObjectInfo->Specific.Directory.DirectoryNodeHdr.TreeLock);
try_exit:
- NOTHING;
+ if ( pParentObjectInfo)
+ {
+
+ AFSReleaseObjectInfo( &pParentObjectInfo);
+ }
}
return ntStatus;
&pResultCB->DirEnum.FileId))
{
- lCount = InterlockedIncrement( &pDirNode->DirOpenReferenceCount);
-
- AFSDbgLogMsg( AFS_SUBSYSTEM_DIRENTRY_REF_COUNTING,
- AFS_TRACE_LEVEL_VERBOSE,
- "AFSNotifyHardLink Increment count on %wZ DE %p Cnt %d\n",
- &pDirNode->NameInformation.FileName,
- pDirNode,
- lCount);
-
- ASSERT( lCount >= 0);
-
- AFSReleaseResource( TargetParentObjectInfo->Specific.Directory.DirectoryNodeHdr.TreeLock);
-
try_return( ntStatus = STATUS_REPARSE);
}
else
TargetParentObjectInfo->DataVersion.QuadPart = (ULONGLONG)-1;
- AFSReleaseResource( TargetParentObjectInfo->Specific.Directory.DirectoryNodeHdr.TreeLock);
-
try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
}
try_exit:
+ if ( TargetDirectoryCB != NULL)
+ {
+
+ lCount = InterlockedIncrement( &pDirNode->DirOpenReferenceCount);
+
+ AFSDbgLogMsg( AFS_SUBSYSTEM_DIRENTRY_REF_COUNTING,
+ AFS_TRACE_LEVEL_VERBOSE,
+ "AFSNotifyHardLink Increment count on %wZ DE %p Cnt %d\n",
+ &pDirNode->NameInformation.FileName,
+ pDirNode,
+ lCount);
+
+ ASSERT( lCount >= 0);
+
+ *TargetDirectoryCB = pDirNode;
+ }
+
if ( bReleaseTargetParentLock)
{
AFSExFreePoolWithTag( pHardLinkCB, AFS_HARDLINK_REQUEST_TAG);
}
-
- if ( TargetDirectoryCB)
- {
-
- *TargetDirectoryCB = pDirNode;
- }
}
return ntStatus;
AFSFileEvalResultCB *pEvalResultCB = NULL;
AFSDirEnumEntry *pDirEnumCB = NULL;
ULONG ulRequestFlags = AFS_REQUEST_FLAG_SYNCHRONOUS;
- AFSObjectInfoCB *pParentInfo = NULL;
+ AFSObjectInfoCB *pParentObjectInfo = NULL;
__Enter
{
RtlZeroMemory( &stTargetID,
sizeof( AFSEvalTargetCB));
- pParentInfo = ObjectInfo->ParentObjectInformation;
-
- if( pParentInfo != NULL)
+ if ( BooleanFlagOn( ObjectInfo->Flags, AFS_OBJECT_FLAGS_PARENT_FID))
{
- stTargetID.ParentId = pParentInfo->FileId;
+ pParentObjectInfo = AFSFindObjectInfo( ObjectInfo->VolumeCB,
+ &ObjectInfo->ParentFileId);
+
+ stTargetID.ParentId = ObjectInfo->ParentFileId;
}
//
if( ntStatus == STATUS_OBJECT_PATH_INVALID)
{
- if( pParentInfo != NULL)
+ if( pParentObjectInfo != NULL)
{
- AFSAcquireExcl( pParentInfo->Specific.Directory.DirectoryNodeHdr.TreeLock,
+ AFSAcquireExcl( pParentObjectInfo->Specific.Directory.DirectoryNodeHdr.TreeLock,
TRUE);
- SetFlag( pParentInfo->Flags, AFS_OBJECT_FLAGS_VERIFY);
+ SetFlag( pParentObjectInfo->Flags, AFS_OBJECT_FLAGS_VERIFY);
- pParentInfo->DataVersion.QuadPart = (ULONGLONG)-1;
+ pParentObjectInfo->DataVersion.QuadPart = (ULONGLONG)-1;
- AFSReleaseResource( pParentInfo->Specific.Directory.DirectoryNodeHdr.TreeLock);
+ AFSReleaseResource( pParentObjectInfo->Specific.Directory.DirectoryNodeHdr.TreeLock);
}
}
}
//
+ // A BSOD can occur if the pEvalResultCB->FileType is FILE but the
+ // ObjectInfo->FileType is something else. The same is true for
+ // pDirEnumEntry->FileType is DIRECTORY. Perform a sanity check
+ // to ensure consistency. An inconsistent pDirEnumEntry can be
+ // produced as a result of invalid status info received from a file
+ // server. If the types are inconsistent or if the type does not
+ // match the implied type derived from the vnode (odd values are
+ // directories and even values are other types), prevent the request
+ // from completing successfully. This may prevent access to the file or
+ // directory but will prevent a BSOD.
+ //
+
+ if ( !AFSIsEqualFID( &ObjectInfo->FileId,
+ &pEvalResultCB->DirEnum.FileId))
+ {
+
+ try_return( ntStatus = STATUS_UNSUCCESSFUL);
+ }
+
+ switch ( pEvalResultCB->DirEnum.FileType)
+ {
+
+ case AFS_FILE_TYPE_DIRECTORY:
+ if ( (pEvalResultCB->DirEnum.FileId.Vnode & 0x1) != 0x1)
+ {
+
+ try_return( ntStatus = STATUS_UNSUCCESSFUL);
+ }
+
+ if ( ObjectInfo->FileType != AFS_FILE_TYPE_UNKNOWN &&
+ ObjectInfo->FileType != AFS_FILE_TYPE_DIRECTORY)
+ {
+
+ try_return( ntStatus = STATUS_UNSUCCESSFUL);
+ }
+
+ break;
+
+ case AFS_FILE_TYPE_FILE:
+ if ( (pEvalResultCB->DirEnum.FileId.Vnode & 0x1) != 0x0)
+ {
+
+ try_return( ntStatus = STATUS_UNSUCCESSFUL);
+ }
+
+ if ( ObjectInfo->FileType != AFS_FILE_TYPE_UNKNOWN &&
+ ObjectInfo->FileType != AFS_FILE_TYPE_FILE)
+ {
+
+ try_return( ntStatus = STATUS_UNSUCCESSFUL);
+ }
+
+ break;
+ }
+
+ //
// Validate the parent data version
//
- if ( pParentInfo != NULL)
+ if ( pParentObjectInfo != NULL)
{
- AFSAcquireExcl( pParentInfo->Specific.Directory.DirectoryNodeHdr.TreeLock,
+ AFSAcquireExcl( pParentObjectInfo->Specific.Directory.DirectoryNodeHdr.TreeLock,
TRUE);
- if ( pParentInfo->DataVersion.QuadPart != pEvalResultCB->ParentDataVersion.QuadPart)
+ if ( pParentObjectInfo->DataVersion.QuadPart != pEvalResultCB->ParentDataVersion.QuadPart)
{
- SetFlag( pParentInfo->Flags, AFS_OBJECT_FLAGS_VERIFY);
+ SetFlag( pParentObjectInfo->Flags, AFS_OBJECT_FLAGS_VERIFY);
- pParentInfo->DataVersion.QuadPart = (ULONGLONG)-1;
+ pParentObjectInfo->DataVersion.QuadPart = (ULONGLONG)-1;
}
- AFSReleaseResource( pParentInfo->Specific.Directory.DirectoryNodeHdr.TreeLock);
+ AFSReleaseResource( pParentObjectInfo->Specific.Directory.DirectoryNodeHdr.TreeLock);
}
//
try_exit:
+ if ( pParentObjectInfo != NULL)
+ {
+
+ AFSReleaseObjectInfo( &pParentObjectInfo);
+ }
+
if( pEvalResultCB != NULL)
{