Windows: DOS Device VolumeInfo max name length
[openafs.git] / src / WINNT / afsrdr / kernel / lib / AFSVolumeInfo.cpp
index c612583..4087465 100644 (file)
@@ -43,10 +43,10 @@ AFSQueryVolumeInfo( IN PDEVICE_OBJECT LibDeviceObject,
                     IN PIRP Irp)
 {
 
+    UNREFERENCED_PARAMETER(LibDeviceObject);
     NTSTATUS ntStatus = STATUS_SUCCESS;
-    AFSDeviceExt *pDeviceExt = (AFSDeviceExt *)AFSRDRDeviceObject->DeviceExtension;
     IO_STACK_LOCATION *pIrpSp;
-    FS_INFORMATION_CLASS FsInformationClass;
+    FS_INFORMATION_CLASS FsInformationClass = FileFsMaximumInformation;
     void *pBuffer = NULL;
     ULONG ulLength = 0;
     BOOLEAN bReleaseResource = FALSE;
@@ -54,6 +54,7 @@ AFSQueryVolumeInfo( IN PDEVICE_OBJECT LibDeviceObject,
     AFSFcb *pFcb = NULL;
     AFSObjectInfoCB *pObjectInfo = NULL;
     AFSVolumeCB *pVolumeCB = NULL;
+    BOOLEAN bDosDevice = FALSE;
 
     pIrpSp = IoGetCurrentIrpStackLocation( Irp);
 
@@ -65,9 +66,9 @@ AFSQueryVolumeInfo( IN PDEVICE_OBJECT LibDeviceObject,
         if( pFileObject == NULL)
         {
 
-            AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
+            AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING,
                           AFS_TRACE_LEVEL_ERROR,
-                          "AFSQueryVolumeInfo Failing request with NULL FileObject\n");
+                          "AFSQueryVolumeInfo Failing request with NULL FileObject\n"));
 
             try_return( ntStatus = STATUS_INVALID_DEVICE_REQUEST);
         }
@@ -77,9 +78,9 @@ AFSQueryVolumeInfo( IN PDEVICE_OBJECT LibDeviceObject,
         if( pFcb == NULL)
         {
 
-            AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
+            AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING,
                           AFS_TRACE_LEVEL_ERROR,
-                          "AFSQueryVolumeInfo Failing request with NULL Fcb\n");
+                          "AFSQueryVolumeInfo Failing request with NULL Fcb\n"));
 
             try_return( ntStatus = STATUS_INVALID_DEVICE_REQUEST);
         }
@@ -89,13 +90,18 @@ AFSQueryVolumeInfo( IN PDEVICE_OBJECT LibDeviceObject,
         if( pObjectInfo == NULL)
         {
 
-            AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
+            AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING,
                           AFS_TRACE_LEVEL_ERROR,
-                          "AFSQueryVolumeInfo Failing request with NULL ObjectInformation\n");
+                          "AFSQueryVolumeInfo Failing request with NULL ObjectInformation\n"));
 
             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;
@@ -114,27 +120,27 @@ AFSQueryVolumeInfo( IN PDEVICE_OBJECT LibDeviceObject,
         if( pFcb->Header.NodeTypeCode == AFS_IOCTL_FCB)
         {
 
-            AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
+            AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING,
                           AFS_TRACE_LEVEL_ERROR,
-                          "AFSQueryVolumeInfo Failing request against PIOCtl Fcb\n");
+                          "AFSQueryVolumeInfo Failing request against PIOCtl Fcb\n"));
 
             try_return( ntStatus = STATUS_INVALID_DEVICE_REQUEST);
         }
         else if( pFcb->Header.NodeTypeCode == AFS_SPECIAL_SHARE_FCB)
         {
 
-            AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
+            AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING,
                           AFS_TRACE_LEVEL_ERROR,
-                          "AFSQueryVolumeInfo Failing request against SpecialShare Fcb\n");
+                          "AFSQueryVolumeInfo Failing request against SpecialShare Fcb\n"));
 
             try_return( ntStatus = STATUS_INVALID_DEVICE_REQUEST);
         }
         else if( pFcb->Header.NodeTypeCode == AFS_INVALID_FCB)
         {
 
-            AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
+            AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING,
                           AFS_TRACE_LEVEL_ERROR,
-                          "AFSQueryVolumeInfo Failing request against SpecialShare Fcb\n");
+                          "AFSQueryVolumeInfo Failing request against SpecialShare Fcb\n"));
 
             try_return( ntStatus = STATUS_INVALID_DEVICE_REQUEST);
         }
@@ -151,6 +157,7 @@ AFSQueryVolumeInfo( IN PDEVICE_OBJECT LibDeviceObject,
 
                 ntStatus = AFSQueryFsVolumeInfo( &pVolumeCB->VolumeInformation,
                                                  (PFILE_FS_VOLUME_INFORMATION)pBuffer,
+                                                 bDosDevice,
                                                  &ulLength);
 
                 break;
@@ -198,10 +205,10 @@ AFSQueryVolumeInfo( IN PDEVICE_OBJECT LibDeviceObject,
 
             default:
 
-                AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
+                AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING,
                               AFS_TRACE_LEVEL_WARNING,
                               "AFSQueryVolumeInfo Invalid class %d\n",
-                              FsInformationClass);
+                              FsInformationClass));
 
                 ntStatus = STATUS_INVALID_PARAMETER;
 
@@ -229,14 +236,14 @@ try_exit:
     __except( AFSExceptionFilter( __FUNCTION__, GetExceptionCode(), GetExceptionInformation()) )
     {
 
-        AFSDbgLogMsg( 0,
+        AFSDbgTrace(( 0,
                       0,
-                      "EXCEPTION - AFSQueryVolumeInfo FO %08lX InfoClass %d FCB %08lX ObjectInfo %08lX VolCB %08lX\n",
+                      "EXCEPTION - AFSQueryVolumeInfo FO %p InfoClass %d FCB %p ObjectInfo %p VolCB %p\n",
                       pFileObject,
                       FsInformationClass,
                       pFcb,
                       pObjectInfo,
-                      pVolumeCB);
+                      pVolumeCB));
 
         AFSDumpTraceFilesFnc();
     }
@@ -249,6 +256,7 @@ AFSSetVolumeInfo( IN PDEVICE_OBJECT DeviceObject,
                   IN PIRP Irp)
 {
 
+    UNREFERENCED_PARAMETER(DeviceObject);
     NTSTATUS ntStatus = STATUS_SUCCESS;
     IO_STACK_LOCATION *pIrpSp;
 
@@ -257,9 +265,10 @@ AFSSetVolumeInfo( IN PDEVICE_OBJECT DeviceObject,
     __try
     {
 
-        AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
+        AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING,
                       AFS_TRACE_LEVEL_WARNING,
-                      "AFSSetVolumeInfo Entry for FO %08lX\n", pIrpSp->FileObject);
+                      "AFSSetVolumeInfo Entry for FO %p\n",
+                      pIrpSp->FileObject));
 
         AFSCompleteRequest( Irp,
                             ntStatus);
@@ -268,9 +277,9 @@ AFSSetVolumeInfo( IN PDEVICE_OBJECT DeviceObject,
     __except( AFSExceptionFilter( __FUNCTION__, GetExceptionCode(), GetExceptionInformation()) )
     {
 
-        AFSDbgLogMsg( 0,
+        AFSDbgTrace(( 0,
                       0,
-                      "EXCEPTION - AFSSetVolumeInfo\n");
+                      "EXCEPTION - AFSSetVolumeInfo\n"));
 
         AFSDumpTraceFilesFnc();
     }
@@ -281,12 +290,13 @@ AFSSetVolumeInfo( IN PDEVICE_OBJECT DeviceObject,
 NTSTATUS
 AFSQueryFsVolumeInfo( IN AFSVolumeInfoCB *VolumeInfo,
                       IN PFILE_FS_VOLUME_INFORMATION Buffer,
+                      IN BOOLEAN bDosDevice,
                       IN OUT PULONG Length)
 
 {
 
     NTSTATUS ntStatus = STATUS_BUFFER_TOO_SMALL;
-    ULONG ulCopyLength;
+    ULONG ulLabelLength;
 
     RtlZeroMemory( Buffer,
                    *Length);
@@ -294,18 +304,26 @@ AFSQueryFsVolumeInfo( IN AFSVolumeInfoCB *VolumeInfo,
     if( *Length >= (ULONG)sizeof( FILE_FS_VOLUME_INFORMATION))
     {
 
-        if( *Length >= (ULONG)(FIELD_OFFSET( FILE_FS_VOLUME_INFORMATION, VolumeLabel) + (LONG)VolumeInfo->VolumeLabelLength))
+        if ( bDosDevice)
         {
 
-            ulCopyLength = (LONG)VolumeInfo->VolumeLabelLength;
+            ulLabelLength = VolumeInfo->VolumeLabelLength;
+        }
+        else
+        {
+
+            ulLabelLength = VolumeInfo->VolumeLabelLength +
+                VolumeInfo->CellLength + sizeof( WCHAR);
+        }
+
+        if( *Length >= (ULONG)(FIELD_OFFSET( FILE_FS_VOLUME_INFORMATION, VolumeLabel) + ulLabelLength))
+        {
 
             ntStatus = STATUS_SUCCESS;
         }
         else
         {
 
-            ulCopyLength = *Length - FIELD_OFFSET( FILE_FS_VOLUME_INFORMATION, VolumeLabel);
-
             ntStatus = STATUS_BUFFER_OVERFLOW;
         }
 
@@ -313,20 +331,50 @@ AFSQueryFsVolumeInfo( IN AFSVolumeInfoCB *VolumeInfo,
 
         Buffer->VolumeSerialNumber = VolumeInfo->VolumeID;
 
-        Buffer->VolumeLabelLength = VolumeInfo->VolumeLabelLength;
+        Buffer->VolumeLabelLength = ulLabelLength;
 
         Buffer->SupportsObjects = FALSE;
 
         *Length -= FIELD_OFFSET( FILE_FS_VOLUME_INFORMATION, VolumeLabel);
 
-        if( ulCopyLength > 0)
+        if( *Length > 0)
         {
 
-            RtlCopyMemory( Buffer->VolumeLabel,
-                           VolumeInfo->VolumeLabel,
-                           ulCopyLength);
+            if ( bDosDevice)
+            {
+
+                RtlCopyMemory( Buffer->VolumeLabel,
+                               VolumeInfo->VolumeLabel,
+                               min( *Length, VolumeInfo->VolumeLabelLength));
 
-            *Length -= ulCopyLength;
+                *Length -= min( *Length, VolumeInfo->VolumeLabelLength);
+            }
+            else
+            {
+
+                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);
+
+                    if ( *Length > 0) {
+
+                        RtlCopyMemory( &Buffer->VolumeLabel[ (VolumeInfo->CellLength + sizeof( WCHAR)) / sizeof( WCHAR)],
+                                       VolumeInfo->VolumeLabel,
+                                       min( *Length, VolumeInfo->VolumeLabelLength));
+
+                        *Length -= min( *Length, VolumeInfo->VolumeLabelLength);
+                    }
+                }
+            }
         }
     }
 
@@ -396,6 +444,14 @@ AFSQueryFsDeviceInfo( IN AFSVolumeInfoCB *VolumeInfo,
     if( *Length >= (LONG)sizeof( FILE_FS_DEVICE_INFORMATION))
     {
 
+        //
+        // This value is used to determine the return type of
+        // Win32 GetFileType().  Returning FILE_DEVICE_NETWORK_FILE_SYSTEM
+        // results in GetFileType returning FILE_TYPE_UNKNOWN which breaks
+        // msys-based applications.  They treat all files as character
+        // special devices instead of files.
+        //
+
         Buffer->DeviceType = FILE_DEVICE_DISK;
 
         Buffer->Characteristics = VolumeInfo->Characteristics;
@@ -424,9 +480,7 @@ AFSQueryFsAttributeInfo( IN AFSVolumeInfoCB *VolumeInfo,
     if( *Length >= (LONG)(sizeof( FILE_FS_ATTRIBUTE_INFORMATION)))
     {
 
-        Buffer->FileSystemAttributes = (FILE_CASE_PRESERVED_NAMES |
-                                        FILE_UNICODE_ON_DISK |
-                                        FILE_SUPPORTS_REPARSE_POINTS);
+        Buffer->FileSystemAttributes = VolumeInfo->FileSystemAttributes;
 
         Buffer->MaximumComponentNameLength = 255;