From 675cd4b2c2e1202f75e42ebb3f0cf898ae5d4661 Mon Sep 17 00:00:00 2001 From: Jeffrey Altman Date: Mon, 8 Apr 2013 23:41:48 -0400 Subject: [PATCH] Windows: DOS Device VolumeInfo max name length In 1.7.2200 the AFS Redirectory began to return cellname{%,#}volume as the volume label in the Volume Information response. For UNC paths this is fine but for DOS devices on Windows 7 and earlier returning a volume label that is longer than the NTFS maximum label length (32 characters) results in the Explorer Shell treating the volume as if it does not support long file names. From this patchset forward if the FileObject->FileName indicates that the query is for a DOS Device, only return the AFS volume name and not the cell informmation in the Volume Information response. FIXES 131632 Change-Id: Iee26a00e0042e2594a5e039ee57688b61b10da45 Reviewed-on: http://gerrit.openafs.org/9751 Tested-by: BuildBot Reviewed-by: Rod Widdowson Reviewed-by: Peter Scott Reviewed-by: Jeffrey Altman --- src/WINNT/afsrdr/kernel/lib/AFSVolumeInfo.cpp | 58 +++++++++++++++++++------ src/WINNT/afsrdr/kernel/lib/Include/AFSCommon.h | 1 + 2 files changed, 45 insertions(+), 14 deletions(-) diff --git a/src/WINNT/afsrdr/kernel/lib/AFSVolumeInfo.cpp b/src/WINNT/afsrdr/kernel/lib/AFSVolumeInfo.cpp index f27e97e..4087465 100644 --- a/src/WINNT/afsrdr/kernel/lib/AFSVolumeInfo.cpp +++ b/src/WINNT/afsrdr/kernel/lib/AFSVolumeInfo.cpp @@ -54,6 +54,7 @@ AFSQueryVolumeInfo( IN PDEVICE_OBJECT LibDeviceObject, AFSFcb *pFcb = NULL; AFSObjectInfoCB *pObjectInfo = NULL; AFSVolumeCB *pVolumeCB = NULL; + BOOLEAN bDosDevice = FALSE; pIrpSp = IoGetCurrentIrpStackLocation( Irp); @@ -96,6 +97,11 @@ AFSQueryVolumeInfo( IN PDEVICE_OBJECT LibDeviceObject, try_return( ntStatus = STATUS_INVALID_DEVICE_REQUEST); } + bDosDevice = pFileObject->FileName.Length > 4 * sizeof( WCHAR) && + pFileObject->FileName.Buffer[0] == L'\\' && + pFileObject->FileName.Buffer[1] == L';' && + pFileObject->FileName.Buffer[3] == L':'; + pVolumeCB = pObjectInfo->VolumeCB; ulLength = pIrpSp->Parameters.QueryVolume.Length; @@ -151,6 +157,7 @@ AFSQueryVolumeInfo( IN PDEVICE_OBJECT LibDeviceObject, ntStatus = AFSQueryFsVolumeInfo( &pVolumeCB->VolumeInformation, (PFILE_FS_VOLUME_INFORMATION)pBuffer, + bDosDevice, &ulLength); break; @@ -283,6 +290,7 @@ AFSSetVolumeInfo( IN PDEVICE_OBJECT DeviceObject, NTSTATUS AFSQueryFsVolumeInfo( IN AFSVolumeInfoCB *VolumeInfo, IN PFILE_FS_VOLUME_INFORMATION Buffer, + IN BOOLEAN bDosDevice, IN OUT PULONG Length) { @@ -296,8 +304,17 @@ AFSQueryFsVolumeInfo( IN AFSVolumeInfoCB *VolumeInfo, if( *Length >= (ULONG)sizeof( FILE_FS_VOLUME_INFORMATION)) { - ulLabelLength = VolumeInfo->VolumeLabelLength + - VolumeInfo->CellLength + sizeof( WCHAR); + if ( bDosDevice) + { + + ulLabelLength = VolumeInfo->VolumeLabelLength; + } + else + { + + ulLabelLength = VolumeInfo->VolumeLabelLength + + VolumeInfo->CellLength + sizeof( WCHAR); + } if( *Length >= (ULONG)(FIELD_OFFSET( FILE_FS_VOLUME_INFORMATION, VolumeLabel) + ulLabelLength)) { @@ -323,26 +340,39 @@ AFSQueryFsVolumeInfo( IN AFSVolumeInfoCB *VolumeInfo, if( *Length > 0) { - RtlCopyMemory( Buffer->VolumeLabel, - VolumeInfo->Cell, - min( *Length, VolumeInfo->CellLength)); + if ( bDosDevice) + { - *Length -= min( *Length, VolumeInfo->CellLength); + RtlCopyMemory( Buffer->VolumeLabel, + VolumeInfo->VolumeLabel, + min( *Length, VolumeInfo->VolumeLabelLength)); - if ( *Length >= sizeof( WCHAR)) + *Length -= min( *Length, VolumeInfo->VolumeLabelLength); + } + else { - Buffer->VolumeLabel[ VolumeInfo->CellLength / sizeof( WCHAR)] = L'#'; + RtlCopyMemory( Buffer->VolumeLabel, + VolumeInfo->Cell, + min( *Length, VolumeInfo->CellLength)); + + *Length -= min( *Length, VolumeInfo->CellLength); + + if ( *Length >= sizeof( WCHAR)) + { + + Buffer->VolumeLabel[ VolumeInfo->CellLength / sizeof( WCHAR)] = L'#'; - *Length -= sizeof( WCHAR); + *Length -= sizeof( WCHAR); - if ( *Length > 0) { + if ( *Length > 0) { - RtlCopyMemory( &Buffer->VolumeLabel[ (VolumeInfo->CellLength + sizeof( WCHAR)) / sizeof( WCHAR)], - VolumeInfo->VolumeLabel, - min( *Length, VolumeInfo->VolumeLabelLength)); + RtlCopyMemory( &Buffer->VolumeLabel[ (VolumeInfo->CellLength + sizeof( WCHAR)) / sizeof( WCHAR)], + VolumeInfo->VolumeLabel, + min( *Length, VolumeInfo->VolumeLabelLength)); - *Length -= min( *Length, VolumeInfo->VolumeLabelLength); + *Length -= min( *Length, VolumeInfo->VolumeLabelLength); + } } } } diff --git a/src/WINNT/afsrdr/kernel/lib/Include/AFSCommon.h b/src/WINNT/afsrdr/kernel/lib/Include/AFSCommon.h index 50aee25..2a70bfe 100644 --- a/src/WINNT/afsrdr/kernel/lib/Include/AFSCommon.h +++ b/src/WINNT/afsrdr/kernel/lib/Include/AFSCommon.h @@ -932,6 +932,7 @@ AFSSetVolumeInfo( IN PDEVICE_OBJECT DeviceObject, NTSTATUS AFSQueryFsVolumeInfo( IN AFSVolumeInfoCB *VolumeInfo, IN PFILE_FS_VOLUME_INFORMATION Buffer, + IN BOOLEAN bDosDevice, IN OUT PULONG Length); NTSTATUS -- 1.9.4