Windows: DOS Device VolumeInfo max name length
authorJeffrey Altman <jaltman@your-file-system.com>
Tue, 9 Apr 2013 03:41:48 +0000 (23:41 -0400)
committerJeffrey Altman <jaltman@your-file-system.com>
Tue, 9 Apr 2013 17:36:56 +0000 (10:36 -0700)
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 <buildbot@rampaginggeek.com>
Reviewed-by: Rod Widdowson <rdw@steadingsoftware.com>
Reviewed-by: Peter Scott <pscott@kerneldrivers.com>
Reviewed-by: Jeffrey Altman <jaltman@your-file-system.com>

src/WINNT/afsrdr/kernel/lib/AFSVolumeInfo.cpp
src/WINNT/afsrdr/kernel/lib/Include/AFSCommon.h

index f27e97e..4087465 100644 (file)
@@ -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);
+                    }
                 }
             }
         }
index 50aee25..2a70bfe 100644 (file)
@@ -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