Windows: FILE_FS_DEVICE_INFORMATION Device Type
[openafs.git] / src / WINNT / afsrdr / kernel / lib / AFSVolumeInfo.cpp
index 72c1e4c..672e4a6 100644 (file)
@@ -43,14 +43,16 @@ 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;
+    PFILE_OBJECT pFileObject = NULL;
     AFSFcb *pFcb = NULL;
+    AFSObjectInfoCB *pObjectInfo = NULL;
     AFSVolumeCB *pVolumeCB = NULL;
 
     pIrpSp = IoGetCurrentIrpStackLocation( Irp);
@@ -58,7 +60,19 @@ AFSQueryVolumeInfo( IN PDEVICE_OBJECT LibDeviceObject,
     __try
     {
 
-        pFcb = (AFSFcb *)pIrpSp->FileObject->FsContext;
+        pFileObject = pIrpSp->FileObject;
+
+        if( pFileObject == NULL)
+        {
+
+            AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
+                          AFS_TRACE_LEVEL_ERROR,
+                          "AFSQueryVolumeInfo Failing request with NULL FileObject\n");
+
+            try_return( ntStatus = STATUS_INVALID_DEVICE_REQUEST);
+        }
+
+        pFcb = (AFSFcb *)pFileObject->FsContext;
 
         if( pFcb == NULL)
         {
@@ -70,10 +84,19 @@ AFSQueryVolumeInfo( IN PDEVICE_OBJECT LibDeviceObject,
             try_return( ntStatus = STATUS_INVALID_DEVICE_REQUEST);
         }
 
-        pVolumeCB = pFcb->ObjectInformation->VolumeCB;
+        pObjectInfo = pFcb->ObjectInformation;
 
-        ASSERT( pVolumeCB->ObjectInformation.FileType == AFS_FILE_TYPE_DIRECTORY &&
-                pVolumeCB->ObjectInformation.FileId.Vnode == 1);
+        if( pObjectInfo == NULL)
+        {
+
+            AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
+                          AFS_TRACE_LEVEL_ERROR,
+                          "AFSQueryVolumeInfo Failing request with NULL ObjectInformation\n");
+
+            try_return( ntStatus = STATUS_INVALID_DEVICE_REQUEST);
+        }
+
+        pVolumeCB = pObjectInfo->VolumeCB;
 
         ulLength = pIrpSp->Parameters.QueryVolume.Length;
         FsInformationClass = pIrpSp->Parameters.QueryVolume.FsInformationClass;
@@ -203,12 +226,19 @@ try_exit:
                             ntStatus);
 
     }
-    __except( AFSExceptionFilter( GetExceptionCode(), GetExceptionInformation()) )
+    __except( AFSExceptionFilter( __FUNCTION__, GetExceptionCode(), GetExceptionInformation()) )
     {
 
         AFSDbgLogMsg( 0,
                       0,
-                      "EXCEPTION - AFSQueryVolumeInfo\n");
+                      "EXCEPTION - AFSQueryVolumeInfo FO %p InfoClass %d FCB %p ObjectInfo %p VolCB %p\n",
+                      pFileObject,
+                      FsInformationClass,
+                      pFcb,
+                      pObjectInfo,
+                      pVolumeCB);
+
+        AFSDumpTraceFilesFnc();
     }
 
     return ntStatus;
@@ -219,6 +249,7 @@ AFSSetVolumeInfo( IN PDEVICE_OBJECT DeviceObject,
                   IN PIRP Irp)
 {
 
+    UNREFERENCED_PARAMETER(DeviceObject);
     NTSTATUS ntStatus = STATUS_SUCCESS;
     IO_STACK_LOCATION *pIrpSp;
 
@@ -229,18 +260,20 @@ AFSSetVolumeInfo( IN PDEVICE_OBJECT DeviceObject,
 
         AFSDbgLogMsg( 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);
 
     }
-    __except( AFSExceptionFilter( GetExceptionCode(), GetExceptionInformation()) )
+    __except( AFSExceptionFilter( __FUNCTION__, GetExceptionCode(), GetExceptionInformation()) )
     {
 
         AFSDbgLogMsg( 0,
                       0,
                       "EXCEPTION - AFSSetVolumeInfo\n");
+
+        AFSDumpTraceFilesFnc();
     }
 
     return ntStatus;
@@ -308,6 +341,8 @@ AFSQueryFsSizeInfo( IN AFSVolumeInfoCB *VolumeInfo,
 {
 
     NTSTATUS ntStatus = STATUS_SUCCESS;
+    AFSFileID FileID;
+    AFSVolumeSizeInfoCB VolumeSizeInfo;
 
     RtlZeroMemory( Buffer,
                    *Length);
@@ -315,15 +350,30 @@ AFSQueryFsSizeInfo( IN AFSVolumeInfoCB *VolumeInfo,
     if( *Length >= sizeof( FILE_FS_SIZE_INFORMATION))
     {
 
-        Buffer->TotalAllocationUnits.QuadPart = VolumeInfo->TotalAllocationUnits.QuadPart;
+        RtlZeroMemory( &FileID,
+                       sizeof(AFSFileID));
 
-        Buffer->AvailableAllocationUnits.QuadPart = VolumeInfo->AvailableAllocationUnits.QuadPart;
+        FileID.Cell = VolumeInfo->CellID;
 
-        Buffer->SectorsPerAllocationUnit = VolumeInfo->SectorsPerAllocationUnit;
+        FileID.Volume = VolumeInfo->VolumeID;
 
-        Buffer->BytesPerSector = VolumeInfo->BytesPerSector;
+        ntStatus = AFSRetrieveVolumeSizeInformation( NULL,
+                                                     &FileID,
+                                                     &VolumeSizeInfo);
 
-        *Length -= sizeof( FILE_FS_SIZE_INFORMATION);
+        if ( NT_SUCCESS( ntStatus))
+        {
+
+            Buffer->TotalAllocationUnits.QuadPart = VolumeSizeInfo.TotalAllocationUnits.QuadPart;
+
+            Buffer->AvailableAllocationUnits.QuadPart = VolumeSizeInfo.AvailableAllocationUnits.QuadPart;
+
+            Buffer->SectorsPerAllocationUnit = VolumeSizeInfo.SectorsPerAllocationUnit;
+
+            Buffer->BytesPerSector = VolumeSizeInfo.BytesPerSector;
+
+            *Length -= sizeof( FILE_FS_SIZE_INFORMATION);
+        }
     }
     else
     {
@@ -347,6 +397,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;
@@ -367,6 +425,7 @@ AFSQueryFsAttributeInfo( IN AFSVolumeInfoCB *VolumeInfo,
                          IN PFILE_FS_ATTRIBUTE_INFORMATION Buffer,
                          IN OUT PULONG Length)
 {
+    UNREFERENCED_PARAMETER(VolumeInfo);
     NTSTATUS ntStatus = STATUS_SUCCESS;
 
     RtlZeroMemory( Buffer,
@@ -377,6 +436,7 @@ AFSQueryFsAttributeInfo( IN AFSVolumeInfoCB *VolumeInfo,
 
         Buffer->FileSystemAttributes = (FILE_CASE_PRESERVED_NAMES |
                                         FILE_UNICODE_ON_DISK |
+                                        FILE_SUPPORTS_HARD_LINKS |
                                         FILE_SUPPORTS_REPARSE_POINTS);
 
         Buffer->MaximumComponentNameLength = 255;
@@ -416,6 +476,8 @@ AFSQueryFsFullSizeInfo( IN AFSVolumeInfoCB *VolumeInfo,
 {
 
     NTSTATUS ntStatus = STATUS_SUCCESS;
+    AFSFileID FileID;
+    AFSVolumeSizeInfoCB VolumeSizeInfo;
 
     RtlZeroMemory( Buffer,
                    *Length);
@@ -423,17 +485,32 @@ AFSQueryFsFullSizeInfo( IN AFSVolumeInfoCB *VolumeInfo,
     if( *Length >= sizeof( FILE_FS_FULL_SIZE_INFORMATION))
     {
 
-        Buffer->TotalAllocationUnits.QuadPart = VolumeInfo->TotalAllocationUnits.QuadPart;
+        RtlZeroMemory( &FileID,
+                       sizeof(AFSFileID));
+
+        FileID.Cell = VolumeInfo->CellID;
+
+        FileID.Volume = VolumeInfo->VolumeID;
+
+        ntStatus = AFSRetrieveVolumeSizeInformation( NULL,
+                                                     &FileID,
+                                                     &VolumeSizeInfo);
 
-        Buffer->CallerAvailableAllocationUnits.QuadPart = VolumeInfo->AvailableAllocationUnits.QuadPart;
+        if ( NT_SUCCESS( ntStatus))
+        {
+
+            Buffer->TotalAllocationUnits.QuadPart = VolumeSizeInfo.TotalAllocationUnits.QuadPart;
 
-        Buffer->ActualAvailableAllocationUnits.QuadPart = VolumeInfo->AvailableAllocationUnits.QuadPart;
+            Buffer->CallerAvailableAllocationUnits.QuadPart = VolumeSizeInfo.AvailableAllocationUnits.QuadPart;
 
-        Buffer->SectorsPerAllocationUnit = VolumeInfo->SectorsPerAllocationUnit;
+            Buffer->ActualAvailableAllocationUnits.QuadPart = VolumeSizeInfo.AvailableAllocationUnits.QuadPart;
 
-        Buffer->BytesPerSector = VolumeInfo->BytesPerSector;
+            Buffer->SectorsPerAllocationUnit = VolumeSizeInfo.SectorsPerAllocationUnit;
 
-        *Length -= sizeof( FILE_FS_FULL_SIZE_INFORMATION);
+            Buffer->BytesPerSector = VolumeSizeInfo.BytesPerSector;
+
+            *Length -= sizeof( FILE_FS_FULL_SIZE_INFORMATION);
+        }
     }
     else
     {