__Enter
{
+ ASSERT( ExIsResourceAcquiredExclusiveLite( ObjectInfoCB->Specific.Directory.DirectoryNodeHdr.TreeLock));
+
uniGUID.Length = 0;
uniGUID.MaximumLength = 0;
uniGUID.Buffer = NULL;
{
//
- // Go and retrieve the directory contents
+ // If the enumeration handle is -1 then we are done
//
- ntStatus = AFSProcessRequest( AFS_REQUEST_TYPE_DIR_ENUM,
- ulRequestFlags,
- AuthGroup,
- NULL,
- &ObjectInfoCB->FileId,
- (void *)pDirQueryCB,
- sizeof( AFSDirQueryCB),
- pBuffer,
- &ulResultLen);
+ if( ((ULONG)-1) == pDirQueryCB->EnumHandle )
+ {
+
+ ntStatus = STATUS_NO_MORE_ENTRIES;
+ }
+ else
+ {
+
+ //
+ // Go and retrieve the directory contents
+ //
+
+ ntStatus = AFSProcessRequest( AFS_REQUEST_TYPE_DIR_ENUM,
+ ulRequestFlags,
+ AuthGroup,
+ NULL,
+ &ObjectInfoCB->FileId,
+ (void *)pDirQueryCB,
+ sizeof( AFSDirQueryCB),
+ pBuffer,
+ &ulResultLen);
+ }
if( ntStatus != STATUS_SUCCESS ||
ulResultLen == 0)
{
ntStatus = STATUS_SUCCESS;
+
+ pDirEnumResponse = (AFSDirEnumResp *)pBuffer;
+
+ AFSAcquireExcl( ObjectInfoCB->Specific.Directory.DirectoryNodeHdr.TreeLock,
+ TRUE);
+
+ AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
+ AFS_TRACE_LEVEL_VERBOSE,
+ "AFSEnumerateDirectory Directory Complete FID %08lX-%08lX-%08lX-%08lX Snapshot-DV %08lX:%08lX Current-DV %08lX:%08lX Status %08lX\n",
+ ObjectInfoCB->FileId.Cell,
+ ObjectInfoCB->FileId.Volume,
+ ObjectInfoCB->FileId.Vnode,
+ ObjectInfoCB->FileId.Unique,
+ pDirEnumResponse->SnapshotDataVersion.HighPart,
+ pDirEnumResponse->SnapshotDataVersion.LowPart,
+ pDirEnumResponse->CurrentDataVersion.HighPart,
+ pDirEnumResponse->CurrentDataVersion.LowPart,
+ ntStatus);
+
+ ObjectInfoCB->DataVersion = pDirEnumResponse->SnapshotDataVersion;
+
+ if ( pDirEnumResponse->SnapshotDataVersion.QuadPart != pDirEnumResponse->CurrentDataVersion.QuadPart )
+ {
+
+ SetFlag( ObjectInfoCB->Flags, AFS_OBJECT_FLAGS_VERIFY);
+
+ ObjectInfoCB->DataVersion.QuadPart = (ULONGLONG)-1;
+
+ AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
+ AFS_TRACE_LEVEL_VERBOSE,
+ "AFSEnumerateDirectory Force Verify due to DV change during enumeration FID %08lX-%08lX-%08lX-%08lX\n",
+ ObjectInfoCB->FileId.Cell,
+ ObjectInfoCB->FileId.Volume,
+ ObjectInfoCB->FileId.Vnode,
+ ObjectInfoCB->FileId.Unique);
+ }
+
+ AFSReleaseResource( ObjectInfoCB->Specific.Directory.DirectoryNodeHdr.TreeLock);
}
else
{
AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
- AFS_TRACE_LEVEL_ERROR,
- "AFSEnumerateDirectory Failed to enumerate directory Status %08lX\n",
+ AFS_TRACE_LEVEL_VERBOSE,
+ "AFSEnumerateDirectory Failed to enumerate directory FID %08lX-%08lX-%08lX-%08lX AuthGroup %wZ Status %08lX\n",
+ ObjectInfoCB->FileId.Cell,
+ ObjectInfoCB->FileId.Volume,
+ ObjectInfoCB->FileId.Vnode,
+ ObjectInfoCB->FileId.Unique,
+ &uniGUID,
ntStatus);
}
pCurrentDirEntry = (AFSDirEnumEntry *)pDirEnumResponse->Entry;
+ AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
+ AFS_TRACE_LEVEL_VERBOSE,
+ "AFSEnumerateDirectory Enumerating FID %08lX-%08lX-%08lX-%08lX Snapshot-DV %08lX:%08lX Current-DV %08lX:%08lX\n",
+ ObjectInfoCB->FileId.Cell,
+ ObjectInfoCB->FileId.Volume,
+ ObjectInfoCB->FileId.Vnode,
+ ObjectInfoCB->FileId.Unique,
+ pDirEnumResponse->SnapshotDataVersion.HighPart,
+ pDirEnumResponse->SnapshotDataVersion.LowPart,
+ pDirEnumResponse->CurrentDataVersion.HighPart,
+ pDirEnumResponse->CurrentDataVersion.LowPart);
+
//
// Remove the leading header from the processed length
//
{
//
- // Duplicate entry, skip it
+ // Check that the FIDs are the same
//
- ulEntryLength = QuadAlign( sizeof( AFSDirEnumEntry) +
- uniDirName.Length +
- uniTargetName.Length);
+ if( AFSIsEqualFID( &pCurrentDirEntry->FileId,
+ &pDirNode->ObjectInformation->FileId))
+ {
- pCurrentDirEntry = (AFSDirEnumEntry *)((char *)pCurrentDirEntry + ulEntryLength);
+ //
+ // Duplicate entry, skip it
+ //
- if( ulResultLen >= ulEntryLength)
- {
- ulResultLen -= ulEntryLength;
+ ulEntryLength = QuadAlign( sizeof( AFSDirEnumEntry) +
+ uniDirName.Length +
+ uniTargetName.Length);
+
+ pCurrentDirEntry = (AFSDirEnumEntry *)((char *)pCurrentDirEntry + ulEntryLength);
+
+ if( ulResultLen >= ulEntryLength)
+ {
+ ulResultLen -= ulEntryLength;
+ }
+ else
+ {
+ ulResultLen = 0;
+ }
+
+ //
+ // Update the metadata for the entry
+ //
+
+ if( pDirNode->ObjectInformation->DataVersion.QuadPart != pCurrentDirEntry->DataVersion.QuadPart)
+ {
+
+ AFSInvalidateObject( &pDirNode->ObjectInformation,
++ AFS_INVALIDATE_DATA_VERSION);
+ }
+ else
+ {
+
+ AFSUpdateMetaData( pDirNode,
+ pCurrentDirEntry);
+ }
+
+ continue;
}
else
{
- ulResultLen = 0;
- }
- continue;
+ //
+ // Need to tear down this entry and rebuild it below
+ //
+
+ if( pDirNode->OpenReferenceCount == 0)
+ {
+
+ AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
+ AFS_TRACE_LEVEL_VERBOSE,
+ "AFSEnumerateDirectory Different FIDs - Deleting DE %p for %wZ Old FID %08lX-%08lX-%08lX-%08lX New FID %08lX-%08lX-%08lX-%08lX\n",
+ pDirNode,
+ &pDirNode->NameInformation.FileName,
+ pDirNode->ObjectInformation->FileId.Cell,
+ pDirNode->ObjectInformation->FileId.Volume,
+ pDirNode->ObjectInformation->FileId.Vnode,
+ pDirNode->ObjectInformation->FileId.Unique,
+ pCurrentDirEntry->FileId.Cell,
+ pCurrentDirEntry->FileId.Volume,
+ pCurrentDirEntry->FileId.Vnode,
+ pCurrentDirEntry->FileId.Unique);
+
+ AFSDeleteDirEntry( ObjectInfoCB,
+ pDirNode);
+ }
+ else
+ {
+
+ SetFlag( pDirNode->Flags, AFS_DIR_ENTRY_DELETED);
+
+ AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
+ AFS_TRACE_LEVEL_VERBOSE,
+ "AFSEnumerateDirectory Different FIDs - Removing DE %p for %wZ Old FID %08lX-%08lX-%08lX-%08lX New FID %08lX-%08lX-%08lX-%08lX\n",
+ pDirNode,
+ &pDirNode->NameInformation.FileName,
+ pDirNode->ObjectInformation->FileId.Cell,
+ pDirNode->ObjectInformation->FileId.Volume,
+ pDirNode->ObjectInformation->FileId.Vnode,
+ pDirNode->ObjectInformation->FileId.Unique,
+ pCurrentDirEntry->FileId.Cell,
+ pCurrentDirEntry->FileId.Volume,
+ pCurrentDirEntry->FileId.Vnode,
+ pCurrentDirEntry->FileId.Unique);
+
+ AFSRemoveNameEntry( ObjectInfoCB,
+ pDirNode);
+ }
+
+ pDirNode = NULL;
+ }
}
pDirNode = AFSInitDirEntry( ObjectInfoCB,
break;
}
+ AFSUpdateMetaData( pDirNode,
+ pCurrentDirEntry);
+
+ if( pDirNode->ObjectInformation->FileType == AFS_FILE_TYPE_DIRECTORY)
+ {
+
+ AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
+ AFS_TRACE_LEVEL_VERBOSE,
+ "AFSEnumerateDirectory Setting VERIFY on entry %wZ for FID %08lX-%08lX-%08lX-%08lX\n",
+ &uniDirName,
+ pDirNode->ObjectInformation->FileId.Cell,
+ pDirNode->ObjectInformation->FileId.Volume,
+ pDirNode->ObjectInformation->FileId.Vnode,
+ pDirNode->ObjectInformation->FileId.Unique);
+
+ AFSAcquireExcl( pDirNode->ObjectInformation->Specific.Directory.DirectoryNodeHdr.TreeLock,
+ TRUE);
+
+ SetFlag( pDirNode->ObjectInformation->Flags, AFS_OBJECT_FLAGS_VERIFY);
+
+ pDirNode->ObjectInformation->DataVersion.QuadPart = (ULONGLONG)-1;
+
+ AFSReleaseResource( pDirNode->ObjectInformation->Specific.Directory.DirectoryNodeHdr.TreeLock);
+ }
+
//
// Set up the entry length
//
ulEntryLength = QuadAlign( sizeof( AFSDirEnumEntry) +
- pCurrentDirEntry->FileNameLength +
- pCurrentDirEntry->TargetNameLength);
+ pCurrentDirEntry->FileNameLength +
+ pCurrentDirEntry->TargetNameLength);
//
// Init the short name if we have one
//
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,
+ "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)));
+ }
}
//
// Insert the node into the name tree
//
- ASSERT( ExIsResourceAcquiredExclusiveLite( ObjectInfoCB->Specific.Directory.DirectoryNodeHdr.TreeLock));
-
if( ObjectInfoCB->Specific.Directory.DirectoryNodeHdr.CaseSensitiveTreeHead == NULL)
{
ObjectInfoCB->Specific.Directory.DirectoryNodeHdr.CaseSensitiveTreeHead = pDirNode;
+
+ AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
+ AFS_TRACE_LEVEL_VERBOSE,
+ "AFSEnumerateDirectory Insert DE %p to head of case sensitive tree for %wZ\n",
+ pDirNode,
+ &pDirNode->NameInformation.FileName);
}
else
{
- AFSInsertCaseSensitiveDirEntry( ObjectInfoCB->Specific.Directory.DirectoryNodeHdr.CaseSensitiveTreeHead,
- pDirNode);
+ AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
+ AFS_TRACE_LEVEL_VERBOSE,
+ "AFSEnumerateDirectory Insert DE %p to case sensitive tree for %wZ\n",
+ pDirNode,
+ &pDirNode->NameInformation.FileName);
+
+ 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)
{
+ AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
+ AFS_TRACE_LEVEL_VERBOSE,
+ "AFSEnumerateDirectory Insert DE %p to head of case insensitive tree for %wZ\n",
+ pDirNode,
+ &pDirNode->NameInformation.FileName);
+
ObjectInfoCB->Specific.Directory.DirectoryNodeHdr.CaseInsensitiveTreeHead = pDirNode;
SetFlag( pDirNode->Flags, AFS_DIR_ENTRY_CASE_INSENSTIVE_LIST_HEAD);
else
{
+ AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
+ AFS_TRACE_LEVEL_VERBOSE,
+ "AFSEnumerateDirectory Insert DE %p to case insensitive tree for %wZ\n",
+ pDirNode,
+ &pDirNode->NameInformation.FileName);
+
AFSInsertCaseInsensitiveDirEntry( ObjectInfoCB->Specific.Directory.DirectoryNodeHdr.CaseInsensitiveTreeHead,
pDirNode);
}
if( ObjectInfoCB->Specific.Directory.ShortNameTree == NULL)
{
+ AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
+ AFS_TRACE_LEVEL_VERBOSE,
+ "AFSEnumerateDirectory Insert DE %p to head of shortname tree for %wZ\n",
+ pDirNode,
+ &pDirNode->NameInformation.FileName);
+
ObjectInfoCB->Specific.Directory.ShortNameTree = pDirNode;
+
+ 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)))
+ {
+ SetFlag( pDirNode->Flags, AFS_DIR_ENTRY_INSERTED_SHORT_NAME);
+
+ AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
+ AFS_TRACE_LEVEL_VERBOSE,
+ "AFSEnumerateDirectory Insert DE %p to shortname tree for %wZ\n",
+ pDirNode,
+ &pDirNode->NameInformation.FileName);
+ }
}
}
AFS_TRACE_LEVEL_VERBOSE,
"AFSEnumerateDirectory EnumHandle %08lX\n",
pDirQueryCB->EnumHandle);
-
- //
- // If the enumeration handle is -1 then we are done
- //
-
- if( ((ULONG)-1) == pDirQueryCB->EnumHandle )
- {
-
- break;
- }
}
try_exit:
__Enter
{
+ ASSERT( ExIsResourceAcquiredExclusiveLite( ObjectInfoCB->Specific.Directory.DirectoryNodeHdr.TreeLock));
+
uniGUID.Length = 0;
uniGUID.MaximumLength = 0;
uniGUID.Buffer = NULL;
{
//
- // Go and retrieve the directory contents
+ // If the enumeration handle is -1 then we are done
//
- ntStatus = AFSProcessRequest( AFS_REQUEST_TYPE_DIR_ENUM,
- ulRequestFlags,
- AuthGroup,
- NULL,
- &ObjectInfoCB->FileId,
- (void *)pDirQueryCB,
- sizeof( AFSDirQueryCB),
- pBuffer,
- &ulResultLen);
+ if( ((ULONG)-1) == pDirQueryCB->EnumHandle )
+ {
+
+ ntStatus = STATUS_NO_MORE_ENTRIES;
+ }
+ else
+ {
+
+ //
+ // Go and retrieve the directory contents
+ //
+
+ ntStatus = AFSProcessRequest( AFS_REQUEST_TYPE_DIR_ENUM,
+ ulRequestFlags,
+ AuthGroup,
+ NULL,
+ &ObjectInfoCB->FileId,
+ (void *)pDirQueryCB,
+ sizeof( AFSDirQueryCB),
+ pBuffer,
+ &ulResultLen);
+ }
if( ntStatus != STATUS_SUCCESS ||
ulResultLen == 0)
ntStatus == STATUS_NO_MORE_ENTRIES)
{
+ pDirEnumResponse = (AFSDirEnumResp *)pBuffer;
+
+ AFSAcquireExcl( ObjectInfoCB->Specific.Directory.DirectoryNodeHdr.TreeLock,
+ TRUE);
+
+ AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
+ AFS_TRACE_LEVEL_VERBOSE,
+ "AFSVerifyDirectoryContent Directory Complete FID %08lX-%08lX-%08lX-%08lX Snapshot-DV %08lX:%08lX Current-DV %08lX:%08lX Status %08lX\n",
+ ObjectInfoCB->FileId.Cell,
+ ObjectInfoCB->FileId.Volume,
+ ObjectInfoCB->FileId.Vnode,
+ ObjectInfoCB->FileId.Unique,
+ pDirEnumResponse->SnapshotDataVersion.HighPart,
+ pDirEnumResponse->SnapshotDataVersion.LowPart,
+ pDirEnumResponse->CurrentDataVersion.HighPart,
+ pDirEnumResponse->CurrentDataVersion.LowPart,
+ ntStatus);
+
ntStatus = STATUS_SUCCESS;
+
+ if ( pDirEnumResponse->SnapshotDataVersion.QuadPart != pDirEnumResponse->CurrentDataVersion.QuadPart )
+ {
+
+ SetFlag( ObjectInfoCB->Flags, AFS_OBJECT_FLAGS_VERIFY);
+
+ ObjectInfoCB->DataVersion.QuadPart = (ULONGLONG)-1;
+
+ AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
+ AFS_TRACE_LEVEL_VERBOSE,
+ "AFSVerifyDirectoryContent Force Verify due to DV change during enumeration FID %08lX-%08lX-%08lX-%08lX\n",
+ ObjectInfoCB->FileId.Cell,
+ ObjectInfoCB->FileId.Volume,
+ ObjectInfoCB->FileId.Vnode,
+ ObjectInfoCB->FileId.Unique);
+ }
+ else
+ {
+
+ ObjectInfoCB->DataVersion = pDirEnumResponse->SnapshotDataVersion;
+ }
+
+ AFSReleaseResource( ObjectInfoCB->Specific.Directory.DirectoryNodeHdr.TreeLock);
}
else
{
AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
AFS_TRACE_LEVEL_ERROR,
- "AFSVerifyDirectoryContent Failed to enumerate directory Status %08lX\n",
+ "AFSVerifyDirectoryContent Failed to enumerate directory FID %08lX-%08lX-%08lX-%08lX AuthGroup %wZ Status %08lX\n",
+ ObjectInfoCB->FileId.Cell,
+ ObjectInfoCB->FileId.Volume,
+ ObjectInfoCB->FileId.Vnode,
+ ObjectInfoCB->FileId.Unique,
+ &uniGUID,
ntStatus);
}
pCurrentDirEntry = (AFSDirEnumEntry *)pDirEnumResponse->Entry;
+ AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
+ AFS_TRACE_LEVEL_VERBOSE,
+ "AFSVerifyDirectoryContent EnumResponse FID %08lX-%08lX-%08lX-%08lX Snapshot-DV %08lX:%08lX Current-DV %08lX:%08lX\n",
+ ObjectInfoCB->FileId.Cell,
+ ObjectInfoCB->FileId.Volume,
+ ObjectInfoCB->FileId.Vnode,
+ ObjectInfoCB->FileId.Unique,
+ pDirEnumResponse->SnapshotDataVersion.HighPart,
+ pDirEnumResponse->SnapshotDataVersion.LowPart,
+ pDirEnumResponse->CurrentDataVersion.HighPart,
+ pDirEnumResponse->CurrentDataVersion.LowPart);
+
//
// Remove the leading header from the processed length
//
ulCRC = AFSGenerateCRC( &uniDirName,
FALSE);
- ASSERT( ExIsResourceAcquiredExclusiveLite( ObjectInfoCB->Specific.Directory.DirectoryNodeHdr.TreeLock));
-
AFSLocateCaseSensitiveDirEntry( ObjectInfoCB->Specific.Directory.DirectoryNodeHdr.CaseSensitiveTreeHead,
ulCRC,
&pDirNode);
pCurrentDirEntry->FileNameLength +
pCurrentDirEntry->TargetNameLength);
- if( pDirNode != NULL)
+ if( pDirNode &&
+ AFSIsEqualFID( &pCurrentDirEntry->FileId,
+ &pDirNode->ObjectInformation->FileId))
{
//
- // Check that the FIDs are the same
+ // Found matching directory entry by name and FileID
//
- if( AFSIsEqualFID( &pCurrentDirEntry->FileId,
- &pDirNode->ObjectInformation->FileId))
- {
+ AFSAcquireShared( ObjectInfoCB->VolumeCB->ObjectInfoTree.TreeLock,
+ TRUE);
- AFSAcquireShared( ObjectInfoCB->VolumeCB->ObjectInfoTree.TreeLock,
- TRUE);
+ ullIndex = AFSCreateLowIndex( &pCurrentDirEntry->FileId);
- ullIndex = AFSCreateLowIndex( &pCurrentDirEntry->FileId);
+ ntStatus = AFSLocateHashEntry( ObjectInfoCB->VolumeCB->ObjectInfoTree.TreeHead,
+ ullIndex,
+ (AFSBTreeEntry **)&pObjectInfo);
- ntStatus = AFSLocateHashEntry( ObjectInfoCB->VolumeCB->ObjectInfoTree.TreeHead,
- ullIndex,
- (AFSBTreeEntry **)&pObjectInfo);
+ AFSReleaseResource( ObjectInfoCB->VolumeCB->ObjectInfoTree.TreeLock);
- AFSReleaseResource( ObjectInfoCB->VolumeCB->ObjectInfoTree.TreeLock);
+ if( NT_SUCCESS( ntStatus) &&
+ pObjectInfo != NULL)
+ {
- if( NT_SUCCESS( ntStatus) &&
- pObjectInfo != NULL)
- {
+ //
+ // Indicate this is a valid entry
+ //
- //
- // Indicate this is a valid entry
- //
+ SetFlag( pDirNode->Flags, AFS_DIR_ENTRY_VALID);
- SetFlag( pDirNode->Flags, AFS_DIR_ENTRY_VALID);
+ if( pCurrentDirEntry->ShortNameLength > 0 &&
+ pDirNode->NameInformation.ShortNameLength > 0)
+ {
+ AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
+ AFS_TRACE_LEVEL_VERBOSE,
+ "AFSVerifyDirectoryContent Verified entry %wZ (%wZ) parent FID %08lX-%08lX-%08lX-%08lX old short name %S New short name %S\n",
+ &uniDirName,
+ &pDirNode->NameInformation.FileName,
+ ObjectInfoCB->FileId.Cell,
+ ObjectInfoCB->FileId.Volume,
+ ObjectInfoCB->FileId.Vnode,
+ ObjectInfoCB->FileId.Unique,
+ pDirNode->NameInformation.ShortName,
+ pCurrentDirEntry->ShortName);
+ }
+ else if( pCurrentDirEntry->ShortNameLength == 0 &&
+ pDirNode->NameInformation.ShortNameLength > 0)
+ {
AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
AFS_TRACE_LEVEL_VERBOSE,
- "AFSVerifyDirectoryContent Verified entry %wZ for parent FID %08lX-%08lX-%08lX-%08lX\n",
+ "AFSVerifyDirectoryContent Verified entry %wZ (%wZ) parent FID %08lX-%08lX-%08lX-%08lX old short name %S New short name NULL\n",
+ &uniDirName,
+ &pDirNode->NameInformation.FileName,
+ ObjectInfoCB->FileId.Cell,
+ ObjectInfoCB->FileId.Volume,
+ ObjectInfoCB->FileId.Vnode,
+ ObjectInfoCB->FileId.Unique,
+ pDirNode->NameInformation.ShortName);
+ }
+ else if( pCurrentDirEntry->ShortNameLength > 0 &&
+ pDirNode->NameInformation.ShortNameLength == 0)
+ {
+ AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
+ AFS_TRACE_LEVEL_VERBOSE,
+ "AFSVerifyDirectoryContent Verified entry %wZ (%wZ) parent FID %08lX-%08lX-%08lX-%08lX old short name NULL New short name %S\n",
&uniDirName,
+ &pDirNode->NameInformation.FileName,
+ ObjectInfoCB->FileId.Cell,
+ ObjectInfoCB->FileId.Volume,
+ ObjectInfoCB->FileId.Vnode,
+ ObjectInfoCB->FileId.Unique,
+ pCurrentDirEntry->ShortName);
+ }
+ else
+ {
+ AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
+ AFS_TRACE_LEVEL_VERBOSE,
+ "AFSVerifyDirectoryContent Verified entry %wZ (%wZ) parent FID %08lX-%08lX-%08lX-%08lX old short name NULL New short name NULL\n",
+ &uniDirName,
+ &pDirNode->NameInformation.FileName,
ObjectInfoCB->FileId.Cell,
ObjectInfoCB->FileId.Volume,
ObjectInfoCB->FileId.Vnode,
ObjectInfoCB->FileId.Unique);
+ }
+ //
+ // Update the metadata for the entry
+ //
- //
- // Update the metadata for the entry
- //
-
- if( pObjectInfo->DataVersion.QuadPart == 0 ||
- pObjectInfo->DataVersion.QuadPart != pCurrentDirEntry->DataVersion.QuadPart)
- {
-
- AFSUpdateMetaData( pDirNode,
- pCurrentDirEntry);
-
- if( pObjectInfo->FileType == AFS_FILE_TYPE_DIRECTORY)
- {
-
- AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
- AFS_TRACE_LEVEL_VERBOSE,
- "AFSVerifyDirectoryContent Setting VERIFY on entry %wZ for FID %08lX-%08lX-%08lX-%08lX\n",
- &uniDirName,
- ObjectInfoCB->FileId.Cell,
- ObjectInfoCB->FileId.Volume,
- ObjectInfoCB->FileId.Vnode,
- ObjectInfoCB->FileId.Unique);
+ if( pObjectInfo->DataVersion.QuadPart != pCurrentDirEntry->DataVersion.QuadPart)
+ {
- SetFlag( pObjectInfo->Flags, AFS_OBJECT_FLAGS_VERIFY);
- pObjectInfo->DataVersion.QuadPart = (ULONGLONG)-1;
- pObjectInfo->Expiration.QuadPart = 0;
- }
- }
+ AFSInvalidateObject( &pObjectInfo,
+ AFS_INVALIDATE_DATA_VERSION);
+ }
+ else
+ {
- //
- // Next dir entry
- //
+ AFSUpdateMetaData( pDirNode,
+ pCurrentDirEntry);
+ }
- pCurrentDirEntry = (AFSDirEnumEntry *)((char *)pCurrentDirEntry + ulEntryLength);
+ //
+ // Next dir entry
+ //
- if( ulResultLen >= ulEntryLength)
- {
- ulResultLen -= ulEntryLength;
- }
- else
- {
- ulResultLen = 0;
- }
+ pCurrentDirEntry = (AFSDirEnumEntry *)((char *)pCurrentDirEntry + ulEntryLength);
- continue;
+ if( ulResultLen >= ulEntryLength)
+ {
+ ulResultLen -= ulEntryLength;
+ }
+ else
+ {
+ ulResultLen = 0;
}
+
+ continue;
}
+ }
+ else if ( pDirNode)
+ {
+
+ //
+ // File name matches but FileID does not.
+ //
AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
AFS_TRACE_LEVEL_VERBOSE,
- "AFSVerifyDirectoryContent Processing dir entry %wZ with different FID, same name in parent FID %08lX-%08lX-%08lX-%08lX\n",
+ "AFSVerifyDirectoryContent Processing dir entry %p %wZ with different FID, same name in parent FID %08lX-%08lX-%08lX-%08lX\n",
+ pDirNode,
&pDirNode->NameInformation.FileName,
ObjectInfoCB->FileId.Cell,
ObjectInfoCB->FileId.Volume,
AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
AFS_TRACE_LEVEL_VERBOSE,
- "AFSVerifyDirectoryContent Deleting dir entry %wZ from parent FID %08lX-%08lX-%08lX-%08lX\n",
+ "AFSVerifyDirectoryContent Different FIDs - Deleting DE %p for %wZ Old FID %08lX-%08lX-%08lX-%08lX New FID %08lX-%08lX-%08lX-%08lX\n",
+ pDirNode,
&pDirNode->NameInformation.FileName,
- ObjectInfoCB->FileId.Cell,
- ObjectInfoCB->FileId.Volume,
- ObjectInfoCB->FileId.Vnode,
- ObjectInfoCB->FileId.Unique);
+ pDirNode->ObjectInformation->FileId.Cell,
+ pDirNode->ObjectInformation->FileId.Volume,
+ pDirNode->ObjectInformation->FileId.Vnode,
+ pDirNode->ObjectInformation->FileId.Unique,
+ pCurrentDirEntry->FileId.Cell,
+ pCurrentDirEntry->FileId.Volume,
+ pCurrentDirEntry->FileId.Vnode,
+ pCurrentDirEntry->FileId.Unique);
AFSDeleteDirEntry( ObjectInfoCB,
pDirNode);
else
{
+ SetFlag( pDirNode->Flags, AFS_DIR_ENTRY_DELETED);
+
AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
- AFS_TRACE_LEVEL_VERBOSE,
- "AFSVerifyDirectoryContent Setting dir entry %p name %wZ DELETED in parent FID %08lX-%08lX-%08lX-%08lX\n",
+ AFS_TRACE_LEVEL_WARNING,
+ "AFSVerifyDirectoryContent Different FIDs - removing DE %p for %wZ Old FID %08lX-%08lX-%08lX-%08lX New FID %08lX-%08lX-%08lX-%08lX\n",
pDirNode,
&pDirNode->NameInformation.FileName,
- ObjectInfoCB->FileId.Cell,
- ObjectInfoCB->FileId.Volume,
- ObjectInfoCB->FileId.Vnode,
- ObjectInfoCB->FileId.Unique);
-
- SetFlag( pDirNode->Flags, AFS_DIR_ENTRY_DELETED);
+ pDirNode->ObjectInformation->FileId.Cell,
+ pDirNode->ObjectInformation->FileId.Volume,
+ pDirNode->ObjectInformation->FileId.Vnode,
+ pDirNode->ObjectInformation->FileId.Unique,
+ pCurrentDirEntry->FileId.Cell,
+ pCurrentDirEntry->FileId.Volume,
+ pCurrentDirEntry->FileId.Vnode,
+ pCurrentDirEntry->FileId.Unique);
AFSRemoveNameEntry( ObjectInfoCB,
pDirNode);
}
}
+ else
+ {
+
+ AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
+ AFS_TRACE_LEVEL_VERBOSE,
+ "AFSVerifyDirectoryContent New entry %wZ for parent FID %08lX-%08lX-%08lX-%08lX\n",
+ &uniDirName,
+ ObjectInfoCB->FileId.Cell,
+ ObjectInfoCB->FileId.Volume,
+ ObjectInfoCB->FileId.Vnode,
+ ObjectInfoCB->FileId.Unique);
+ }
pDirNode = AFSInitDirEntry( ObjectInfoCB,
&uniDirName,
break;
}
+ AFSUpdateMetaData( pDirNode,
+ pCurrentDirEntry);
+
+ if( pDirNode->ObjectInformation->FileType == AFS_FILE_TYPE_DIRECTORY)
+ {
+
+ AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
+ AFS_TRACE_LEVEL_VERBOSE,
+ "AFSVerifyDirectoryContent Setting VERIFY on entry %wZ for FID %08lX-%08lX-%08lX-%08lX\n",
+ &uniDirName,
+ pDirNode->ObjectInformation->FileId.Cell,
+ pDirNode->ObjectInformation->FileId.Volume,
+ pDirNode->ObjectInformation->FileId.Vnode,
+ pDirNode->ObjectInformation->FileId.Unique);
+
+ AFSAcquireExcl( pDirNode->ObjectInformation->Specific.Directory.DirectoryNodeHdr.TreeLock,
+ TRUE);
+
+ SetFlag( pDirNode->ObjectInformation->Flags, AFS_OBJECT_FLAGS_VERIFY);
+
+ pDirNode->ObjectInformation->DataVersion.QuadPart = (ULONGLONG)-1;
+
+ AFSReleaseResource( pDirNode->ObjectInformation->Specific.Directory.DirectoryNodeHdr.TreeLock);
+ }
+
//
// Init the short name if we have one
//
//
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,
+ "AFSVerifyDirectoryContent NO short name for DE %p for %wZ FID %08lX-%08lX-%08lX-%08lX\n",
+ pDirNode,
+ &pDirNode->NameInformation.FileName,
+ pCurrentDirEntry->FileId.Cell,
+ pCurrentDirEntry->FileId.Volume,
+ pCurrentDirEntry->FileId.Vnode,
+ pCurrentDirEntry->FileId.Unique);
}
//
{
ObjectInfoCB->Specific.Directory.DirectoryNodeHdr.CaseSensitiveTreeHead = pDirNode;
+
+ AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
+ AFS_TRACE_LEVEL_VERBOSE,
+ "AFSVerifyDirectoryContent Insert DE %p to head of case sensitive tree for %wZ\n",
+ pDirNode,
+ &pDirNode->NameInformation.FileName);
}
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 insert DE %p to case sensitive tree for %wZ\n",
+ pDirNode,
+ &pDirNode->NameInformation.FileName);
+
+ //
+ // Delete this dir entry and continue on
+ //
+
+ 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)
{
ObjectInfoCB->Specific.Directory.DirectoryNodeHdr.CaseInsensitiveTreeHead = pDirNode;
SetFlag( pDirNode->Flags, AFS_DIR_ENTRY_CASE_INSENSTIVE_LIST_HEAD);
+
+ AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
+ AFS_TRACE_LEVEL_VERBOSE,
+ "AFSVerifyDirectoryContent Insert DE %p to head of case insensitive tree for %wZ\n",
+ pDirNode,
+ &pDirNode->NameInformation.FileName);
}
else
{
AFSInsertCaseInsensitiveDirEntry( ObjectInfoCB->Specific.Directory.DirectoryNodeHdr.CaseInsensitiveTreeHead,
pDirNode);
+
+ AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
+ AFS_TRACE_LEVEL_VERBOSE,
+ "AFSVerifyDirectoryContent Insert DE %p to case insensitive tree for %wZ\n",
+ pDirNode,
+ &pDirNode->NameInformation.FileName);
}
if( ObjectInfoCB->Specific.Directory.DirectoryNodeListHead == NULL)
{
ObjectInfoCB->Specific.Directory.ShortNameTree = pDirNode;
+
+ AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
+ AFS_TRACE_LEVEL_VERBOSE,
+ "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);
+ }
}
}
+ SetFlag( pDirNode->Flags, AFS_DIR_ENTRY_VALID);
+
//
// Next dir entry
//
//
pDirQueryCB->EnumHandle = pDirEnumResponse->EnumHandle;
-
- //
- // If the enumeration handle is -1 then we are done
- //
-
- if( ((ULONG)-1) == pDirQueryCB->EnumHandle )
- {
-
- break;
- }
}
try_exit:
// The check is to ensure the DV has been modified
//
- if( liOldDataVersion.QuadPart != pResultCB->ParentDataVersion.QuadPart - 1 ||
- liOldDataVersion.QuadPart != ParentObjectInfo->DataVersion.QuadPart)
+ AFSAcquireExcl( ParentObjectInfo->Specific.Directory.DirectoryNodeHdr.TreeLock,
+ TRUE);
+
+ if( ParentObjectInfo->DataVersion.QuadPart != pResultCB->ParentDataVersion.QuadPart - 1)
{
AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
- AFS_TRACE_LEVEL_VERBOSE,
- "AFSNotifyFileCreate Raced with an invalidate call and a re-enumeration for entry %wZ\n",
- FileName);
+ AFS_TRACE_LEVEL_WARNING,
+ "AFSNotifyFileCreate Raced with an invalidate call and a re-enumeration for entry %wZ ParentFID %08lX-%08lX-%08lX-%08lX Version (%08lX:%08lX != %08lX:%08lX - 1)\n",
+ FileName,
+ ParentObjectInfo->FileId.Cell,
+ ParentObjectInfo->FileId.Volume,
+ ParentObjectInfo->FileId.Vnode,
+ ParentObjectInfo->FileId.Unique,
+ ParentObjectInfo->DataVersion.QuadPart,
+ pResultCB->ParentDataVersion.QuadPart);
//
// We raced so go and lookup the directory entry in the parent
ulCRC = AFSGenerateCRC( FileName,
FALSE);
- AFSAcquireShared( ParentObjectInfo->Specific.Directory.DirectoryNodeHdr.TreeLock,
- TRUE);
-
AFSLocateCaseSensitiveDirEntry( ParentObjectInfo->Specific.Directory.DirectoryNodeHdr.CaseSensitiveTreeHead,
ulCRC,
&pDirNode);
- AFSReleaseResource( ParentObjectInfo->Specific.Directory.DirectoryNodeHdr.TreeLock);
-
if( pDirNode != NULL)
{
AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
AFS_TRACE_LEVEL_VERBOSE,
- "AFSNotifyFileCreate Located dir entry for file %wZ\n",
+ "AFSNotifyFileCreate Located dir entry %p for file %wZ\n",
+ pDirNode,
FileName);
- *DirNode = pDirNode;
+ if ( AFSIsEqualFID( &pDirNode->ObjectInformation->FileId,
+ &pResultCB->DirEnum.FileId))
+ {
+
+ InterlockedIncrement( &pDirNode->OpenReferenceCount);
+
+ AFSDbgLogMsg( AFS_SUBSYSTEM_DIRENTRY_REF_COUNTING,
+ AFS_TRACE_LEVEL_VERBOSE,
+ "AFSNotifyFileCreate Increment count on %wZ DE %p Cnt %d\n",
+ &pDirNode->NameInformation.FileName,
+ pDirNode,
+ pDirNode->OpenReferenceCount);
+
+ *DirNode = pDirNode;
+
+ AFSReleaseResource( ParentObjectInfo->Specific.Directory.DirectoryNodeHdr.TreeLock);
+
+ try_return( ntStatus = STATUS_REPARSE);
+ }
+ else
+ {
+
+ //
+ // We found an entry that matches the desired name but it is not the
+ // same as the one that was created for us by the file server.
+ //
+
+ AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
+ AFS_TRACE_LEVEL_ERROR,
+ "AFSNotifyFileCreate Found matching name entry %wZ DE %p FID %08lX-%08lX-%08lX-%08lX != FID %08lX-%08lX-%08lX-%08lX\n",
+ FileName,
+ pDirNode,
+ pDirNode->ObjectInformation->FileId.Cell,
+ pDirNode->ObjectInformation->FileId.Volume,
+ pDirNode->ObjectInformation->FileId.Vnode,
+ pDirNode->ObjectInformation->FileId.Unique,
+ pResultCB->DirEnum.FileId.Cell,
+ pResultCB->DirEnum.FileId.Volume,
+ pResultCB->DirEnum.FileId.Vnode,
+ pResultCB->DirEnum.FileId.Unique);
+
+ if( pDirNode->OpenReferenceCount == 0)
+ {
+
+ AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
+ AFS_TRACE_LEVEL_VERBOSE,
+ "AFSNotifyFileCreate Different FIDs - Deleting DE %p for %wZ Old FID %08lX-%08lX-%08lX-%08lX New FID %08lX-%08lX-%08lX-%08lX\n",
+ pDirNode,
+ &pDirNode->NameInformation.FileName,
+ pDirNode->ObjectInformation->FileId.Cell,
+ pDirNode->ObjectInformation->FileId.Volume,
+ pDirNode->ObjectInformation->FileId.Vnode,
+ pDirNode->ObjectInformation->FileId.Unique,
+ pResultCB->DirEnum.FileId.Cell,
+ pResultCB->DirEnum.FileId.Volume,
+ pResultCB->DirEnum.FileId.Vnode,
+ pResultCB->DirEnum.FileId.Unique);
+
+ AFSDeleteDirEntry( ParentObjectInfo,
+ pDirNode);
+ }
+ else
+ {
+
+ SetFlag( pDirNode->Flags, AFS_DIR_ENTRY_DELETED);
+
+ AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
+ AFS_TRACE_LEVEL_VERBOSE,
+ "AFSNotifyFileCreate Different FIDs - Removing DE %p for %wZ Old FID %08lX-%08lX-%08lX-%08lX New FID %08lX-%08lX-%08lX-%08lX\n",
+ pDirNode,
+ &pDirNode->NameInformation.FileName,
+ pDirNode->ObjectInformation->FileId.Cell,
+ pDirNode->ObjectInformation->FileId.Volume,
+ pDirNode->ObjectInformation->FileId.Vnode,
+ pDirNode->ObjectInformation->FileId.Unique,
+ pResultCB->DirEnum.FileId.Cell,
+ pResultCB->DirEnum.FileId.Volume,
+ pResultCB->DirEnum.FileId.Vnode,
+ pResultCB->DirEnum.FileId.Unique);
+
+ AFSRemoveNameEntry( ParentObjectInfo,
+ pDirNode);
+ }
- try_return( ntStatus = STATUS_REPARSE);
+ pDirNode = NULL;
+ }
}
//
ParentObjectInfo->DataVersion.QuadPart = (ULONGLONG)-1;
}
- else
- {
-
- //
- // Update the parent data version
- //
-
- ParentObjectInfo->DataVersion = pResultCB->ParentDataVersion;
- }
AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
AFS_TRACE_LEVEL_VERBOSE,
if( pDirNode == NULL)
{
+ SetFlag( ParentObjectInfo->Flags, AFS_OBJECT_FLAGS_VERIFY);
+
+ ParentObjectInfo->DataVersion.QuadPart = (ULONGLONG)-1;
+
+ AFSReleaseResource( ParentObjectInfo->Specific.Directory.DirectoryNodeHdr.TreeLock);
+
try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
}
pDirNode->Type.Data.ShortNameTreeEntry.HashIndex = AFSGenerateCRC( &uniShortName,
TRUE);
+
+ AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
+ AFS_TRACE_LEVEL_VERBOSE,
+ "AFSNotifyFileCreate Initialized short name %wZ for DE %p for %wZ\n",
+ &uniShortName,
+ pDirNode,
+ &pDirNode->NameInformation.FileName);
+ }
+
+ if ( !BooleanFlagOn( ParentObjectInfo->Flags, AFS_OBJECT_FLAGS_VERIFY))
+ {
+
+ //
+ // Update the parent data version
+ //
+
+ ParentObjectInfo->DataVersion = pResultCB->ParentDataVersion;
+
+ AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
+ AFS_TRACE_LEVEL_VERBOSE,
+ "AFSNotifyFileCreate entry %wZ ParentFID %08lX-%08lX-%08lX-%08lX Version %08lX:%08lX\n",
+ FileName,
+ ParentObjectInfo->FileId.Cell,
+ ParentObjectInfo->FileId.Volume,
+ ParentObjectInfo->FileId.Vnode,
+ ParentObjectInfo->FileId.Unique,
+ ParentObjectInfo->DataVersion.QuadPart);
}
+ AFSReleaseResource( ParentObjectInfo->Specific.Directory.DirectoryNodeHdr.TreeLock);
+
//
// Return the directory node
//
// Update the data version
//
- ObjectInfo->DataVersion = pUpdateResultCB->DirEnum.DataVersion;
+ AFSAcquireExcl( ObjectInfo->Specific.Directory.DirectoryNodeHdr.TreeLock,
+ TRUE);
+
+ if ( !BooleanFlagOn( ObjectInfo->Flags, AFS_OBJECT_FLAGS_VERIFY))
+ {
+
+ ObjectInfo->DataVersion = pUpdateResultCB->DirEnum.DataVersion;
+ }
+
+ AFSReleaseResource( ObjectInfo->Specific.Directory.DirectoryNodeHdr.TreeLock);
try_exit:
NTSTATUS
AFSNotifyDelete( IN AFSDirectoryCB *DirectoryCB,
- IN BOOLEAN CheckOnly)
+ IN GUID *AuthGroup,
+ IN BOOLEAN CheckOnly)
{
NTSTATUS ntStatus = STATUS_SUCCESS;
ULONG ulResultLen = 0;
AFSFileDeleteCB stDelete;
AFSFileDeleteResultCB stDeleteResult;
ULONG ulRequestFlags = AFS_REQUEST_FLAG_SYNCHRONOUS;
- GUID *pAuthGroup = NULL;
__Enter
{
ulRequestFlags |= AFS_REQUEST_FLAG_CHECK_ONLY;
}
- if( DirectoryCB->ObjectInformation->Fcb != NULL)
- {
- pAuthGroup = &DirectoryCB->ObjectInformation->Fcb->AuthGroup;
- }
-
ntStatus = AFSProcessRequest( AFS_REQUEST_TYPE_DELETE_FILE,
ulRequestFlags,
- pAuthGroup,
+ AuthGroup,
&DirectoryCB->NameInformation.FileName,
&DirectoryCB->ObjectInformation->FileId,
&stDelete,
AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
AFS_TRACE_LEVEL_ERROR,
- "AFSNotifyDelete failed FID %08lX-%08lX-%08lX-%08lX Status %08lX\n",
- &DirectoryCB->ObjectInformation->FileId.Cell,
- &DirectoryCB->ObjectInformation->FileId.Volume,
- &DirectoryCB->ObjectInformation->FileId.Vnode,
- &DirectoryCB->ObjectInformation->FileId.Unique,
+ "AFSNotifyDelete failed ParentFID %08lX-%08lX-%08lX-%08lX %wZ FID %08lX-%08lX-%08lX-%08lX Status %08lX\n",
+ stDelete.ParentId.Cell,
+ stDelete.ParentId.Volume,
+ 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,
ntStatus);
try_return( ntStatus);
}
- if( !CheckOnly)
+ AFSAcquireExcl( DirectoryCB->ObjectInformation->Specific.Directory.DirectoryNodeHdr.TreeLock,
+ TRUE);
+
+ if( CheckOnly)
{
//
- // Update the parent data version
+ // Validate the parent data version
//
if( DirectoryCB->ObjectInformation->ParentObjectInformation->DataVersion.QuadPart != stDeleteResult.ParentDataVersion.QuadPart)
DirectoryCB->ObjectInformation->ParentObjectInformation->DataVersion.QuadPart = (ULONGLONG)-1;
}
}
+ else
+ {
+
+ //
+ // Update the parent data version
+ //
+
+ if( DirectoryCB->ObjectInformation->ParentObjectInformation->DataVersion.QuadPart != stDeleteResult.ParentDataVersion.QuadPart - 1)
+ {
+
+ SetFlag( DirectoryCB->ObjectInformation->ParentObjectInformation->Flags, AFS_OBJECT_FLAGS_VERIFY);
+
+ DirectoryCB->ObjectInformation->ParentObjectInformation->DataVersion.QuadPart = (ULONGLONG)-1;
+ }
+ else
+ {
+
+ //
+ // TODO -- The entry must be removed from the directory at which point the
+ // Directory data version number can be updated. Until then we must force
+ // a verification.
+ //
+ // DirectoryCB->ObjectInformation->ParentObjectInformation->DataVersion.QuadPart = stDeleteResult.ParentDataVersion.QuadPart;
+ //
+
+ SetFlag( DirectoryCB->ObjectInformation->ParentObjectInformation->Flags, AFS_OBJECT_FLAGS_VERIFY);
+
+ DirectoryCB->ObjectInformation->ParentObjectInformation->DataVersion.QuadPart = (ULONGLONG)-1;
+ }
+ }
+
+ AFSReleaseResource( DirectoryCB->ObjectInformation->Specific.Directory.DirectoryNodeHdr.TreeLock);
try_exit:
NTSTATUS
AFSNotifyRename( IN AFSObjectInfoCB *ObjectInfo,
+ IN GUID *AuthGroup,
IN AFSObjectInfoCB *ParentObjectInfo,
IN AFSObjectInfoCB *TargetParentObjectInfo,
IN AFSDirectoryCB *DirectoryCB,
AFSFileRenameCB *pRenameCB = NULL;
AFSFileRenameResultCB *pRenameResultCB = NULL;
ULONG ulResultLen = 0;
- GUID *pAuthGroup = NULL;
__Enter
{
TargetName->Buffer,
TargetName->Length);
- if( ObjectInfo->Fcb != NULL)
- {
- pAuthGroup = &ObjectInfo->Fcb->AuthGroup;
- }
-
//
// Use the same buffer for the result control block
//
ntStatus = AFSProcessRequest( AFS_REQUEST_TYPE_RENAME_FILE,
AFS_REQUEST_FLAG_SYNCHRONOUS,
- pAuthGroup,
+ AuthGroup,
&DirectoryCB->NameInformation.FileName,
&ObjectInfo->FileId,
pRenameCB,
// Update the information from the returned data
//
- ParentObjectInfo->DataVersion = pRenameResultCB->SourceParentDataVersion;
+ AFSAcquireExcl( ParentObjectInfo->Specific.Directory.DirectoryNodeHdr.TreeLock,
+ TRUE);
+
+ if ( ParentObjectInfo->DataVersion.QuadPart == pRenameResultCB->SourceParentDataVersion.QuadPart - 1)
+ {
+
+ ParentObjectInfo->DataVersion = pRenameResultCB->SourceParentDataVersion;
+ }
+ else
+ {
+
+ SetFlag( ParentObjectInfo->Flags, AFS_OBJECT_FLAGS_VERIFY);
+
+ ParentObjectInfo->DataVersion.QuadPart = (ULONGLONG)-1;
+ }
+
+ if ( ParentObjectInfo != TargetParentObjectInfo)
+ {
+
+ if ( TargetParentObjectInfo->DataVersion.QuadPart == pRenameResultCB->TargetParentDataVersion.QuadPart - 1)
+ {
+
+ TargetParentObjectInfo->DataVersion = pRenameResultCB->TargetParentDataVersion;
+ }
+ else
+ {
+
+ SetFlag( TargetParentObjectInfo->Flags, AFS_OBJECT_FLAGS_VERIFY);
- TargetParentObjectInfo->DataVersion = pRenameResultCB->TargetParentDataVersion;
+ TargetParentObjectInfo->DataVersion.QuadPart = (ULONGLONG)-1;
+ }
+ }
//
// Move over the short name
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;
}
+ AFSReleaseResource( ParentObjectInfo->Specific.Directory.DirectoryNodeHdr.TreeLock);
+
if( UpdatedFID != NULL)
{
-
*UpdatedFID = pRenameResultCB->DirEnum.FileId;
}
NTSTATUS ntStatus = STATUS_SUCCESS;
AFSEvalTargetCB stTargetID;
ULONG ulResultBufferLength;
+ AFSFileEvalResultCB *pEvalResultCB = NULL;
AFSDirEnumEntry *pDirEnumCB = NULL;
ULONG ulRequestFlags = AFS_REQUEST_FLAG_SYNCHRONOUS;
// Allocate our response buffer
//
- pDirEnumCB = (AFSDirEnumEntry *)AFSExAllocatePoolWithTag( PagedPool,
- PAGE_SIZE,
- AFS_GENERIC_MEMORY_2_TAG);
+ pEvalResultCB = (AFSFileEvalResultCB *)AFSExAllocatePoolWithTag( PagedPool,
+ PAGE_SIZE,
+ AFS_GENERIC_MEMORY_30_TAG);
- if( pDirEnumCB == NULL)
+ if( pEvalResultCB == NULL)
{
try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
&ObjectInfo->FileId,
&stTargetID,
sizeof( AFSEvalTargetCB),
- pDirEnumCB,
+ pEvalResultCB,
&ulResultBufferLength);
if( ntStatus != STATUS_SUCCESS)
// verification
//
- if( ntStatus == STATUS_INVALID_HANDLE)
+ if( ntStatus == STATUS_OBJECT_PATH_INVALID)
{
if( ObjectInfo->ParentObjectInformation != NULL)
{
+ AFSAcquireExcl( ObjectInfo->ParentObjectInformation->Specific.Directory.DirectoryNodeHdr.TreeLock,
+ TRUE);
+
SetFlag( ObjectInfo->ParentObjectInformation->Flags, AFS_OBJECT_FLAGS_VERIFY);
+
+ ObjectInfo->ParentObjectInformation->DataVersion.QuadPart = (ULONGLONG)-1;
+
+ AFSReleaseResource( ObjectInfo->ParentObjectInformation->Specific.Directory.DirectoryNodeHdr.TreeLock);
}
}
}
//
+ // Validate the parent data version
+ //
+
+ if ( ObjectInfo->ParentObjectInformation != NULL)
+ {
+
+ AFSAcquireExcl( ObjectInfo->ParentObjectInformation->Specific.Directory.DirectoryNodeHdr.TreeLock,
+ TRUE);
+
+ if ( ObjectInfo->ParentObjectInformation->DataVersion.QuadPart != pEvalResultCB->ParentDataVersion.QuadPart)
+ {
+
+ SetFlag( ObjectInfo->ParentObjectInformation->Flags, AFS_OBJECT_FLAGS_VERIFY);
+
+ ObjectInfo->ParentObjectInformation->DataVersion.QuadPart = (ULONGLONG)-1;
+ }
+
+ AFSReleaseResource( ObjectInfo->ParentObjectInformation->Specific.Directory.DirectoryNodeHdr.TreeLock);
+ }
+
+ //
// Pass back the dir enum entry
//
if( DirEnumEntry != NULL)
{
+ pDirEnumCB = (AFSDirEnumEntry *)AFSExAllocatePoolWithTag( PagedPool,
+ PAGE_SIZE,
+ AFS_GENERIC_MEMORY_2_TAG);
+
+ if( pDirEnumCB == NULL)
+ {
+
+ try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
+ }
+
+ RtlCopyMemory( pDirEnumCB, &pEvalResultCB->DirEnum,
+ ulResultBufferLength - sizeof( AFSFileEvalResultCB) + sizeof( AFSDirEnumEntry));
+
*DirEnumEntry = pDirEnumCB;
}
- else
+
+try_exit:
+
+ if( pEvalResultCB != NULL)
{
- AFSExFreePool( pDirEnumCB);
+ AFSExFreePool( pEvalResultCB);
}
-try_exit:
-
if( !NT_SUCCESS( ntStatus))
{
NTSTATUS
AFSEvaluateTargetByName( IN GUID *AuthGroup,
- IN AFSFileID *ParentFileId,
+ IN AFSObjectInfoCB *ParentObjectInfo,
IN PUNICODE_STRING SourceName,
OUT AFSDirEnumEntry **DirEnumEntry)
{
NTSTATUS ntStatus = STATUS_SUCCESS;
AFSEvalTargetCB stTargetID;
ULONG ulResultBufferLength;
+ AFSFileEvalResultCB *pEvalResultCB = NULL;
AFSDirEnumEntry *pDirEnumCB = NULL;
__Enter
{
- stTargetID.ParentId = *ParentFileId;
+ stTargetID.ParentId = ParentObjectInfo->FileId;
//
// Allocate our response buffer
//
- pDirEnumCB = (AFSDirEnumEntry *)AFSExAllocatePoolWithTag( PagedPool,
- PAGE_SIZE,
- AFS_GENERIC_MEMORY_3_TAG);
+ pEvalResultCB = (AFSFileEvalResultCB *)AFSExAllocatePoolWithTag( PagedPool,
+ PAGE_SIZE,
+ AFS_GENERIC_MEMORY_31_TAG);
- if( pDirEnumCB == NULL)
+ if( pEvalResultCB == NULL)
{
try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
NULL,
&stTargetID,
sizeof( AFSEvalTargetCB),
- pDirEnumCB,
+ pEvalResultCB,
&ulResultBufferLength);
if( ntStatus != STATUS_SUCCESS)
{
+ if( ntStatus == STATUS_OBJECT_PATH_INVALID)
+ {
+
+ AFSAcquireExcl( ParentObjectInfo->Specific.Directory.DirectoryNodeHdr.TreeLock,
+ TRUE);
+
+ SetFlag( ParentObjectInfo->Flags, AFS_OBJECT_FLAGS_VERIFY);
+
+ ParentObjectInfo->DataVersion.QuadPart = (ULONGLONG)-1;
+
+ AFSReleaseResource( ParentObjectInfo->Specific.Directory.DirectoryNodeHdr.TreeLock);
+ }
+
try_return( ntStatus);
}
//
+ // Validate the parent data version
+ //
+
+ AFSAcquireExcl( ParentObjectInfo->Specific.Directory.DirectoryNodeHdr.TreeLock,
+ TRUE);
+
+ if ( ParentObjectInfo->DataVersion.QuadPart != pEvalResultCB->ParentDataVersion.QuadPart)
+ {
+
+ SetFlag( ParentObjectInfo->Flags, AFS_OBJECT_FLAGS_VERIFY);
+
+ ParentObjectInfo->DataVersion.QuadPart = (ULONGLONG)-1;
+ }
+
+ AFSReleaseResource( ParentObjectInfo->Specific.Directory.DirectoryNodeHdr.TreeLock);
+
+ //
// Pass back the dir enum entry
//
if( DirEnumEntry != NULL)
{
+ pDirEnumCB = (AFSDirEnumEntry *)AFSExAllocatePoolWithTag( PagedPool,
+ PAGE_SIZE,
+ AFS_GENERIC_MEMORY_3_TAG);
+
+ if( pDirEnumCB == NULL)
+ {
+
+ try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
+ }
+
+ RtlCopyMemory( pDirEnumCB, &pEvalResultCB->DirEnum,
+ ulResultBufferLength - sizeof( AFSFileEvalResultCB) + sizeof( AFSDirEnumEntry));
+
*DirEnumEntry = pDirEnumCB;
}
- else
+
+try_exit:
+
+ if( pEvalResultCB != NULL)
{
- AFSExFreePool( pDirEnumCB);
+ AFSExFreePool( pEvalResultCB);
}
-try_exit:
-
if( !NT_SUCCESS( ntStatus))
{
void *pInputSystemBuffer = NULL, *pOutputSystemBuffer = NULL;
ULONG ulBufferLength = OutputLength;
AFSPipeIORequestCB *pIoRequest = NULL;
- GUID *pAuthGroup = NULL;
__Enter
{
try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
}
- if( Ccb->DirectoryCB->ObjectInformation->Fcb != NULL)
- {
- pAuthGroup = &Ccb->DirectoryCB->ObjectInformation->Fcb->AuthGroup;
- }
-
//
// Send the call to the service
//
ntStatus = AFSProcessRequest( AFS_REQUEST_TYPE_PIPE_TRANSCEIVE,
AFS_REQUEST_FLAG_SYNCHRONOUS,
- pAuthGroup,
+ &Ccb->AuthGroup,
&Ccb->DirectoryCB->NameInformation.FileName,
NULL,
pIoRequest,
NTSTATUS ntStatus = STATUS_SUCCESS;
AFSPipeInfoRequestCB *pInfoRequest = NULL;
- GUID *pAuthGroup = NULL;
__Enter
{
DataBuffer,
InputLength);
- if( Ccb->DirectoryCB->ObjectInformation->Fcb != NULL)
- {
- pAuthGroup = &Ccb->DirectoryCB->ObjectInformation->Fcb->AuthGroup;
- }
-
//
// Send the call to the service
//
ntStatus = AFSProcessRequest( AFS_REQUEST_TYPE_PIPE_SET_INFO,
AFS_REQUEST_FLAG_SYNCHRONOUS,
- pAuthGroup,
+ &Ccb->AuthGroup,
&Ccb->DirectoryCB->NameInformation.FileName,
NULL,
pInfoRequest,
NTSTATUS ntStatus = STATUS_SUCCESS;
AFSPipeInfoRequestCB stInfoRequest;
ULONG ulBytesProcessed = 0;
- GUID *pAuthGroup = NULL;
__Enter
{
ulBytesProcessed = OutputLength;
- if( Ccb->DirectoryCB->ObjectInformation->Fcb != NULL)
- {
- pAuthGroup = &Ccb->DirectoryCB->ObjectInformation->Fcb->AuthGroup;
- }
-
//
// Send the call to the service
//
ntStatus = AFSProcessRequest( AFS_REQUEST_TYPE_PIPE_QUERY_INFO,
AFS_REQUEST_FLAG_SYNCHRONOUS,
- pAuthGroup,
+ &Ccb->AuthGroup,
&Ccb->DirectoryCB->NameInformation.FileName,
NULL,
&stInfoRequest,