Enabled caching for FAT32 partitions.
[reactos.git] / reactos / drivers / fs / vfat / volume.c
index ba132b4..907b9c2 100644 (file)
@@ -1,4 +1,4 @@
-/* $Id: volume.c,v 1.7 2001/03/01 07:48:17 dwelch Exp $
+/* $Id: volume.c,v 1.11 2001/07/20 08:00:21 ekohl Exp $
  *
  * COPYRIGHT:        See COPYING in the top level directory
  * PROJECT:          ReactOS kernel
 
 /* FUNCTIONS ****************************************************************/
 
-NTSTATUS
-FsdGetFsVolumeInformation (PFILE_OBJECT FileObject,
-                          PVFATFCB FCB,
-                          PDEVICE_OBJECT DeviceObject,
-                          PFILE_FS_VOLUME_INFORMATION FsVolumeInfo)
+static NTSTATUS
+FsdGetFsVolumeInformation(PFILE_OBJECT FileObject,
+                         PVFATFCB FCB,
+                         PDEVICE_OBJECT DeviceObject,
+                         PFILE_FS_VOLUME_INFORMATION FsVolumeInfo,
+                         PULONG BufferLength)
 {
-  DPRINT ("FsdGetFsVolumeInformation()\n");
-  DPRINT ("FsVolumeInfo = %p\n", FsVolumeInfo);
-
-  if (!FsVolumeInfo)
-    return (STATUS_SUCCESS);
-
+  ULONG LabelLength;
+  
+  DPRINT("FsdGetFsVolumeInformation()\n");
+  DPRINT("FsVolumeInfo = %p\n", FsVolumeInfo);
+  DPRINT("BufferLength %lu\n", *BufferLength);
+  DPRINT("Required length %lu\n", (sizeof(FILE_FS_VOLUME_INFORMATION) + LabelLength));
+  
+  LabelLength = DeviceObject->Vpb->VolumeLabelLength;
+  DPRINT("LabelLength %lu\n", LabelLength);
+  
+  /* FIXME: This does not work correctly! Why?? */
+//  if (*BufferLength < (sizeof(FILE_FS_VOLUME_INFORMATION) + LabelLength));
+//    return(STATUS_BUFFER_OVERFLOW);
 
   /* valid entries */
   FsVolumeInfo->VolumeSerialNumber = DeviceObject->Vpb->SerialNumber;
-  FsVolumeInfo->VolumeLabelLength = DeviceObject->Vpb->VolumeLabelLength;
-  wcscpy (FsVolumeInfo->VolumeLabel, DeviceObject->Vpb->VolumeLabel);
-
+  FsVolumeInfo->VolumeLabelLength = LabelLength;
+  wcscpy(FsVolumeInfo->VolumeLabel, DeviceObject->Vpb->VolumeLabel);
+  
   /* dummy entries */
   FsVolumeInfo->VolumeCreationTime.QuadPart = 0;
   FsVolumeInfo->SupportsObjects = FALSE;
-
-  DPRINT ("Finished FsdGetFsVolumeInformation()\n");
-
-  return (STATUS_SUCCESS);
+  
+  DPRINT("Finished FsdGetFsVolumeInformation()\n");
+  
+  *BufferLength -= (sizeof(FILE_FS_VOLUME_INFORMATION) + LabelLength);
+  
+  DPRINT("BufferLength %lu\n", *BufferLength);
+  
+  return(STATUS_SUCCESS);
 }
 
 
-NTSTATUS
-FsdGetFsAttributeInformation (PFILE_FS_ATTRIBUTE_INFORMATION FsAttributeInfo)
+static NTSTATUS
+FsdGetFsAttributeInformation(PFILE_FS_ATTRIBUTE_INFORMATION FsAttributeInfo,
+                            PULONG BufferLength)
 {
-  DPRINT ("FsdGetFsAttributeInformation()\n");
-  DPRINT ("FsAttributeInfo = %p\n", FsAttributeInfo);
-
-  if (!FsAttributeInfo)
-    return (STATUS_SUCCESS);
-
-  FsAttributeInfo->FileSystemAttributes = FS_CASE_IS_PRESERVED;
+  DPRINT("FsdGetFsAttributeInformation()\n");
+  DPRINT("FsAttributeInfo = %p\n", FsAttributeInfo);
+  DPRINT("BufferLength %lu\n", *BufferLength);
+  DPRINT("Required length %lu\n", (sizeof(FILE_FS_ATTRIBUTE_INFORMATION) + 6));
+  
+  /* FIXME: This does not work correctly! Why?? */
+//  if (*BufferLength < (sizeof(FILE_FS_ATTRIBUTE_INFORMATION) + 6));
+//    return(STATUS_BUFFER_OVERFLOW);
+  
+  FsAttributeInfo->FileSystemAttributes =
+    FILE_CASE_PRESERVED_NAMES | FILE_UNICODE_ON_DISK;
   FsAttributeInfo->MaximumComponentNameLength = 255;
-  FsAttributeInfo->FileSystemNameLength = 3;
-  wcscpy (FsAttributeInfo->FileSystemName, L"FAT");
-
-  DPRINT ("Finished FsdGetFsAttributeInformation()\n");
-
-  return (STATUS_SUCCESS);
+  FsAttributeInfo->FileSystemNameLength = 6;
+  wcscpy(FsAttributeInfo->FileSystemName, L"FAT");
+  
+  DPRINT("Finished FsdGetFsAttributeInformation()\n");
+  
+  *BufferLength -= (sizeof(FILE_FS_ATTRIBUTE_INFORMATION) + 6);
+  DPRINT("BufferLength %lu\n", *BufferLength);
+  
+  return(STATUS_SUCCESS);
 }
 
-NTSTATUS
-FsdGetFsSizeInformation (PDEVICE_OBJECT DeviceObject,
-                        PFILE_FS_SIZE_INFORMATION FsSizeInfo)
-{
-  PDEVICE_EXTENSION DeviceExt = DeviceObject->DeviceExtension;
-
-  DPRINT ("FsdGetFsSizeInformation()\n");
-  DPRINT ("FsSizeInfo = %p\n", FsSizeInfo);
-
-  if (!FsSizeInfo)
-    return (STATUS_SUCCESS);
 
+static NTSTATUS
+FsdGetFsSizeInformation(PDEVICE_OBJECT DeviceObject,
+                       PFILE_FS_SIZE_INFORMATION FsSizeInfo,
+                       PULONG BufferLength)
+{
+  PDEVICE_EXTENSION DeviceExt;
+  NTSTATUS Status;
+  
+  DPRINT("FsdGetFsSizeInformation()\n");
+  DPRINT("FsSizeInfo = %p\n", FsSizeInfo);
+  
+  /* FIXME: This does not work correctly! Why?? */
+//  if (*BufferLength < sizeof(FILE_FS_SIZE_INFORMATION));
+//    return(STATUS_BUFFER_OVERFLOW);
+  
+  DeviceExt = DeviceObject->DeviceExtension;
+  
   if (DeviceExt->FatType == FAT32)
     {
       struct _BootSector32 *BootSect =
@@ -85,9 +111,8 @@ FsdGetFsSizeInformation (PDEVICE_OBJECT DeviceObject,
 
       FsSizeInfo->TotalAllocationUnits.QuadPart = ((BootSect->Sectors ? BootSect->Sectors : BootSect->SectorsHuge)-DeviceExt->dataStart)/BootSect->SectorsPerCluster;
 
-
-
-      FsSizeInfo->AvailableAllocationUnits.QuadPart = FAT32CountAvailableClusters (DeviceExt);
+      Status = FAT32CountAvailableClusters(DeviceExt,
+                                          &FsSizeInfo->AvailableAllocationUnits);
 
       FsSizeInfo->SectorsPerAllocationUnit = BootSect->SectorsPerCluster;
       FsSizeInfo->BytesPerSector = BootSect->BytesPerSector;
@@ -99,88 +124,187 @@ FsdGetFsSizeInformation (PDEVICE_OBJECT DeviceObject,
       FsSizeInfo->TotalAllocationUnits.QuadPart = ((BootSect->Sectors ? BootSect->Sectors : BootSect->SectorsHuge)-DeviceExt->dataStart)/BootSect->SectorsPerCluster;
 
       if (DeviceExt->FatType == FAT16)
-       FsSizeInfo->AvailableAllocationUnits.QuadPart =
-#if 0
-         FAT16CountAvailableClusters (DeviceExt);
-#else
-0;
-#endif
+       Status = FAT16CountAvailableClusters(DeviceExt,
+                                            &FsSizeInfo->AvailableAllocationUnits);
       else
-       FsSizeInfo->AvailableAllocationUnits.QuadPart =
-         FAT12CountAvailableClusters (DeviceExt);
+       Status = FAT12CountAvailableClusters(DeviceExt,
+                                            &FsSizeInfo->AvailableAllocationUnits);
       FsSizeInfo->SectorsPerAllocationUnit = BootSect->SectorsPerCluster;
       FsSizeInfo->BytesPerSector = BootSect->BytesPerSector;
     }
+  
+  DPRINT("Finished FsdGetFsSizeInformation()\n");
+  if (NT_SUCCESS(Status))
+    *BufferLength -= sizeof(FILE_FS_SIZE_INFORMATION);
+  
+  return(Status);
+}
+
+
+static NTSTATUS
+FsdGetFsDeviceInformation(PFILE_FS_DEVICE_INFORMATION FsDeviceInfo,
+                         PULONG BufferLength)
+{
+  DPRINT("FsdGetFsDeviceInformation()\n");
+  DPRINT("FsDeviceInfo = %p\n", FsDeviceInfo);
+  DPRINT("BufferLength %lu\n", *BufferLength);
+  DPRINT("Required length %lu\n", sizeof(FILE_FS_DEVICE_INFORMATION));
+  
+  /* FIXME: This does not work correctly! Why?? */
+//  if (*BufferLength < sizeof(FILE_FS_DEVICE_INFORMATION));
+//    return(STATUS_BUFFER_OVERFLOW);
+  
+  FsDeviceInfo->DeviceType = FILE_DEVICE_DISK;
+  FsDeviceInfo->Characteristics = 0; /* FIXME: fix this !! */
+  
+  DPRINT("FsdGetFsDeviceInformation() finished.\n");
+  
+  *BufferLength -= sizeof(FILE_FS_DEVICE_INFORMATION);
+  DPRINT("BufferLength %lu\n", *BufferLength);
+  
+  return(STATUS_SUCCESS);
+}
 
-  DPRINT ("Finished FsdGetFsSizeInformation()\n");
 
-  return (STATUS_SUCCESS);
+static NTSTATUS
+FsdSetFsLabelInformation(PDEVICE_OBJECT DeviceObject,
+                        PFILE_FS_LABEL_INFORMATION FsLabelInfo)
+{
+  DPRINT("FsdSetFsLabelInformation()\n");
+  
+  return(STATUS_NOT_IMPLEMENTED);
 }
 
 
 NTSTATUS STDCALL
-VfatQueryVolumeInformation (PDEVICE_OBJECT DeviceObject, PIRP Irp)
+VfatQueryVolumeInformation(PDEVICE_OBJECT DeviceObject,
+                          PIRP Irp)
 /*
- * FUNCTION: Retrieve the specified file information
+ * FUNCTION: Retrieve the specified volume information
  */
 {
-  PIO_STACK_LOCATION Stack = IoGetCurrentIrpStackLocation (Irp);
-  FILE_INFORMATION_CLASS FileInformationClass =
-    Stack->Parameters.QueryVolume.FileInformationClass;
+  PIO_STACK_LOCATION Stack;
+  FS_INFORMATION_CLASS FsInformationClass;
   PFILE_OBJECT FileObject = NULL;
   PVFATFCB FCB = NULL;
-//   PVfatCCB CCB = NULL;
-
   NTSTATUS RC = STATUS_SUCCESS;
-  void *SystemBuffer;
+  PVOID SystemBuffer;
+  ULONG BufferLength;
 
   /* PRECONDITION */
-  assert (DeviceObject != NULL);
-  assert (Irp != NULL);
+  assert(DeviceObject != NULL);
+  assert(Irp != NULL);
 
-  DPRINT ("FsdQueryVolumeInformation(DeviceObject %x, Irp %x)\n",
-         DeviceObject, Irp);
+  DPRINT("FsdQueryVolumeInformation(DeviceObject %x, Irp %x)\n",
+        DeviceObject, Irp);
 
   /* INITIALIZATION */
   Stack = IoGetCurrentIrpStackLocation (Irp);
-  FileInformationClass = Stack->Parameters.QueryVolume.FileInformationClass;
+  FsInformationClass = Stack->Parameters.QueryVolume.FsInformationClass;
+  BufferLength = Stack->Parameters.QueryVolume.Length;
+  SystemBuffer = Irp->AssociatedIrp.SystemBuffer;
   FileObject = Stack->FileObject;
 //   CCB = (PVfatCCB)(FileObject->FsContext2);
 //   FCB = CCB->Buffer; // Should be CCB->FCB???
   FCB = ((PVFATCCB) (FileObject->FsContext2))->pFcb;
 
-  // FIXME : determine Buffer for result :
-  if (Irp->MdlAddress)
-    SystemBuffer = MmGetSystemAddressForMdl (Irp->MdlAddress);
-  else
-    SystemBuffer = Irp->UserBuffer;
-//   SystemBuffer = Irp->AssociatedIrp.SystemBuffer;
-
-  DPRINT ("FileInformationClass %d\n", FileInformationClass);
+  DPRINT ("FsInformationClass %d\n", FsInformationClass);
   DPRINT ("SystemBuffer %x\n", SystemBuffer);
 
-  switch (FileInformationClass)
+  switch (FsInformationClass)
     {
     case FileFsVolumeInformation:
-      RC = FsdGetFsVolumeInformation (FileObject,
-                                     FCB, DeviceObject, SystemBuffer);
+      RC = FsdGetFsVolumeInformation(FileObject,
+                                    FCB,
+                                    DeviceObject,
+                                    SystemBuffer,
+                                    &BufferLength);
       break;
 
     case FileFsAttributeInformation:
-      RC = FsdGetFsAttributeInformation (SystemBuffer);
+      RC = FsdGetFsAttributeInformation(SystemBuffer,
+                                       &BufferLength);
       break;
 
     case FileFsSizeInformation:
-      RC = FsdGetFsSizeInformation (DeviceObject, SystemBuffer);
+      RC = FsdGetFsSizeInformation(DeviceObject,
+                                  SystemBuffer,
+                                  &BufferLength);
+      break;
+
+    case FileFsDeviceInformation:
+      RC = FsdGetFsDeviceInformation(SystemBuffer,
+                                    &BufferLength);
       break;
 
     default:
-      RC = STATUS_NOT_IMPLEMENTED;
+      RC = STATUS_NOT_SUPPORTED;
     }
 
   Irp->IoStatus.Status = RC;
-  Irp->IoStatus.Information = 0;
-  IoCompleteRequest (Irp, IO_NO_INCREMENT);
+  if (NT_SUCCESS(RC))
+    Irp->IoStatus.Information =
+      Stack->Parameters.QueryVolume.Length - BufferLength;
+  else
+    Irp->IoStatus.Information = 0;
+  IoCompleteRequest(Irp,
+                   IO_NO_INCREMENT);
 
   return RC;
 }
+
+
+NTSTATUS STDCALL
+VfatSetVolumeInformation(PDEVICE_OBJECT DeviceObject,
+                        PIRP Irp)
+/*
+ * FUNCTION: Set the specified volume information
+ */
+{
+  PIO_STACK_LOCATION Stack;
+  FS_INFORMATION_CLASS FsInformationClass;
+//  PFILE_OBJECT FileObject = NULL;
+//  PVFATFCB FCB = NULL;
+  NTSTATUS Status = STATUS_SUCCESS;
+  PVOID SystemBuffer;
+  ULONG BufferLength;
+
+  /* PRECONDITION */
+  assert(DeviceObject != NULL);
+  assert(Irp != NULL);
+
+  DPRINT("FsdSetVolumeInformation(DeviceObject %x, Irp %x)\n",
+        DeviceObject,
+        Irp);
+
+  Stack = IoGetCurrentIrpStackLocation(Irp);
+  FsInformationClass = Stack->Parameters.SetVolume.FsInformationClass;
+  BufferLength = Stack->Parameters.SetVolume.Length;
+  SystemBuffer = Irp->AssociatedIrp.SystemBuffer;
+//  FileObject = Stack->FileObject;
+//  FCB = ((PVFATCCB) (FileObject->FsContext2))->pFcb;
+
+  DPRINT("FsInformationClass %d\n", FsInformationClass);
+  DPRINT("BufferLength %d\n", BufferLength);
+  DPRINT("SystemBuffer %x\n", SystemBuffer);
+
+  switch(FsInformationClass)
+    {
+    case FileFsLabelInformation:
+      Status = FsdSetFsLabelInformation(DeviceObject,
+                                       SystemBuffer);
+      break;
+
+    default:
+      Status = STATUS_NOT_SUPPORTED;
+    }
+
+  Irp->IoStatus.Status = Status;
+  Irp->IoStatus.Information = 0;
+  IoCompleteRequest(Irp,
+                   IO_NO_INCREMENT);
+
+  return(Status);
+}
+
+/* EOF */