Added some fixes for accessing the page file.
authorHartmut Birr <osexpert@googlemail.com>
Tue, 15 Jan 2002 21:54:51 +0000 (21:54 +0000)
committerHartmut Birr <osexpert@googlemail.com>
Tue, 15 Jan 2002 21:54:51 +0000 (21:54 +0000)
svn path=/trunk/; revision=2519

reactos/drivers/fs/vfat/create.c
reactos/drivers/fs/vfat/fcb.c
reactos/drivers/fs/vfat/rw.c

index a1896c8..aa67ad5 100644 (file)
@@ -1,4 +1,4 @@
-/* $Id: create.c,v 1.35 2002/01/08 00:49:01 dwelch Exp $
+/* $Id: create.c,v 1.36 2002/01/15 21:54:51 hbirr Exp $
  *
  * COPYRIGHT:        See COPYING in the top level directory
  * PROJECT:          ReactOS kernel
@@ -643,7 +643,19 @@ VfatCreateFile (PDEVICE_OBJECT DeviceObject, PIRP Irp)
                      (Stack->Parameters.
                       Create.FileAttributes & FILE_ATTRIBUTE_VALID_FLAGS));
          if (NT_SUCCESS (Status))
+         {
+               if (PagingFileCreate)
+               {
+                 DPRINT("Creating a new paging file.\n");
+                 pCcb = FileObject->FsContext2;
+                 pFcb = pCcb->pFcb;
+             pFcb->Flags |= FCB_IS_PAGE_FILE;
+             pFcb->FatChainSize = 0;
+                 pFcb->FatChain = NULL;
+               }
+
            Irp->IoStatus.Information = FILE_CREATED;
+         }
          /* FIXME set size if AllocationSize requested */
          /* FIXME set extended attributes? */
          /* FIXME set share access */
@@ -703,12 +715,15 @@ VfatCreateFile (PDEVICE_OBJECT DeviceObject, PIRP Irp)
     if (PagingFileCreate)
       {
        ULONG CurrentCluster, NextCluster, i;
-
+       DPRINT("Open an existing paging file\n");
        pFcb->Flags |= FCB_IS_PAGE_FILE;
        pFcb->FatChainSize = 
-         ((pFcb->entry.FileSize / DeviceExt->BytesPerCluster) + 2);
-       pFcb->FatChain = ExAllocatePool(NonPagedPool, 
+         ((pFcb->entry.FileSize + DeviceExt->BytesPerCluster - 1) / DeviceExt->BytesPerCluster);
+       if (pFcb->FatChainSize)
+       {
+         pFcb->FatChain = ExAllocatePool(NonPagedPool, 
                                        pFcb->FatChainSize * sizeof(ULONG));
+       }
 
        if (DeviceExt->FatType == FAT32)
          {
@@ -721,16 +736,18 @@ VfatCreateFile (PDEVICE_OBJECT DeviceObject, PIRP Irp)
          }
 
        i = 0;
-       while (CurrentCluster != 0xffffffff)
-         {
-           Status = GetNextCluster (DeviceExt, CurrentCluster, &NextCluster, 
+       if (pFcb->FatChainSize)
+       {
+               while (CurrentCluster != 0xffffffff)
+               {
+                 pFcb->FatChain[i] = CurrentCluster;   
+             Status = GetNextCluster (DeviceExt, CurrentCluster, &NextCluster, 
                                     FALSE);
-           pFcb->FatChain[i] = NextCluster;
-           i++;
-           CurrentCluster = NextCluster;
-         }
-       pFcb->FatChain[i] = 0xFFFFFFFF;
+             i++;
+             CurrentCluster = NextCluster;
+               }
       }
+       }
 
     /*
      * Check the file has the requested attributes
index b3ff4b0..0baee0a 100644 (file)
@@ -1,4 +1,4 @@
-/* $Id: fcb.c,v 1.12 2002/01/08 00:49:01 dwelch Exp $
+/* $Id: fcb.c,v 1.13 2002/01/15 21:54:51 hbirr Exp $
  *
  *
  * FILE:             fcb.c
@@ -58,6 +58,8 @@ vfatDestroyFCB(PVFATFCB  pFCB)
 {
   ExDeleteResourceLite(&pFCB->PagingIoResource);
   ExDeleteResourceLite(&pFCB->MainResource);
+  if ((pFCB->Flags & FCB_IS_PAGE_FILE) && pFCB->FatChainSize)
+       ExFreePool(pFCB->FatChain);
   ExFreePool (pFCB);
 }
 
index 1ed7984..874a5ea 100644 (file)
@@ -1,5 +1,5 @@
 
-/* $Id: rw.c,v 1.35 2002/01/08 00:49:01 dwelch Exp $
+/* $Id: rw.c,v 1.36 2002/01/15 21:54:51 hbirr Exp $
  *
  * COPYRIGHT:        See COPYING in the top level directory
  * PROJECT:          ReactOS kernel
@@ -40,10 +40,79 @@ NextCluster(PDEVICE_EXTENSION DeviceExt,
 {
   if (Fcb != NULL && Fcb->Flags & FCB_IS_PAGE_FILE)
     {
-      ULONG NextCluster;
-      NextCluster = Fcb->FatChain[(*CurrentCluster)];
-      (*CurrentCluster) = NextCluster;
-      return(STATUS_SUCCESS);
+      ULONG i;
+      PULONG FatChain;
+      NTSTATUS Status;
+      DPRINT("NextCluster(Fcb %x, FirstCluster %x, Extend %d)\n", Fcb, FirstCluster, Extend);
+      if (Fcb->FatChainSize == 0)
+      {
+        // paging file with zero length
+        *CurrentCluster = 0xffffffff;
+        if (Extend)
+        {
+          Fcb->FatChain = ExAllocatePool(NonPagedPool, sizeof(ULONG));
+          if (!Fcb->FatChain)
+          {
+            return STATUS_UNSUCCESSFUL;
+          }
+          Status = GetNextCluster(DeviceExt, 0, CurrentCluster, TRUE);
+          if (!NT_SUCCESS(Status))
+          {
+            ExFreePool(Fcb->FatChain);
+            return Status;
+          }
+          Fcb->FatChain[0] = *CurrentCluster;
+          Fcb->FatChainSize = 1;
+          return Status;
+        }
+        else
+        {
+          return STATUS_UNSUCCESSFUL;
+        }
+      }
+      else
+      {
+        for (i = 0; i < Fcb->FatChainSize; i++)
+        {
+          if (Fcb->FatChain[i] == *CurrentCluster)
+            break;
+        }
+        if (i >= Fcb->FatChainSize)
+        {
+          return STATUS_UNSUCCESSFUL;
+        }
+        if (i == Fcb->FatChainSize - 1)
+        {
+          if (Extend)
+          {
+            FatChain = ExAllocatePool(NonPagedPool, (i + 2) * sizeof(ULONG));
+            if (!FatChain)
+            {
+              *CurrentCluster = 0xffffffff;
+              return STATUS_UNSUCCESSFUL;
+            }
+            Status = GetNextCluster(DeviceExt, *CurrentCluster, CurrentCluster, TRUE);
+            if (NT_SUCCESS(Status) && *CurrentCluster != 0xffffffff)
+            {
+              memcpy(FatChain, Fcb->FatChain, (i + 1) * sizeof(ULONG));
+              FatChain[i + 1] = *CurrentCluster;
+              ExFreePool(Fcb->FatChain);
+              Fcb->FatChain = FatChain;
+              Fcb->FatChainSize = i + 2;
+            }
+            else
+              ExFreePool(FatChain);
+            return Status;
+          }
+          else
+          {
+            *CurrentCluster = 0xffffffff;
+            return STATUS_UNSUCCESSFUL;
+          }
+        }
+        *CurrentCluster = Fcb->FatChain[i + 1];
+        return STATUS_SUCCESS;
+      }
     }
   if (FirstCluster == 1)
     {
@@ -90,19 +159,75 @@ OffsetToCluster(PDEVICE_EXTENSION DeviceExt,
   ULONG CurrentCluster;
   ULONG i;
   NTSTATUS Status;
+  DPRINT("OffsetToCluster(DeviceExt %x, Fcb %x, FirstCluster %x,"
+         " FileOffset %x, Cluster %x, Extend %d)\n", DeviceExt, 
+         Fcb, FirstCluster, FileOffset, Cluster, Extend);
+  if (FirstCluster == 0)
+  {
+    DbgPrint("OffsetToCluster is called with FirstCluster = 0!\n");
+    KeBugCheck(0);
+  }
 
   if (Fcb != NULL && Fcb->Flags & FCB_IS_PAGE_FILE)
     {
       ULONG NCluster;
       ULONG Offset = FileOffset / DeviceExt->BytesPerCluster;
-      if (Offset == 0)
-       {
-         (*Cluster) = FirstCluster;
-       }
+      PULONG FatChain;
+      int i;
+      if (Fcb->FatChainSize == 0)
+      {
+        DbgPrint("OffsetToCluster is called with FirstCluster = %x"
+                 " and Fcb->FatChainSize = 0!\n", FirstCluster);
+        KeBugCheck(0);
+      }
+      if (Offset < Fcb->FatChainSize)
+      {
+        *Cluster = Fcb->FatChain[Offset];
+        return STATUS_SUCCESS;
+      }
       else
+      {
+        if (!Extend)
+        {
+          *Cluster = 0xffffffff;
+          return STATUS_UNSUCCESSFUL;
+        }
+        else
        {
-         (*Cluster) = Fcb->FatChain[Offset - 1];
-       }
+          FatChain = ExAllocatePool(NonPagedPool, (Offset + 1) * sizeof(ULONG));
+          if (!FatChain)
+          {
+            *Cluster = 0xffffffff;
+            return STATUS_UNSUCCESSFUL;
+          }
+                 
+          CurrentCluster = Fcb->FatChain[Fcb->FatChainSize - 1];
+          FatChain[Fcb->FatChainSize - 1] = CurrentCluster;
+          for (i = Fcb->FatChainSize; i < Offset + 1; i++)
+          {
+            Status = GetNextCluster(DeviceExt, CurrentCluster, &CurrentCluster, TRUE);
+            if (!NT_SUCCESS(Status) || CurrentCluster == 0xFFFFFFFF)
+            {
+              while (i >= Fcb->FatChainSize)
+              {
+                WriteCluster(DeviceExt, FatChain[i - 1], 0xFFFFFFFF);
+                i--;
+              }
+              *Cluster = 0xffffffff;
+              ExFreePool(FatChain);
+              if (!NT_SUCCESS(Status))
+                 return Status;
+              return STATUS_UNSUCCESSFUL;
+            }
+            FatChain[i] = CurrentCluster;
+          }
+          memcpy (FatChain, Fcb->FatChain, Fcb->FatChainSize * sizeof(ULONG));
+          ExFreePool(Fcb->FatChain);
+          Fcb->FatChain = FatChain;
+          Fcb->FatChainSize = Offset + 1;
+        }
+      }
+      *Cluster = CurrentCluster;
       return(STATUS_SUCCESS);
     }
   if (FirstCluster == 1)