Reworked code for handling of asynchonous i/o requests.
authorHartmut Birr <osexpert@googlemail.com>
Fri, 2 Nov 2001 22:47:36 +0000 (22:47 +0000)
committerHartmut Birr <osexpert@googlemail.com>
Fri, 2 Nov 2001 22:47:36 +0000 (22:47 +0000)
svn path=/trunk/; revision=2346

reactos/drivers/fs/vfat/cleanup.c
reactos/drivers/fs/vfat/close.c
reactos/drivers/fs/vfat/create.c
reactos/drivers/fs/vfat/dir.c
reactos/drivers/fs/vfat/finfo.c
reactos/drivers/fs/vfat/iface.c
reactos/drivers/fs/vfat/makefile
reactos/drivers/fs/vfat/misc.c [new file with mode: 0644]
reactos/drivers/fs/vfat/rw.c
reactos/drivers/fs/vfat/volume.c

index edbf757..576129b 100644 (file)
@@ -1,4 +1,4 @@
-/* $Id: cleanup.c,v 1.2 2001/03/08 22:06:02 dwelch Exp $
+/* $Id: cleanup.c,v 1.3 2001/11/02 22:44:34 hbirr Exp $
  *
  * COPYRIGHT:        See COPYING in the top level directory
  * PROJECT:          ReactOS kernel
@@ -26,32 +26,36 @@ VfatCleanupFile(PDEVICE_EXTENSION DeviceExt,
  */
 {
    DPRINT("VfatCleanupFile(DeviceExt %x, FileObject %x)\n",
-         DeviceExt, FileObject);
+        DeviceExt, FileObject);
 
    /* FIXME: handle file/directory deletion here */
 
-   return STATUS_SUCCESS;
+  return STATUS_SUCCESS;
 }
 
-NTSTATUS STDCALL
-VfatCleanup (PDEVICE_OBJECT DeviceObject, PIRP Irp)
+NTSTATUS VfatCleanup (PVFAT_IRP_CONTEXT IrpContext)
 /*
  * FUNCTION: Cleans up after a file has been closed.
  */
 {
-   PIO_STACK_LOCATION Stack = IoGetCurrentIrpStackLocation (Irp);
-   PFILE_OBJECT FileObject = Stack->FileObject;
-   PDEVICE_EXTENSION DeviceExtension = DeviceObject->DeviceExtension;
    NTSTATUS Status;
 
    DPRINT("VfatCleanup(DeviceObject %x, Irp %x)\n", DeviceObject, Irp);
 
-   Status = VfatCleanupFile(DeviceExtension, FileObject);
+   if (!ExAcquireResourceExclusiveLite (&IrpContext->DeviceExt->DirResource, IrpContext->Flags & IRPCONTEXT_CANWAIT))
+   {
+     return VfatQueueRequest (IrpContext);
+   }
 
-   Irp->IoStatus.Status = Status;
-   Irp->IoStatus.Information = 0;
+   Status = VfatCleanupFile(IrpContext->DeviceExt, IrpContext->FileObject);
 
-   IoCompleteRequest (Irp, IO_NO_INCREMENT);
+   ExReleaseResourceLite (&IrpContext->DeviceExt->DirResource);
+
+   IrpContext->Irp->IoStatus.Status = Status;
+   IrpContext->Irp->IoStatus.Information = 0;
+
+   IoCompleteRequest (IrpContext->Irp, IO_NO_INCREMENT);
+   VfatFreeIrpContext(IrpContext);
    return (Status);
 }
 
index 79defef..ca295be 100644 (file)
@@ -1,4 +1,4 @@
-/* $Id: close.c,v 1.8 2001/08/14 20:47:30 hbirr Exp $
+/* $Id: close.c,v 1.9 2001/11/02 22:44:34 hbirr Exp $
  *
  * COPYRIGHT:        See COPYING in the top level directory
  * PROJECT:          ReactOS kernel
@@ -65,27 +65,28 @@ VfatCloseFile (PDEVICE_EXTENSION DeviceExt, PFILE_OBJECT FileObject)
   return  Status;
 }
 
-NTSTATUS STDCALL
-VfatClose (PDEVICE_OBJECT DeviceObject, PIRP Irp)
+NTSTATUS VfatClose (PVFAT_IRP_CONTEXT IrpContext)
 /*
  * FUNCTION: Closes a file
  */
 {
-  PIO_STACK_LOCATION Stack = IoGetCurrentIrpStackLocation (Irp);
-  PFILE_OBJECT FileObject = Stack->FileObject;
-  PDEVICE_EXTENSION DeviceExtension = DeviceObject->DeviceExtension;
   NTSTATUS Status;
 
   DPRINT ("VfatClose(DeviceObject %x, Irp %x)\n", DeviceObject, Irp);
 
-  ExAcquireResourceExclusiveLite (&DeviceExtension->DirResource, TRUE);
-  Status = VfatCloseFile (DeviceExtension, FileObject);
-  ExReleaseResourceLite (&DeviceExtension->DirResource);
+  if (!ExAcquireResourceExclusiveLite (&IrpContext->DeviceExt->DirResource, IrpContext->Flags & IRPCONTEXT_CANWAIT))
+  {
+     return VfatQueueRequest (IrpContext);
+  }
+
+  Status = VfatCloseFile (IrpContext->DeviceExt, IrpContext->FileObject);
+  ExReleaseResourceLite (&IrpContext->DeviceExt->DirResource);
 
-  Irp->IoStatus.Status = Status;
-  Irp->IoStatus.Information = 0;
+  IrpContext->Irp->IoStatus.Status = Status;
+  IrpContext->Irp->IoStatus.Information = 0;
+  IoCompleteRequest (IrpContext->Irp, IO_NO_INCREMENT);
+  VfatFreeIrpContext(IrpContext);
 
-  IoCompleteRequest (Irp, IO_NO_INCREMENT);
   return (Status);
 }
 
index 55b8b8e..8ca6b0e 100644 (file)
@@ -1,4 +1,4 @@
-/* $Id: create.c,v 1.33 2001/10/10 22:12:34 hbirr Exp $
+/* $Id: create.c,v 1.34 2001/11/02 22:44:34 hbirr Exp $
  *
  * COPYRIGHT:        See COPYING in the top level directory
  * PROJECT:          ReactOS kernel
@@ -83,7 +83,7 @@ static void  vfat8Dot3ToVolumeLabel (PCHAR pBasename, PCHAR pExtension, PWSTR pN
 {
   int  fromIndex, toIndex;
 
-  fromIndex = toIndex = 0; 
+  fromIndex = toIndex = 0;
   while (fromIndex < 8 && pBasename [fromIndex] != ' ')
   {
     pName [toIndex++] = pBasename [fromIndex++];
@@ -667,32 +667,32 @@ VfatCreateFile (PDEVICE_OBJECT DeviceObject, PIRP Irp)
      * same name
      */
     if (RequestedDisposition == FILE_SUPERSEDE)
-       {
-         ULONG Cluster, NextCluster;
-         /* FIXME set size to 0 and free clusters */
-         pFcb->entry.FileSize = 0;
-         if (DeviceExt->FatType == FAT32)
+    {
+       ULONG Cluster, NextCluster;
+       /* FIXME set size to 0 and free clusters */
+       pFcb->entry.FileSize = 0;
+       if (DeviceExt->FatType == FAT32)
            Cluster = pFcb->entry.FirstCluster
              + pFcb->entry.FirstClusterHigh * 65536;
-         else
-           Cluster = pFcb->entry.FirstCluster;
-         pFcb->entry.FirstCluster = 0;
-         pFcb->entry.FirstClusterHigh = 0;
-         updEntry (DeviceExt, FileObject);
-         if ((ULONG)pFcb->RFCB.FileSize.QuadPart > 0)
-         {
-           pFcb->RFCB.AllocationSize.QuadPart = 0;
-           pFcb->RFCB.FileSize.QuadPart = 0;
-           pFcb->RFCB.ValidDataLength.QuadPart = 0;
-           CcSetFileSizes(FileObject, (PCC_FILE_SIZES)&pFcb->RFCB.AllocationSize);
-         }
-         while (Cluster != 0xffffffff && Cluster > 1)
-         {
-           Status = GetNextCluster (DeviceExt, Cluster, &NextCluster, FALSE);
-           WriteCluster (DeviceExt, Cluster, 0);
-           Cluster = NextCluster;
-         }
-       }
+       else
+         Cluster = pFcb->entry.FirstCluster;
+       pFcb->entry.FirstCluster = 0;
+       pFcb->entry.FirstClusterHigh = 0;
+       updEntry (DeviceExt, FileObject);
+       if ((ULONG)pFcb->RFCB.FileSize.QuadPart > 0)
+       {
+         pFcb->RFCB.AllocationSize.QuadPart = 0;
+        pFcb->RFCB.FileSize.QuadPart = 0;
+        pFcb->RFCB.ValidDataLength.QuadPart = 0;
+        CcSetFileSizes(FileObject, (PCC_FILE_SIZES)&pFcb->RFCB.AllocationSize);
+       }
+       while (Cluster != 0xffffffff && Cluster > 1)
+       {
+        Status = GetNextCluster (DeviceExt, Cluster, &NextCluster, FALSE);
+        WriteCluster (DeviceExt, Cluster, 0);
+        Cluster = NextCluster;
+       }
+    }
 
     /*
      * Check the file has the requested attributes
@@ -707,7 +707,7 @@ VfatCreateFile (PDEVICE_OBJECT DeviceObject, PIRP Irp)
        {
          Status = STATUS_NOT_A_DIRECTORY;
        }
-      /* FIXME : test share access */
+    /* FIXME : test share access */
       /* FIXME : test write access if requested */
     if (!NT_SUCCESS (Status))
          VfatCloseFile (DeviceExt, FileObject);
@@ -722,39 +722,37 @@ VfatCreateFile (PDEVICE_OBJECT DeviceObject, PIRP Irp)
 }
 
 
-NTSTATUS STDCALL
-VfatCreate (PDEVICE_OBJECT DeviceObject, PIRP Irp)
+NTSTATUS VfatCreate (PVFAT_IRP_CONTEXT IrpContext)
 /*
  * FUNCTION: Create or open a file
  */
 {
-  NTSTATUS Status = STATUS_SUCCESS;
-  PDEVICE_EXTENSION DeviceExt;
+  NTSTATUS Status;
 
-  assert (DeviceObject);
-  assert (Irp);
+  assert (IrpContext);
 
-  if (DeviceObject->Size == sizeof (DEVICE_OBJECT))
-    {
-      /* DeviceObject represents FileSystem instead of logical volume */
-      DbgPrint ("FsdCreate called with file system\n");
-      Irp->IoStatus.Status = Status;
-      Irp->IoStatus.Information = FILE_OPENED;
-      IoCompleteRequest (Irp, IO_NO_INCREMENT);
-      return (Status);
-    }
-
-  DeviceExt = DeviceObject->DeviceExtension;
-  assert (DeviceExt);
-  ExAcquireResourceExclusiveLite (&DeviceExt->DirResource, TRUE);
-
-  Status = VfatCreateFile (DeviceObject, Irp);
+  if (IrpContext->DeviceObject->Size == sizeof (DEVICE_OBJECT))
+  {
+     /* DeviceObject represents FileSystem instead of logical volume */
+     DbgPrint ("FsdCreate called with file system\n");
+     IrpContext->Irp->IoStatus.Information = FILE_OPENED;
+     Status = STATUS_SUCCESS;
+     goto ByeBye;
+  }
 
-  ExReleaseResourceLite (&DeviceExt->DirResource);
+  if (!(IrpContext->Flags & IRPCONTEXT_CANWAIT))
+  {
+     return VfatQueueRequest (IrpContext);
+  }
 
-  Irp->IoStatus.Status = Status;
-  IoCompleteRequest (Irp, IO_NO_INCREMENT);
+  ExAcquireResourceExclusiveLite (&IrpContext->DeviceExt->DirResource, TRUE);
+  Status = VfatCreateFile (IrpContext->DeviceObject, IrpContext->Irp);
+  ExReleaseResourceLite (&IrpContext->DeviceExt->DirResource);
 
+ByeBye:
+  IrpContext->Irp->IoStatus.Status = Status;
+  IoCompleteRequest (IrpContext->Irp, NT_SUCCESS(Status) ? IO_DISK_INCREMENT : IO_NO_INCREMENT);
+  VfatFreeIrpContext(IrpContext);
   return Status;
 }
 
index 91cd912..7dc3f39 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * $Id: dir.c,v 1.20 2001/10/10 22:13:26 hbirr Exp $
+ * $Id: dir.c,v 1.21 2001/11/02 22:44:34 hbirr Exp $
  *
  * COPYRIGHT:        See COPYING in the top level directory
  * PROJECT:          ReactOS kernel
@@ -225,8 +225,7 @@ VfatGetFileBothInformation (PVFATFCB pFcb,
   return STATUS_SUCCESS;
 }
 
-NTSTATUS
-DoQuery (PDEVICE_OBJECT DeviceObject, PIRP Irp, PIO_STACK_LOCATION Stack)
+NTSTATUS DoQuery (PVFAT_IRP_CONTEXT IrpContext)
 {
   NTSTATUS RC = STATUS_SUCCESS;
   long BufferLength = 0;
@@ -235,32 +234,35 @@ DoQuery (PDEVICE_OBJECT DeviceObject, PIRP Irp, PIO_STACK_LOCATION Stack)
   unsigned long FileIndex = 0;
   unsigned char *Buffer = NULL;
   PFILE_NAMES_INFORMATION Buffer0 = NULL;
-  PFILE_OBJECT pFileObject = NULL;
   PVFATFCB pFcb;
   VFATFCB tmpFcb;
   PVFATCCB pCcb;
-  PDEVICE_EXTENSION DeviceExt;
   WCHAR star[5], *pCharPattern;
   unsigned long OldEntry, OldSector;
-  DeviceExt = DeviceObject->DeviceExtension;
+
+  pCcb = (PVFATCCB) IrpContext->FileObject->FsContext2;
+  pFcb = pCcb->pFcb;
+
+  if (!ExAcquireResourceSharedLite(&pFcb->MainResource, IrpContext->Flags & IRPCONTEXT_CANWAIT))
+  {
+     return STATUS_PENDING;
+  }
+
   // Obtain the callers parameters
-  BufferLength = Stack->Parameters.QueryDirectory.Length;
-  pSearchPattern = Stack->Parameters.QueryDirectory.FileName;
+  BufferLength = IrpContext->Stack->Parameters.QueryDirectory.Length;
+  pSearchPattern = IrpContext->Stack->Parameters.QueryDirectory.FileName;
   FileInformationClass =
-    Stack->Parameters.QueryDirectory.FileInformationClass;
-  FileIndex = Stack->Parameters.QueryDirectory.FileIndex;
-  pFileObject = Stack->FileObject;
-  pCcb = (PVFATCCB) pFileObject->FsContext2;
-  pFcb = pCcb->pFcb;
-  if (Stack->Flags & SL_RESTART_SCAN)
+    IrpContext->Stack->Parameters.QueryDirectory.FileInformationClass;
+  FileIndex = IrpContext->Stack->Parameters.QueryDirectory.FileIndex;
+  if (IrpContext->Stack->Flags & SL_RESTART_SCAN)
     {                          //FIXME : what is really use of RestartScan ?
       pCcb->StartEntry = pCcb->StartSector = 0;
     }
   // determine Buffer for result :
-  if (Irp->MdlAddress)
-    Buffer = MmGetSystemAddressForMdl (Irp->MdlAddress);
+  if (IrpContext->Irp->MdlAddress)
+    Buffer = MmGetSystemAddressForMdl (IrpContext->Irp->MdlAddress);
   else
-    Buffer = Irp->UserBuffer;
+    Buffer = IrpContext->Irp->UserBuffer;
   DPRINT ("Buffer=%x tofind=%S\n", Buffer, pSearchPattern->Buffer);
   if (pSearchPattern == NULL)
     {
@@ -278,7 +280,7 @@ DoQuery (PDEVICE_OBJECT DeviceObject, PIRP Irp, PIO_STACK_LOCATION Stack)
       if (OldSector)
        pCcb->StartEntry++;
       RC =
-       FindFile (DeviceExt, &tmpFcb, pFcb, pCharPattern, &pCcb->StartEntry, NULL);
+       FindFile (IrpContext->DeviceExt, &tmpFcb, pFcb, pCharPattern, &pCcb->StartEntry, NULL);
     pCcb->StartSector = 1;
       DPRINT ("Found %S,RC=%x, sector %x entry %x\n", tmpFcb.ObjectName, RC,
              pCcb->StartSector, pCcb->StartEntry);
@@ -294,19 +296,19 @@ DoQuery (PDEVICE_OBJECT DeviceObject, PIRP Irp, PIO_STACK_LOCATION Stack)
              break;
            case FileDirectoryInformation:
              RC =
-               VfatGetFileDirectoryInformation (&tmpFcb, DeviceExt,
+               VfatGetFileDirectoryInformation (&tmpFcb, IrpContext->DeviceExt,
                                                (PFILE_DIRECTORY_INFORMATION)
                                                Buffer, BufferLength);
              break;
            case FileFullDirectoryInformation:
              RC =
-               VfatGetFileFullDirectoryInformation (&tmpFcb, DeviceExt,
+               VfatGetFileFullDirectoryInformation (&tmpFcb, IrpContext->DeviceExt,
                                                    (PFILE_FULL_DIRECTORY_INFORMATION)
                                                    Buffer, BufferLength);
              break;
            case FileBothDirectoryInformation:
              RC =
-               VfatGetFileBothInformation (&tmpFcb, DeviceExt,
+               VfatGetFileBothInformation (&tmpFcb, IrpContext->DeviceExt,
                                           (PFILE_BOTH_DIRECTORY_INFORMATION)
                                           Buffer, BufferLength);
              break;
@@ -330,7 +332,7 @@ DoQuery (PDEVICE_OBJECT DeviceObject, PIRP Irp, PIO_STACK_LOCATION Stack)
        }
       Buffer0 = (PFILE_NAMES_INFORMATION) Buffer;
       Buffer0->FileIndex = FileIndex++;
-      if (Stack->Flags & SL_RETURN_SINGLE_ENTRY)
+      if (IrpContext->Stack->Flags & SL_RETURN_SINGLE_ENTRY)
        break;
       BufferLength -= Buffer0->NextEntryOffset;
       Buffer += Buffer0->NextEntryOffset;
@@ -338,27 +340,28 @@ DoQuery (PDEVICE_OBJECT DeviceObject, PIRP Irp, PIO_STACK_LOCATION Stack)
   if (Buffer0)
     Buffer0->NextEntryOffset = 0;
   if (FileIndex > 0)
-    return STATUS_SUCCESS;
+    RC = STATUS_SUCCESS;
+
+  if (IrpContext->Flags & IRPCONTEXT_CANWAIT)
+  {
+     ExReleaseResourceLite(&pFcb->MainResource);
+  }
+
   return RC;
 }
 
 
-NTSTATUS STDCALL
-VfatDirectoryControl (PDEVICE_OBJECT DeviceObject, PIRP Irp)
+NTSTATUS VfatDirectoryControl (PVFAT_IRP_CONTEXT IrpContext)
 /*
  * FUNCTION: directory control : read/write directory informations
  */
 {
   NTSTATUS RC = STATUS_SUCCESS;
-  PFILE_OBJECT FileObject = NULL;
-  PIO_STACK_LOCATION Stack;
-  Stack = IoGetCurrentIrpStackLocation (Irp);
   CHECKPOINT;
-  FileObject = Stack->FileObject;
-  switch (Stack->MinorFunction)
+  switch (IrpContext->MinorFunction)
     {
     case IRP_MN_QUERY_DIRECTORY:
-      RC = DoQuery (DeviceObject, Irp, Stack);
+      RC = DoQuery (IrpContext);
       break;
     case IRP_MN_NOTIFY_CHANGE_DIRECTORY:
       DPRINT (" vfat, dir : change\n");
@@ -367,14 +370,21 @@ VfatDirectoryControl (PDEVICE_OBJECT DeviceObject, PIRP Irp)
     default:
       // error
       DbgPrint ("unexpected minor function %x in VFAT driver\n",
-               Stack->MinorFunction);
+               IrpContext->MinorFunction);
       RC = STATUS_INVALID_DEVICE_REQUEST;
       break;
     }
-  Irp->IoStatus.Status = RC;
-  Irp->IoStatus.Information = 0;
-
-  IoCompleteRequest (Irp, IO_NO_INCREMENT);
+  if (RC == STATUS_PENDING)
+  {
+     RC = VfatQueueRequest(IrpContext);
+  }
+  else
+  {
+    IrpContext->Irp->IoStatus.Status = RC;
+    IrpContext->Irp->IoStatus.Information = 0;
+    IoCompleteRequest (IrpContext->Irp, IO_NO_INCREMENT);
+    VfatFreeIrpContext(IrpContext);
+  }
   return RC;
 }
 
index 739ec30..cb4c67b 100644 (file)
@@ -1,4 +1,4 @@
-/* $Id: finfo.c,v 1.10 2001/11/01 10:44:11 hbirr Exp $
+/* $Id: finfo.c,v 1.11 2001/11/02 22:47:36 hbirr Exp $
  *
  * COPYRIGHT:        See COPYING in the top level directory
  * PROJECT:          ReactOS kernel
@@ -224,8 +224,8 @@ VfatGetNameInformation(PFILE_OBJECT FileObject,
 
 static NTSTATUS
 VfatGetInternalInformation(PVFATFCB Fcb,
-                           PFILE_INTERNAL_INFORMATION InternalInfo,
-                           PULONG BufferLength)
+                          PFILE_INTERNAL_INFORMATION InternalInfo,
+                          PULONG BufferLength)
 {
   assert (InternalInfo);
   assert (Fcb);
@@ -238,71 +238,72 @@ VfatGetInternalInformation(PVFATFCB Fcb,
   return STATUS_SUCCESS;
 }
 
-NTSTATUS STDCALL
-VfatQueryInformation(PDEVICE_OBJECT DeviceObject,
-                    PIRP Irp)
+
+
+NTSTATUS VfatQueryInformation(PVFAT_IRP_CONTEXT IrpContext)
 /*
  * FUNCTION: Retrieve the specified file information
  */
 {
-  PIO_STACK_LOCATION Stack;
   FILE_INFORMATION_CLASS FileInformationClass;
-  PFILE_OBJECT FileObject = NULL;
   PVFATFCB FCB = NULL;
-//   PVFATCCB CCB = NULL;
 
   NTSTATUS RC = STATUS_SUCCESS;
   PVOID SystemBuffer;
   ULONG BufferLength;
 
   /* PRECONDITION */
-  assert (DeviceObject != NULL);
-  assert (Irp != NULL);
+  assert (IrpContext);
 
   /* INITIALIZATION */
-  Stack = IoGetCurrentIrpStackLocation (Irp);
-  FileInformationClass = Stack->Parameters.QueryFile.FileInformationClass;
-  FileObject = Stack->FileObject;
-//   CCB = (PVFATCCB)(FileObject->FsContext2);
-//   FCB = CCB->Buffer; // Should be CCB->FCB???
-  FCB = ((PVFATCCB) (FileObject->FsContext2))->pFcb;
+  FileInformationClass = IrpContext->Stack->Parameters.QueryFile.FileInformationClass;
+  FCB = ((PVFATCCB) IrpContext->FileObject->FsContext2)->pFcb;
+
+  SystemBuffer = IrpContext->Irp->AssociatedIrp.SystemBuffer;
+  BufferLength = IrpContext->Stack->Parameters.QueryFile.Length;
+
+  if (!(FCB->Flags & FCB_IS_PAGE_FILE))
+  {
+     if (!ExAcquireResourceSharedLite(&FCB->MainResource, IrpContext->Flags & IRPCONTEXT_CANWAIT))
+     {
+        return VfatQueueRequest (IrpContext);
+     }
+  }
 
-  SystemBuffer = Irp->AssociatedIrp.SystemBuffer;
-  BufferLength = Stack->Parameters.QueryFile.Length;
 
   switch (FileInformationClass)
     {
     case FileStandardInformation:
       RC = VfatGetStandardInformation(FCB,
-                                     DeviceObject,
+                                     IrpContext->DeviceObject,
                                      SystemBuffer,
                                      &BufferLength);
       break;
     case FilePositionInformation:
-      RC = VfatGetPositionInformation(FileObject,
+      RC = VfatGetPositionInformation(IrpContext->FileObject,
                                      FCB,
-                                     DeviceObject,
+                                     IrpContext->DeviceObject,
                                      SystemBuffer,
                                      &BufferLength);
       break;
     case FileBasicInformation:
-      RC = VfatGetBasicInformation(FileObject,
+      RC = VfatGetBasicInformation(IrpContext->FileObject,
                                   FCB,
-                                  DeviceObject,
+                                  IrpContext->DeviceObject,
                                   SystemBuffer,
                                   &BufferLength);
       break;
     case FileNameInformation:
-      RC = VfatGetNameInformation(FileObject,
+      RC = VfatGetNameInformation(IrpContext->FileObject,
                                  FCB,
-                                 DeviceObject,
+                                 IrpContext->DeviceObject,
                                  SystemBuffer,
                                  &BufferLength);
       break;
     case FileInternalInformation:
       RC = VfatGetInternalInformation(FCB,
-                                      SystemBuffer,
-                                      &BufferLength);
+                                     SystemBuffer,
+                                     &BufferLength);
       break;
     case FileAlternateNameInformation:
     case FileAllInformation:
@@ -312,61 +313,72 @@ VfatQueryInformation(PDEVICE_OBJECT DeviceObject,
       RC = STATUS_NOT_SUPPORTED;
     }
 
-  Irp->IoStatus.Status = RC;
+  if (!(FCB->Flags & FCB_IS_PAGE_FILE))
+  {
+     ExReleaseResourceLite(&FCB->MainResource);
+  }
+  IrpContext->Irp->IoStatus.Status = RC;
   if (NT_SUCCESS(RC))
-    Irp->IoStatus.Information =
-      Stack->Parameters.QueryFile.Length - BufferLength;
+    IrpContext->Irp->IoStatus.Information =
+      IrpContext->Stack->Parameters.QueryFile.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
-VfatSetInformation(PDEVICE_OBJECT DeviceObject,
-                  PIRP Irp)
+NTSTATUS VfatSetInformation(PVFAT_IRP_CONTEXT IrpContext)
 /*
  * FUNCTION: Retrieve the specified file information
  */
 {
-  PIO_STACK_LOCATION Stack;
   FILE_INFORMATION_CLASS FileInformationClass;
-  PFILE_OBJECT FileObject = NULL;
   PVFATFCB FCB = NULL;
-//   PVFATCCB CCB = NULL;
   NTSTATUS RC = STATUS_SUCCESS;
   PVOID SystemBuffer;
 
   /* PRECONDITION */
-  assert(DeviceObject != NULL);
-  assert(Irp != NULL);
+  assert(IrpContext);
 
-  DPRINT("VfatSetInformation(DeviceObject %x, Irp %x)\n", DeviceObject, Irp);
+  DPRINT("VfatSetInformation(IrpContext %x)\n", IrpContext);
 
   /* INITIALIZATION */
-  Stack = IoGetCurrentIrpStackLocation (Irp);
-  FileInformationClass = Stack->Parameters.SetFile.FileInformationClass;
-  FileObject = Stack->FileObject;
-  FCB = ((PVFATCCB) (FileObject->FsContext2))->pFcb;
-  SystemBuffer = Irp->AssociatedIrp.SystemBuffer;
+  FileInformationClass = IrpContext->Stack->Parameters.SetFile.FileInformationClass;
+  FCB = ((PVFATCCB) IrpContext->FileObject->FsContext2)->pFcb;
+  SystemBuffer = IrpContext->Irp->AssociatedIrp.SystemBuffer;
 
   DPRINT("FileInformationClass %d\n", FileInformationClass);
   DPRINT("SystemBuffer %x\n", SystemBuffer);
 
+  if (FCB->Flags & FCB_IS_PAGE_FILE)
+  {
+     if (!ExAcquireResourceExclusiveLite(&FCB->PagingIoResource, IrpContext->Flags & IRPCONTEXT_CANWAIT))
+     {
+        return VfatQueueRequest (IrpContext);
+     }
+  }
+  else
+  {
+     if (!ExAcquireResourceExclusiveLite(&FCB->MainResource, IrpContext->Flags & IRPCONTEXT_CANWAIT))
+     {
+        return VfatQueueRequest (IrpContext);
+     }
+  }
+
   switch (FileInformationClass)
     {
     case FilePositionInformation:
-      RC = VfatSetPositionInformation(FileObject,
+      RC = VfatSetPositionInformation(IrpContext->FileObject,
                                      FCB,
-                                     DeviceObject,
+                                     IrpContext->DeviceObject,
                                      SystemBuffer);
       break;
     case FileDispositionInformation:
-      RC = VfatSetDispositionInformation(FileObject,
+      RC = VfatSetDispositionInformation(IrpContext->FileObject,
                                         FCB,
-                                        DeviceObject,
+                                        IrpContext->DeviceObject,
                                         SystemBuffer);
       break;
     case FileBasicInformation:
@@ -379,10 +391,19 @@ VfatSetInformation(PDEVICE_OBJECT DeviceObject,
       RC = STATUS_NOT_SUPPORTED;
     }
 
-  Irp->IoStatus.Status = RC;
-  Irp->IoStatus.Information = 0;
-  IoCompleteRequest(Irp,
-                   IO_NO_INCREMENT);
+  if (FCB->Flags & FCB_IS_PAGE_FILE)
+  {
+     ExReleaseResourceLite(&FCB->PagingIoResource);
+  }
+  else
+  {
+     ExReleaseResourceLite(&FCB->MainResource);
+  }
+
+  IrpContext->Irp->IoStatus.Status = RC;
+  IrpContext->Irp->IoStatus.Information = 0;
+  IoCompleteRequest(IrpContext->Irp, IO_NO_INCREMENT);
+  VfatFreeIrpContext(IrpContext);
 
   return RC;
 }
index 68268fd..efd37ce 100644 (file)
@@ -1,4 +1,4 @@
-/* $Id: iface.c,v 1.58 2001/10/10 22:18:58 hbirr Exp $
+/* $Id: iface.c,v 1.59 2001/11/02 22:47:36 hbirr Exp $
  *
  * COPYRIGHT:        See COPYING in the top level directory
  * PROJECT:          ReactOS kernel
@@ -61,7 +61,7 @@ VfatHasFileSystem(PDEVICE_OBJECT DeviceToMount,
        return(Status);
      }
 
-   DPRINT("Boot->SysType %.5s\n", Boot->SysType);
+   DPRINT1("Boot->SysType %.5s\n", Boot->SysType);
    if (strncmp(Boot->SysType, "FAT12", 5) == 0 ||
        strncmp(Boot->SysType, "FAT16", 5) == 0 ||
        strncmp(((struct _BootSector32 *) (Boot))->SysType, "FAT32", 5) == 0)
@@ -153,29 +153,41 @@ VfatMountDevice(PDEVICE_EXTENSION DeviceExt,
 
 
 static NTSTATUS
-VfatMount (PDEVICE_OBJECT DeviceToMount)
+VfatMount (PVFAT_IRP_CONTEXT IrpContext)
 /*
  * FUNCTION: Mount the filesystem
  */
 {
-  PDEVICE_OBJECT DeviceObject;
-  PDEVICE_EXTENSION DeviceExt;
+  PDEVICE_OBJECT DeviceObject = NULL;
+  PDEVICE_EXTENSION DeviceExt = NULL;
   BOOLEAN RecognizedFS;
   NTSTATUS Status;
-  PVFATFCB Fcb;
-  PVFATCCB Ccb;
+  PVFATFCB Fcb = NULL;
+  PVFATCCB Ccb = NULL;
 
-  Status = VfatHasFileSystem (DeviceToMount, &RecognizedFS);
+  DPRINT1("VfatMount(IrpContext %x)\n", IrpContext);
+
+  assert (IrpContext);
+
+  if (IrpContext->DeviceObject != VfatDriverObject->DeviceObject)
+  {
+     // Only allowed on the main device object
+     Status = STATUS_INVALID_DEVICE_REQUEST;
+     goto ByeBye;
+  }
+
+  Status = VfatHasFileSystem (IrpContext->Stack->Parameters.Mount.DeviceObject, &RecognizedFS);
   if (!NT_SUCCESS(Status))
-    {
-      return(Status);
-    }
+  {
+     goto ByeBye;
+  }
 
   if (RecognizedFS == FALSE)
-    {
-      DPRINT("VFAT: Unrecognized Volume\n");
-      return(STATUS_UNRECOGNIZED_VOLUME);
-    }
+  {
+     DPRINT("VFAT: Unrecognized Volume\n");
+     Status = STATUS_UNRECOGNIZED_VOLUME;
+     goto ByeBye;
+  }
 
   DPRINT("VFAT: Recognized volume\n");
 
@@ -187,21 +199,22 @@ VfatMount (PDEVICE_OBJECT DeviceToMount)
                          FALSE,
                          &DeviceObject);
   if (!NT_SUCCESS(Status))
-    {
-      return(Status);
-    }
+  {
+    goto ByeBye;
+  }
 
   DeviceObject->Flags = DeviceObject->Flags | DO_DIRECT_IO;
   DeviceExt = (PVOID) DeviceObject->DeviceExtension;
+  RtlZeroMemory(DeviceExt, sizeof(DEVICE_EXTENSION));
+
   /* use same vpb as device disk */
-  DeviceObject->Vpb = DeviceToMount->Vpb;
-  Status = VfatMountDevice(DeviceExt,
-                          DeviceToMount);
+  DeviceObject->Vpb = IrpContext->Stack->Parameters.Mount.DeviceObject->Vpb;
+  Status = VfatMountDevice(DeviceExt, IrpContext->Stack->Parameters.Mount.DeviceObject);
   if (!NT_SUCCESS(Status))
-    {
-      /* FIXME: delete device object */
-      return(Status);
-    }
+  {
+    /* FIXME: delete device object */
+    goto ByeBye;
+  }
 
 #if 1
   DbgPrint("BytesPerSector:     %d\n", DeviceExt->Boot->BytesPerSector);
@@ -230,24 +243,26 @@ VfatMount (PDEVICE_OBJECT DeviceToMount)
     }
 #endif
   DeviceObject->Vpb->Flags |= VPB_MOUNTED;
-  DeviceExt->StorageDevice = IoAttachDeviceToDeviceStack(DeviceObject,
-                                                        DeviceToMount);
+  DeviceExt->StorageDevice = IoAttachDeviceToDeviceStack(DeviceObject, IrpContext->Stack->Parameters.Mount.DeviceObject);
 
   DeviceExt->FATFileObject = IoCreateStreamFileObject(NULL, DeviceExt->StorageDevice);
   Fcb = vfatNewFCB(NULL);
   if (Fcb == NULL)
   {
-    return STATUS_INSUFFICIENT_RESOURCES;
+    Status = STATUS_INSUFFICIENT_RESOURCES;
+    goto ByeBye;
   }
   Ccb = ExAllocatePoolWithTag (NonPagedPool, sizeof (VFATCCB), TAG_CCB);
   if (Ccb == NULL)
   {
-    return STATUS_INSUFFICIENT_RESOURCES;
+    Status =  STATUS_INSUFFICIENT_RESOURCES;
+    goto ByeBye;
   }
   memset(Ccb, 0, sizeof (VFATCCB));
   DeviceExt->FATFileObject->Flags = DeviceExt->FATFileObject->Flags | FO_FCB_IS_VALID | FO_DIRECT_CACHE_PAGING_READ;
   DeviceExt->FATFileObject->FsContext = (PVOID) &Fcb->RFCB;
   DeviceExt->FATFileObject->FsContext2 = Ccb;
+  DeviceExt->FATFileObject->SectionObjectPointers = &Fcb->SectionObjectPointers;
   Ccb->pFcb = Fcb;
   Ccb->PtrFileObject = DeviceExt->FATFileObject;
   Fcb->FileObject = DeviceExt->FATFileObject;
@@ -255,6 +270,16 @@ VfatMount (PDEVICE_OBJECT DeviceToMount)
 
   Fcb->Flags = FCB_IS_FAT;
 
+  if (DeviceExt->Boot->Sectors != 0)
+  {
+    DeviceExt->NumberOfClusters = (DeviceExt->Boot->Sectors - DeviceExt->dataStart)
+                                    / DeviceExt->Boot->SectorsPerCluster + 2;
+  }
+  else
+  {
+    DeviceExt->NumberOfClusters = (DeviceExt->Boot->SectorsHuge - DeviceExt->dataStart)
+                                    / DeviceExt->Boot->SectorsPerCluster + 2;
+  }
   if (DeviceExt->FatType == FAT32)
   {
     Fcb->RFCB.FileSize.QuadPart = ((struct _BootSector32 *)DeviceExt->Boot)->FATSectors32 * BLOCKSIZE;
@@ -282,12 +307,10 @@ VfatMount (PDEVICE_OBJECT DeviceToMount)
   if (!NT_SUCCESS (Status))
   {
      DbgPrint ("CcRosInitializeFileCache failed\n");
-//     KeBugCheck (0);
-     // FIXME: delete device object
-     return(Status);
+     goto ByeBye;
   }
 
-
+  DeviceExt->LastAvailableCluster = 0;
   ExInitializeResourceLite(&DeviceExt->DirResource);
   ExInitializeResourceLite(&DeviceExt->FatResource);
 
@@ -304,22 +327,39 @@ VfatMount (PDEVICE_OBJECT DeviceToMount)
 
   /* read volume label */
   ReadVolumeLabel(DeviceExt,  DeviceObject->Vpb);
+  Status = STATUS_SUCCESS;
+
+ByeBye:
 
-  return(STATUS_SUCCESS);
+  if (!NT_SUCCESS(Status))
+  {
+     // cleanup
+     if (DeviceExt && DeviceExt->FATFileObject)
+        ObDereferenceObject (DeviceExt->FATFileObject);
+     if (Fcb)
+        ExFreePool(Fcb);
+     if (Ccb)
+        ExFreePool(Ccb);
+     if (DeviceObject)
+       IoDeleteDevice(DeviceObject);
+  }
+  return Status;
 }
 
 
-NTSTATUS STDCALL
-VfatFileSystemControl(PDEVICE_OBJECT DeviceObject,
-                     PIRP Irp)
+NTSTATUS VfatFileSystemControl(PVFAT_IRP_CONTEXT IrpContext)
 /*
  * FUNCTION: File system control
  */
 {
-   PIO_STACK_LOCATION Stack = IoGetCurrentIrpStackLocation (Irp);
+
    NTSTATUS Status;
 
-   switch (Stack->MinorFunction)
+   DPRINT1("VfatFileSystemControl(IrpContext %x)\n", IrpContext);
+
+   assert (IrpContext);
+
+   switch (IrpContext->MinorFunction)
      {
        case IRP_MN_USER_FS_REQUEST:
           DPRINT1("VFAT FSC: IRP_MN_USER_FS_REQUEST\n");
@@ -327,7 +367,7 @@ VfatFileSystemControl(PDEVICE_OBJECT DeviceObject,
           break;
 
        case IRP_MN_MOUNT_VOLUME:
-          Status = VfatMount(Stack->Parameters.Mount.DeviceObject);
+          Status = VfatMount(IrpContext);
           break;
 
        case IRP_MN_VERIFY_VOLUME:
@@ -336,15 +376,15 @@ VfatFileSystemControl(PDEVICE_OBJECT DeviceObject,
           break;
 
        default:
-          DPRINT1("VFAT FSC: MinorFunction %d\n", Stack->MinorFunction);
+          DPRINT1("VFAT FSC: MinorFunction %d\n", IrpContext->MinorFunction);
           Status = STATUS_INVALID_DEVICE_REQUEST;
           break;
      }
 
-   Irp->IoStatus.Status = Status;
-   Irp->IoStatus.Information = 0;
+   IrpContext->Irp->IoStatus.Status = Status;
+   IrpContext->Irp->IoStatus.Information = 0;
 
-   IoCompleteRequest (Irp, IO_NO_INCREMENT);
+   IoCompleteRequest (IrpContext->Irp, IO_NO_INCREMENT);
    return (Status);
 }
 
@@ -383,24 +423,24 @@ DriverEntry(PDRIVER_OBJECT _DriverObject,
      }
 
    DeviceObject->Flags = DO_DIRECT_IO;
-   VfatDriverObject->MajorFunction[IRP_MJ_CLOSE] = VfatClose;
-   VfatDriverObject->MajorFunction[IRP_MJ_CREATE] = VfatCreate;
-   VfatDriverObject->MajorFunction[IRP_MJ_READ] = VfatRead;
-   VfatDriverObject->MajorFunction[IRP_MJ_WRITE] = VfatWrite;
+   VfatDriverObject->MajorFunction[IRP_MJ_CLOSE] = VfatBuildRequest;
+   VfatDriverObject->MajorFunction[IRP_MJ_CREATE] = VfatBuildRequest;
+   VfatDriverObject->MajorFunction[IRP_MJ_READ] = VfatBuildRequest;
+   VfatDriverObject->MajorFunction[IRP_MJ_WRITE] = VfatBuildRequest;
    VfatDriverObject->MajorFunction[IRP_MJ_FILE_SYSTEM_CONTROL] =
-     VfatFileSystemControl;
+     VfatBuildRequest;
    VfatDriverObject->MajorFunction[IRP_MJ_QUERY_INFORMATION] =
-     VfatQueryInformation;
+     VfatBuildRequest;
    VfatDriverObject->MajorFunction[IRP_MJ_SET_INFORMATION] =
-     VfatSetInformation;
+     VfatBuildRequest;
    VfatDriverObject->MajorFunction[IRP_MJ_DIRECTORY_CONTROL] =
-     VfatDirectoryControl;
+     VfatBuildRequest;
    VfatDriverObject->MajorFunction[IRP_MJ_QUERY_VOLUME_INFORMATION] =
-     VfatQueryVolumeInformation;
+     VfatBuildRequest;
    VfatDriverObject->MajorFunction[IRP_MJ_SET_VOLUME_INFORMATION] =
-     VfatSetVolumeInformation;
+     VfatBuildRequest;
    VfatDriverObject->MajorFunction[IRP_MJ_SHUTDOWN] = VfatShutdown;
-   VfatDriverObject->MajorFunction[IRP_MJ_CLEANUP] = VfatCleanup;
+   VfatDriverObject->MajorFunction[IRP_MJ_CLEANUP] = VfatBuildRequest;
 
    VfatDriverObject->DriverUnload = NULL;
 
index 72fb11c..c36c04b 100644 (file)
@@ -1,4 +1,4 @@
-# $Id: makefile,v 1.35 2001/08/21 20:13:13 chorns Exp $
+# $Id: makefile,v 1.36 2001/11/02 22:47:36 hbirr Exp $
 
 PATH_TO_TOP = ../../..
 
@@ -21,8 +21,14 @@ TARGET_OBJECTS = \
   rw.o \
   shutdown.o \
   string.o \
-  volume.o
+  volume.o \
+  misc.o
+
+DEP_OBJECTS = $(TARGET_OBJECTS)
 
 include $(PATH_TO_TOP)/rules.mak
 
 include $(TOOLS_PATH)/helper.mk
+
+include $(TOOLS_PATH)/depend.mk
+
diff --git a/reactos/drivers/fs/vfat/misc.c b/reactos/drivers/fs/vfat/misc.c
new file mode 100644 (file)
index 0000000..95850f6
--- /dev/null
@@ -0,0 +1,209 @@
+/* $Id: misc.c,v 1.1 2001/11/02 22:44:34 hbirr Exp $
+ *
+ * COPYRIGHT:        See COPYING in the top level directory
+ * PROJECT:          ReactOS kernel
+ * FILE:             services/fs/vfat/misc.c
+ * PURPOSE:          VFAT Filesystem
+ * PROGRAMMER:       Hartmut Birr
+ *
+ */
+
+/* INCLUDES *****************************************************************/
+
+#include <ddk/ntddk.h>
+#include <wchar.h>
+
+#define NDEBUG
+#include <debug.h>
+
+#include "vfat.h"
+
+/* FUNCTIONS ****************************************************************/
+
+static LONG QueueCount = 0;
+
+NTSTATUS VfatDispatchRequest (
+        IN PVFAT_IRP_CONTEXT IrpContext)
+{
+   DPRINT ("VfatDispatchRequest (IrpContext %x), MajorFunction %x\n", IrpContext, IrpContext->MajorFunction);
+
+   assert (IrpContext);
+
+   switch (IrpContext->MajorFunction)
+   {
+      case IRP_MJ_CLOSE:
+         return VfatClose (IrpContext);
+      case IRP_MJ_CREATE:
+         return VfatCreate (IrpContext);
+      case IRP_MJ_READ:
+         return VfatRead (IrpContext);
+      case IRP_MJ_WRITE:
+         return VfatWrite (IrpContext);
+      case IRP_MJ_FILE_SYSTEM_CONTROL:
+         return VfatFileSystemControl(IrpContext);
+      case IRP_MJ_QUERY_INFORMATION:
+         return VfatQueryInformation (IrpContext);
+      case IRP_MJ_SET_INFORMATION:
+         return VfatSetInformation (IrpContext);
+      case IRP_MJ_DIRECTORY_CONTROL:
+         return VfatDirectoryControl(IrpContext);
+      case IRP_MJ_QUERY_VOLUME_INFORMATION:
+         return VfatQueryVolumeInformation(IrpContext);
+      case IRP_MJ_SET_VOLUME_INFORMATION:
+         return VfatSetVolumeInformation(IrpContext);
+      case IRP_MJ_CLEANUP:
+         return VfatCleanup(IrpContext);
+      default:
+         DPRINT1 ("Unexpected major function %x\n", IrpContext->MajorFunction);
+         IrpContext->Irp->IoStatus.Status = STATUS_DRIVER_INTERNAL_ERROR;
+         IoCompleteRequest(IrpContext->Irp, IO_NO_INCREMENT);
+         VfatFreeIrpContext(IrpContext);
+         return STATUS_DRIVER_INTERNAL_ERROR;
+   }
+}
+
+
+NTSTATUS STDCALL VfatBuildRequest (
+        IN PDEVICE_OBJECT DeviceObject,
+        IN PIRP Irp)
+{
+   NTSTATUS Status;
+   PVFAT_IRP_CONTEXT IrpContext;
+
+   DPRINT ("VfatBuildRequest (DeviceObject %x, Irp %x)\n", DeviceObject, Irp);
+
+   assert (DeviceObject);
+   assert (Irp);
+
+   FsRtlEnterFileSystem();
+   IrpContext = VfatAllocateIrpContext(DeviceObject, Irp);
+   if (IrpContext == NULL)
+   {
+      Status = STATUS_INSUFFICIENT_RESOURCES;
+      Irp->IoStatus.Status = Status;
+      IoCompleteRequest (Irp, IO_NO_INCREMENT);
+   }
+   else
+   {
+      Status = VfatDispatchRequest (IrpContext);
+   }
+   FsRtlExitFileSystem();
+   return Status;
+}
+
+VOID VfatFreeIrpContext (PVFAT_IRP_CONTEXT IrpContext)
+{
+   assert (IrpContext);
+   ExFreePool(IrpContext);
+}
+
+// Copyed from ntoskrnl\io\irp.c and changed access to FileObject
+BOOLEAN
+STDCALL
+VfatIoIsOperationSynchronous (
+       IN      PIRP    Irp
+       )
+{
+       ULONG           Flags = 0;
+       PFILE_OBJECT    FileObject = NULL;
+       PIO_STACK_LOCATION Stack;
+       /*
+        * Check the associated FILE_OBJECT's
+        * flags first.
+        */
+//     FileObject = Irp->Tail.Overlay.OriginalFileObject;
+        Stack = IoGetCurrentIrpStackLocation(Irp);
+        FileObject = Stack->FileObject;
+
+        assert (FileObject);
+       if (!(FO_SYNCHRONOUS_IO & FileObject->Flags))
+       {
+               /* Check IRP's flags. */
+               Flags = Irp->Flags;
+               if (!(  (IRP_SYNCHRONOUS_API | IRP_SYNCHRONOUS_PAGING_IO)
+                       & Flags
+                       ))
+               {
+                       return FALSE;
+               }
+       }
+       /*
+        * Check more IRP's flags.
+        */
+       Flags = Irp->Flags;
+       if (    !(IRP_MOUNT_COMPLETION & Flags)
+               || (IRP_SYNCHRONOUS_PAGING_IO & Flags)
+               )
+       {
+               return TRUE;
+       }
+       /*
+        * Otherwise, it is an
+        * asynchronous operation.
+        */
+       return FALSE;
+}
+
+PVFAT_IRP_CONTEXT VfatAllocateIrpContext(PDEVICE_OBJECT DeviceObject, PIRP Irp)
+{
+   PVFAT_IRP_CONTEXT IrpContext;
+   PIO_STACK_LOCATION Stack;
+   UCHAR MajorFunction;
+   DPRINT ("VfatAllocateIrpContext(DeviceObject %x, Irp %x)\n", DeviceObject, Irp);
+
+   assert (DeviceObject);
+   assert (Irp);
+
+   IrpContext = ExAllocatePool (NonPagedPool, sizeof(VFAT_IRP_CONTEXT));
+   if (IrpContext)
+   {
+      RtlZeroMemory(IrpContext, sizeof(IrpContext));
+      IrpContext->Irp = Irp;
+      IrpContext->DeviceObject = DeviceObject;
+      IrpContext->DeviceExt = DeviceObject->DeviceExtension;
+      IrpContext->Stack = IoGetCurrentIrpStackLocation(Irp);
+      assert (IrpContext->Stack);
+      MajorFunction = IrpContext->MajorFunction = IrpContext->Stack->MajorFunction;
+      IrpContext->MinorFunction = IrpContext->Stack->MinorFunction;
+      IrpContext->FileObject = IrpContext->Stack->FileObject;
+      if (MajorFunction == IRP_MJ_FILE_SYSTEM_CONTROL ||
+          MajorFunction == IRP_MJ_DEVICE_CONTROL ||
+          MajorFunction == IRP_MJ_SHUTDOWN)
+      {
+         IrpContext->Flags |= IRPCONTEXT_CANWAIT;
+      }
+      else if (MajorFunction != IRP_MJ_CLEANUP &&
+               MajorFunction != IRP_MJ_CLOSE &&
+               VfatIoIsOperationSynchronous(Irp))
+      {
+         IrpContext->Flags |= IRPCONTEXT_CANWAIT;
+      }
+   }
+   return IrpContext;
+}
+
+VOID STDCALL VfatDoRequest (PVOID IrpContext)
+{
+   ULONG Count = InterlockedDecrement(&QueueCount);
+   DPRINT ("VfatDoRequest (IrpContext %x), MajorFunction %x, %d\n", IrpContext, ((PVFAT_IRP_CONTEXT)IrpContext)->MajorFunction, Count);
+   VfatDispatchRequest((PVFAT_IRP_CONTEXT)IrpContext);
+
+}
+
+NTSTATUS VfatQueueRequest(PVFAT_IRP_CONTEXT IrpContext)
+{
+   ULONG Count = InterlockedIncrement(&QueueCount);
+   DPRINT ("VfatQueueRequest (IrpContext %x), %d\n", IrpContext, Count);
+
+   assert (IrpContext != NULL);
+   assert (IrpContext->Irp != NULL);
+
+   IrpContext->Flags |= IRPCONTEXT_CANWAIT;
+   IoMarkIrpPending (IrpContext->Irp);
+   ExInitializeWorkItem (&IrpContext->WorkQueueItem, VfatDoRequest, IrpContext);
+   ExQueueWorkItem(&IrpContext->WorkQueueItem, CriticalWorkQueue);
+   return STATUS_PENDING;
+}
+
+
+
index d99e60f..15ad7ab 100644 (file)
@@ -1,5 +1,5 @@
 
-/* $Id: rw.c,v 1.33 2001/10/11 15:39:51 hbirr Exp $
+/* $Id: rw.c,v 1.34 2001/11/02 22:47:36 hbirr Exp $
  *
  * COPYRIGHT:        See COPYING in the top level directory
  * PROJECT:          ReactOS kernel
@@ -419,7 +419,7 @@ VfatWriteFile (PDEVICE_EXTENSION DeviceExt, PFILE_OBJECT FileObject,
   // Is this a write to the FAT ?
   if (Fcb->Flags & FCB_IS_FAT)
   {
-    if (!NoCache)
+    if (!NoCache && !PageIo)
     {
       DbgPrint ("Cached FAT write outside from VFATFS.SYS\n");
       KeBugCheck (0);
@@ -604,119 +604,6 @@ VfatWriteFile (PDEVICE_EXTENSION DeviceExt, PFILE_OBJECT FileObject,
   return Status;
 }
 
-NTSTATUS STDCALL
-VfatWrite (PDEVICE_OBJECT DeviceObject, PIRP Irp)
-/*
- * FUNCTION: Write to a file
- */
-{
-  ULONG Length;
-  PVOID Buffer;
-  ULONG Offset;
-  PIO_STACK_LOCATION Stack = IoGetCurrentIrpStackLocation (Irp);
-  PFILE_OBJECT FileObject = Stack->FileObject;
-  PDEVICE_EXTENSION DeviceExt = DeviceObject->DeviceExtension;
-  NTSTATUS Status;
-  ULONG NoCache;
-
-  DPRINT ("VfatWrite(DeviceObject %x Irp %x)\n", DeviceObject, Irp);
-
-  Length = Stack->Parameters.Write.Length;
-  Buffer = MmGetSystemAddressForMdl (Irp->MdlAddress);
-  Offset = Stack->Parameters.Write.ByteOffset.u.LowPart;
-
-  if (Irp->Flags & IRP_PAGING_IO ||
-      FileObject->Flags & FO_NO_INTERMEDIATE_BUFFERING)
-  {
-    NoCache = TRUE;
-  }
-  else
-  {
-    NoCache = FALSE;
-  }
-
-  Status = VfatWriteFile (DeviceExt, FileObject, Buffer, Length, Offset,
-                         NoCache, Irp->Flags & IRP_PAGING_IO ? TRUE : FALSE);
-
-  if (!(Irp->Flags & IRP_PAGING_IO) && NT_SUCCESS(Status))
-  {
-    FileObject->CurrentByteOffset.QuadPart = Offset + Length;
-  }
-
-  Irp->IoStatus.Status = Status;
-  Irp->IoStatus.Information = Length;
-  IoCompleteRequest (Irp, IO_NO_INCREMENT);
-
-  return (Status);
-}
-
-NTSTATUS STDCALL
-VfatRead (PDEVICE_OBJECT DeviceObject, PIRP Irp)
-/*
- * FUNCTION: Read from a file
- */
-{
-  ULONG Length;
-  PVOID Buffer;
-  ULONG Offset;
-  PIO_STACK_LOCATION Stack;
-  PFILE_OBJECT FileObject;
-  PDEVICE_EXTENSION DeviceExt;
-  NTSTATUS Status;
-  ULONG LengthRead;
-  PVFATFCB Fcb;
-  ULONG NoCache;
-
-  DPRINT ("VfatRead(DeviceObject %x, Irp %x)\n", DeviceObject, Irp);
-
-  /* Precondition / Initialization */
-  assert (Irp != NULL);
-  Stack = IoGetCurrentIrpStackLocation (Irp);
-  assert (Stack != NULL);
-  FileObject = Stack->FileObject;
-  assert (FileObject != NULL);
-  DeviceExt = DeviceObject->DeviceExtension;
-  assert (DeviceExt != NULL);
-
-  Length = Stack->Parameters.Read.Length;
-  Buffer = MmGetSystemAddressForMdl (Irp->MdlAddress);
-  Offset = Stack->Parameters.Read.ByteOffset.u.LowPart;
-
-  if (Irp->Flags & IRP_PAGING_IO ||
-      FileObject->Flags & FO_NO_INTERMEDIATE_BUFFERING)
-  {
-    NoCache = TRUE;
-  }
-  else
-  {
-    NoCache = FALSE;
-  }
-
-  Fcb = ((PVFATCCB) (FileObject->FsContext2))->pFcb;
-  /* fail if file is a directory and no paged read */
-  if (Fcb->entry.Attrib & FILE_ATTRIBUTE_DIRECTORY && !(Irp->Flags & IRP_PAGING_IO))
-  {
-    Status = STATUS_FILE_IS_A_DIRECTORY;
-  }
-  else
-  {
-    Status = VfatReadFile (DeviceExt, FileObject, Buffer, Length,
-               Offset, &LengthRead, NoCache);
-  }
-
-  if (!(Irp->Flags & IRP_PAGING_IO))
-  {
-    // update the file pointer
-    FileObject->CurrentByteOffset.QuadPart = Offset + LengthRead;
-  }
-
-  Irp->IoStatus.Status = Status;
-  Irp->IoStatus.Information = LengthRead;
-  IoCompleteRequest (Irp, IO_NO_INCREMENT);
-
-  return (Status);
-}
-
 NTSTATUS vfatExtendSpace (PDEVICE_EXTENSION pDeviceExt, PFILE_OBJECT pFileObject, ULONG NewSize)
 {
   ULONG FirstCluster;
@@ -833,3 +720,159 @@ NTSTATUS vfatExtendSpace (PDEVICE_EXTENSION pDeviceExt, PFILE_OBJECT pFileObject
   }
   return STATUS_SUCCESS;
 }
+
+NTSTATUS VfatRead(PVFAT_IRP_CONTEXT IrpContext)
+{
+   PVFATFCB Fcb;
+   PVFATCCB Ccb;
+   NTSTATUS Status = STATUS_SUCCESS;
+   ULONG ReadLength;
+   ULONG ReturnedReadLength = 0;
+   LARGE_INTEGER ReadOffset;
+   PVOID Buffer;
+
+   DPRINT ("VfatRead(IrpContext %x)\n", IrpContext);
+   assert (IrpContext);
+   Ccb = (PVFATCCB) IrpContext->FileObject->FsContext2;
+   assert (Ccb);
+   Fcb = Ccb->pFcb;
+   assert (Fcb);
+
+   if (IrpContext->Irp->Flags & IRP_PAGING_IO)
+   {
+      if (!ExAcquireResourceSharedLite(&Fcb->PagingIoResource, IrpContext->Flags & IRPCONTEXT_CANWAIT))
+      {
+         return VfatQueueRequest (IrpContext);
+      }
+   }
+   else
+   {
+      if (!ExAcquireResourceSharedLite(&Fcb->MainResource, IrpContext->Flags & IRPCONTEXT_CANWAIT))
+      {
+         return VfatQueueRequest (IrpContext);
+      }
+   }
+
+   ReadLength = IrpContext->Stack->Parameters.Read.Length;
+   ReadOffset = IrpContext->Stack->Parameters.Read.ByteOffset;
+   Buffer = MmGetSystemAddressForMdl (IrpContext->Irp->MdlAddress);
+
+   /* fail if file is a directory and no paged read */
+   if (Fcb->entry.Attrib & FILE_ATTRIBUTE_DIRECTORY && !(IrpContext->Irp->Flags & IRP_PAGING_IO))
+   {
+      Status = STATUS_FILE_IS_A_DIRECTORY;
+   }
+   else
+   {
+      Status = VfatReadFile (IrpContext->DeviceExt, IrpContext->FileObject,
+                 Buffer, ReadLength, ReadOffset.u.LowPart, &ReturnedReadLength,
+                 IrpContext->FileObject->Flags & FO_NO_INTERMEDIATE_BUFFERING
+                  || IrpContext->Irp->Flags & IRP_PAGING_IO);
+   }
+
+   if (IrpContext->Irp->Flags & IRP_PAGING_IO)
+   {
+      ExReleaseResourceLite(&Fcb->PagingIoResource);
+   }
+   else
+   {
+      ExReleaseResourceLite(&Fcb->MainResource);
+   }
+
+   if (NT_SUCCESS(Status))
+   {
+      if (IrpContext->FileObject->Flags & FO_SYNCHRONOUS_IO && !(IrpContext->Irp->Flags & IRP_PAGING_IO))
+      {
+         IrpContext->FileObject->CurrentByteOffset.QuadPart = ReadOffset.QuadPart + ReturnedReadLength;
+      }
+      IrpContext->Irp->IoStatus.Information = ReturnedReadLength;
+   }
+   else
+   {
+      IrpContext->Irp->IoStatus.Information = 0;
+   }
+
+   IrpContext->Irp->IoStatus.Status = Status;
+   IoCompleteRequest (IrpContext->Irp, IO_NO_INCREMENT);
+   VfatFreeIrpContext (IrpContext);
+
+   return Status;
+}
+
+NTSTATUS VfatWrite(PVFAT_IRP_CONTEXT IrpContext)
+{
+   PVFATFCB Fcb;
+   PVFATCCB Ccb;
+   NTSTATUS Status = STATUS_SUCCESS;
+   ULONG WriteLength;
+   LARGE_INTEGER WriteOffset;
+   PVOID Buffer;
+
+   DPRINT ("VfatWrite(), %S\n", ((PVFATCCB) IrpContext->FileObject->FsContext2)->pFcb->FileName);
+   assert (IrpContext);
+   Ccb = (PVFATCCB) IrpContext->FileObject->FsContext2;
+   assert (Ccb);
+   Fcb = Ccb->pFcb;
+   assert (Fcb);
+
+   if (IrpContext->Irp->Flags & IRP_PAGING_IO)
+   {
+      if (!ExAcquireResourceExclusiveLite(&Fcb->PagingIoResource, IrpContext->Flags & IRPCONTEXT_CANWAIT))
+      {
+         return VfatQueueRequest (IrpContext);
+      }
+   }
+   else
+   {
+      if (!ExAcquireResourceExclusiveLite(&Fcb->MainResource, IrpContext->Flags & IRPCONTEXT_CANWAIT))
+      {
+         return VfatQueueRequest (IrpContext);
+      }
+   }
+
+   WriteLength = IrpContext->Stack->Parameters.Write.Length;
+   WriteOffset = IrpContext->Stack->Parameters.Write.ByteOffset;
+   Buffer = MmGetSystemAddressForMdl (IrpContext->Irp->MdlAddress);
+
+   /* fail if file is a directory and no paged read */
+   if (Fcb->entry.Attrib & FILE_ATTRIBUTE_DIRECTORY && !(IrpContext->Irp->Flags & IRP_PAGING_IO))
+   {
+      Status = STATUS_FILE_IS_A_DIRECTORY;
+   }
+   else
+   {
+      Status = VfatWriteFile (IrpContext->DeviceExt, IrpContext->FileObject,
+                 Buffer, WriteLength, WriteOffset.u.LowPart,
+                 IrpContext->FileObject->Flags & FO_NO_INTERMEDIATE_BUFFERING,
+                  IrpContext->Irp->Flags & IRP_PAGING_IO);
+   }
+
+   if (IrpContext->Irp->Flags & IRP_PAGING_IO)
+   {
+      ExReleaseResourceLite(&Fcb->PagingIoResource);
+   }
+   else
+   {
+      ExReleaseResourceLite(&Fcb->MainResource);
+   }
+
+   if (NT_SUCCESS(Status))
+   {
+      if (IrpContext->FileObject->Flags & FO_SYNCHRONOUS_IO && !(IrpContext->Irp->Flags & IRP_PAGING_IO))
+      {
+         IrpContext->FileObject->CurrentByteOffset.QuadPart = WriteOffset.QuadPart + WriteLength;
+      }
+      IrpContext->Irp->IoStatus.Information = WriteLength;
+   }
+   else
+   {
+      IrpContext->Irp->IoStatus.Information = 0;
+   }
+
+   IrpContext->Irp->IoStatus.Status = Status;
+   IoCompleteRequest (IrpContext->Irp, IO_NO_INCREMENT);
+   VfatFreeIrpContext (IrpContext);
+   return Status;
+}
+
+
index c2c1b74..2044bff 100644 (file)
@@ -1,4 +1,4 @@
-/* $Id: volume.c,v 1.13 2001/11/01 10:41:53 hbirr 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
@@ -20,9 +20,7 @@
 /* FUNCTIONS ****************************************************************/
 
 static NTSTATUS
-FsdGetFsVolumeInformation(PFILE_OBJECT FileObject,
-                         PVFATFCB FCB,
-                         PDEVICE_OBJECT DeviceObject,
+FsdGetFsVolumeInformation(PDEVICE_OBJECT DeviceObject,
                          PFILE_FS_VOLUME_INFORMATION FsVolumeInfo,
                          PULONG BufferLength)
 {
@@ -38,12 +36,15 @@ FsdGetFsVolumeInformation(PFILE_OBJECT FileObject,
   DPRINT("LabelLength %lu\n", LabelLength);
   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);
+    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 */
@@ -69,9 +70,11 @@ FsdGetFsAttributeInformation(PFILE_FS_ATTRIBUTE_INFORMATION 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;
@@ -175,37 +178,31 @@ FsdSetFsLabelInformation(PDEVICE_OBJECT DeviceObject,
 }
 
 
-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);
@@ -213,9 +210,7 @@ VfatQueryVolumeInformation(PDEVICE_OBJECT DeviceObject,
   switch (FsInformationClass)
     {
     case FileFsVolumeInformation:
-      RC = FsdGetFsVolumeInformation(FileObject,
-                                    FCB,
-                                    DeviceObject,
+      RC = FsdGetFsVolumeInformation(IrpContext->DeviceObject,
                                     SystemBuffer,
                                     &BufferLength);
       break;
@@ -226,7 +221,7 @@ VfatQueryVolumeInformation(PDEVICE_OBJECT DeviceObject,
       break;
 
     case FileFsSizeInformation:
-      RC = FsdGetFsSizeInformation(DeviceObject,
+      RC = FsdGetFsSizeInformation(IrpContext->DeviceObject,
                                   SystemBuffer,
                                   &BufferLength);
       break;
@@ -240,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;
 
@@ -298,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);
 }