else
{
+ ntStatus = STATUS_UNSUCCESSFUL;
+
AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
AFS_TRACE_LEVEL_VERBOSE,
"AFSInsertShortNameDirEntry Collision with DE %p for shortname %S and %wZ\n",
//
uniShortName.Length = pDirNode->NameInformation.ShortNameLength;
+ uniShortName.MaximumLength = uniShortName.Length;
uniShortName.Buffer = pDirNode->NameInformation.ShortName;
- pDirNode->Type.Data.ShortNameTreeEntry.HashIndex = AFSGenerateCRC( &uniShortName,
- TRUE);
+ if( !RtlIsNameLegalDOS8Dot3( &pDirNode->NameInformation.FileName,
+ NULL,
+ NULL))
+ {
- AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
- AFS_TRACE_LEVEL_VERBOSE,
- "AFSEnumerateDirectory Initialized short name %wZ for DE %p for %wZ\n",
- &uniShortName,
- pDirNode,
- &pDirNode->NameInformation.FileName);
+ pDirNode->Type.Data.ShortNameTreeEntry.HashIndex = AFSGenerateCRC( &uniShortName,
+ TRUE);
+
+ AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
+ AFS_TRACE_LEVEL_VERBOSE,
+ "AFSEnumerateDirectory Initialized short name %wZ for DE %p for %wZ FID %08lX-%08lX-%08lX-%08lX\n",
+ &uniShortName,
+ pDirNode,
+ &pDirNode->NameInformation.FileName,
+ pCurrentDirEntry->FileId.Cell,
+ pCurrentDirEntry->FileId.Volume,
+ pCurrentDirEntry->FileId.Vnode,
+ pCurrentDirEntry->FileId.Unique);
+ }
+ else
+ {
+ pDirNode->NameInformation.ShortNameLength = 0;
+
+ RtlZeroMemory( pDirNode->NameInformation.ShortName,
+ (12 * sizeof( WCHAR)));
+ }
}
//
pDirNode,
&pDirNode->NameInformation.FileName);
- AFSInsertCaseSensitiveDirEntry( ObjectInfoCB->Specific.Directory.DirectoryNodeHdr.CaseSensitiveTreeHead,
- pDirNode);
+ if( !NT_SUCCESS( AFSInsertCaseSensitiveDirEntry( ObjectInfoCB->Specific.Directory.DirectoryNodeHdr.CaseSensitiveTreeHead,
+ pDirNode)))
+ {
+
+ //
+ // Delete this dir entry and continue on
+ //
+
+ AFSDeleteDirEntry( ObjectInfoCB,
+ pDirNode);
+
+ pCurrentDirEntry = (AFSDirEnumEntry *)((char *)pCurrentDirEntry + ulEntryLength);
+
+ if( ulResultLen >= ulEntryLength)
+ {
+ ulResultLen -= ulEntryLength;
+ }
+ else
+ {
+ ulResultLen = 0;
+ }
+
+ continue;
+ }
}
+ ClearFlag( pDirNode->Flags, AFS_DIR_ENTRY_NOT_IN_PARENT_TREE);
+
if( ObjectInfoCB->Specific.Directory.DirectoryNodeHdr.CaseInsensitiveTreeHead == NULL)
{
&pDirNode->NameInformation.FileName);
ObjectInfoCB->Specific.Directory.ShortNameTree = pDirNode;
+
+ SetFlag( pDirNode->Flags, AFS_DIR_ENTRY_INSERTED_SHORT_NAME);
}
else
{
- AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
- AFS_TRACE_LEVEL_VERBOSE,
- "AFSEnumerateDirectory Insert DE %p to shortname tree for %wZ\n",
- pDirNode,
- &pDirNode->NameInformation.FileName);
+ if( NT_SUCCESS( AFSInsertShortNameDirEntry( ObjectInfoCB->Specific.Directory.ShortNameTree,
+ pDirNode)))
+ {
+ SetFlag( pDirNode->Flags, AFS_DIR_ENTRY_INSERTED_SHORT_NAME);
- AFSInsertShortNameDirEntry( ObjectInfoCB->Specific.Directory.ShortNameTree,
- pDirNode);
+ AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
+ AFS_TRACE_LEVEL_VERBOSE,
+ "AFSEnumerateDirectory Insert DE %p to shortname tree for %wZ\n",
+ pDirNode,
+ &pDirNode->NameInformation.FileName);
+ }
}
}
//
uniShortName.Length = pDirNode->NameInformation.ShortNameLength;
+ uniShortName.MaximumLength = uniShortName.Length;
uniShortName.Buffer = pDirNode->NameInformation.ShortName;
- pDirNode->Type.Data.ShortNameTreeEntry.HashIndex = AFSGenerateCRC( &uniShortName,
- TRUE);
+ if( !RtlIsNameLegalDOS8Dot3( &pDirNode->NameInformation.FileName,
+ NULL,
+ NULL))
+ {
+
+ pDirNode->Type.Data.ShortNameTreeEntry.HashIndex = AFSGenerateCRC( &uniShortName,
+ TRUE);
+
+ AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
+ AFS_TRACE_LEVEL_VERBOSE,
+ "AFSVerifyDirectoryContent Initialized short name %wZ for DE %p for %wZ FID %08lX-%08lX-%08lX-%08lX\n",
+ &uniShortName,
+ pDirNode,
+ &pDirNode->NameInformation.FileName,
+ pCurrentDirEntry->FileId.Cell,
+ pCurrentDirEntry->FileId.Volume,
+ pCurrentDirEntry->FileId.Vnode,
+ pCurrentDirEntry->FileId.Unique);
+ }
+ else
+ {
+ pDirNode->NameInformation.ShortNameLength = 0;
+
+ RtlZeroMemory( pDirNode->NameInformation.ShortName,
+ (12 * sizeof( WCHAR)));
+ }
+ }
+ else
+ {
AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
AFS_TRACE_LEVEL_VERBOSE,
else
{
- AFSInsertCaseSensitiveDirEntry( ObjectInfoCB->Specific.Directory.DirectoryNodeHdr.CaseSensitiveTreeHead,
- pDirNode);
+ if( !NT_SUCCESS( AFSInsertCaseSensitiveDirEntry( ObjectInfoCB->Specific.Directory.DirectoryNodeHdr.CaseSensitiveTreeHead,
+ pDirNode)))
+ {
+ AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
+ AFS_TRACE_LEVEL_VERBOSE,
+ "AFSVerifyDirectoryContent Failed to nsert DE %p to case sensitive tree for %wZ\n",
+ pDirNode,
+ &pDirNode->NameInformation.FileName);
+
+ //
+ // Delete this dir entry and continue on
+ //
- AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
- AFS_TRACE_LEVEL_VERBOSE,
- "AFSVerifyDirectoryContent Insert DE %p to case sensitive tree for %wZ\n",
- pDirNode,
- &pDirNode->NameInformation.FileName);
+ AFSDeleteDirEntry( ObjectInfoCB,
+ pDirNode);
+
+ pCurrentDirEntry = (AFSDirEnumEntry *)((char *)pCurrentDirEntry + ulEntryLength);
+
+ if( ulResultLen >= ulEntryLength)
+ {
+ ulResultLen -= ulEntryLength;
+ }
+ else
+ {
+ ulResultLen = 0;
+ }
+
+ continue;
+ }
+ else
+ {
+ AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
+ AFS_TRACE_LEVEL_VERBOSE,
+ "AFSVerifyDirectoryContent Insert DE %p to case sensitive tree for %wZ\n",
+ pDirNode,
+ &pDirNode->NameInformation.FileName);
+ }
}
+ ClearFlag( pDirNode->Flags, AFS_DIR_ENTRY_NOT_IN_PARENT_TREE);
+
if( ObjectInfoCB->Specific.Directory.DirectoryNodeHdr.CaseInsensitiveTreeHead == NULL)
{
"AFSVerifyDirectoryContent Insert DE %p to head of shortname tree for %wZ\n",
pDirNode,
&pDirNode->NameInformation.FileName);
+
+ SetFlag( pDirNode->Flags, AFS_DIR_ENTRY_INSERTED_SHORT_NAME);
}
else
{
- AFSInsertShortNameDirEntry( ObjectInfoCB->Specific.Directory.ShortNameTree,
- pDirNode);
+ if( !NT_SUCCESS( AFSInsertShortNameDirEntry( ObjectInfoCB->Specific.Directory.ShortNameTree,
+ pDirNode)))
+ {
+ AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
+ AFS_TRACE_LEVEL_VERBOSE,
+ "AFSVerifyDirectoryContent Failed to insert DE %p (%08lX) to shortname tree for %wZ\n",
+ pDirNode,
+ pDirNode->Type.Data.ShortNameTreeEntry.HashIndex,
+ &pDirNode->NameInformation.FileName);
+ }
+ else
+ {
+ SetFlag( pDirNode->Flags, AFS_DIR_ENTRY_INSERTED_SHORT_NAME);
- AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
- AFS_TRACE_LEVEL_VERBOSE,
- "AFSVerifyDirectoryContent Insert DE %p to shortname tree for %wZ\n",
- pDirNode,
- &pDirNode->NameInformation.FileName);
+ AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
+ AFS_TRACE_LEVEL_VERBOSE,
+ "AFSVerifyDirectoryContent Insert DE %p to shortname tree for %wZ\n",
+ pDirNode,
+ &pDirNode->NameInformation.FileName);
+ }
}
}
if( DirectoryCB->NameInformation.ShortNameLength > 0)
{
+ UNICODE_STRING uniShortName;
+
+ uniShortName.Length = DirectoryCB->NameInformation.ShortNameLength;
+ uniShortName.MaximumLength = uniShortName.Length;
+ uniShortName.Buffer = DirectoryCB->NameInformation.ShortName;
+
+ AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
+ AFS_TRACE_LEVEL_VERBOSE,
+ "AFSNotifyRename Update old short name %wZ for DE %p for %wZ\n",
+ &uniShortName,
+ DirectoryCB,
+ &DirectoryCB->NameInformation.FileName);
+
+ DirectoryCB->NameInformation.ShortNameLength = pRenameResultCB->DirEnum.ShortNameLength;
+
RtlCopyMemory( DirectoryCB->NameInformation.ShortName,
pRenameResultCB->DirEnum.ShortName,
DirectoryCB->NameInformation.ShortNameLength);
+
+ uniShortName.Length = DirectoryCB->NameInformation.ShortNameLength;
+ uniShortName.MaximumLength = uniShortName.Length;
+ uniShortName.Buffer = DirectoryCB->NameInformation.ShortName;
+
+ AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
+ AFS_TRACE_LEVEL_VERBOSE,
+ "AFSNotifyRename Initialized short name %wZ for DE %p for %wZ\n",
+ &uniShortName,
+ DirectoryCB,
+ &DirectoryCB->NameInformation.FileName);
+ }
+ else
+ {
+
+ UNICODE_STRING uniShortName;
+
+ uniShortName.Length = DirectoryCB->NameInformation.ShortNameLength;
+ uniShortName.MaximumLength = uniShortName.Length;
+ uniShortName.Buffer = DirectoryCB->NameInformation.ShortName;
+
+ AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
+ AFS_TRACE_LEVEL_VERBOSE,
+ "AFSNotifyRename Removing old short name %wZ for DE %p for %wZ\n",
+ &uniShortName,
+ DirectoryCB,
+ &DirectoryCB->NameInformation.FileName);
+
+ DirectoryCB->NameInformation.ShortNameLength = 0;
+
+ DirectoryCB->Type.Data.ShortNameTreeEntry.HashIndex = 0;
}
if( UpdatedFID != NULL)
{
-
*UpdatedFID = pRenameResultCB->DirEnum.FileId;
}
pObjectInfo = pDirEntry->ObjectInformation;
+ if( BooleanFlagOn( pObjectInfo->Flags, AFS_OBJECT_FLAGS_NOT_EVALUATED) ||
+ pObjectInfo->FileType == AFS_FILE_TYPE_UNKNOWN)
+ {
+
+ AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
+ AFS_TRACE_LEVEL_VERBOSE,
+ "AFSProcessCreate (%08lX) Evaluating object %wZ FID %08lX-%08lX-%08lX-%08lX\n",
+ Irp,
+ &pDirEntry->NameInformation.FileName,
+ pObjectInfo->FileId.Cell,
+ pObjectInfo->FileId.Volume,
+ pObjectInfo->FileId.Vnode,
+ pObjectInfo->FileId.Unique);
+
+ ntStatus = AFSEvaluateNode( AuthGroup,
+ pDirEntry);
+
+ if( !NT_SUCCESS( ntStatus))
+ {
+
+ AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
+ AFS_TRACE_LEVEL_ERROR,
+ "AFSProcessCreate (%08lX) Failed to evaluate object %wZ FID %08lX-%08lX-%08lX-%08lX Status %08lX\n",
+ Irp,
+ &pDirEntry->NameInformation.FileName,
+ pObjectInfo->FileId.Cell,
+ pObjectInfo->FileId.Volume,
+ pObjectInfo->FileId.Vnode,
+ pObjectInfo->FileId.Unique,
+ ntStatus);
+
+ try_return( ntStatus);
+ }
+
+ ClearFlag( pObjectInfo->Flags, AFS_OBJECT_FLAGS_NOT_EVALUATED);
+ }
+
//
// We may have raced and the Fcb is already created
//
AFSAcquireExcl( pParentObjectInfo->Specific.Directory.DirectoryNodeHdr.TreeLock,
TRUE);
- AFSDeleteDirEntry( pParentObjectInfo,
- pDirEntry);
+ SetFlag( pDirEntry->Flags, AFS_DIR_ENTRY_DELETED);
+
+ //
+ // Pull the directory entry from the parent
+ //
+
+ AFSRemoveDirNodeFromParent( pParentObjectInfo,
+ pDirEntry,
+ FALSE); // Leave it in the enum list so the worker cleans it up
+
+ AFSNotifyDelete( pDirEntry,
+ FALSE);
+
+ //
+ // Tag the parent as needing verification
+ //
+
+ SetFlag( pParentObjectInfo->Flags, AFS_OBJECT_FLAGS_VERIFY);
AFSReleaseResource( pParentObjectInfo->Specific.Directory.DirectoryNodeHdr.TreeLock);
}
}
//
- // 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( &pFcb->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
//
{
ntStatus = AFSSnapshotDirectory( pFcb,
- pCcb);
+ pCcb,
+ TRUE);
if( !NT_SUCCESS( ntStatus))
{
FileInformationClass);
try_return( ntStatus = STATUS_INVALID_INFO_CLASS);
- }
+ }
AFSReleaseResource( pFcb->ObjectInformation->Specific.Directory.DirectoryNodeHdr.TreeLock);
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;
}
}
pCcb->CurrentDirIndex--;
+ InterlockedDecrement( &pDirEntry->OpenReferenceCount);
+
try_return( ntStatus = STATUS_SUCCESS);
}
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
// 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:
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
+ //
+
+ 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;
+ Ccb->CurrentDirIndex = AFS_DIR_ENTRY_INITIAL_ROOT_INDEX;
+ }
}
if( Fcb->ObjectInformation->Specific.Directory.DirectoryNodeCount == 0)
AFSObjectInfoCB *pSrcObject = NULL, *pTargetObject = NULL;
AFSObjectInfoCB *pSrcParentObject = NULL, *pTargetParentObject = NULL;
AFSFileID stNewFid, stTmpTargetFid;
- UNICODE_STRING uniTmpTargetName;
- BOOLEAN bReplaceTmpTargetEntry = FALSE;
ULONG ulNotificationAction = 0, ulNotifyFilter = 0;
UNICODE_STRING uniFullTargetPath;
BOOLEAN bCommonParent = FALSE;
ULONG oldFileIndex;
+ BOOLEAN bReleaseVolumeLock = FALSE;
+ BOOLEAN bReleaseTargetDirLock = FALSE;
+ BOOLEAN bReleaseSourceDirLock = FALSE;
__Enter
{
pSrcObject = pSrcFcb->ObjectInformation;
- uniTmpTargetName.Length = 0;
- uniTmpTargetName.MaximumLength = 0;
- uniTmpTargetName.Buffer = NULL;
-
//
// Perform some basic checks to ensure FS integrity
//
// If the target exists be sure the ReplaceIfExists flag is set
//
- AFSAcquireShared( pTargetParentObject->VolumeCB->VolumeLock,
- TRUE);
+ AFSAcquireExcl( pTargetParentObject->VolumeCB->VolumeLock,
+ TRUE);
+
+ bReleaseVolumeLock = TRUE;
ulTargetCRC = AFSGenerateCRC( &uniTargetName,
FALSE);
- AFSAcquireShared( pTargetParentObject->Specific.Directory.DirectoryNodeHdr.TreeLock,
- TRUE);
+ AFSAcquireExcl( pTargetParentObject->Specific.Directory.DirectoryNodeHdr.TreeLock,
+ TRUE);
+
+ bReleaseTargetDirLock = TRUE;
+
+ if( pTargetParentObject != pSrcFcb->ObjectInformation->ParentObjectInformation)
+ {
+ AFSAcquireExcl( pSrcFcb->ObjectInformation->ParentObjectInformation->Specific.Directory.DirectoryNodeHdr.TreeLock,
+ TRUE);
+
+ bReleaseSourceDirLock = TRUE;
+ }
AFSLocateCaseSensitiveDirEntry( pTargetParentObject->Specific.Directory.DirectoryNodeHdr.CaseSensitiveTreeHead,
ulTargetCRC,
ulTargetCRC,
&pTargetDirEntry);
}
+
//
// Increment our ref count on the dir entry
//
if( pTargetDirEntry != NULL)
{
- InterlockedIncrement( &pTargetDirEntry->OpenReferenceCount);
- }
- AFSReleaseResource( pTargetParentObject->Specific.Directory.DirectoryNodeHdr.TreeLock);
+ ASSERT( pTargetParentObject == pTargetDirEntry->ObjectInformation->ParentObjectInformation);
- if( pTargetDirEntry != NULL)
- {
+ InterlockedIncrement( &pTargetDirEntry->OpenReferenceCount);
if( !bReplaceIfExists)
{
- AFSReleaseResource( pTargetParentObject->VolumeCB->VolumeLock);
-
AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
AFS_TRACE_LEVEL_ERROR,
"AFSSetRenameInfo Attempt to rename directory with target collision %wZ Target %wZ\n",
pTargetDirEntry,
pTargetDirEntry->OpenReferenceCount);
+ //
+ // Pull the directory entry from the parent
+ //
+
+ AFSRemoveDirNodeFromParent( pTargetParentObject,
+ pTargetDirEntry,
+ FALSE);
+
bTargetEntryExists = TRUE;
}
-
- AFSReleaseResource( pTargetParentObject->VolumeCB->VolumeLock);
+ else
+ {
+ AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
+ AFS_TRACE_LEVEL_ERROR,
+ "AFSSetRenameInfo Target Target does NOT exist, normal rename\n");
+ }
//
// Extract off the final component name from the Fcb
if( FsRtlAreNamesEqual( &uniTargetName,
&uniSourceName,
- TRUE,
+ FALSE,
NULL))
{
-
- //
- // Check for case only rename
- //
-
- if( !FsRtlAreNamesEqual( &uniTargetName,
- &uniSourceName,
- FALSE,
- NULL))
- {
-
- //
- // Just move in the new case form of the name
- //
-
- RtlCopyMemory( pSrcCcb->DirectoryCB->NameInformation.FileName.Buffer,
- uniTargetName.Buffer,
- uniTargetName.Length);
- }
-
try_return( ntStatus = STATUS_SUCCESS);
}
}
bCommonParent = FALSE;
}
- //
- // If the target name exists then we need to 'move' the target before
- // sending the rename to the service
- //
-
- if( bReplaceIfExists &&
- pTargetDirEntry != NULL)
- {
-
- //
- // What we will do is temporarily rename the file to a tmp file
- // so we can back out if anything fails below
- // First thing is to remove the original target from the parent
- //
-
- AFSAcquireExcl( pTargetDirEntry->ObjectInformation->ParentObjectInformation->Specific.Directory.DirectoryNodeHdr.TreeLock,
- TRUE);
-
- AFSRemoveDirNodeFromParent( pTargetDirEntry->ObjectInformation->ParentObjectInformation,
- pTargetDirEntry,
- TRUE);
-
- AFSReleaseResource( pTargetDirEntry->ObjectInformation->ParentObjectInformation->Specific.Directory.DirectoryNodeHdr.TreeLock);
-
- pTargetDirEntry->FileIndex = (ULONG)InterlockedIncrement( &pTargetDirEntry->ObjectInformation->ParentObjectInformation->Specific.Directory.DirectoryNodeHdr.ContentIndex);
-
- uniTmpTargetName.Length = 0;
- uniTmpTargetName.MaximumLength = uniTargetName.Length + (4 * sizeof( WCHAR));
-
- uniTmpTargetName.Buffer = (WCHAR *)AFSExAllocatePoolWithTag( PagedPool,
- uniTmpTargetName.MaximumLength,
- AFS_GENERIC_MEMORY_11_TAG);
-
- if( uniTmpTargetName.Buffer == NULL)
- {
-
- //
- // Re-insert the entry
- //
-
- AFSInsertDirectoryNode( pTargetDirEntry->ObjectInformation->ParentObjectInformation,
- pTargetDirEntry,
- TRUE);
-
- AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
- AFS_TRACE_LEVEL_ERROR,
- "AFSSetRenameInfo Failed tmp buffer allocation during rename of %wZ\n",
- &pSrcCcb->DirectoryCB->NameInformation.FileName);
-
- try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
- }
-
- RtlZeroMemory( uniTmpTargetName.Buffer,
- uniTmpTargetName.MaximumLength);
-
- uniTmpTargetName.Length = uniTargetName.Length;
-
- RtlCopyMemory( uniTmpTargetName.Buffer,
- uniTargetName.Buffer,
- uniTmpTargetName.Length);
-
- RtlCopyMemory( &uniTmpTargetName.Buffer[ uniTmpTargetName.Length/sizeof( WCHAR)],
- L".tmp",
- 4 * sizeof( WCHAR));
-
- uniTmpTargetName.Length += (4 * sizeof( WCHAR));
-
- ntStatus = AFSNotifyRename( pTargetDirEntry->ObjectInformation,
- pTargetDirEntry->ObjectInformation->ParentObjectInformation,
- pTargetDcb->ObjectInformation,
- pTargetDirEntry,
- &uniTmpTargetName,
- &stTmpTargetFid);
-
- if( !NT_SUCCESS( ntStatus))
- {
-
- //
- // Re-insert the entry
- //
-
- AFSInsertDirectoryNode( pTargetDirEntry->ObjectInformation->ParentObjectInformation,
- pTargetDirEntry,
- TRUE);
-
- AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
- AFS_TRACE_LEVEL_ERROR,
- "AFSSetRenameInfo Failed rename of %wZ to tmp %wZ Status %08lX\n",
- &pSrcCcb->DirectoryCB->NameInformation.FileName,
- &uniTmpTargetName,
- ntStatus);
-
- try_return( ntStatus);
- }
-
- //
- // Indicate we need to replace this entry if any failure occurs below
- //
-
- bReplaceTmpTargetEntry = TRUE;
- }
-
//
// We need to remove the DirEntry from the parent node, update the index
// and reinsert it into the parent tree. Note that for entries with the
// same parent we do not pull the node from the enumeration list
//
- AFSAcquireExcl( pSrcFcb->ObjectInformation->ParentObjectInformation->Specific.Directory.DirectoryNodeHdr.TreeLock,
- TRUE);
-
AFSRemoveDirNodeFromParent( pSrcFcb->ObjectInformation->ParentObjectInformation,
pSrcCcb->DirectoryCB,
!bCommonParent);
- AFSReleaseResource( pSrcFcb->ObjectInformation->ParentObjectInformation->Specific.Directory.DirectoryNodeHdr.TreeLock);
-
oldFileIndex = pSrcCcb->DirectoryCB->FileIndex;
+
if( !bCommonParent)
{
//
if( pSrcCcb->DirectoryCB->ObjectInformation->ParentObjectInformation == pTargetParentObject &&
- !bReplaceTmpTargetEntry)
+ !bTargetEntryExists)
{
ulNotificationAction = FILE_ACTION_RENAMED_OLD_NAME;
// Remove the old information entry
//
- AFSAcquireExcl( pSrcObject->VolumeCB->ObjectInfoTree.TreeLock,
- TRUE);
-
AFSRemoveHashEntry( &pSrcObject->VolumeCB->ObjectInfoTree.TreeHead,
&pSrcObject->TreeEntry);
AFSInsertHashEntry( pSrcObject->VolumeCB->ObjectInfoTree.TreeHead,
&pSrcObject->TreeEntry);
}
-
- AFSReleaseResource( pSrcObject->VolumeCB->ObjectInfoTree.TreeLock);
}
//
pSrcCcb->DirectoryCB->CaseInsensitiveTreeEntry.HashIndex = AFSGenerateCRC( &pSrcCcb->DirectoryCB->NameInformation.FileName,
TRUE);
- if( pSrcCcb->DirectoryCB->NameInformation.ShortNameLength > 0)
+ if( pSrcCcb->DirectoryCB->NameInformation.ShortNameLength > 0 &&
+ !RtlIsNameLegalDOS8Dot3( &pSrcCcb->DirectoryCB->NameInformation.FileName,
+ NULL,
+ NULL))
{
uniShortName.Length = pSrcCcb->DirectoryCB->NameInformation.ShortNameLength;
+ uniShortName.MaximumLength = uniShortName.Length;
uniShortName.Buffer = pSrcCcb->DirectoryCB->NameInformation.ShortName;
pSrcCcb->DirectoryCB->Type.Data.ShortNameTreeEntry.HashIndex = AFSGenerateCRC( &uniShortName,
// delete the tmp target we created above
//
- if( bReplaceTmpTargetEntry)
+ if( bTargetEntryExists)
{
- RtlCopyMemory( &pTargetDirEntry->ObjectInformation->FileId,
- &stTmpTargetFid,
- sizeof( AFSFileID));
-
- //
- // Update the name in the dir entry
- //
-
- ntStatus = AFSUpdateDirEntryName( pTargetDirEntry,
- &uniTmpTargetName);
-
- if( !NT_SUCCESS( ntStatus))
- {
-
- AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
- AFS_TRACE_LEVEL_ERROR,
- "AFSSetRenameInfo Failed update of target dir entry %wZ to tmp %wZ Status %08lX\n",
- &pTargetDirEntry->NameInformation.FileName,
- &uniTmpTargetName,
- ntStatus);
-
- try_return( ntStatus);
- }
-
- ntStatus = AFSNotifyDelete( pTargetDirEntry,
- FALSE);
-
- if( !NT_SUCCESS( ntStatus))
- {
-
- AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
- AFS_TRACE_LEVEL_VERBOSE,
- "AFSSetRenameInfo object deletion failure dir entry %p name %wZ to tmp %wZ\n",
- pTargetDirEntry,
- &pTargetDirEntry->NameInformation.FileName,
- &uniTmpTargetName);
-
- try_return( ntStatus);
- }
-
AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
AFS_TRACE_LEVEL_VERBOSE,
"AFSSetRenameInfo Setting DELETE flag in dir entry %p name %wZ\n",
TRUE);
//
- // Try and flush the cache map
+ // Close the section in the event it was mapped
//
- if( !MmFlushImageSection( &pTargetFcb->NPFcb->SectionObjectPointers,
- MmFlushForDelete))
+ if( !MmForceSectionClosed( &pTargetFcb->NPFcb->SectionObjectPointers,
+ TRUE))
{
AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
ASSERT( pTargetDirEntry->OpenReferenceCount > 0);
- InterlockedDecrement( &pTargetDirEntry->OpenReferenceCount);
+ InterlockedDecrement( &pTargetDirEntry->OpenReferenceCount); // The count we added above
if( pTargetDirEntry->OpenReferenceCount == 0)
{
- SetFlag( pTargetDirEntry->ObjectInformation->Flags, AFS_OBJECT_FLAGS_DELETED);
-
- ASSERT( BooleanFlagOn( pTargetDirEntry->Flags, AFS_DIR_ENTRY_NOT_IN_PARENT_TREE));
-
- //
- // Free up the name buffer if it was reallocated
- //
-
- if( BooleanFlagOn( pTargetDirEntry->Flags, AFS_DIR_RELEASE_NAME_BUFFER))
- {
-
- AFSExFreePool( pTargetDirEntry->NameInformation.FileName.Buffer);
- }
-
- if( BooleanFlagOn( pTargetDirEntry->Flags, AFS_DIR_RELEASE_TARGET_NAME_BUFFER))
- {
-
- AFSExFreePool( pTargetDirEntry->NameInformation.TargetName.Buffer);
- }
-
- //
- // Dereference the object for this dir entry
- //
-
- ASSERT( pTargetDirEntry->ObjectInformation->ObjectReferenceCount > 0);
-
- InterlockedDecrement( &pTargetDirEntry->ObjectInformation->ObjectReferenceCount);
-
- AFSDbgLogMsg( AFS_SUBSYSTEM_OBJECT_REF_COUNTING,
+ AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
AFS_TRACE_LEVEL_VERBOSE,
- "AFSSetRenameInfo Decrement3 count on object %08lX Cnt %d\n",
- pTargetDirEntry->ObjectInformation,
- pTargetDirEntry->ObjectInformation->ObjectReferenceCount);
-
- //
- // Free up the dir entry
- //
-
- ExDeleteResourceLite( &pTargetDirEntry->NonPaged->Lock);
-
- AFSExFreePool( pTargetDirEntry->NonPaged);
+ "AFSSetRenameInfo Deleting dir entry %p name %wZ\n",
+ pTargetDirEntry,
+ &pTargetDirEntry->NameInformation.FileName);
- AFSExFreePool( pTargetDirEntry);
+ AFSDeleteDirEntry( pTargetParentObject,
+ pTargetDirEntry);
}
pTargetDirEntry = NULL;
if( !NT_SUCCESS( ntStatus))
{
- if( bReplaceTmpTargetEntry)
+ if( bTargetEntryExists)
{
-
- AFSNotifyRename( pTargetDirEntry->ObjectInformation,
- pTargetDirEntry->ObjectInformation->ParentObjectInformation,
- pTargetDcb->ObjectInformation,
- pTargetDirEntry,
- &uniTargetName,
- &stTmpTargetFid);
-
- //
- // Replace the target entry
- //
-
- AFSAcquireExcl( pTargetDirEntry->ObjectInformation->VolumeCB->ObjectInfoTree.TreeLock,
- TRUE);
-
- if( pTargetDirEntry->ObjectInformation->VolumeCB->ObjectInfoTree.TreeHead == NULL)
- {
-
- pTargetDirEntry->ObjectInformation->VolumeCB->ObjectInfoTree.TreeHead = &pTargetDirEntry->ObjectInformation->TreeEntry;
- }
- else
- {
- AFSInsertHashEntry( pTargetDirEntry->ObjectInformation->VolumeCB->ObjectInfoTree.TreeHead,
- &pTargetDirEntry->ObjectInformation->TreeEntry);
- }
-
- AFSReleaseResource( pTargetDirEntry->ObjectInformation->VolumeCB->ObjectInfoTree.TreeLock);
-
- //
- // We always need to update the FileIndex since this entry will be put at the 'end'
- // of the enumeraiton list. If we don't it will cause recursion ...
- //
-
- pTargetDirEntry->FileIndex = (ULONG)InterlockedIncrement( &pTargetDirEntry->ObjectInformation->ParentObjectInformation->Specific.Directory.DirectoryNodeHdr.ContentIndex);
-
AFSInsertDirectoryNode( pTargetDirEntry->ObjectInformation->ParentObjectInformation,
pTargetDirEntry,
- TRUE);
+ FALSE);
}
}
InterlockedDecrement( &pTargetDirEntry->OpenReferenceCount);
}
- if( uniTmpTargetName.Buffer != NULL)
+ if( bReleaseVolumeLock)
{
+ AFSReleaseResource( pTargetParentObject->VolumeCB->VolumeLock);
+ }
- AFSExFreePool( uniTmpTargetName.Buffer);
+ if( bReleaseTargetDirLock)
+ {
+ AFSReleaseResource( pTargetParentObject->Specific.Directory.DirectoryNodeHdr.TreeLock);
+ }
+
+ if( bReleaseSourceDirLock)
+ {
+ AFSReleaseResource( pSrcFcb->ObjectInformation->ParentObjectInformation->Specific.Directory.DirectoryNodeHdr.TreeLock);
}
}
pDirNode->ObjectInformation = pObjectInfoCB;
//
- // Set valid entry
+ // Set valid entry and NOT_IN_PARENT flag
//
- SetFlag( pDirNode->Flags, AFS_DIR_ENTRY_VALID);
+ SetFlag( pDirNode->Flags, AFS_DIR_ENTRY_VALID | AFS_DIR_ENTRY_NOT_IN_PARENT_TREE);
pDirNode->FileIndex = FileIndex;
while( pCurrentDirEntry != NULL)
{
+ pNextDirEntry = (AFSDirectoryCB *)pCurrentDirEntry->ListEntry.fLink;
+
if( !BooleanFlagOn( pCurrentDirEntry->Flags, AFS_DIR_ENTRY_FAKE))
{
- ClearFlag( pCurrentDirEntry->Flags, AFS_DIR_ENTRY_VALID);
+ //
+ // If this entry has been deleted then process it here
+ //
- AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
- AFS_TRACE_LEVEL_VERBOSE,
- "AFSValidateDirectoryCache Clear VALID flag on DE %p Reference count %08lX\n",
- pCurrentDirEntry,
- pCurrentDirEntry->OpenReferenceCount);
+ if( BooleanFlagOn( pCurrentDirEntry->Flags, AFS_DIR_ENTRY_DELETED) &&
+ pCurrentDirEntry->OpenReferenceCount == 0)
+ {
+
+ AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
+ AFS_TRACE_LEVEL_VERBOSE,
+ "AFSValidateDirectoryCache Deleting dir entry %p name %wZ\n",
+ pCurrentDirEntry,
+ &pCurrentDirEntry->NameInformation.FileName);
+
+ AFSDeleteDirEntry( ObjectInfo,
+ pCurrentDirEntry);
+ }
+ else
+ {
+
+ ClearFlag( pCurrentDirEntry->Flags, AFS_DIR_ENTRY_VALID);
+ AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
+ AFS_TRACE_LEVEL_VERBOSE,
+ "AFSValidateDirectoryCache Clear VALID flag on DE %p Reference count %08lX\n",
+ pCurrentDirEntry,
+ pCurrentDirEntry->OpenReferenceCount);
+
+ //
+ // We pull the short name from the parent tree since it could change below
+ //
+
+ if( BooleanFlagOn( pCurrentDirEntry->Flags, AFS_DIR_ENTRY_INSERTED_SHORT_NAME))
+ {
+
+ AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
+ AFS_TRACE_LEVEL_VERBOSE,
+ "AFSValidateDirectoryCache Removing DE %p (%08lX) from shortname tree for %wZ\n",
+ pCurrentDirEntry,
+ pCurrentDirEntry->Type.Data.ShortNameTreeEntry.HashIndex,
+ &pCurrentDirEntry->NameInformation.FileName);
+
+ AFSRemoveShortNameDirEntry( &ObjectInfo->Specific.Directory.ShortNameTree,
+ pCurrentDirEntry);
+
+ ClearFlag( pCurrentDirEntry->Flags, AFS_DIR_ENTRY_INSERTED_SHORT_NAME);
+ }
+ }
}
- pCurrentDirEntry = (AFSDirectoryCB *)pCurrentDirEntry->ListEntry.fLink;
+ pCurrentDirEntry = pNextDirEntry;
}
//
if( BooleanFlagOn( pCurrentDirEntry->Flags, AFS_DIR_ENTRY_VALID))
{
+ if( !BooleanFlagOn( pCurrentDirEntry->Flags, AFS_DIR_ENTRY_INSERTED_SHORT_NAME) &&
+ pCurrentDirEntry->Type.Data.ShortNameTreeEntry.HashIndex > 0)
+ {
+
+ if( ObjectInfo->Specific.Directory.ShortNameTree == NULL)
+ {
+
+ ObjectInfo->Specific.Directory.ShortNameTree = pCurrentDirEntry;
+
+ AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
+ AFS_TRACE_LEVEL_VERBOSE,
+ "AFSValidateDirectoryCache Insert DE %p to head of shortname tree for %wZ\n",
+ pCurrentDirEntry,
+ &pCurrentDirEntry->NameInformation.FileName);
+
+ SetFlag( pCurrentDirEntry->Flags, AFS_DIR_ENTRY_INSERTED_SHORT_NAME);
+ }
+ else
+ {
+
+ if( !NT_SUCCESS( AFSInsertShortNameDirEntry( ObjectInfo->Specific.Directory.ShortNameTree,
+ pCurrentDirEntry)))
+ {
+ AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
+ AFS_TRACE_LEVEL_VERBOSE,
+ "AFSValidateDirectoryCache Failed to insert DE %p (%08lX) to shortname tree for %wZ\n",
+ pCurrentDirEntry,
+ pCurrentDirEntry->Type.Data.ShortNameTreeEntry.HashIndex,
+ &pCurrentDirEntry->NameInformation.FileName);
+ }
+ else
+ {
+ SetFlag( pCurrentDirEntry->Flags, AFS_DIR_ENTRY_INSERTED_SHORT_NAME);
+
+ AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
+ AFS_TRACE_LEVEL_VERBOSE,
+ "AFSValidateDirectoryCache Insert DE %p to shortname tree for %wZ\n",
+ pCurrentDirEntry,
+ &pCurrentDirEntry->NameInformation.FileName);
+ }
+ }
+ }
+
pCurrentDirEntry = pNextDirEntry;
continue;
AFSRemoveCaseInsensitiveDirEntry( &ParentObjectInfo->Specific.Directory.DirectoryNodeHdr.CaseInsensitiveTreeHead,
DirEntry);
- if( ParentObjectInfo->Specific.Directory.ShortNameTree &&
- DirEntry->Type.Data.ShortNameTreeEntry.HashIndex != 0)
+ if( BooleanFlagOn( DirEntry->Flags, AFS_DIR_ENTRY_INSERTED_SHORT_NAME))
{
//
AFSRemoveShortNameDirEntry( &ParentObjectInfo->Specific.Directory.ShortNameTree,
DirEntry);
+
+ ClearFlag( DirEntry->Flags, AFS_DIR_ENTRY_INSERTED_SHORT_NAME);
}
AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
SetFlag( DirEntry->Flags, AFS_DIR_ENTRY_NOT_IN_PARENT_TREE);
+ ClearFlag( DirEntry->Flags, AFS_DIR_ENTRY_CASE_INSENSTIVE_LIST_HEAD);
+
try_exit:
NOTHING;
BOOLEAN bIsValid = TRUE;
ULONG ulCount = 0;
- AFSDirectoryCB *pCurrentDirEntry = NULL;
+ AFSDirectoryCB *pCurrentDirEntry = NULL, *pDirEntry = NULL;
pCurrentDirEntry = ObjectInfo->Specific.Directory.DirectoryNodeListHead;
if( !BooleanFlagOn( pCurrentDirEntry->Flags, AFS_DIR_ENTRY_FAKE))
{
ulCount++;
+
+ if( !BooleanFlagOn( pCurrentDirEntry->Flags, AFS_DIR_ENTRY_NOT_IN_PARENT_TREE))
+ {
+
+ pDirEntry = NULL;
+
+ AFSLocateCaseSensitiveDirEntry( ObjectInfo->Specific.Directory.DirectoryNodeHdr.CaseSensitiveTreeHead,
+ (ULONG)pCurrentDirEntry->CaseSensitiveTreeEntry.HashIndex,
+ &pDirEntry);
+
+ if( pDirEntry == NULL)
+ {
+ DbgBreakPoint();
+ }
+ }
}
pCurrentDirEntry = (AFSDirectoryCB *)pCurrentDirEntry->ListEntry.fLink;
{
NTSTATUS ntStatus = STATUS_SUCCESS;
- AFSDirectoryCB *pDirNode = NULL;
+ AFSDirectoryCB *pDirNode = NULL, *pExistingDirNode = NULL;
UNICODE_STRING uniShortName;
LARGE_INTEGER liFileSize = {0,0};
try_return( ntStatus);
}
+ AFSAcquireExcl( ParentObjectInfo->Specific.Directory.DirectoryNodeHdr.TreeLock,
+ TRUE);
+
+ //
+ // Before attempting to insert the new entry, check if we need to validate the parent
+ //
+
+ if( BooleanFlagOn( ParentObjectInfo->Flags, AFS_OBJECT_FLAGS_VERIFY))
+ {
+
+ AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
+ AFS_TRACE_LEVEL_VERBOSE,
+ "AFSCreateDirEntry Verifying parent %wZ FID %08lX-%08lX-%08lX-%08lX\n",
+ &ParentDirCB->NameInformation.FileName,
+ ParentObjectInfo->FileId.Cell,
+ ParentObjectInfo->FileId.Volume,
+ ParentObjectInfo->FileId.Vnode,
+ ParentObjectInfo->FileId.Unique);
+
+ ntStatus = AFSVerifyEntry( AuthGroup,
+ ParentDirCB);
+
+ if( !NT_SUCCESS( ntStatus))
+ {
+
+ AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
+ AFS_TRACE_LEVEL_ERROR,
+ "AFSCreateDirEntry Failed to verify parent %wZ FID %08lX-%08lX-%08lX-%08lX Status %08lX\n",
+ &ParentDirCB->NameInformation.FileName,
+ ParentObjectInfo->FileId.Cell,
+ ParentObjectInfo->FileId.Volume,
+ ParentObjectInfo->FileId.Vnode,
+ ParentObjectInfo->FileId.Unique,
+ ntStatus);
+
+ AFSReleaseResource( ParentObjectInfo->Specific.Directory.DirectoryNodeHdr.TreeLock);
+
+ try_return( ntStatus);
+ }
+ }
+
+ //
+ // Check for the entry in the event we raced with some other thread
+ //
+
+ AFSLocateCaseSensitiveDirEntry( ParentObjectInfo->Specific.Directory.DirectoryNodeHdr.CaseSensitiveTreeHead,
+ (ULONG)pDirNode->CaseSensitiveTreeEntry.HashIndex,
+ &pExistingDirNode);
+
+ if( pExistingDirNode != NULL)
+ {
+
+ AFSDeleteDirEntry( ParentObjectInfo,
+ pDirNode);
+
+ *DirEntry = pExistingDirNode;
+
+ AFSReleaseResource( ParentObjectInfo->Specific.Directory.DirectoryNodeHdr.TreeLock);
+
+ try_return( ntStatus = STATUS_SUCCESS);
+ }
+
AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
AFS_TRACE_LEVEL_VERBOSE_2,
"AFSCreateDirEntry Inserting dir entry in parent %wZ FID %08lX-%08lX-%08lX-%08lX Component %wZ\n",
*DirEntry = pDirNode;
+ AFSReleaseResource( ParentObjectInfo->Specific.Directory.DirectoryNodeHdr.TreeLock);
+
try_exit:
NOTHING;
__Enter
{
- AFSAcquireExcl( ParentObjectInfo->Specific.Directory.DirectoryNodeHdr.TreeLock,
- TRUE);
+ ASSERT( ExIsResourceAcquiredExclusiveLite( ParentObjectInfo->Specific.Directory.DirectoryNodeHdr.TreeLock));
//
// Insert the node into the directory node tree
"AFSInsertDirectoryNode Insert DE %p to head of shortname tree for %wZ\n",
DirEntry,
&DirEntry->NameInformation.FileName);
+
+ SetFlag( DirEntry->Flags, AFS_DIR_ENTRY_INSERTED_SHORT_NAME);
}
else
{
- AFSInsertShortNameDirEntry( ParentObjectInfo->Specific.Directory.ShortNameTree,
- DirEntry);
+ if( !NT_SUCCESS( AFSInsertShortNameDirEntry( ParentObjectInfo->Specific.Directory.ShortNameTree,
+ DirEntry)))
+ {
+ AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
+ AFS_TRACE_LEVEL_VERBOSE,
+ "AFSInsertDirectoryNode Failed to insert DE %p to shortname tree for %wZ\n",
+ DirEntry,
+ &DirEntry->NameInformation.FileName);
+ }
+ else
+ {
+ SetFlag( DirEntry->Flags, AFS_DIR_ENTRY_INSERTED_SHORT_NAME);
- AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
- AFS_TRACE_LEVEL_VERBOSE,
- "AFSInsertDirectoryNode Insert DE %p to shortname tree for %wZ\n",
- DirEntry,
- &DirEntry->NameInformation.FileName);
+ AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
+ AFS_TRACE_LEVEL_VERBOSE,
+ "AFSInsertDirectoryNode Insert DE %p to shortname tree for %wZ\n",
+ DirEntry,
+ &DirEntry->NameInformation.FileName);
+ }
}
}
ParentObjectInfo->FileId.Vnode,
ParentObjectInfo->FileId.Unique);
}
-
- AFSReleaseResource( ParentObjectInfo->Specific.Directory.DirectoryNodeHdr.TreeLock);
}
return;
ASSERT( DirEntry->ObjectInformation->ObjectReferenceCount > 0);
- InterlockedDecrement( &DirEntry->ObjectInformation->ObjectReferenceCount);
+ if( InterlockedDecrement( &DirEntry->ObjectInformation->ObjectReferenceCount) == 0)
+ {
+ SetFlag( DirEntry->ObjectInformation->Flags, AFS_OBJECT_FLAGS_DELETED);
+ }
AFSDbgLogMsg( AFS_SUBSYSTEM_OBJECT_REF_COUNTING,
AFS_TRACE_LEVEL_VERBOSE,
else
{
- AFSInsertCaseSensitiveDirEntry( pDirHdr->CaseSensitiveTreeHead,
- pDirNode);
+ if( !NT_SUCCESS( AFSInsertCaseSensitiveDirEntry( pDirHdr->CaseSensitiveTreeHead,
+ pDirNode)))
+ {
+
+ AFSDeleteDirEntry( &AFSGlobalRoot->ObjectInformation,
+ pDirNode);
+
+ AFSReleaseResource( AFSGlobalRoot->ObjectInformation.Specific.Directory.DirectoryNodeHdr.TreeLock);
+
+ try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
+ }
}
+ ClearFlag( pDirNode->Flags, AFS_DIR_ENTRY_NOT_IN_PARENT_TREE);
+
if( pDirHdr->CaseInsensitiveTreeHead == NULL)
{
NTSTATUS
AFSSnapshotDirectory( IN AFSFcb *Fcb,
- IN AFSCcb *Ccb);
+ IN AFSCcb *Ccb,
+ IN BOOLEAN ResetIndex);
NTSTATUS
AFSFsRtlNotifyFullChangeDirectory( IN AFSObjectInfoCB *ObjectInfo,
#define AFS_DIR_ENTRY_SERVER_SERVICE 0x00000400
#define AFS_DIR_ENTRY_WORKSTATION_SERVICE 0x00000800
#define AFS_DIR_ENTRY_IPC 0x00001000
+#define AFS_DIR_ENTRY_INSERTED_SHORT_NAME 0x00002000
//
// Network provider errors