Reworked code for handling of asynchonous i/o requests.
[reactos.git] / reactos / drivers / fs / vfat / volume.c
index 907b9c2..2044bff 100644 (file)
@@ -1,4 +1,4 @@
-/* $Id: volume.c,v 1.11 2001/07/20 08:00:21 ekohl Exp $
+/* $Id: volume.c,v 1.14 2001/11/02 22:47:36 hbirr Exp $
  *
  * COPYRIGHT:        See COPYING in the top level directory
  * PROJECT:          ReactOS kernel
 /* FUNCTIONS ****************************************************************/
 
 static NTSTATUS
-FsdGetFsVolumeInformation(PFILE_OBJECT FileObject,
-                         PVFATFCB FCB,
-                         PDEVICE_OBJECT DeviceObject,
+FsdGetFsVolumeInformation(PDEVICE_OBJECT DeviceObject,
                          PFILE_FS_VOLUME_INFORMATION FsVolumeInfo,
                          PULONG BufferLength)
 {
   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("Required length %lu\n", (sizeof(FILE_FS_VOLUME_INFORMATION) + LabelLength*sizeof(WCHAR)));
   DPRINT("LabelLength %lu\n", LabelLength);
-  
-  /* FIXME: This does not work correctly! Why?? */
-//  if (*BufferLength < (sizeof(FILE_FS_VOLUME_INFORMATION) + LabelLength));
-//    return(STATUS_BUFFER_OVERFLOW);
+  DPRINT("Label %S\n", DeviceObject->Vpb->VolumeLabel);
+
+  if (*BufferLength < sizeof(FILE_FS_VOLUME_INFORMATION))
+    return STATUS_INFO_LENGTH_MISMATCH;
+
+  if (*BufferLength < (sizeof(FILE_FS_VOLUME_INFORMATION) + LabelLength*sizeof(WCHAR)))
+    return STATUS_BUFFER_OVERFLOW;
 
   /* valid entries */
   FsVolumeInfo->VolumeSerialNumber = DeviceObject->Vpb->SerialNumber;
-  FsVolumeInfo->VolumeLabelLength = LabelLength;
+  FsVolumeInfo->VolumeLabelLength = LabelLength * sizeof (WCHAR);
   wcscpy(FsVolumeInfo->VolumeLabel, DeviceObject->Vpb->VolumeLabel);
-  
+
   /* dummy entries */
   FsVolumeInfo->VolumeCreationTime.QuadPart = 0;
   FsVolumeInfo->SupportsObjects = FALSE;
-  
+
   DPRINT("Finished FsdGetFsVolumeInformation()\n");
-  
-  *BufferLength -= (sizeof(FILE_FS_VOLUME_INFORMATION) + LabelLength);
-  
+
+  *BufferLength -= (sizeof(FILE_FS_VOLUME_INFORMATION) + LabelLength * sizeof(WCHAR));
+
   DPRINT("BufferLength %lu\n", *BufferLength);
-  
+
   return(STATUS_SUCCESS);
 }
 
@@ -67,22 +69,24 @@ FsdGetFsAttributeInformation(PFILE_FS_ATTRIBUTE_INFORMATION FsAttributeInfo,
   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);
-  
+
+  if (*BufferLength < sizeof (FILE_FS_ATTRIBUTE_INFORMATION))
+    return STATUS_INFO_LENGTH_MISMATCH;
+
+  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 = 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);
 }
 
@@ -94,16 +98,15 @@ FsdGetFsSizeInformation(PDEVICE_OBJECT DeviceObject,
 {
   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);
-  
+
+  if (*BufferLength < sizeof(FILE_FS_SIZE_INFORMATION))
+    return(STATUS_BUFFER_OVERFLOW);
+
   DeviceExt = DeviceObject->DeviceExtension;
-  
+
   if (DeviceExt->FatType == FAT32)
     {
       struct _BootSector32 *BootSect =
@@ -132,11 +135,11 @@ FsdGetFsSizeInformation(PDEVICE_OBJECT DeviceObject,
       FsSizeInfo->SectorsPerAllocationUnit = BootSect->SectorsPerCluster;
       FsSizeInfo->BytesPerSector = BootSect->BytesPerSector;
     }
-  
+
   DPRINT("Finished FsdGetFsSizeInformation()\n");
   if (NT_SUCCESS(Status))
     *BufferLength -= sizeof(FILE_FS_SIZE_INFORMATION);
-  
+
   return(Status);
 }
 
@@ -149,19 +152,18 @@ FsdGetFsDeviceInformation(PFILE_FS_DEVICE_INFORMATION FsDeviceInfo,
   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);
-  
+
+  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);
 }
 
@@ -171,42 +173,36 @@ FsdSetFsLabelInformation(PDEVICE_OBJECT DeviceObject,
                         PFILE_FS_LABEL_INFORMATION FsLabelInfo)
 {
   DPRINT("FsdSetFsLabelInformation()\n");
-  
+
   return(STATUS_NOT_IMPLEMENTED);
 }
 
 
-NTSTATUS STDCALL
-VfatQueryVolumeInformation(PDEVICE_OBJECT DeviceObject,
-                          PIRP Irp)
+NTSTATUS VfatQueryVolumeInformation(PVFAT_IRP_CONTEXT IrpContext)
 /*
  * FUNCTION: Retrieve the specified volume information
  */
 {
-  PIO_STACK_LOCATION Stack;
   FS_INFORMATION_CLASS FsInformationClass;
-  PFILE_OBJECT FileObject = NULL;
-  PVFATFCB FCB = NULL;
   NTSTATUS RC = STATUS_SUCCESS;
   PVOID SystemBuffer;
   ULONG BufferLength;
 
   /* PRECONDITION */
-  assert(DeviceObject != NULL);
-  assert(Irp != NULL);
+  assert(IrpContext);
 
-  DPRINT("FsdQueryVolumeInformation(DeviceObject %x, Irp %x)\n",
-        DeviceObject, Irp);
+  DPRINT("VfatQueryVolumeInformation(IrpContext %x)\n", IrpContext);
+
+  if (!ExAcquireResourceSharedLite(&((PDEVICE_EXTENSION)IrpContext->DeviceObject->DeviceExtension)->DirResource, IrpContext->Flags & IRPCONTEXT_CANWAIT))
+  {
+     return VfatQueueRequest (IrpContext);
+  }
 
   /* INITIALIZATION */
-  Stack = IoGetCurrentIrpStackLocation (Irp);
-  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;
+  FsInformationClass = IrpContext->Stack->Parameters.QueryVolume.FsInformationClass;
+  BufferLength = IrpContext->Stack->Parameters.QueryVolume.Length;
+  SystemBuffer = IrpContext->Irp->AssociatedIrp.SystemBuffer;
+
 
   DPRINT ("FsInformationClass %d\n", FsInformationClass);
   DPRINT ("SystemBuffer %x\n", SystemBuffer);
@@ -214,9 +210,7 @@ VfatQueryVolumeInformation(PDEVICE_OBJECT DeviceObject,
   switch (FsInformationClass)
     {
     case FileFsVolumeInformation:
-      RC = FsdGetFsVolumeInformation(FileObject,
-                                    FCB,
-                                    DeviceObject,
+      RC = FsdGetFsVolumeInformation(IrpContext->DeviceObject,
                                     SystemBuffer,
                                     &BufferLength);
       break;
@@ -227,7 +221,7 @@ VfatQueryVolumeInformation(PDEVICE_OBJECT DeviceObject,
       break;
 
     case FileFsSizeInformation:
-      RC = FsdGetFsSizeInformation(DeviceObject,
+      RC = FsdGetFsSizeInformation(IrpContext->DeviceObject,
                                   SystemBuffer,
                                   &BufferLength);
       break;
@@ -241,57 +235,52 @@ VfatQueryVolumeInformation(PDEVICE_OBJECT DeviceObject,
       RC = STATUS_NOT_SUPPORTED;
     }
 
-  Irp->IoStatus.Status = RC;
+  ExReleaseResourceLite(&((PDEVICE_EXTENSION)IrpContext->DeviceObject->DeviceExtension)->DirResource);
+  IrpContext->Irp->IoStatus.Status = RC;
   if (NT_SUCCESS(RC))
-    Irp->IoStatus.Information =
-      Stack->Parameters.QueryVolume.Length - BufferLength;
+    IrpContext->Irp->IoStatus.Information =
+      IrpContext->Stack->Parameters.QueryVolume.Length - BufferLength;
   else
-    Irp->IoStatus.Information = 0;
-  IoCompleteRequest(Irp,
-                   IO_NO_INCREMENT);
+    IrpContext->Irp->IoStatus.Information = 0;
+  IoCompleteRequest(IrpContext->Irp, IO_NO_INCREMENT);
+  VfatFreeIrpContext(IrpContext);
 
   return RC;
 }
 
 
-NTSTATUS STDCALL
-VfatSetVolumeInformation(PDEVICE_OBJECT DeviceObject,
-                        PIRP Irp)
+NTSTATUS VfatSetVolumeInformation(PVFAT_IRP_CONTEXT IrpContext)
 /*
  * 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);
+  assert(IrpContext);
+
+  DPRINT1("VfatSetVolumeInformation(IrpContext %x)\n", IrpContext);
 
-  DPRINT("FsdSetVolumeInformation(DeviceObject %x, Irp %x)\n",
-        DeviceObject,
-        Irp);
+  if (!ExAcquireResourceExclusiveLite(&((PDEVICE_EXTENSION)IrpContext->DeviceObject->DeviceExtension)->DirResource, IrpContext->Flags & IRPCONTEXT_CANWAIT))
+  {
+     return VfatQueueRequest (IrpContext);
+  }
 
-  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;
+  FsInformationClass = IrpContext->Stack->Parameters.SetVolume.FsInformationClass;
+  BufferLength = IrpContext->Stack->Parameters.SetVolume.Length;
+  SystemBuffer = IrpContext->Irp->AssociatedIrp.SystemBuffer;
 
-  DPRINT("FsInformationClass %d\n", FsInformationClass);
-  DPRINT("BufferLength %d\n", BufferLength);
-  DPRINT("SystemBuffer %x\n", SystemBuffer);
+  DPRINT1("FsInformationClass %d\n", FsInformationClass);
+  DPRINT1("BufferLength %d\n", BufferLength);
+  DPRINT1("SystemBuffer %x\n", SystemBuffer);
 
   switch(FsInformationClass)
     {
     case FileFsLabelInformation:
-      Status = FsdSetFsLabelInformation(DeviceObject,
+      Status = FsdSetFsLabelInformation(IrpContext->DeviceObject,
                                        SystemBuffer);
       break;
 
@@ -299,10 +288,11 @@ VfatSetVolumeInformation(PDEVICE_OBJECT DeviceObject,
       Status = STATUS_NOT_SUPPORTED;
     }
 
-  Irp->IoStatus.Status = Status;
-  Irp->IoStatus.Information = 0;
-  IoCompleteRequest(Irp,
-                   IO_NO_INCREMENT);
+  ExReleaseResourceLite(&((PDEVICE_EXTENSION)IrpContext->DeviceObject->DeviceExtension)->DirResource);
+  IrpContext->Irp->IoStatus.Status = Status;
+  IrpContext->Irp->IoStatus.Information = 0;
+  IoCompleteRequest(IrpContext->Irp, IO_NO_INCREMENT);
+  VfatFreeIrpContext(IrpContext);
 
   return(Status);
 }