branch update for HEAD-2003091401
[reactos.git] / drivers / fs / vfat / rw.c
index a28ca12..6b70bb4 100644 (file)
@@ -15,6 +15,8 @@
 #include <wchar.h>
 #include <ntos/minmax.h>
 
+#include <ntos.h>
+
 #define NDEBUG
 #include <debug.h>
 
@@ -24,7 +26,6 @@
 
 NTSTATUS
 NextCluster(PDEVICE_EXTENSION DeviceExt,
-           PVFATFCB Fcb,
            ULONG FirstCluster,
            PULONG CurrentCluster,
            BOOLEAN Extend)
@@ -33,88 +34,7 @@ NextCluster(PDEVICE_EXTENSION DeviceExt,
       * necessary
       */
 {
-  if (Fcb != NULL && Fcb->Flags & FCB_IS_PAGE_FILE)
-    {
-      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 == NULL)
-               {
-                 return(STATUS_NO_MEMORY);
-               }
-             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_NO_MEMORY;
-                   }
-                 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_SUCCESS;
-               }
-           }
-         *CurrentCluster = Fcb->FatChain[i + 1];
-         return STATUS_SUCCESS;
-       }
-    }
-  if (FirstCluster == 1)
+ if (FirstCluster == 1)
     {
       (*CurrentCluster) += DeviceExt->FatInfo.SectorsPerCluster;
       return(STATUS_SUCCESS);
@@ -146,7 +66,6 @@ NextCluster(PDEVICE_EXTENSION DeviceExt,
 
 NTSTATUS
 OffsetToCluster(PDEVICE_EXTENSION DeviceExt,
-               PVFATFCB Fcb,
                ULONG FirstCluster,
                ULONG FileOffset,
                PULONG Cluster,
@@ -159,77 +78,17 @@ 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);
+    KEBUGCHECK(0);
   }
 
-  if (Fcb != NULL && Fcb->Flags & FCB_IS_PAGE_FILE)
-    {
-      ULONG NCluster;
-      ULONG Offset = FileOffset / DeviceExt->FatInfo.BytesPerCluster;
-      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
-       {
-          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)
     {
       /* root of FAT16 or FAT12 */
@@ -361,7 +220,7 @@ VfatReadFileData (PVFAT_IRP_CONTEXT IrpContext, PVOID Buffer,
   {
     CurrentCluster = Ccb->LastCluster;
   }
-  Status = OffsetToCluster(DeviceExt, Fcb, FirstCluster,
+  Status = OffsetToCluster(DeviceExt, FirstCluster,
                           ROUND_DOWN(ReadOffset.u.LowPart, BytesPerCluster),
                           &CurrentCluster, FALSE);
   if (!NT_SUCCESS(Status))
@@ -399,7 +258,7 @@ VfatReadFileData (PVFAT_IRP_CONTEXT IrpContext, PVOID Buffer,
          BytesDone = Length;
        }
       }
-      Status = NextCluster(DeviceExt, Fcb, FirstCluster, &CurrentCluster, FALSE);
+      Status = NextCluster(DeviceExt, FirstCluster, &CurrentCluster, FALSE);
     }
     while (StartCluster + ClusterCount == CurrentCluster && NT_SUCCESS(Status) && Length > BytesDone);
     DPRINT("start %08x, next %08x, count %d\n",
@@ -414,7 +273,15 @@ VfatReadFileData (PVFAT_IRP_CONTEXT IrpContext, PVOID Buffer,
     if (NT_SUCCESS(Status))
     {
       *LengthRead += BytesDone;
+/* GCC allows arithmetics on the void type. Conforming compilers do not. */
+#ifdef __GNUC__
       Buffer += BytesDone;
+#else
+      {
+        char* pBuf = (char*)Buffer + BytesDone;
+        Buffer = (PVOID)pBuf;
+      }
+#endif
       Length -= BytesDone;
       ReadOffset.u.LowPart += BytesDone;
     }
@@ -515,7 +382,7 @@ NTSTATUS VfatWriteFileData(PVFAT_IRP_CONTEXT IrpContext,
       CurrentCluster = Ccb->LastCluster;
    }
 
-   Status = OffsetToCluster(DeviceExt, Fcb, FirstCluster,
+   Status = OffsetToCluster(DeviceExt, FirstCluster,
                            ROUND_DOWN(WriteOffset.u.LowPart, BytesPerCluster),
                            &CurrentCluster, FALSE);
 
@@ -554,7 +421,7 @@ NTSTATUS VfatWriteFileData(PVFAT_IRP_CONTEXT IrpContext,
               BytesDone = Length;
            }
          }
-         Status = NextCluster(DeviceExt, Fcb, FirstCluster, &CurrentCluster, FALSE);
+         Status = NextCluster(DeviceExt, FirstCluster, &CurrentCluster, FALSE);
       }
       while (StartCluster + ClusterCount == CurrentCluster && NT_SUCCESS(Status) && Length > BytesDone);
       DPRINT("start %08x, next %08x, count %d\n",
@@ -567,7 +434,15 @@ NTSTATUS VfatWriteFileData(PVFAT_IRP_CONTEXT IrpContext,
       Status = VfatWriteDisk (DeviceExt->StorageDevice, &StartOffset, BytesDone, Buffer);
       if (NT_SUCCESS(Status))
       {
+/* GCC allows arithmetics on the void type. Conforming compilers do not. */
+#ifdef __GNUC__
          Buffer += BytesDone;
+#else
+         {
+            char* pBuf = (char*)Buffer + BytesDone;
+            Buffer = (PVOID)pBuf;
+         }
+#endif
          Length -= BytesDone;
          WriteOffset.u.LowPart += BytesDone;
       }
@@ -585,7 +460,7 @@ VfatRead(PVFAT_IRP_CONTEXT IrpContext)
    PERESOURCE Resource = NULL;
    LARGE_INTEGER ByteOffset;
    PVOID Buffer;
-   PDEVICE_OBJECT DeviceToVerify;
+   /*PDEVICE_OBJECT DeviceToVerify;*/
    ULONG BytesPerSector;
 
    assert(IrpContext);
@@ -609,6 +484,19 @@ VfatRead(PVFAT_IRP_CONTEXT IrpContext)
 
    DPRINT("<%S>\n", Fcb->PathName);
 
+   if (Fcb->Flags & FCB_IS_PAGE_FILE)
+   {
+      PIO_STACK_LOCATION Stack;
+      PFATINFO FatInfo = &IrpContext->DeviceExt->FatInfo;
+      IoCopyCurrentIrpStackLocationToNext(IrpContext->Irp);
+      Stack = IoGetNextIrpStackLocation(IrpContext->Irp);
+      Stack->Parameters.Read.ByteOffset.QuadPart += FatInfo->dataStart * FatInfo->BytesPerSector;
+      DPRINT("Read from page file, disk offset %I64x\n", Stack->Parameters.Read.ByteOffset.QuadPart);
+      Status = IoCallDriver(IrpContext->DeviceExt->StorageDevice, IrpContext->Irp);
+      VfatFreeIrpContext(IrpContext);
+      return Status;
+   }
+
    ByteOffset = IrpContext->Stack->Parameters.Read.ByteOffset;
    Length = IrpContext->Stack->Parameters.Read.Length;
    BytesPerSector = IrpContext->DeviceExt->FatInfo.BytesPerSector;
@@ -663,7 +551,8 @@ VfatRead(PVFAT_IRP_CONTEXT IrpContext)
    {
       Resource = &Fcb->MainResource;
    }
-   if (!ExAcquireResourceSharedLite(Resource, IrpContext->Flags & IRPCONTEXT_CANWAIT))
+   if (!ExAcquireResourceSharedLite(Resource,
+                                    (BOOLEAN)(IrpContext->Flags & IRPCONTEXT_CANWAIT)))
    {
       Resource = NULL;
       Status = STATUS_PENDING;
@@ -711,7 +600,7 @@ VfatRead(PVFAT_IRP_CONTEXT IrpContext)
          CcRosInitializeFileCache(IrpContext->FileObject, CacheSize);
       }
       if (!CcCopyRead(IrpContext->FileObject, &ByteOffset, Length,
-                      IrpContext->Flags & IRPCONTEXT_CANWAIT, Buffer,
+                      (BOOLEAN)(IrpContext->Flags & IRPCONTEXT_CANWAIT), Buffer,
                       &IrpContext->Irp->IoStatus))
       {
          Status = STATUS_PENDING;
@@ -729,7 +618,7 @@ VfatRead(PVFAT_IRP_CONTEXT IrpContext)
       CHECKPOINT;
       if (ByteOffset.QuadPart + Length > ROUND_UP(Fcb->RFCB.FileSize.QuadPart, BytesPerSector))
       {
-         Length = ROUND_UP(Fcb->RFCB.FileSize.QuadPart, BytesPerSector) - ByteOffset.QuadPart;
+         Length = (ULONG)(ROUND_UP(Fcb->RFCB.FileSize.QuadPart, BytesPerSector) - ByteOffset.QuadPart);
       }
 
       Buffer = VfatGetUserBuffer(IrpContext->Irp);
@@ -793,7 +682,7 @@ ByeBye:
       }
 
       IoCompleteRequest(IrpContext->Irp,
-                        NT_SUCCESS(Status) ? IO_DISK_INCREMENT : IO_NO_INCREMENT);
+                        (CCHAR)(NT_SUCCESS(Status) ? IO_DISK_INCREMENT : IO_NO_INCREMENT));
       VfatFreeIrpContext(IrpContext);
    }
    DPRINT("%x\n", Status);
@@ -833,7 +722,20 @@ NTSTATUS VfatWrite (PVFAT_IRP_CONTEXT IrpContext)
 
    DPRINT("<%S>\n", Fcb->PathName);
 
-   /* fail if file is a directory and no paged read */
+   if (Fcb->Flags & FCB_IS_PAGE_FILE)
+   {
+      PIO_STACK_LOCATION Stack;
+      PFATINFO FatInfo = &IrpContext->DeviceExt->FatInfo;
+      IoCopyCurrentIrpStackLocationToNext(IrpContext->Irp);
+      Stack = IoGetNextIrpStackLocation(IrpContext->Irp);
+      Stack->Parameters.Write.ByteOffset.QuadPart += FatInfo->dataStart * FatInfo->BytesPerSector;
+      DPRINT("Write to page file, disk offset %I64x\n", Stack->Parameters.Write.ByteOffset.QuadPart);
+      Status = IoCallDriver(IrpContext->DeviceExt->StorageDevice, IrpContext->Irp);
+      VfatFreeIrpContext(IrpContext);
+      return Status;
+   }
+
+  /* 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_INVALID_PARAMETER;
@@ -906,7 +808,8 @@ NTSTATUS VfatWrite (PVFAT_IRP_CONTEXT IrpContext)
 
    if (Fcb->Flags & FCB_IS_PAGE_FILE)
    {
-      if (!ExAcquireResourceSharedLite(Resource, IrpContext->Flags & IRPCONTEXT_CANWAIT))
+      if (!ExAcquireResourceSharedLite(Resource,
+                                       (BOOLEAN)(IrpContext->Flags & IRPCONTEXT_CANWAIT)))
       {
          Resource = NULL;
          Status = STATUS_PENDING;
@@ -915,7 +818,8 @@ NTSTATUS VfatWrite (PVFAT_IRP_CONTEXT IrpContext)
    }
    else
    {
-      if (!ExAcquireResourceExclusiveLite(Resource, IrpContext->Flags & IRPCONTEXT_CANWAIT))
+      if (!ExAcquireResourceExclusiveLite(Resource,
+                                          (BOOLEAN)(IrpContext->Flags & IRPCONTEXT_CANWAIT)))
       {
          Resource = NULL;
          Status = STATUS_PENDING;
@@ -1071,7 +975,7 @@ ByeBye:
       }
 
       IoCompleteRequest(IrpContext->Irp,
-                        NT_SUCCESS(Status) ? IO_DISK_INCREMENT : IO_NO_INCREMENT);
+                        (CCHAR)(NT_SUCCESS(Status) ? IO_DISK_INCREMENT : IO_NO_INCREMENT));
       VfatFreeIrpContext(IrpContext);
    }
    DPRINT("%x\n", Status);