}
//
-// Function: AFSBuildCRCTable
-//
-// Description:
-//
-// This function builds the CRC table for mapping filenames to a CRC value.
-//
-// Return:
-//
-// A status is returned for the function
-//
-
-void
-AFSBuildCRCTable()
-{
- ULONG crc;
- int i, j;
-
- for ( i = 0; i <= 255; i++)
- {
- crc = i;
- for ( j = 8; j > 0; j--)
- {
- if (crc & 1)
- {
- crc = ( crc >> 1 ) ^ CRC32_POLYNOMIAL;
- }
- else
- {
- crc >>= 1;
- }
- }
-
- AFSCRCTable[ i ] = crc;
- }
-}
-
-//
// Function: AFSGenerateCRC
//
// Description:
IN BOOLEAN UpperCaseName)
{
- ULONG crc;
- ULONG temp1, temp2;
- UNICODE_STRING UpcaseString;
- WCHAR *lpbuffer;
- USHORT size = 0;
-
- if( !AFSCRCTable[1])
- {
- AFSBuildCRCTable();
- }
-
- crc = 0xFFFFFFFFL;
-
- if( UpperCaseName)
- {
-
- RtlUpcaseUnicodeString( &UpcaseString,
- FileName,
- TRUE);
-
- lpbuffer = UpcaseString.Buffer;
-
- size = (UpcaseString.Length/sizeof( WCHAR));
- }
- else
- {
-
- lpbuffer = FileName->Buffer;
-
- size = (FileName->Length/sizeof( WCHAR));
- }
+ ULONG ulCRC = 0;
+ NTSTATUS ntStatus = STATUS_SUCCESS;
- while (size--)
- {
- temp1 = (crc >> 8) & 0x00FFFFFFL;
- temp2 = AFSCRCTable[((int)crc ^ *lpbuffer++) & 0xff];
- crc = temp1 ^ temp2;
- }
+ ntStatus = RtlHashUnicodeString( FileName,
+ UpperCaseName,
+ HASH_STRING_ALGORITHM_DEFAULT,
+ &ulCRC);
- if( UpperCaseName)
+ if( !NT_SUCCESS( ntStatus))
{
-
- RtlFreeUnicodeString( &UpcaseString);
+ ulCRC = 0;
}
- crc ^= 0xFFFFFFFFL;
-
- return crc;
+ return ulCRC;
}
void *
bAllocatedObjectCB = TRUE;
- AFSDbgLogMsg( AFS_SUBSYSTEM_CLEANUP_PROCESSING,
+ AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
AFS_TRACE_LEVEL_VERBOSE,
"AFSInitDirEntry initialized object %08lX Parent Object %08lX for %wZ\n",
pObjectInfoCB,
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;
TRUE);
}
+ AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
+ AFS_TRACE_LEVEL_VERBOSE,
+ "AFSInitDirEntry Initialized DE %p for %wZ in parent FID %08lX-%08lX-%08lX-%08lX\n",
+ pDirNode,
+ FileName,
+ ParentObjectInfo->FileId.Cell,
+ ParentObjectInfo->FileId.Volume,
+ ParentObjectInfo->FileId.Vnode,
+ ParentObjectInfo->FileId.Unique);
+
if( TargetName != NULL &&
TargetName->Length > 0)
{
DirEntry->ObjectInformation->FileAttributes = pDirEntry->FileAttributes;
+ if( pDirEntry->FileType == AFS_FILE_TYPE_MOUNTPOINT ||
+ pDirEntry->FileType == AFS_FILE_TYPE_SYMLINK ||
+ pDirEntry->FileType == AFS_FILE_TYPE_DFSLINK)
+ {
+
+ DirEntry->ObjectInformation->FileAttributes |= FILE_ATTRIBUTE_REPARSE_POINT;
+ }
+
DirEntry->ObjectInformation->EaSize = pDirEntry->EaSize;
DirEntry->ObjectInformation->Links = pDirEntry->Links;
DirEntry->ObjectInformation->FileAttributes = pDirEntry->FileAttributes;
+ if( pDirEntry->FileType == AFS_FILE_TYPE_MOUNTPOINT ||
+ pDirEntry->FileType == AFS_FILE_TYPE_SYMLINK ||
+ pDirEntry->FileType == AFS_FILE_TYPE_DFSLINK)
+ {
+
+ DirEntry->ObjectInformation->FileAttributes |= FILE_ATTRIBUTE_REPARSE_POINT;
+ }
+
DirEntry->ObjectInformation->EaSize = pDirEntry->EaSize;
DirEntry->ObjectInformation->Links = pDirEntry->Links;
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
+ //
+
+ 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;
}
+ AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
+ AFS_TRACE_LEVEL_VERBOSE,
+ "AFSValidateDirectoryCache Processing INVALID DE %p Reference count %08lX\n",
+ pCurrentDirEntry,
+ pCurrentDirEntry->OpenReferenceCount);
+
if( pCurrentDirEntry->OpenReferenceCount == 0)
{
AFSDbgLogMsg( AFS_SUBSYSTEM_OBJECT_REF_COUNTING,
AFS_TRACE_LEVEL_VERBOSE,
"AFSInitializeSpecialShareNameList (srvsvc) Initializing count (1) on object %08lX\n",
- pObjectInfoCB);
+ pObjectInfoCB);
pObjectInfoCB->ObjectReferenceCount = 1;
AFSDbgLogMsg( AFS_SUBSYSTEM_OBJECT_REF_COUNTING,
AFS_TRACE_LEVEL_VERBOSE,
"AFSInitializeSpecialShareNameList (wkssvc) Initializing count (1) on object %08lX\n",
- pObjectInfoCB);
+ pObjectInfoCB);
pObjectInfoCB->ObjectReferenceCount = 1;
AFSDbgLogMsg( AFS_SUBSYSTEM_OBJECT_REF_COUNTING,
AFS_TRACE_LEVEL_VERBOSE,
"AFSInitializeSpecialShareNameList (ipc$) Initializing count (1) on object %08lX\n",
- pObjectInfoCB);
+ pObjectInfoCB);
pObjectInfoCB->ObjectReferenceCount = 1;
pObjectInfoCB->FileAttributes = FILE_ATTRIBUTE_HIDDEN | FILE_ATTRIBUTE_SYSTEM;
- ulEntryLength = sizeof( AFSDirectoryCB) +
- AFSPIOCtlName.Length;
+ ulEntryLength = sizeof( AFSDirectoryCB) + AFSPIOCtlName.Length;
pDirNode = (AFSDirectoryCB *)AFSExAllocatePoolWithTag( PagedPool,
ulEntryLength,
if( pNonPagedDirEntry == NULL)
{
- AFSExFreePool( pDirNode);
-
- AFSDeleteObjectInfo( pObjectInfoCB);
-
try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
}
try_exit:
- NOTHING;
+ if ( !NT_SUCCESS( ntStatus))
+ {
+
+ if ( pDirNode != NULL)
+ {
+
+ AFSExFreePool( pDirNode);
+ }
+
+ if ( pObjectInfoCB != NULL)
+ {
+
+ AFSDeleteObjectInfo( pObjectInfoCB);
+ }
+ }
}
return ntStatus;
// offset by the length of the server name
//
- AFSExFreePool( pwchBuffer);
-
if( uniFullPathName.Length > 0 &&
pwchBuffer != (WCHAR *)((char *)uniFullPathName.Buffer - ulNameDifference))
{
AFSExFreePool( uniFullPathName.Buffer);
}
+
+ AFSExFreePool( pwchBuffer);
}
}
// offset by the length of the server name
//
- AFSExFreePool( pwchBuffer);
-
if( uniFullPathName.Length > 0 &&
pwchBuffer != (WCHAR *)((char *)uniFullPathName.Buffer - ulNameDifference))
{
AFSExFreePool( uniFullPathName.Buffer);
}
+
+ AFSExFreePool( pwchBuffer);
}
}
if( BooleanFlagOn( DirEntry->Flags, AFS_DIR_ENTRY_NOT_IN_PARENT_TREE))
{
+ AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
+ AFS_TRACE_LEVEL_VERBOSE,
+ "AFSRemoveNameEntry DE %p for %wZ has NOT_IN flag set\n",
+ DirEntry,
+ &DirEntry->NameInformation.FileName);
+
try_return( ntStatus);
}
// Remove the entry from the parent tree
//
+ AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
+ AFS_TRACE_LEVEL_VERBOSE,
+ "AFSRemoveNameEntry DE %p for %wZ removing from case sensitive tree\n",
+ DirEntry,
+ &DirEntry->NameInformation.FileName);
+
AFSRemoveCaseSensitiveDirEntry( &ParentObjectInfo->Specific.Directory.DirectoryNodeHdr.CaseSensitiveTreeHead,
DirEntry);
+ AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
+ AFS_TRACE_LEVEL_VERBOSE,
+ "AFSRemoveNameEntry DE %p for %wZ removing from case insensitive tree\n",
+ DirEntry,
+ &DirEntry->NameInformation.FileName);
+
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))
{
//
// From the short name tree
//
+ AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
+ AFS_TRACE_LEVEL_VERBOSE,
+ "AFSRemoveNameEntry DE %p for %wZ removing from shortname tree\n",
+ DirEntry,
+ &DirEntry->NameInformation.FileName);
+
AFSRemoveShortNameDirEntry( &ParentObjectInfo->Specific.Directory.ShortNameTree,
DirEntry);
+
+ ClearFlag( DirEntry->Flags, AFS_DIR_ENTRY_INSERTED_SHORT_NAME);
}
+ AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
+ AFS_TRACE_LEVEL_VERBOSE,
+ "AFSRemoveNameEntry DE %p for %wZ setting NOT_IN flag\n",
+ DirEntry,
+ &DirEntry->NameInformation.FileName);
+
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;