From 830744ff437a27b00044e7e94f3824b0db969c0b Mon Sep 17 00:00:00 2001 From: Jeffrey Altman Date: Sat, 16 Mar 2013 01:18:14 -0400 Subject: [PATCH] Windows: File Attribute Reporting Consistency Do a better job of consistently reporting file attribute information via directory queries and file information queries. Avoid computing file attribute information for file information queries that do not return them (e.g., Name Information) because computing it is expensive. Change-Id: I5c8120698261f555edfa98e92230705b593aca36 Reviewed-on: http://gerrit.openafs.org/9613 Tested-by: BuildBot Reviewed-by: Jeffrey Altman Tested-by: Jeffrey Altman --- src/WINNT/afsrdr/kernel/lib/AFSDirControl.cpp | 90 ++++++++------- src/WINNT/afsrdr/kernel/lib/AFSFileInfo.cpp | 108 +++++++++++------- src/WINNT/afsrdr/kernel/lib/AFSGeneric.cpp | 84 ++++++++++---- src/WINNT/afsrdr/user/RDRFunction.c | 11 +- 4 files changed, 181 insertions(+), 112 deletions(-) diff --git a/src/WINNT/afsrdr/kernel/lib/AFSDirControl.cpp b/src/WINNT/afsrdr/kernel/lib/AFSDirControl.cpp index eda3fe5d5..ba335bc10 100644 --- a/src/WINNT/afsrdr/kernel/lib/AFSDirControl.cpp +++ b/src/WINNT/afsrdr/kernel/lib/AFSDirControl.cpp @@ -928,58 +928,67 @@ AFSQueryDirectory( IN PIRP Irp) } - // - // For Symlinks and Mount Points the reparse point attribute - // must be associated with the directory entry. In addition, - // for Symlinks it must be determined if the target object is - // a directory or not. If so, the directory attribute must be - // specified. Mount points always refer to directories and - // must have the directory attribute set. - // - - switch( pObjectInfo->FileType) - { - - case AFS_FILE_TYPE_MOUNTPOINT: - case AFS_FILE_TYPE_DFSLINK: - { - - ulAdditionalAttributes = FILE_ATTRIBUTE_DIRECTORY | FILE_ATTRIBUTE_REPARSE_POINT; - - break; - } - - case AFS_FILE_TYPE_SYMLINK: + switch ( FileInformationClass) { + case FileIdBothDirectoryInformation: + case FileBothDirectoryInformation: + case FileIdFullDirectoryInformation: + case FileFullDirectoryInformation: + case FileDirectoryInformation: // - // Go grab the file information for this entry - // No worries on failures since we will just display - // pseudo information + // For Symlinks and Mount Points the reparse point attribute + // must be associated with the directory entry. In addition, + // for Symlinks it must be determined if the target object is + // a directory or not. If so, the directory attribute must be + // specified. Mount points always refer to directories and + // must have the directory attribute set. // - RtlZeroMemory( &stFileInfo, - sizeof( AFSFileInfoCB)); - - if( NT_SUCCESS( AFSRetrieveFileAttributes( pCcb->DirectoryCB, - pDirEntry, - &pCcb->FullFileName, - pCcb->NameArray, - &pCcb->AuthGroup, - &stFileInfo))) + switch( pObjectInfo->FileType) { - if ( stFileInfo.FileAttributes & FILE_ATTRIBUTE_DIRECTORY) + case AFS_FILE_TYPE_MOUNTPOINT: + case AFS_FILE_TYPE_DFSLINK: { - ulAdditionalAttributes = FILE_ATTRIBUTE_DIRECTORY; + ulAdditionalAttributes = FILE_ATTRIBUTE_DIRECTORY | FILE_ATTRIBUTE_REPARSE_POINT; + + break; } - } - ulAdditionalAttributes |= FILE_ATTRIBUTE_REPARSE_POINT; + case AFS_FILE_TYPE_SYMLINK: + { - break; - } + // + // Go grab the file information for this entry + // No worries on failures since we will just display + // pseudo information + // + + RtlZeroMemory( &stFileInfo, + sizeof( AFSFileInfoCB)); + + if( NT_SUCCESS( AFSRetrieveFileAttributes( pCcb->DirectoryCB, + pDirEntry, + &pCcb->FullFileName, + pCcb->NameArray, + &pCcb->AuthGroup, + &stFileInfo))) + { + + if ( stFileInfo.FileAttributes & FILE_ATTRIBUTE_DIRECTORY) + { + + ulAdditionalAttributes = FILE_ATTRIBUTE_DIRECTORY; + } + } + + ulAdditionalAttributes |= FILE_ATTRIBUTE_REPARSE_POINT; + + break; + } + } } // @@ -2015,7 +2024,6 @@ AFSProcessDirectoryQueryDirect( IN AFSFcb *Fcb, PUCHAR pBuffer = NULL; ULONG ulBaseLength = 0; ULONG ulAdditionalAttributes = 0; - AFSFileInfoCB stFileInfo; ULONG ulBytesConverted = 0; PFILE_DIRECTORY_INFORMATION pDirInfo; PFILE_FULL_DIR_INFORMATION pFullDirInfo; diff --git a/src/WINNT/afsrdr/kernel/lib/AFSFileInfo.cpp b/src/WINNT/afsrdr/kernel/lib/AFSFileInfo.cpp index e1f3d992e..f6a9d6653 100644 --- a/src/WINNT/afsrdr/kernel/lib/AFSFileInfo.cpp +++ b/src/WINNT/afsrdr/kernel/lib/AFSFileInfo.cpp @@ -846,6 +846,22 @@ AFSQueryBasicInfo( IN PIRP Irp, AFSReleaseResource( &pFcb->NPFcb->Resource); + // + // Its a reparse point regardless of whether the file attributes + // can be retrieved for the target. + // + + if ( ulFileAttribs == FILE_ATTRIBUTE_NORMAL) + { + + ulFileAttribs = FILE_ATTRIBUTE_REPARSE_POINT; + } + else + { + + ulFileAttribs |= FILE_ATTRIBUTE_REPARSE_POINT; + } + if( NT_SUCCESS( AFSRetrieveFileAttributes( pParentDirectoryCB, DirectoryCB, &uniParentPath, @@ -854,17 +870,6 @@ AFSQueryBasicInfo( IN PIRP Irp, &stFileInfo))) { - if ( ulFileAttribs == FILE_ATTRIBUTE_NORMAL) - { - - ulFileAttribs = FILE_ATTRIBUTE_REPARSE_POINT; - } - else - { - - ulFileAttribs |= FILE_ATTRIBUTE_REPARSE_POINT; - } - if ( stFileInfo.FileAttributes & FILE_ATTRIBUTE_DIRECTORY) { @@ -967,6 +972,22 @@ AFSQueryStandardInfo( IN PIRP Irp, AFSReleaseResource( &pFcb->NPFcb->Resource); + // + // Its a reparse point regardless of whether or not the + // file attributes can be retrieved. + // + + if ( ulFileAttribs == FILE_ATTRIBUTE_NORMAL) + { + + ulFileAttribs = FILE_ATTRIBUTE_REPARSE_POINT; + } + else + { + + ulFileAttribs |= FILE_ATTRIBUTE_REPARSE_POINT; + } + if( NT_SUCCESS( AFSRetrieveFileAttributes( pParentDirectoryCB, DirectoryCB, &uniParentPath, @@ -975,17 +996,6 @@ AFSQueryStandardInfo( IN PIRP Irp, &stFileInfo))) { - if ( ulFileAttribs == FILE_ATTRIBUTE_NORMAL) - { - - ulFileAttribs = FILE_ATTRIBUTE_REPARSE_POINT; - } - else - { - - ulFileAttribs |= FILE_ATTRIBUTE_REPARSE_POINT; - } - if ( stFileInfo.FileAttributes & FILE_ATTRIBUTE_DIRECTORY) { @@ -1478,6 +1488,22 @@ AFSQueryNetworkInfo( IN PIRP Irp, AFSReleaseResource( &pFcb->NPFcb->Resource); + // + // Its a reparse point regardless of whether the file attributes + // can be retrieved for the target. + // + + if ( ulFileAttribs == FILE_ATTRIBUTE_NORMAL) + { + + ulFileAttribs = FILE_ATTRIBUTE_REPARSE_POINT; + } + else + { + + ulFileAttribs |= FILE_ATTRIBUTE_REPARSE_POINT; + } + if( NT_SUCCESS( AFSRetrieveFileAttributes( pParentDirectoryCB, DirectoryCB, &uniParentPath, @@ -1486,17 +1512,6 @@ AFSQueryNetworkInfo( IN PIRP Irp, &stFileInfo))) { - if ( ulFileAttribs == FILE_ATTRIBUTE_NORMAL) - { - - ulFileAttribs = FILE_ATTRIBUTE_REPARSE_POINT; - } - else - { - - ulFileAttribs |= FILE_ATTRIBUTE_REPARSE_POINT; - } - if ( stFileInfo.FileAttributes & FILE_ATTRIBUTE_DIRECTORY) { @@ -1668,6 +1683,22 @@ AFSQueryAttribTagInfo( IN PIRP Irp, AFSReleaseResource( &pFcb->NPFcb->Resource); + // + // Its a reparse point regardless of whether the file attributes + // can be retrieved for the target. + // + + if ( ulFileAttribs == FILE_ATTRIBUTE_NORMAL) + { + + ulFileAttribs = FILE_ATTRIBUTE_REPARSE_POINT; + } + else + { + + ulFileAttribs |= FILE_ATTRIBUTE_REPARSE_POINT; + } + if( NT_SUCCESS( AFSRetrieveFileAttributes( pParentDirectoryCB, DirectoryCB, &uniParentPath, @@ -1676,17 +1707,6 @@ AFSQueryAttribTagInfo( IN PIRP Irp, &stFileInfo))) { - if ( ulFileAttribs == FILE_ATTRIBUTE_NORMAL) - { - - ulFileAttribs = FILE_ATTRIBUTE_REPARSE_POINT; - } - else - { - - ulFileAttribs |= FILE_ATTRIBUTE_REPARSE_POINT; - } - if ( stFileInfo.FileAttributes & FILE_ATTRIBUTE_DIRECTORY) { diff --git a/src/WINNT/afsrdr/kernel/lib/AFSGeneric.cpp b/src/WINNT/afsrdr/kernel/lib/AFSGeneric.cpp index 505c70dca..fb5346589 100644 --- a/src/WINNT/afsrdr/kernel/lib/AFSGeneric.cpp +++ b/src/WINNT/afsrdr/kernel/lib/AFSGeneric.cpp @@ -1139,17 +1139,26 @@ AFSInitDirEntry( IN AFSObjectInfoCB *ParentObjectInfo, pObjectInfoCB->FileAttributes = DirEnumEntry->FileAttributes; - if( pObjectInfoCB->FileType == AFS_FILE_TYPE_MOUNTPOINT) + if( pObjectInfoCB->FileType == AFS_FILE_TYPE_MOUNTPOINT || + pObjectInfoCB->FileType == AFS_FILE_TYPE_DFSLINK) { - pObjectInfoCB->FileAttributes = (FILE_ATTRIBUTE_DIRECTORY | FILE_ATTRIBUTE_REPARSE_POINT); + pObjectInfoCB->FileAttributes |= (FILE_ATTRIBUTE_DIRECTORY | FILE_ATTRIBUTE_REPARSE_POINT); } - if (pObjectInfoCB->FileType == AFS_FILE_TYPE_SYMLINK || - pObjectInfoCB->FileType == AFS_FILE_TYPE_DFSLINK) + if (pObjectInfoCB->FileType == AFS_FILE_TYPE_SYMLINK) { - pObjectInfoCB->FileAttributes = FILE_ATTRIBUTE_REPARSE_POINT; + if ( pObjectInfoCB->FileAttributes == FILE_ATTRIBUTE_NORMAL) + { + + pObjectInfoCB->FileAttributes = FILE_ATTRIBUTE_REPARSE_POINT; + } + else + { + + pObjectInfoCB->FileAttributes |= FILE_ATTRIBUTE_REPARSE_POINT; + } } pObjectInfoCB->EaSize = DirEnumEntry->EaSize; @@ -1365,17 +1374,26 @@ AFSEvaluateNode( IN GUID *AuthGroup, DirEntry->ObjectInformation->FileAttributes = pDirEntry->FileAttributes; - if( pDirEntry->FileType == AFS_FILE_TYPE_MOUNTPOINT) + if( pDirEntry->FileType == AFS_FILE_TYPE_MOUNTPOINT || + pDirEntry->FileType == AFS_FILE_TYPE_DFSLINK) { - DirEntry->ObjectInformation->FileAttributes = (FILE_ATTRIBUTE_DIRECTORY | FILE_ATTRIBUTE_REPARSE_POINT); + DirEntry->ObjectInformation->FileAttributes |= (FILE_ATTRIBUTE_DIRECTORY | FILE_ATTRIBUTE_REPARSE_POINT); } - if( pDirEntry->FileType == AFS_FILE_TYPE_SYMLINK || - pDirEntry->FileType == AFS_FILE_TYPE_DFSLINK) + if( pDirEntry->FileType == AFS_FILE_TYPE_SYMLINK) { - DirEntry->ObjectInformation->FileAttributes = FILE_ATTRIBUTE_REPARSE_POINT; + if ( DirEntry->ObjectInformation->FileAttributes == FILE_ATTRIBUTE_NORMAL) + { + + DirEntry->ObjectInformation->FileAttributes = FILE_ATTRIBUTE_REPARSE_POINT; + } + else + { + + DirEntry->ObjectInformation->FileAttributes |= FILE_ATTRIBUTE_REPARSE_POINT; + } } DirEntry->ObjectInformation->EaSize = pDirEntry->EaSize; @@ -1554,17 +1572,26 @@ AFSValidateSymLink( IN GUID *AuthGroup, DirEntry->ObjectInformation->FileAttributes = pDirEntry->FileAttributes; - if( pDirEntry->FileType == AFS_FILE_TYPE_MOUNTPOINT) + if( pDirEntry->FileType == AFS_FILE_TYPE_MOUNTPOINT || + pDirEntry->FileType == AFS_FILE_TYPE_DFSLINK) { - DirEntry->ObjectInformation->FileAttributes = (FILE_ATTRIBUTE_DIRECTORY | FILE_ATTRIBUTE_REPARSE_POINT); + DirEntry->ObjectInformation->FileAttributes |= (FILE_ATTRIBUTE_DIRECTORY | FILE_ATTRIBUTE_REPARSE_POINT); } - if( pDirEntry->FileType == AFS_FILE_TYPE_SYMLINK || - pDirEntry->FileType == AFS_FILE_TYPE_DFSLINK) + if( pDirEntry->FileType == AFS_FILE_TYPE_SYMLINK) { - DirEntry->ObjectInformation->FileAttributes = FILE_ATTRIBUTE_REPARSE_POINT; + if ( DirEntry->ObjectInformation->FileAttributes == FILE_ATTRIBUTE_NORMAL) + { + + DirEntry->ObjectInformation->FileAttributes = FILE_ATTRIBUTE_REPARSE_POINT; + } + else + { + + DirEntry->ObjectInformation->FileAttributes |= FILE_ATTRIBUTE_REPARSE_POINT; + } } DirEntry->ObjectInformation->EaSize = pDirEntry->EaSize; @@ -3728,17 +3755,26 @@ AFSUpdateMetaData( IN AFSDirectoryCB *DirEntry, pObjectInfo->FileAttributes = DirEnumEntry->FileAttributes; - if( pObjectInfo->FileType == AFS_FILE_TYPE_MOUNTPOINT) + if( pObjectInfo->FileType == AFS_FILE_TYPE_MOUNTPOINT || + pObjectInfo->FileType == AFS_FILE_TYPE_DFSLINK) { - pObjectInfo->FileAttributes = (FILE_ATTRIBUTE_DIRECTORY | FILE_ATTRIBUTE_REPARSE_POINT); + pObjectInfo->FileAttributes |= (FILE_ATTRIBUTE_DIRECTORY | FILE_ATTRIBUTE_REPARSE_POINT); } - if( pObjectInfo->FileType == AFS_FILE_TYPE_SYMLINK || - pObjectInfo->FileType == AFS_FILE_TYPE_DFSLINK) + if( pObjectInfo->FileType == AFS_FILE_TYPE_SYMLINK) { - pObjectInfo->FileAttributes = FILE_ATTRIBUTE_REPARSE_POINT; + if ( pObjectInfo->FileAttributes == FILE_ATTRIBUTE_NORMAL) + { + + pObjectInfo->FileAttributes = FILE_ATTRIBUTE_REPARSE_POINT; + } + else + { + + pObjectInfo->FileAttributes |= FILE_ATTRIBUTE_REPARSE_POINT; + } } pObjectInfo->EaSize = DirEnumEntry->EaSize; @@ -6416,13 +6452,13 @@ AFSRetrieveFileAttributes( IN AFSDirectoryCB *ParentDirectoryCB, // Check for the mount point being returned // - if( pDirectoryEntry->ObjectInformation->FileType == AFS_FILE_TYPE_MOUNTPOINT) + if( pDirectoryEntry->ObjectInformation->FileType == AFS_FILE_TYPE_MOUNTPOINT || + pDirectoryEntry->ObjectInformation->FileType == AFS_FILE_TYPE_DFSLINK) { - FileInfo->FileAttributes = (FILE_ATTRIBUTE_DIRECTORY | FILE_ATTRIBUTE_REPARSE_POINT); + FileInfo->FileAttributes |= (FILE_ATTRIBUTE_DIRECTORY | FILE_ATTRIBUTE_REPARSE_POINT); } - else if( pDirectoryEntry->ObjectInformation->FileType == AFS_FILE_TYPE_SYMLINK || - pDirectoryEntry->ObjectInformation->FileType == AFS_FILE_TYPE_DFSLINK) + else if( pDirectoryEntry->ObjectInformation->FileType == AFS_FILE_TYPE_SYMLINK) { if ( FileInfo->FileAttributes == FILE_ATTRIBUTE_NORMAL) diff --git a/src/WINNT/afsrdr/user/RDRFunction.c b/src/WINNT/afsrdr/user/RDRFunction.c index d565eefb1..4207e1028 100644 --- a/src/WINNT/afsrdr/user/RDRFunction.c +++ b/src/WINNT/afsrdr/user/RDRFunction.c @@ -540,6 +540,7 @@ RDR_PopulateCurrentEntry( IN AFSDirEnumEntry * pCurrentEntry, break; case CM_SCACHETYPE_MOUNTPOINT: case CM_SCACHETYPE_INVALID: + case CM_SCACHETYPE_DFSLINK: pCurrentEntry->FileAttributes = SMB_ATTR_DIRECTORY | SMB_ATTR_REPARSE_POINT; break; case CM_SCACHETYPE_SYMLINK: @@ -822,8 +823,6 @@ RDR_PopulateCurrentEntryNoScp( IN AFSDirEnumEntry * pCurrentEntry, pCurrentEntry->FileId.Unique = fidp->unique; pCurrentEntry->FileId.Hash = fidp->hash; - pCurrentEntry->FileType = CM_SCACHETYPE_UNKNOWN; - pCurrentEntry->DataVersion.QuadPart = CM_SCACHE_VERSION_BAD; cm_LargeSearchTimeFromUnixTime(&ft, 0); @@ -839,8 +838,14 @@ RDR_PopulateCurrentEntryNoScp( IN AFSDirEnumEntry * pCurrentEntry, pCurrentEntry->EndOfFile.QuadPart = 0; pCurrentEntry->AllocationSize.QuadPart = 0; - pCurrentEntry->FileAttributes = 0; + if (fidp->vnode & 0x1) { + pCurrentEntry->FileType = CM_SCACHETYPE_DIRECTORY; + pCurrentEntry->FileAttributes = SMB_ATTR_DIRECTORY; + } else { + pCurrentEntry->FileType = CM_SCACHETYPE_UNKNOWN; + pCurrentEntry->FileAttributes = SMB_ATTR_NORMAL; pCurrentEntry->EaSize = 0; + } pCurrentEntry->Links = 0; len = wcslen(shortName); -- 2.39.5