All:
authorHartmut Birr <osexpert@googlemail.com>
Mon, 18 Mar 2002 22:37:13 +0000 (22:37 +0000)
committerHartmut Birr <osexpert@googlemail.com>
Mon, 18 Mar 2002 22:37:13 +0000 (22:37 +0000)
Changed directory and fat access to pining-interface.
Removed unused values from DEVICE_EXTENSION structure.
Changed calculation of available and free clusters.
Changed mount and type determining procedure.
Moved some functions to fsctl.c

volume.c:
Added FAT32 fs type.

dirw.c:
Fixed a directory creation bug on FAT32 (Thanks to Eric Kohl).
Fixed a directory deletion bug.

dir.c:
Fixed a dead lock in DoQuery.
Fixed some memory leakages.

svn path=/trunk/; revision=2737

14 files changed:
reactos/drivers/fs/vfat/blockdev.c
reactos/drivers/fs/vfat/create.c
reactos/drivers/fs/vfat/dir.c
reactos/drivers/fs/vfat/direntry.c
reactos/drivers/fs/vfat/dirwr.c
reactos/drivers/fs/vfat/fat.c
reactos/drivers/fs/vfat/fcb.c
reactos/drivers/fs/vfat/finfo.c
reactos/drivers/fs/vfat/fsctl.c [new file with mode: 0644]
reactos/drivers/fs/vfat/iface.c
reactos/drivers/fs/vfat/makefile
reactos/drivers/fs/vfat/rw.c
reactos/drivers/fs/vfat/vfat.h
reactos/drivers/fs/vfat/volume.c

index 7bf65fa..bae26a7 100644 (file)
@@ -141,3 +141,67 @@ VfatWriteSectors (IN PDEVICE_OBJECT pDeviceObject,
   DPRINT ("Block request succeeded\n");
   return (STATUS_SUCCESS);
 }
+
+NTSTATUS
+VfatBlockDeviceIoControl (IN PDEVICE_OBJECT DeviceObject,
+                         IN ULONG CtlCode,
+                         IN PVOID InputBuffer,
+                         IN ULONG InputBufferSize,
+                         IN OUT PVOID OutputBuffer, 
+                         IN OUT PULONG pOutputBufferSize)
+{
+       ULONG OutputBufferSize = 0;
+       KEVENT Event;
+       PIRP Irp;
+       IO_STATUS_BLOCK IoStatus;
+       NTSTATUS Status;
+
+       DPRINT("VfatBlockDeviceIoControl(DeviceObject %x, CtlCode %x, "
+              "InputBuffer %x, InputBufferSize %x, OutputBuffer %x, " 
+              "POutputBufferSize %x (%x)\n", DeviceObject, CtlCode, 
+              InputBuffer, InputBufferSize, OutputBuffer, pOutputBufferSize, 
+              pOutputBufferSize ? *pOutputBufferSize : 0);
+
+       if (pOutputBufferSize)
+       {
+               OutputBufferSize = *pOutputBufferSize;
+       }
+
+       KeInitializeEvent (&Event, NotificationEvent, FALSE);
+
+       DPRINT("Building device I/O control request ...\n");
+       Irp = IoBuildDeviceIoControlRequest(CtlCode, 
+                                           DeviceObject, 
+                                           InputBuffer, 
+                                           InputBufferSize, 
+                                           OutputBuffer,
+                                           OutputBufferSize, 
+                                           FALSE, 
+                                           &Event, 
+                                           &IoStatus);
+
+       if (Irp == NULL)
+       {
+               DPRINT("IoBuildDeviceIoControlRequest failed\n");
+               return STATUS_INSUFFICIENT_RESOURCES;
+       }
+
+       DPRINT ("Calling IO Driver... with irp %x\n", Irp);
+       Status = IoCallDriver(DeviceObject, Irp);
+
+       DPRINT ("Waiting for IO Operation for %x\n", Irp);
+       if (Status == STATUS_PENDING)
+       {
+               DPRINT ("Operation pending\n");
+               KeWaitForSingleObject (&Event, Suspended, KernelMode, FALSE, NULL);
+               DPRINT ("Getting IO Status... for %x\n", Irp);
+
+               Status = IoStatus.Status;
+       }
+       if (OutputBufferSize)
+       {
+               *pOutputBufferSize = OutputBufferSize;
+       }
+       DPRINT("Returning Status %x\n", Status);
+       return Status;
+}
index 833deaa..307e713 100644 (file)
@@ -1,4 +1,4 @@
-/* $Id: create.c,v 1.38 2002/02/08 02:57:09 chorns Exp $
+/* $Id: create.c,v 1.39 2002/03/18 22:37:12 hbirr Exp $
  *
  * COPYRIGHT:        See COPYING in the top level directory
  * PROJECT:          ReactOS kernel
@@ -220,80 +220,60 @@ ReadVolumeLabel (PDEVICE_EXTENSION DeviceExt, PVPB Vpb)
  * FUNCTION: Read the volume label
  */
 {
-  ULONG i = 0;
-  ULONG j;
-  ULONG Size;
-  char *block;
-  ULONG StartingSector;
-  ULONG NextCluster;
-  NTSTATUS Status;
+  PVOID Context = NULL;
+  ULONG Offset = 0;
+  ULONG DirIndex = 0;
+  FATDirEntry* Entry;
+  PVFATFCB pFcb;
+  LARGE_INTEGER FileOffset;
 
-  Size = DeviceExt->rootDirectorySectors;      /* FIXME : in fat32, no limit */
-  StartingSector = DeviceExt->rootStart;
-  NextCluster = 0;
+  *(Vpb->VolumeLabel) = 0;
+  Vpb->VolumeLabelLength = 0;
 
-  block = ExAllocatePool (NonPagedPool, BLOCKSIZE);
-  DPRINT ("ReadVolumeLabel : start at sector %lx, entry %ld\n", StartingSector, i);
-  for (j = 0; j < Size; j++)
-    {
-      /* FIXME: Check status */
-      Status = VfatReadSectors (DeviceExt->StorageDevice, StartingSector, 1, block);
-      if (!NT_SUCCESS(Status))
-       {
-         *(Vpb->VolumeLabel) = 0;
-         Vpb->VolumeLabelLength = 0;
-         ExFreePool(block);
-         return(Status);
-       }
+  pFcb = vfatOpenRootFCB (DeviceExt);
 
-      for (i = 0; i < ENTRIES_PER_SECTOR; i++)
-       {
-         if (IsVolEntry ((PVOID) block, i))
-           {
-             FATDirEntry *test = (FATDirEntry *) block;
-
-             /* copy volume label */
-             vfat8Dot3ToVolumeLabel (test[i].Filename, test[i].Ext, Vpb->VolumeLabel);
-             Vpb->VolumeLabelLength = wcslen (Vpb->VolumeLabel);
-
-             ExFreePool (block);
-             return (STATUS_SUCCESS);
-           }
-         if (IsLastEntry ((PVOID) block, i))
-           {
-             *(Vpb->VolumeLabel) = 0;
-             Vpb->VolumeLabelLength = 0;
-             ExFreePool (block);
-             return (STATUS_UNSUCCESSFUL);
-           }
-       }
-      /* not found in this sector, try next : */
+  while (TRUE)
+  {
+    if (Context == NULL || Offset == ENTRIES_PER_PAGE)
+    {
+      if (Offset == ENTRIES_PER_PAGE)
+      {
+        Offset = 0;
+      }
+      if (Context)
+      {
+        CcUnpinData(Context);
+      }
+      FileOffset.u.HighPart = 0;
+      FileOffset.u.LowPart = (DirIndex - Offset) * sizeof(FATDirEntry);
+      if (!CcMapData(pFcb->FileObject, &FileOffset, PAGESIZE, TRUE, &Context, (PVOID*)&Entry))
+      {
+        Context = NULL;
+        break;
+      }
+    }
+    if (IsVolEntry(Entry, Offset))
+    {
+      /* copy volume label */
+      vfat8Dot3ToVolumeLabel (Entry[Offset].Filename, Entry[Offset].Ext, Vpb->VolumeLabel);
+      Vpb->VolumeLabelLength = wcslen (Vpb->VolumeLabel) * sizeof(WCHAR);
+      break;
+    }
+    if (IsLastEntry(Entry, Offset))
+    {
+      break;
+    }
+    Offset++;
+    DirIndex++;
+  }
 
-      /* directory can be fragmented although it is best to keep them
-         unfragmented.*/
-      StartingSector++;
+  if (Context)
+  {
+    CcUnpinData(Context);
+  }
+  vfatReleaseFCB (DeviceExt, pFcb);
 
-      if (DeviceExt->FatType == FAT32)
-       {
-         if (StartingSector == ClusterToSector (DeviceExt, NextCluster + 1))
-           {
-             Status = GetNextCluster (DeviceExt, NextCluster, &NextCluster,
-                                      FALSE);
-             if (NextCluster == 0 || NextCluster == 0xffffffff)
-               {
-                 *(Vpb->VolumeLabel) = 0;
-                 Vpb->VolumeLabelLength = 0;
-                 ExFreePool (block);
-                 return (STATUS_UNSUCCESSFUL);
-               }
-             StartingSector = ClusterToSector (DeviceExt, NextCluster);
-           }
-       }
-    }
-  *(Vpb->VolumeLabel) = 0;
-  Vpb->VolumeLabelLength = 0;
-  ExFreePool (block);
-  return (STATUS_UNSUCCESSFUL);
+  return STATUS_SUCCESS;
 }
 
 NTSTATUS
@@ -336,9 +316,9 @@ FindFile (PDEVICE_EXTENSION DeviceExt,
   if (Parent)
   {
     FirstCluster = vfatDirEntryGetFirstCluster(DeviceExt, &Parent->entry);
-    if (DeviceExt->FatType == FAT32)
+    if (DeviceExt->FatInfo.FatType == FAT32)
     {
-      if (FirstCluster == ((struct _BootSector32*)(DeviceExt->Boot))->RootCluster)
+      if (FirstCluster == DeviceExt->FatInfo.RootCluster)
         isRoot = TRUE;
     }
     else
@@ -351,8 +331,8 @@ FindFile (PDEVICE_EXTENSION DeviceExt,
     isRoot = TRUE;
   if (isRoot)
   {
-    if (DeviceExt->FatType == FAT32)
-      FirstCluster = ((struct _BootSector32*)(DeviceExt->Boot))->RootCluster;
+    if (DeviceExt->FatInfo.FatType == FAT32)
+      FirstCluster = DeviceExt->FatInfo.RootCluster;
     else
       FirstCluster = 1;
 
@@ -366,9 +346,9 @@ FindFile (PDEVICE_EXTENSION DeviceExt,
          CHECKPOINT;
          Fcb->PathName[0]='\\';
          Fcb->ObjectName = &Fcb->PathName[1];
-         Fcb->entry.FileSize = DeviceExt->rootDirectorySectors * BLOCKSIZE;
+         Fcb->entry.FileSize = DeviceExt->FatInfo.rootDirectorySectors * BLOCKSIZE;
          Fcb->entry.Attrib = FILE_ATTRIBUTE_DIRECTORY;
-         if (DeviceExt->FatType == FAT32)
+         if (DeviceExt->FatInfo.FatType == FAT32)
       {
            Fcb->entry.FirstCluster = ((PUSHORT)FirstCluster)[0];
         Fcb->entry.FirstClusterHigh = ((PUSHORT)FirstCluster)[1];
@@ -630,7 +610,11 @@ VfatCreateFile (PDEVICE_OBJECT DeviceObject, PIRP Irp)
       Irp->IoStatus.Status = Status;
       return Status;
     }
-
+  if (Status == STATUS_INVALID_PARAMETER)
+    {
+      Irp->IoStatus.Status = Status;
+      return Status;
+    }
   if (Status == STATUS_DELETE_PENDING)
   {
     Irp->IoStatus.Status = Status;
@@ -694,7 +678,7 @@ VfatCreateFile (PDEVICE_OBJECT DeviceObject, PIRP Irp)
        ULONG Cluster, NextCluster;
        /* FIXME set size to 0 and free clusters */
        pFcb->entry.FileSize = 0;
-       if (DeviceExt->FatType == FAT32)
+       if (DeviceExt->FatInfo.FatType == FAT32)
            Cluster = pFcb->entry.FirstCluster
              + pFcb->entry.FirstClusterHigh * 65536;
        else
@@ -726,15 +710,15 @@ VfatCreateFile (PDEVICE_OBJECT DeviceObject, PIRP Irp)
        ULONG CurrentCluster, NextCluster, i;
        DPRINT("Open an existing paging file\n");
        pFcb->Flags |= FCB_IS_PAGE_FILE;
-       pFcb->FatChainSize = 
-         ((pFcb->entry.FileSize + DeviceExt->BytesPerCluster - 1) / DeviceExt->BytesPerCluster);
+       pFcb->FatChainSize =
+         ((pFcb->entry.FileSize + DeviceExt->FatInfo.BytesPerCluster - 1) / DeviceExt->FatInfo.BytesPerCluster);
        if (pFcb->FatChainSize)
        {
          pFcb->FatChain = ExAllocatePool(NonPagedPool, 
                                        pFcb->FatChainSize * sizeof(ULONG));
        }
 
-       if (DeviceExt->FatType == FAT32)
+       if (DeviceExt->FatInfo.FatType == FAT32)
          {
            CurrentCluster = pFcb->entry.FirstCluster + 
              pFcb->entry.FirstClusterHigh * 65536;
index 82b3dee..2d4e954 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * $Id: dir.c,v 1.23 2002/02/05 21:31:03 hbirr Exp $
+ * $Id: dir.c,v 1.24 2002/03/18 22:37:12 hbirr Exp $
  *
  * COPYRIGHT:        See COPYING in the top level directory
  * PROJECT:          ReactOS kernel
@@ -136,8 +136,8 @@ VfatGetFileDirectoryInformation (PVFATFCB pFcb,
                            &pInfo->ChangeTime);
   pInfo->EndOfFile = RtlConvertUlongToLargeInteger (pFcb->entry.FileSize);
   /* Make allocsize a rounded up multiple of BytesPerCluster */
-  AllocSize = ((pFcb->entry.FileSize + DeviceExt->BytesPerCluster - 1) /
-              DeviceExt->BytesPerCluster) * DeviceExt->BytesPerCluster;
+  AllocSize = ((pFcb->entry.FileSize + DeviceExt->FatInfo.BytesPerCluster - 1) /
+              DeviceExt->FatInfo.BytesPerCluster) * DeviceExt->FatInfo.BytesPerCluster;
   pInfo->AllocationSize.QuadPart = AllocSize;
   pInfo->FileAttributes = pFcb->entry.Attrib;
 
@@ -170,8 +170,8 @@ VfatGetFileFullDirectoryInformation (PVFATFCB pFcb,
                            &pInfo->ChangeTime);
   pInfo->EndOfFile = RtlConvertUlongToLargeInteger (pFcb->entry.FileSize);
   /* Make allocsize a rounded up multiple of BytesPerCluster */
-  AllocSize = ((pFcb->entry.FileSize + DeviceExt->BytesPerCluster - 1) /
-              DeviceExt->BytesPerCluster) * DeviceExt->BytesPerCluster;
+  AllocSize = ((pFcb->entry.FileSize + DeviceExt->FatInfo.BytesPerCluster - 1) /
+              DeviceExt->FatInfo.BytesPerCluster) * DeviceExt->FatInfo.BytesPerCluster;
   pInfo->AllocationSize.QuadPart = AllocSize;
   pInfo->FileAttributes = pFcb->entry.Attrib;
 //      pInfo->EaSize=;
@@ -205,8 +205,8 @@ VfatGetFileBothInformation (PVFATFCB pFcb,
                            &pInfo->ChangeTime);
   pInfo->EndOfFile = RtlConvertUlongToLargeInteger (pFcb->entry.FileSize);
   /* Make allocsize a rounded up multiple of BytesPerCluster */
-  AllocSize = ((pFcb->entry.FileSize + DeviceExt->BytesPerCluster - 1) /
-              DeviceExt->BytesPerCluster) * DeviceExt->BytesPerCluster;
+  AllocSize = ((pFcb->entry.FileSize + DeviceExt->FatInfo.BytesPerCluster - 1) /
+              DeviceExt->FatInfo.BytesPerCluster) * DeviceExt->FatInfo.BytesPerCluster;
   pInfo->AllocationSize.QuadPart = AllocSize;
   pInfo->FileAttributes = pFcb->entry.Attrib;
 //      pInfo->EaSize=;
@@ -255,10 +255,11 @@ NTSTATUS DoQuery (PVFAT_IRP_CONTEXT IrpContext)
     if (!pCcb->DirectorySearchPattern)
     {
       First = TRUE;
-      pCcb->DirectorySearchPattern = 
+      pCcb->DirectorySearchPattern =
         ExAllocatePool(NonPagedPool, pSearchPattern->Length + sizeof(WCHAR));
       if (!pCcb->DirectorySearchPattern)
       {
+        ExReleaseResourceLite(&pFcb->MainResource);
         return STATUS_INSUFFICIENT_RESOURCES;
       }
       memcpy(pCcb->DirectorySearchPattern, pSearchPattern->Buffer,
@@ -272,12 +273,13 @@ NTSTATUS DoQuery (PVFAT_IRP_CONTEXT IrpContext)
     pCcb->DirectorySearchPattern = ExAllocatePool(NonPagedPool, 2 * sizeof(WCHAR));
     if (!pCcb->DirectorySearchPattern)
     {
+      ExReleaseResourceLite(&pFcb->MainResource);
       return STATUS_INSUFFICIENT_RESOURCES;
     }
     pCcb->DirectorySearchPattern[0] = L'*';
     pCcb->DirectorySearchPattern[1] = 0;
-  }  
-     
+  }
+
   if (IrpContext->Stack->Flags & SL_INDEX_SPECIFIED)
   {
     pCcb->Entry = pCcb->CurrentByteOffset.u.LowPart;
@@ -369,11 +371,7 @@ NTSTATUS DoQuery (PVFAT_IRP_CONTEXT IrpContext)
   {
     RC = STATUS_SUCCESS;
   }
-  if (IrpContext->Flags & IRPCONTEXT_CANWAIT)
-  {
-    ExReleaseResourceLite(&pFcb->MainResource);
-  }
-
+  ExReleaseResourceLite(&pFcb->MainResource);
   return RC;
 }
 
index bbfda01..910f790 100644 (file)
@@ -1,4 +1,4 @@
-/* $Id: direntry.c,v 1.5 2001/10/10 22:14:34 hbirr Exp $
+/* $Id: direntry.c,v 1.6 2002/03/18 22:37:12 hbirr Exp $
  *
  *
  * FILE:             DirEntry.c
 
 #include "vfat.h"
 
-#define  CACHEPAGESIZE(pDeviceExt) ((pDeviceExt)->BytesPerCluster > PAGESIZE ? \
-                  (pDeviceExt)->BytesPerCluster : PAGESIZE)
+#define  CACHEPAGESIZE(pDeviceExt) ((pDeviceExt)->FatInfo.BytesPerCluster > PAGESIZE ? \
+                  (pDeviceExt)->FatInfo.BytesPerCluster : PAGESIZE)
 
 #define  ENTRIES_PER_CACHEPAGE(pDeviceExt)  (ENTRIES_PER_SECTOR * \
-                  (CACHEPAGESIZE(pDeviceExt) / ((pDeviceExt)->BytesPerSector)))
+                  (CACHEPAGESIZE(pDeviceExt) / ((pDeviceExt)->FatInfo.BytesPerSector)))
 
 
 ULONG 
@@ -33,7 +33,7 @@ vfatDirEntryGetFirstCluster (PDEVICE_EXTENSION  pDeviceExt,
 {
   ULONG  cluster;
 
-  if (pDeviceExt->FatType == FAT32)
+  if (pDeviceExt->FatInfo.FatType == FAT32)
   {
     cluster = pFatDirEntry->FirstCluster + 
       pFatDirEntry->FirstClusterHigh * 65536;
index 5d5a183..82347c6 100644 (file)
@@ -1,4 +1,4 @@
-/* $Id: dirwr.c,v 1.23 2002/01/08 00:49:01 dwelch Exp $
+/* $Id: dirwr.c,v 1.24 2002/03/18 22:37:12 hbirr Exp $
  *
  * COPYRIGHT:        See COPYING in the top level directory
  * PROJECT:          ReactOS kernel
@@ -31,69 +31,10 @@ vfatIsShortIllegal(char c)
   return FALSE;
 }
 
-/*
- * Copies a file name into a directory slot (long file name entry)
- * and fills trailing slot space with 0xFFFF. This keeps scandisk
- * from complaining.
- */
-static VOID
-FillSlot (slot * Slot, WCHAR * FileName)
-{
-  BOOLEAN fill = FALSE;
-  WCHAR *src = FileName;
-  WCHAR *dst;
-  int i;
-
-  i = 5;
-  dst = Slot->name0_4;
-  while (i-- > 0)
-    {
-      if (fill == FALSE)
-       *dst = *src;
-      else
-       *dst = 0xffff;
-
-      if (fill == FALSE && (*src == 0))
-       fill = TRUE;
-      dst++;
-      src++;
-    }
-
-  i = 6;
-  dst = Slot->name5_10;
-  while (i-- > 0)
-    {
-      if (fill == FALSE)
-       *dst = *src;
-      else
-       *dst = 0xffff;
-
-      if (fill == FALSE && (*src == 0))
-       fill = TRUE;
-      dst++;
-      src++;
-    }
-
-  i = 2;
-  dst = Slot->name11_12;
-  while (i-- > 0)
-    {
-      if (fill == FALSE)
-       *dst = *src;
-      else
-       *dst = 0xffff;
-
-      if (fill == FALSE && (*src == 0))
-       fill = TRUE;
-      dst++;
-      src++;
-    }
-}
-
 NTSTATUS updEntry (PDEVICE_EXTENSION DeviceExt, PFILE_OBJECT pFileObject)
 /*
-  update an existing FAT entry
-*/
* update an existing FAT entry
+ */
 {
   PVOID Context;
   PVOID Buffer;
@@ -118,9 +59,10 @@ NTSTATUS updEntry (PDEVICE_EXTENSION DeviceExt, PFILE_OBJECT pFileObject)
     return status;
   }
 
-  Offset.QuadPart = pFcb->dirIndex * sizeof(FATDirEntry);
-  if(CcMapData (pDirFcb->FileObject, &Offset, sizeof(FATDirEntry),
-    TRUE, &Context, &Buffer))
+  Offset.u.HighPart = 0;
+  Offset.u.LowPart = pFcb->dirIndex * sizeof(FATDirEntry);
+  if (CcMapData (pDirFcb->FileObject, &Offset, sizeof(FATDirEntry),
+    TRUE, &Context, (PVOID*)&Buffer))
   {
      memcpy(Buffer, &pFcb->entry, sizeof(FATDirEntry));
      CcSetDirtyPinnedData(Context, NULL);
@@ -128,42 +70,147 @@ NTSTATUS updEntry (PDEVICE_EXTENSION DeviceExt, PFILE_OBJECT pFileObject)
   }
   else
      DPRINT1 ("Failed write to \'%S\'.\n", pDirFcb->PathName);
-   vfatReleaseFCB(DeviceExt, pDirFcb);
+  vfatReleaseFCB(DeviceExt, pDirFcb);
   return STATUS_SUCCESS;
 }
 
+BOOLEAN
+findDirSpace(PDEVICE_EXTENSION DeviceExt,
+             PVFATFCB pDirFcb,
+             ULONG nbSlots,
+             PULONG start)
+{
+/*
+ * try to find contiguous entries frees in directory,
+ * extend a directory if is neccesary
+ */
+  LARGE_INTEGER FileOffset;
+  ULONG i, count, size, nbFree = 0;
+  FATDirEntry* pFatEntry;
+  PVOID Context = NULL;
+  NTSTATUS Status;
+  FileOffset.QuadPart = 0;
+  count = pDirFcb->RFCB.FileSize.u.LowPart / sizeof(FATDirEntry);
+  size = DeviceExt->FatInfo.BytesPerCluster / sizeof(FATDirEntry);
+  for (i = 0; i < count; i++, pFatEntry++)
+  {
+    if (Context == NULL || (i % size) == 0)
+    {
+      if (Context)
+      {
+        CcUnpinData(Context);
+      }
+      // FIXME: check return value
+      CcMapData (pDirFcb->FileObject, &FileOffset, DeviceExt->FatInfo.BytesPerCluster,
+                 TRUE, &Context, (PVOID*)&pFatEntry);
+      FileOffset.u.LowPart += DeviceExt->FatInfo.BytesPerCluster;
+    }
+    if (vfatIsDirEntryEndMarker(pFatEntry))
+    {
+      break;
+    }
+    if (vfatIsDirEntryDeleted(pFatEntry))
+    {
+      nbFree++;
+    }
+    else
+    {
+      nbFree = 0;
+    }
+    if (nbFree == nbSlots)
+    {
+      break;
+    }
+  }
+  if (Context)
+  {
+    CcUnpinData(Context);
+  }
+  if (nbFree == nbSlots)
+  {
+    // found enough contiguous free slots
+    *start = i - nbSlots + 1;
+  }
+  else
+  {
+    *start = i - nbFree;
+    if (*start + nbSlots > count)
+    {
+      CHECKPOINT;
+      // extend the directory
+      if (vfatFCBIsRoot(pDirFcb) && DeviceExt->FatInfo.FatType != FAT32)
+      {
+        // We can't extend a root directory on a FAT12/FAT16 partition
+        return FALSE;
+      }
+      Status = vfatExtendSpace (DeviceExt, pDirFcb->FileObject,
+                 pDirFcb->RFCB.FileSize.u.LowPart + DeviceExt->FatInfo.BytesPerCluster);
+      if (!NT_SUCCESS(Status))
+      {
+        return FALSE;
+      }
+      // clear the new dir cluster
+      FileOffset.u.LowPart = pDirFcb->RFCB.FileSize.QuadPart -
+                               DeviceExt->FatInfo.BytesPerCluster;
+      CcMapData (pDirFcb->FileObject, &FileOffset, DeviceExt->FatInfo.BytesPerCluster,
+                 TRUE, &Context, (PVOID*)&pFatEntry);
+      RtlZeroMemory(pFatEntry, DeviceExt->FatInfo.BytesPerCluster);
+    }
+    else if (*start + nbSlots < count)
+    {
+      // clear the entry after the last new entry
+      FileOffset.u.LowPart = (*start + nbSlots) * sizeof(FATDirEntry);
+      CcMapData (pDirFcb->FileObject, &FileOffset, sizeof(FATDirEntry),
+                 TRUE, &Context, (PVOID*)&pFatEntry);
+      RtlZeroMemory(pFatEntry, sizeof(FATDirEntry));
+    }
+    CcSetDirtyPinnedData(Context, NULL);
+    CcUnpinData(Context);
+  }
+  DPRINT ("nbSlots %d nbFree %d, entry number %d\n", nbSlots, nbFree, *start);
+  return TRUE;
+}
+
 NTSTATUS
 addEntry (PDEVICE_EXTENSION DeviceExt,
-         PFILE_OBJECT pFileObject, ULONG RequestedOptions, UCHAR ReqAttr)
+          PFILE_OBJECT pFileObject,
+          ULONG RequestedOptions,
+          UCHAR ReqAttr)
 /*
   create a new FAT entry
 */
 {
   WCHAR DirName[MAX_PATH], *FileName, *PathFileName;
   VFATFCB FileFcb;
-  FATDirEntry FatEntry;
-  NTSTATUS status;
-  FATDirEntry *pEntry;
+  PVOID Context = NULL;
+  FATDirEntry *pFatEntry, *pEntry;
   slot *pSlots;
-  ULONG LengthRead, Offset;
-  short nbSlots = 0, nbFree = 0, i, j, posCar, NameLen;
-  PUCHAR Buffer, Buffer2;
+  short nbSlots = 0, nbFree = 0, j, posCar, NameLen;
+  PUCHAR Buffer;
   BOOLEAN needTilde = FALSE, needLong = FALSE;
   PVFATFCB newFCB;
   ULONG CurrentCluster;
-  LARGE_INTEGER SystemTime, LocalTime;
+  LARGE_INTEGER SystemTime, LocalTime, FileOffset;
   NTSTATUS Status = STATUS_SUCCESS;
   PVFATFCB pDirFcb;
+  ULONG start, size;
+  long i;
 
   PathFileName = pFileObject->FileName.Buffer;
   DPRINT ("addEntry: Pathname=%S\n", PathFileName);
   //find last \ in PathFileName
   posCar = -1;
   for (i = 0; PathFileName[i]; i++)
-    if (PathFileName[i] == '\\')
+  {
+    if (PathFileName[i] == L'\\')
+    {
       posCar = i;
+    }
+  }
   if (posCar == -1)
+  {
     return STATUS_UNSUCCESSFUL;
+  }
   FileName = &PathFileName[posCar + 1];
   for (NameLen = 0; FileName[NameLen]; NameLen++);
   // extract directory name from pathname
@@ -186,9 +233,8 @@ addEntry (PDEVICE_EXTENSION DeviceExt,
   }
   nbSlots = (NameLen + 12) / 13 + 1;   //nb of entry needed for long name+normal entry
   DPRINT ("NameLen= %d, nbSlots =%d\n", NameLen, nbSlots);
-  Buffer =
-    ExAllocatePool (NonPagedPool, (nbSlots + 1) * sizeof (FATDirEntry));
-  memset (Buffer, 0, (nbSlots + 1) * sizeof (FATDirEntry));
+  Buffer = ExAllocatePool (NonPagedPool, nbSlots * sizeof (FATDirEntry));
+  RtlZeroMemory (Buffer, nbSlots * sizeof (FATDirEntry));
   pEntry = (FATDirEntry *) (Buffer + (nbSlots - 1) * sizeof (FATDirEntry));
   pSlots = (slot *) Buffer;
   // create 8.3 name
@@ -196,21 +242,29 @@ addEntry (PDEVICE_EXTENSION DeviceExt,
   // find last point in name
   posCar = j = 0;
   for (i = 0; FileName[i]; i++)
+  {
     if (FileName[i] == '.')
     {
       posCar = i;
       if (i == j)
+      {
         j++;
+      }
     }
+  }
   if (!posCar)
+  {
     posCar = i;
+  }
   if (posCar < j)
   {
     posCar = i;
     needTilde = TRUE;
   }
   if (posCar > 8)
+  {
     needTilde = TRUE;
+  }
   //copy 8 characters max
   memset (pEntry, ' ', 11);
   for (i = 0, j = 0; j < 8 && i < posCar; i++)
@@ -223,13 +277,18 @@ addEntry (PDEVICE_EXTENSION DeviceExt,
     else
     {
       if (FileName[i] == '.')
+      {
         needTilde = TRUE;
+      }
       else
+      {
         pEntry->Filename[j++] = toupper ((char) FileName[i]);
+      }
     }
   }
   //copy extension
   if (FileName[posCar])
+  {
     for (j = 0, i = posCar + 1; FileName[i] && j < 3; i++)
     {
       if (vfatIsShortIllegal(FileName[i]))
@@ -240,13 +299,20 @@ addEntry (PDEVICE_EXTENSION DeviceExt,
       else
       {
         if (FileName[i] == '.')
+        {
           needTilde = TRUE;
+        }
         else
-               pEntry->Ext[j++] = toupper ((char) (FileName[i] & 0x7F));
+        {
+          pEntry->Ext[j++] = toupper ((char) (FileName[i] & 0x7F));
+        }
       }
     }
+  }
   if (FileName[i])
+  {
     needTilde = TRUE;
+  }
   //find good value for tilde
   if (needTilde)
   {
@@ -254,10 +320,14 @@ addEntry (PDEVICE_EXTENSION DeviceExt,
     DPRINT ("searching a good value for tilde\n");
     for (posCar = 0; posCar < 8 && pEntry->Filename[posCar] != ' '; posCar++);
     if (posCar == 0) // ??????????????????????
+    {
       pEntry->Filename[posCar++] = '_';
+    }
     posCar += 2;
     if (posCar > 8)
+    {
       posCar = 8;
+    }
     pEntry->Filename[posCar - 2] = '~';
     pEntry->Filename[posCar - 1] = '1';
     vfat8Dot3ToString (pEntry->Filename, pEntry->Ext, DirName);
@@ -266,15 +336,19 @@ addEntry (PDEVICE_EXTENSION DeviceExt,
     {
       DirName[posCar-1] = '0' + i;
       pEntry->Filename[posCar - 1] = '0' + i;
-           status = FindFile (DeviceExt, &FileFcb, pDirFcb, DirName, NULL, NULL);
-           if (!NT_SUCCESS(status))
-             break;
+      Status = FindFile (DeviceExt, &FileFcb, pDirFcb, DirName, NULL, NULL);
+      if (!NT_SUCCESS(Status))
+      {
+        break;
+      }
     }
     if (i == 10)
     {
       posCar++;
       if (posCar > 8)
+      {
         posCar = 8;
+      }
       pEntry->Filename[posCar - 3] = '~';
       pEntry->Filename[posCar - 2] = '1';
       pEntry->Filename[posCar - 1] = '0';
@@ -286,38 +360,44 @@ addEntry (PDEVICE_EXTENSION DeviceExt,
         DirName[posCar - 2] = '0' + i / 10;
         pEntry->Filename[posCar - 1] = '0' + i % 10;
         pEntry->Filename[posCar - 2] = '0' + i / 10;
-             status = FindFile (DeviceExt, &FileFcb, pDirFcb, DirName, NULL, NULL);
-             if (!NT_SUCCESS(status))
-               break;
+        Status = FindFile (DeviceExt, &FileFcb, pDirFcb, DirName, NULL, NULL);
+        if (!NT_SUCCESS(Status))
+        {
+          break;
+        }
       }
       if (i == 100) //FIXME : what to do after 99 tilde ?
-           {
-             vfatReleaseFCB(DeviceExt, pDirFcb);
-             ExFreePool (Buffer);
-             return STATUS_UNSUCCESSFUL;
-           }
+      {
+        vfatReleaseFCB(DeviceExt, pDirFcb);
+        ExFreePool (Buffer);
+        return STATUS_UNSUCCESSFUL;
+      }
     }
   }
   else
   {
     DPRINT ("check if long name entry needed, needlong=%d\n", needLong);
     for (i = 0; i < posCar; i++)
-           if ((USHORT) pEntry->Filename[i] != FileName[i])
-           {
-             DPRINT ("i=%d,%d,%d\n", i, pEntry->Filename[i], FileName[i]);
-             needLong = TRUE;
-           }
-    if (FileName[i])
-         {
-           i++;                        //jump on point char
-           for (j = 0, i = posCar + 1; FileName[i] && i < posCar + 4; i++)
-           if ((USHORT) pEntry->Ext[j++] != FileName[i])
-           {
-                   DPRINT ("i=%d,j=%d,%d,%d\n", i, j, pEntry->Filename[i],
-                     FileName[i]);
+    {
+      if ((USHORT) pEntry->Filename[i] != FileName[i])
+      {
+        DPRINT ("i=%d,%d,%d\n", i, pEntry->Filename[i], FileName[i]);
         needLong = TRUE;
       }
     }
+    if (FileName[i])
+    {
+      i++;                     //jump on point char
+      for (j = 0, i = posCar + 1; FileName[i] && i < posCar + 4; i++)
+      {
+        if ((USHORT) pEntry->Ext[j++] != FileName[i])
+        {
+          DPRINT ("i=%d,j=%d,%d,%d\n", i, j, pEntry->Filename[i],
+          FileName[i]);
+          needLong = TRUE;
+        }
+      }
+    }
   }
   if (needLong == FALSE)
   {
@@ -337,150 +417,148 @@ addEntry (PDEVICE_EXTENSION DeviceExt,
   /* set attributes */
   pEntry->Attrib = ReqAttr;
   if (RequestedOptions & FILE_DIRECTORY_FILE)
+  {
     pEntry->Attrib |= FILE_ATTRIBUTE_DIRECTORY;
-
+  }
   /* set dates and times */
   KeQuerySystemTime (&SystemTime);
   ExSystemTimeToLocalTime (&SystemTime, &LocalTime);
-  FsdFileTimeToDosDateTime ((TIME *) & LocalTime,
-                           &pEntry->CreationDate, &pEntry->CreationTime);
+  FsdFileTimeToDosDateTime ((TIME *) & LocalTime, &pEntry->CreationDate,
+                            &pEntry->CreationTime);
   pEntry->UpdateDate = pEntry->CreationDate;
   pEntry->UpdateTime = pEntry->CreationTime;
   pEntry->AccessDate = pEntry->CreationDate;
 
   // calculate checksum for 8.3 name
   for (pSlots[0].alias_checksum = i = 0; i < 11; i++)
-    {
-      pSlots[0].alias_checksum = (((pSlots[0].alias_checksum & 1) << 7
-                                  | ((pSlots[0].alias_checksum & 0xfe) >> 1))
-                                 + pEntry->Filename[i]);
-    }
+  {
+    pSlots[0].alias_checksum = (((pSlots[0].alias_checksum & 1) << 7
+                                | ((pSlots[0].alias_checksum & 0xfe) >> 1))
+                                + pEntry->Filename[i]);
+  }
   //construct slots and entry
   for (i = nbSlots - 2; i >= 0; i--)
+  {
+    DPRINT ("construct slot %d\n", i);
+    pSlots[i].attr = 0xf;
+    if (i)
     {
-      DPRINT ("construct slot %d\n", i);
-      pSlots[i].attr = 0xf;
-      if (i)
-       pSlots[i].id = nbSlots - i - 1;
-      else
-       pSlots[i].id = nbSlots - i - 1 + 0x40;
-      pSlots[i].alias_checksum = pSlots[0].alias_checksum;
-//FIXME      pSlots[i].start=;
-      FillSlot (&pSlots[i], FileName + (nbSlots - i - 2) * 13);
+      pSlots[i].id = nbSlots - i - 1;
     }
-
-  //try to find nbSlots contiguous entries frees in directory
-  for (i = 0, status = STATUS_SUCCESS; status == STATUS_SUCCESS; i++)
+    else
     {
-      status =
-       VfatReadFile (DeviceExt, pDirFcb->FileObject, 
-          &FatEntry, sizeof (FATDirEntry), 
-          i * sizeof (FATDirEntry), &LengthRead, FALSE);
-      if (status == STATUS_END_OF_FILE)
-       break;
-      if (!NT_SUCCESS (status))
-       {
-         DPRINT1 ("VfatReadFile failed to read the directory entry\n");
-         break;
-       }
-      if (LengthRead != sizeof (FATDirEntry))
-       {
-         DPRINT1 ("VfatReadFile did not read a complete directory entry\n");
-         break;
-       }
-    if (vfatIsDirEntryEndMarker(&FatEntry))
-      break;
-    if (vfatIsDirEntryDeleted(&FatEntry))
-       nbFree++;
-      else
-       nbFree = 0;
-
-      if (nbFree == nbSlots)
-       break;
+      pSlots[i].id = nbSlots - i - 1 + 0x40;
     }
-  DPRINT ("nbSlots %d nbFree %d, entry number %d\n", nbSlots, nbFree, i);
+    pSlots[i].alias_checksum = pSlots[0].alias_checksum;
+//FIXME      pSlots[i].start=;
+    memcpy (pSlots[i].name0_4, DirName + (nbSlots - i - 2) * 13, 10);
+    memcpy (pSlots[i].name5_10, DirName + (nbSlots - i - 2) * 13 + 5, 12);
+    memcpy (pSlots[i].name11_12, DirName + (nbSlots - i - 2) * 13 + 11, 4);
+  }
+
+  //try to find nbSlots contiguous entries frees in directory
+  if (!findDirSpace(DeviceExt, pDirFcb, nbSlots, &start))
+  {
+    vfatReleaseFCB(DeviceExt, pDirFcb);
+    ExFreePool (Buffer);
+    return STATUS_DISK_FULL;
+  }
 
   if (RequestedOptions & FILE_DIRECTORY_FILE)
-    {
+  {
     CurrentCluster = 0xffffffff;
-    status = NextCluster (DeviceExt, NULL, 0, &CurrentCluster, TRUE);
-    if (CurrentCluster == 0xffffffff || !NT_SUCCESS(status))
+    Status = NextCluster (DeviceExt, NULL, 0, &CurrentCluster, TRUE);
+    if (CurrentCluster == 0xffffffff || !NT_SUCCESS(Status))
     {
       vfatReleaseFCB(DeviceExt, pDirFcb);
       ExFreePool (Buffer);
-      if (!NT_SUCCESS(status))
+      if (!NT_SUCCESS(Status))
       {
-        return status;
+        return Status;
       }
       return STATUS_DISK_FULL;
     }
-      // zero the cluster
-      Buffer2 = ExAllocatePool (NonPagedPool, DeviceExt->BytesPerCluster);
-      memset (Buffer2, 0, DeviceExt->BytesPerCluster);
-      VfatRawWriteCluster (DeviceExt, 0, Buffer2, CurrentCluster, 1);
-      ExFreePool (Buffer2);
-      if (DeviceExt->FatType == FAT32)
-       {
-         pEntry->FirstClusterHigh = CurrentCluster >> 16;
-         pEntry->FirstCluster = CurrentCluster;
-       }
-      else
-       pEntry->FirstCluster = CurrentCluster;
-    }
-  if (nbFree == nbSlots)
-    {                          //use old slots
-      Offset = (i - nbSlots + 1) * sizeof (FATDirEntry);
-      status =
-       VfatWriteFile (DeviceExt, pDirFcb->FileObject, 
-          Buffer, sizeof (FATDirEntry) * nbSlots, 
-          Offset, FALSE, FALSE);
-    DPRINT ("VfatWriteFile() returned: %x\n", status);
+    if (DeviceExt->FatInfo.FatType == FAT32)
+    {
+      pEntry->FirstClusterHigh = CurrentCluster >> 16;
     }
+    pEntry->FirstCluster = CurrentCluster;
+  }
+
+  size = DeviceExt->FatInfo.BytesPerCluster / sizeof(FATDirEntry);
+  if (start / size == (start + nbSlots - 1) / size)
+  {
+    // one cluster
+    CHECKPOINT;
+    FileOffset.u.HighPart = 0;
+    FileOffset.u.LowPart = start * sizeof(FATDirEntry);
+    CcMapData (pDirFcb->FileObject, &FileOffset, nbSlots * sizeof(FATDirEntry),
+               TRUE, &Context, (PVOID*)&pFatEntry);
+    memcpy(pFatEntry, Buffer, nbSlots * sizeof(FATDirEntry));
+  }
   else
-    {                          //write at end of directory
-      Offset = (i - nbFree) * sizeof (FATDirEntry);
-      status =
-       VfatWriteFile (DeviceExt, pDirFcb->FileObject, 
-          Buffer, sizeof (FATDirEntry) * (nbSlots + 1), 
-          Offset, FALSE, FALSE);
-    }
-  DPRINT ("write entry offset %d status=%x\n", Offset, status);
-  if (!NT_SUCCESS(status))
   {
-    vfatReleaseFCB (DeviceExt, pDirFcb);
-    if (RequestedOptions & FILE_DIRECTORY_FILE)
-    {
-      // free the reserved cluster
-      WriteCluster(DeviceExt, CurrentCluster, 0);
-    }
-    ExFreePool (Buffer);
-    return status;
+    // two clusters
+    CHECKPOINT;
+    FileOffset.u.HighPart = 0;
+    FileOffset.u.LowPart = start * sizeof(FATDirEntry);
+    size = DeviceExt->FatInfo.BytesPerCluster -
+             (start * sizeof(FATDirEntry)) % DeviceExt->FatInfo.BytesPerCluster;
+    CcMapData (pDirFcb->FileObject, &FileOffset, size, TRUE,
+               &Context, (PVOID*)&pFatEntry);
+    memcpy(pFatEntry, Buffer, size);
+    CcSetDirtyPinnedData(Context, NULL);
+    CcUnpinData(Context);
+    FileOffset.u.LowPart += size;
+    CcMapData (pDirFcb->FileObject, &FileOffset,
+               nbSlots * sizeof(FATDirEntry) - size,
+               TRUE, &Context, (PVOID*)&pFatEntry);
+    memcpy(pFatEntry, (PVOID)Buffer + size, nbSlots * sizeof(FATDirEntry) - size);
   }
+  CcSetDirtyPinnedData(Context, NULL);
+  CcUnpinData(Context);
 
   // FEXME: check status
-  vfatMakeFCBFromDirEntry (DeviceExt, pDirFcb, FileName, 
-    pEntry, Offset / sizeof(FATDirEntry) + nbSlots-1, &newFCB);
+  vfatMakeFCBFromDirEntry (DeviceExt, pDirFcb, FileName, pEntry,
+                           start + nbSlots - 1, &newFCB);
   vfatAttachFCBToFileObject (DeviceExt, newFCB, pFileObject);
 
   DPRINT ("new : entry=%11.11s\n", newFCB->entry.Filename);
   DPRINT ("new : entry=%11.11s\n", pEntry->Filename);
 
   if (RequestedOptions & FILE_DIRECTORY_FILE)
+  {
+    FileOffset.QuadPart = 0;
+    CcMapData (pFileObject, &FileOffset, DeviceExt->FatInfo.BytesPerCluster, TRUE,
+               &Context, (PVOID*)&pFatEntry);
+    // clear the new directory cluster
+    RtlZeroMemory (pFatEntry, DeviceExt->FatInfo.BytesPerCluster);
+    // create '.' and '..'
+    memcpy (&pFatEntry[0].Attrib, &pEntry->Attrib, sizeof(FATDirEntry) - 11);
+    memcpy (pFatEntry[0].Filename, ".          ", 11);
+    memcpy (&pFatEntry[1].Attrib, &pEntry->Attrib, sizeof(FATDirEntry) - 11);
+    memcpy (pFatEntry[1].Filename, "..         ", 11);
+    pFatEntry[1].FirstCluster = pDirFcb->entry.FirstCluster;
+    pFatEntry[1].FirstClusterHigh = pDirFcb->entry.FirstClusterHigh;
+    if (DeviceExt->FatInfo.FatType == FAT32)
+    {
+      if (pFatEntry[1].FirstCluster == (DeviceExt->FatInfo.RootCluster & 0xffff) &&
+         pFatEntry[1].FirstClusterHigh == (DeviceExt->FatInfo.RootCluster >> 16))
+      {
+        pFatEntry[1].FirstCluster = 0;
+       pFatEntry[1].FirstClusterHigh = 0;
+      }
+    }
+    else
     {
-      // create . and ..
-      memcpy (pEntry->Filename, ".          ", 11);
-      status =
-       VfatWriteFile (DeviceExt, pFileObject, pEntry, sizeof (FATDirEntry),
-                     0L, FALSE, FALSE);
-      pEntry->FirstCluster = pDirFcb->entry.FirstCluster;
-      pEntry->FirstClusterHigh = pDirFcb->entry.FirstClusterHigh;
-      memcpy (pEntry->Filename, "..         ", 11);
-      if (pEntry->FirstCluster == 1 && DeviceExt->FatType != FAT32)
-       pEntry->FirstCluster = 0;
-      status =
-       VfatWriteFile (DeviceExt, pFileObject, pEntry, sizeof (FATDirEntry),
-                     sizeof (FATDirEntry), FALSE, FALSE);
+      if (pFatEntry[1].FirstCluster == 1)
+      {
+        pFatEntry[1].FirstCluster = 0;
+      }
     }
+    CcSetDirtyPinnedData(Context, NULL);
+    CcUnpinData(Context);
+  }
   vfatReleaseFCB (DeviceExt, pDirFcb);
   ExFreePool (Buffer);
   DPRINT ("addentry ok\n");
@@ -490,8 +568,8 @@ addEntry (PDEVICE_EXTENSION DeviceExt,
 NTSTATUS
 delEntry (PDEVICE_EXTENSION DeviceExt, PFILE_OBJECT pFileObject)
 /*
-  deleting an existing FAT entry
-*/
* deleting an existing FAT entry
+ */
 {
   VFATFCB Fcb;
   PVFATFCB pFcb = NULL, pDirFcb = NULL;
@@ -502,7 +580,8 @@ delEntry (PDEVICE_EXTENSION DeviceExt, PFILE_OBJECT pFileObject)
 
   DPRINT ("delEntry PathFileName \'%S\'\n", pFileObject->FileName.Buffer);
 
-  status = vfatGetFCBForFile(DeviceExt, &pDirFcb, &pFcb, pFileObject->FileName.Buffer);
+  status = vfatGetFCBForFile(DeviceExt, &pDirFcb, &pFcb,
+                             pFileObject->FileName.Buffer);
   if (pFcb != NULL)
   {
     vfatReleaseFCB(DeviceExt, pFcb);
@@ -524,18 +603,38 @@ delEntry (PDEVICE_EXTENSION DeviceExt, PFILE_OBJECT pFileObject)
 
   if (NT_SUCCESS(status))
   {
+    PVOID Context = NULL;
+    LARGE_INTEGER Offset;
+    FATDirEntry* pDirEntry;
     DPRINT ("delete entry: %d to %d\n", startEntry, Entry);
+    Offset.u.HighPart = 0;
     for (i = startEntry; i <= Entry; i++)
     {
-      // FIXME: using Cc-functions
-      VfatReadFile (DeviceExt, pDirFcb->FileObject, &DirEntry, 
-        sizeof (FATDirEntry), i * sizeof(FATDirEntry), &Read, FALSE);
-      DirEntry.Filename[0] = 0xe5;
-      // FIXME: check status
-      VfatWriteFile (DeviceExt, pDirFcb->FileObject, &DirEntry, 
-        sizeof(FATDirEntry), i * sizeof(FATDirEntry), FALSE, FALSE);
+      if (Context == NULL || ((i * sizeof(FATDirEntry)) % PAGESIZE) == 0)
+      {
+        if (Context)
+        {
+          CcSetDirtyPinnedData(Context, NULL);
+          CcUnpinData(Context);
+        }
+        Offset.u.LowPart = (i * sizeof(FATDirEntry) / PAGESIZE) * PAGESIZE;
+        CcMapData (pDirFcb->FileObject, &Offset, PAGESIZE, TRUE,
+                   &Context, (PVOID*)&pDirEntry);
+      }
+      pDirEntry[i % (PAGESIZE / sizeof(FATDirEntry))].Filename[0] = 0xe5;
+      if (i == Entry)
+      {
+        CurrentCluster =
+          vfatDirEntryGetFirstCluster (DeviceExt,
+            &pDirEntry[i % (PAGESIZE / sizeof(FATDirEntry))]);
+      }
     }
-    CurrentCluster = vfatDirEntryGetFirstCluster (DeviceExt, &DirEntry);
+    if (Context)
+    {
+      CcSetDirtyPinnedData(Context, NULL);
+      CcUnpinData(Context);
+    }
+
     while (CurrentCluster && CurrentCluster != 0xffffffff)
     {
       GetNextCluster (DeviceExt, CurrentCluster, &NextCluster, FALSE);
@@ -544,6 +643,7 @@ delEntry (PDEVICE_EXTENSION DeviceExt, PFILE_OBJECT pFileObject)
       CurrentCluster = NextCluster;
     }
   }
+  vfatReleaseFCB(DeviceExt, pDirFcb);
   return status;
 }
 
index d828519..9ec2f05 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * $Id: fat.c,v 1.35 2001/11/20 23:40:26 hbirr Exp $
+ * $Id: fat.c,v 1.36 2002/03/18 22:37:12 hbirr Exp $
  *
  * COPYRIGHT:        See COPYING in the top level directory
  * PROJECT:          ReactOS kernel
@@ -24,8 +24,8 @@
 
 #define ROUND_DOWN(N, S) ((N) - ((N) % (S)))
 
-#define  CACHEPAGESIZE(pDeviceExt) ((pDeviceExt)->BytesPerCluster > PAGESIZE ? \
-                  (pDeviceExt)->BytesPerCluster : PAGESIZE)
+#define  CACHEPAGESIZE(pDeviceExt) ((pDeviceExt)->FatInfo.BytesPerCluster > PAGESIZE ? \
+                  (pDeviceExt)->FatInfo.BytesPerCluster : PAGESIZE)
 
 /* FUNCTIONS ****************************************************************/
 
@@ -98,7 +98,7 @@ Fat12GetNextCluster(PDEVICE_EXTENSION DeviceExt,
  * FUNCTION: Retrieve the next FAT12 cluster from the FAT table
  */
 {
-  PUCHAR CBlock;
+  PUSHORT CBlock;
   ULONG FATOffset;
   ULONG Entry;
   NTSTATUS Status;
@@ -110,22 +110,18 @@ Fat12GetNextCluster(PDEVICE_EXTENSION DeviceExt,
   *NextCluster = 0;
 
   Offset.QuadPart = 0;
-  if(!CcMapData(DeviceExt->FATFileObject, &Offset, DeviceExt->Boot->FATSectors * BLOCKSIZE, 1, &Context, &BaseAddress))
+  if(!CcMapData(DeviceExt->FATFileObject, &Offset, DeviceExt->FatInfo.FATSectors * BLOCKSIZE, 1, &Context, &BaseAddress))
   {
     return STATUS_UNSUCCESSFUL;
   }
-  CBlock = (PUCHAR)BaseAddress;
-
-  FATOffset = (CurrentCluster * 12) / 8; /* first byte containing value */
+  CBlock = (PUSHORT)(BaseAddress + (CurrentCluster * 12) / 8);
   if ((CurrentCluster % 2) == 0)
     {
-      Entry = CBlock[FATOffset];
-      Entry |= ((CBlock[FATOffset+1] & 0xf)<<8);
+      Entry = *CBlock & 0x0fff;
     }
   else
     {
-      Entry = (CBlock[FATOffset] >> 4);
-      Entry |= (CBlock[FATOffset+1] << 4);
+      Entry = *CBlock >> 4;
     }
 //  DPRINT("Entry %x\n",Entry);
   if (Entry >= 0xff8 && Entry <= 0xfff)
@@ -152,15 +148,16 @@ FAT16FindAvailableCluster(PDEVICE_EXTENSION DeviceExt,
   ULONG ChunkSize;
   PVOID Context = 0;
   LARGE_INTEGER Offset;
+  PUSHORT Block;
 
   ChunkSize = CACHEPAGESIZE(DeviceExt);
-  FatLength = DeviceExt->NumberOfClusters * 2;
+  FatLength = (DeviceExt->FatInfo.NumberOfClusters +2 ) * 2;
   *Cluster = 0;
   StartCluster = DeviceExt->LastAvailableCluster;
 
   for (j = 0; j < 2; j++)
   {
-    for (i = StartCluster * 2; i < FatLength; i += 2)
+    for (i = StartCluster * 2; i < FatLength; i += 2, Block++)
     {
       if ((i % ChunkSize) == 0 || Context == NULL)
           {
@@ -169,14 +166,17 @@ FAT16FindAvailableCluster(PDEVICE_EXTENSION DeviceExt,
         {
           CcUnpinData(Context);
         }
+        CHECKPOINT;
         if(!CcMapData(DeviceExt->FATFileObject, &Offset, ChunkSize, 1, &Context, &BaseAddress))
         {
           DPRINT1("CcMapData(Offset %x, Length %d) failed\n", (ULONG)Offset.QuadPart, ChunkSize);
           return STATUS_UNSUCCESSFUL;
         }
+        CHECKPOINT;
+               Block = (PUSHORT)(BaseAddress + i % ChunkSize);
           }
 
-      if (*((PUSHORT)(BaseAddress + (i % ChunkSize))) == 0)
+      if (*Block == 0)
           {
             DPRINT("Found available cluster 0x%x\n", i / 2);
             DeviceExt->LastAvailableCluster = *Cluster = i / 2;
@@ -186,8 +186,12 @@ FAT16FindAvailableCluster(PDEVICE_EXTENSION DeviceExt,
     }
     FatLength = StartCluster * 2;
     StartCluster = 2;
+    if (Context != NULL)
+    {
+      CcUnpinData(Context);
+      Context =NULL;
+    }
   }
-  CcUnpinData(Context);
   return(STATUS_DISK_FULL);
 }
 
@@ -201,38 +205,35 @@ FAT12FindAvailableCluster(PDEVICE_EXTENSION DeviceExt, PULONG Cluster)
   ULONG FATOffset;
   ULONG StartCluster;
   ULONG Entry;
-  PUCHAR CBlock;
+  PUSHORT CBlock;
   ULONG i, j;
   PVOID BaseAddress;
   NTSTATUS Status;
   PVOID Context;
   LARGE_INTEGER Offset;
 
-  FatLength = DeviceExt->NumberOfClusters;
+  FatLength = DeviceExt->FatInfo.NumberOfClusters + 2;
   *Cluster = 0;
   StartCluster = DeviceExt->LastAvailableCluster;
   Offset.QuadPart = 0;
-  if(!CcMapData(DeviceExt->FATFileObject, &Offset, DeviceExt->Boot->FATSectors * BLOCKSIZE, 1, &Context, &BaseAddress))
+  if(!CcMapData(DeviceExt->FATFileObject, &Offset, DeviceExt->FatInfo.FATSectors * BLOCKSIZE, 1, &Context, &BaseAddress))
   {
-    DPRINT1("CcMapData(Offset %x, Length %d) failed\n", (ULONG)Offset.QuadPart, DeviceExt->Boot->FATSectors * BLOCKSIZE);
+    DPRINT1("CcMapData(Offset %x, Length %d) failed\n", (ULONG)Offset.QuadPart, DeviceExt->FatInfo.FATSectors * BLOCKSIZE);
     return STATUS_UNSUCCESSFUL;
   }
-  CBlock = (PUCHAR)BaseAddress;
 
   for (j = 0; j < 2; j++)
   {
     for (i = StartCluster; i < FatLength; i++)
     {
-      FATOffset = (i * 12) / 8;
+      CBlock = (PUSHORT)(BaseAddress + (i * 12) / 8);
       if ((i % 2) == 0)
           {
-            Entry = CBlock[FATOffset];
-            Entry |= ((CBlock[FATOffset + 1] & 0xf) << 8);
+            Entry = *CBlock & 0xfff;
           }
       else
           {
-            Entry = (CBlock[FATOffset] >> 4);
-            Entry |= (CBlock[FATOffset + 1] << 4);
+            Entry = *CBlock >> 4;
           }
       if (Entry == 0)
           {
@@ -256,243 +257,229 @@ FAT32FindAvailableCluster (PDEVICE_EXTENSION DeviceExt, PULONG Cluster)
  */
 {
   ULONG FatLength;
-  ULONG i;
+  ULONG StartCluster;
+  ULONG i, j;
   NTSTATUS Status;
   PVOID BaseAddress;
   ULONG ChunkSize;
-  PVOID Context = NULL;
+  PVOID Context = 0;
   LARGE_INTEGER Offset;
-  ULONG StartCluster;
+  PULONG Block;
 
   ChunkSize = CACHEPAGESIZE(DeviceExt);
-  FatLength = DeviceExt->NumberOfClusters * 4;
-  StartCluster = DeviceExt->LastAvailableCluster;
-  if (StartCluster == 0)
-  {
-    StartCluster = 2;
-  }
-
+  FatLength = (DeviceExt->FatInfo.NumberOfClusters + 2) * 4;
   *Cluster = 0;
+  StartCluster = DeviceExt->LastAvailableCluster;
 
-  for (i = StartCluster * 4; i < FatLength; i += 4)
+  for (j = 0; j < 2; j++)
   {
-    if ((i % ChunkSize) == 0 || Context == NULL)
-       {
-      Offset.QuadPart = ROUND_DOWN(i, ChunkSize);
-      if (Context != NULL)
-      {
-        CcUnpinData(Context);
-      }
-      if(!CcMapData(DeviceExt->FATFileObject, &Offset, ChunkSize, 1, &Context, &BaseAddress))
+    for (i = StartCluster * 4; i < FatLength; i += 4, Block++)
+    {
+      if ((i % ChunkSize) == 0 || Context == NULL)
       {
-        DPRINT1("CcMapData(Offset %x, Length %d) failed\n", (ULONG)Offset.QuadPart, ChunkSize);
-        return STATUS_UNSUCCESSFUL;
-      }
-       }
-    if ((*((PULONG)(BaseAddress + (i % ChunkSize))) & 0x0fffffff) == 0)
+        Offset.QuadPart = ROUND_DOWN(i, ChunkSize);
+        if (Context != NULL)
        {
-         DPRINT("Found available cluster 0x%x\n", i / 4);
-         DeviceExt->LastAvailableCluster = *Cluster = i / 4;
-      CcUnpinData(Context);
-         return(STATUS_SUCCESS);
+          CcUnpinData(Context);
        }
-  }
-  FatLength = StartCluster * 4;
-  for (i = 8; i < FatLength; i += 4)
-  {
-    if ((i % ChunkSize) == 0 || Context == NULL)
+        if(!CcMapData(DeviceExt->FATFileObject, &Offset, ChunkSize, 1, &Context, &BaseAddress))
        {
-      Offset.QuadPart = ROUND_DOWN(i, ChunkSize);
-      if (Context != NULL)
-      {
-        CcUnpinData(Context);
+          DPRINT1("CcMapData(Offset %x, Length %d) failed\n", (ULONG)Offset.QuadPart, ChunkSize);
+          return STATUS_UNSUCCESSFUL;
+       }
+       Block = (PULONG)(BaseAddress + i % ChunkSize);
       }
-      if(!CcMapData(DeviceExt->FATFileObject, &Offset, ChunkSize, 1, &Context, &BaseAddress))
+
+      if ((*Block & 0x0fffffff) == 0)
       {
-        DPRINT1("CcMapData(Offset %x, Length %d) failed\n", (ULONG)Offset.QuadPart, ChunkSize);
-        return STATUS_UNSUCCESSFUL;
+        DPRINT("Found available cluster 0x%x\n", i / 4);
+        DeviceExt->LastAvailableCluster = *Cluster = i / 4;
+        CcUnpinData(Context);
+        return(STATUS_SUCCESS);
       }
-       }
-    if ((*((PULONG)(BaseAddress + (i % ChunkSize))) & 0x0fffffff) == 0)
-       {
-         DPRINT("Found available cluster 0x%x\n", i / 4);
-         DeviceExt->LastAvailableCluster = *Cluster = i / 4;
+    }
+    FatLength = StartCluster * 4;
+    StartCluster = 2;
+    if (Context != NULL)
+    {
       CcUnpinData(Context);
-         return(STATUS_SUCCESS);
-       }
+      Context=NULL;
+    }
   }
-  CcUnpinData(Context);
   return (STATUS_DISK_FULL);
 }
 
 
 NTSTATUS
-FAT12CountAvailableClusters(PDEVICE_EXTENSION DeviceExt,
-                           PLARGE_INTEGER Clusters)
+FAT12CountAvailableClusters(PDEVICE_EXTENSION DeviceExt)
 /*
  * FUNCTION: Counts free cluster in a FAT12 table
  */
 {
   ULONG FATOffset;
   ULONG Entry;
-  PUCHAR CBlock;
+  PVOID BaseAddress;
   ULONG ulCount = 0;
   ULONG i;
-  PVOID BaseAddress;
   NTSTATUS Status;
   ULONG numberofclusters;
   LARGE_INTEGER Offset;
   PVOID Context;
+  PUSHORT CBlock;
 
-  ExAcquireResourceSharedLite (&DeviceExt->FatResource, TRUE);
   Offset.QuadPart = 0;
-  if(!CcMapData(DeviceExt->FATFileObject, &Offset, DeviceExt->Boot->FATSectors * BLOCKSIZE, 1, &Context, &BaseAddress))
+  if(!CcMapData(DeviceExt->FATFileObject, &Offset, DeviceExt->FatInfo.FATSectors * BLOCKSIZE, 1, &Context, &BaseAddress))
   {
-    ExReleaseResourceLite (&DeviceExt->FatResource);
     return STATUS_UNSUCCESSFUL;
   }
-  CBlock = (PUCHAR)BaseAddress;
-  numberofclusters = DeviceExt->NumberOfClusters;
+
+  numberofclusters = DeviceExt->FatInfo.NumberOfClusters + 2;
 
   for (i = 2; i < numberofclusters; i++)
     {
-      FATOffset = (i * 12) / 8;
+    CBlock = (PUSHORT)(BaseAddress + (i * 12) / 8);
       if ((i % 2) == 0)
        {
-         Entry = CBlock[FATOffset];
-         Entry |= ((CBlock[FATOffset + 1] & 0xf) << 8);
+      Entry = *CBlock & 0x0fff;
        }
       else
        {
-         Entry = (CBlock[FATOffset] >> 4);
-         Entry |= (CBlock[FATOffset + 1] << 4);
+      Entry = *CBlock >> 4;
        }
       if (Entry == 0)
        ulCount++;
     }
 
   CcUnpinData(Context);
-  ExReleaseResourceLite (&DeviceExt->FatResource);
-
-  Clusters->QuadPart = ulCount;
+  DeviceExt->AvailableClusters = ulCount;
+  DeviceExt->AvailableClustersValid = TRUE;
 
   return(STATUS_SUCCESS);
 }
 
 
 NTSTATUS
-FAT16CountAvailableClusters(PDEVICE_EXTENSION DeviceExt,
-                           PLARGE_INTEGER Clusters)
+FAT16CountAvailableClusters(PDEVICE_EXTENSION DeviceExt)
 /*
  * FUNCTION: Counts free clusters in a FAT16 table
  */
 {
   PUSHORT Block;
+  PVOID BaseAddress = NULL;
   ULONG ulCount = 0;
   ULONG i;
-  ULONG numberofclusters;
-  ULONG numberofsectors;
-  ULONG sector;
-  ULONG forto;
+  ULONG ChunkSize;
   NTSTATUS Status;
+  PVOID Context = NULL;
+  LARGE_INTEGER Offset;
+  ULONG FatLength;
 
-  ExAcquireResourceSharedLite (&DeviceExt->FatResource, TRUE);
-  Block = ExAllocatePool (NonPagedPool, BLOCKSIZE);
-
-  numberofclusters = ((DeviceExt->Boot->Sectors ? DeviceExt->Boot->Sectors : DeviceExt->Boot->SectorsHuge)-DeviceExt->dataStart)/DeviceExt->Boot->SectorsPerCluster+2;
-  numberofsectors = (numberofclusters + 255) / 256;
-  numberofclusters %= 256;
+  ChunkSize = CACHEPAGESIZE(DeviceExt);
+  FatLength = (DeviceExt->FatInfo.NumberOfClusters + 2) * 2;
 
-  for (sector = 0; sector < numberofsectors; sector++)
+  for (i = 4; i< FatLength; i += 2, Block++)
+  {
+    if ((i % ChunkSize) == 0 || Context == NULL)
     {
-      Status = VfatReadSectors(DeviceExt->StorageDevice,
-                              DeviceExt->FATStart + sector,
-                              1,
-                              (PUCHAR)Block);
-      if (!NT_SUCCESS(Status))
+               DPRINT("%d\n", i/2);
+               if (Context)
        {
-          ExFreePool(Block);
-          ExReleaseResourceLite(&DeviceExt->FatResource);
-          return(Status);
+                       CcUnpinData(Context);
        }
-
-      if (sector == numberofsectors - 1)
-       forto = numberofclusters;
-      else
-       forto = 256;
-
-      for (i = 0; i < forto; i++)
+               Offset.QuadPart = ROUND_DOWN(i, ChunkSize);
+               if(!CcMapData(DeviceExt->FATFileObject, &Offset, ChunkSize, 1, &Context, &BaseAddress))
        {
-         if (Block[i] == 0)
+                       return STATUS_UNSUCCESSFUL;
+               }
+               Block = (PUSHORT)(BaseAddress + i % ChunkSize);
+       }
+       if (*Block == 0)
            ulCount++;
        }
-    }
-  ExReleaseResourceLite (&DeviceExt->FatResource);
 
-  Clusters->QuadPart = ulCount;
-  ExFreePool(Block);
+  DeviceExt->AvailableClusters = ulCount;
+  DeviceExt->AvailableClustersValid = TRUE;
+  CcUnpinData(Context);
 
   return(STATUS_SUCCESS);
 }
 
 
 NTSTATUS
-FAT32CountAvailableClusters(PDEVICE_EXTENSION DeviceExt,
-                           PLARGE_INTEGER Clusters)
+FAT32CountAvailableClusters(PDEVICE_EXTENSION DeviceExt)
 /*
  * FUNCTION: Counts free clusters in a FAT32 table
  */
 {
-  ULONG sector;
   PULONG Block;
+  PVOID BaseAddress = NULL;
   ULONG ulCount = 0;
-  ULONG i,forto;
-  ULONG numberofclusters;
-  ULONG numberofsectors;
+  ULONG i;
+  ULONG ChunkSize;
   NTSTATUS Status;
+  PVOID Context = NULL;
+  LARGE_INTEGER Offset;
+  ULONG FatLength;
 
-  ExAcquireResourceSharedLite (&DeviceExt->FatResource, TRUE);
-
-  Block = ExAllocatePool (NonPagedPool, BLOCKSIZE);
-
-  numberofclusters = ((DeviceExt->Boot->Sectors ? DeviceExt->Boot->Sectors : DeviceExt->Boot->SectorsHuge)-DeviceExt->dataStart)/DeviceExt->Boot->SectorsPerCluster+2;
-  numberofsectors = (numberofclusters +127) / 128;
-  numberofclusters %= 128;
+  ChunkSize = CACHEPAGESIZE(DeviceExt);
+  FatLength = (DeviceExt->FatInfo.NumberOfClusters + 2) * 4;
 
-  for (sector = 0; sector < numberofsectors; sector++)
-    {
-      Status = VfatReadSectors(DeviceExt->StorageDevice,
-                              (ULONG) (DeviceExt->FATStart + sector), 1,
-                              (UCHAR *) Block);
-      if (!NT_SUCCESS(Status))
+  for (i = 8; i< FatLength; i += 4, Block++)
+  {
+     if ((i % ChunkSize) == 0 || Context == NULL)
+     {
+       if (Context)
        {
-         ExFreePool(Block);
-         ExReleaseResourceLite(&DeviceExt->FatResource);
-         return(Status);
+          CcUnpinData(Context);
        }
-
-      if (sector == numberofsectors - 1)
-       forto=numberofclusters;
-      else
-       forto=128;
-      for (i = 0; i < forto; i++)
+       Offset.QuadPart = ROUND_DOWN(i, ChunkSize);
+       if(!CcMapData(DeviceExt->FATFileObject, &Offset, ChunkSize, 1, &Context, &BaseAddress))
        {
-         if ((Block[i] & 0x0fffffff) == 0)
-           ulCount++;
+          return STATUS_UNSUCCESSFUL;
        }
-    }
-  ExFreePool (Block);
-  ExReleaseResourceLite (&DeviceExt->FatResource);
+       Block = (PULONG)(BaseAddress + i % ChunkSize);
+     }
+     if ((*Block & 0x0fffffff) == 0)
+       ulCount++;
+  }
 
-  Clusters->QuadPart = ulCount;
+  DeviceExt->AvailableClusters = ulCount;
+  DeviceExt->AvailableClustersValid = TRUE;
+  CcUnpinData(Context);
 
   return(STATUS_SUCCESS);
 }
 
+NTSTATUS
+CountAvailableClusters(PDEVICE_EXTENSION DeviceExt,
+                           PLARGE_INTEGER Clusters)
+{
+  NTSTATUS Status = STATUS_SUCCESS;
+  ExAcquireResourceExclusiveLite (&DeviceExt->FatResource, TRUE);
+  if (!DeviceExt->AvailableClustersValid)
+  {
+       if (DeviceExt->FatInfo.FatType == FAT12)
+         Status = FAT12CountAvailableClusters(DeviceExt);
+       else if (DeviceExt->FatInfo.FatType == FAT16)
+         Status = FAT16CountAvailableClusters(DeviceExt);
+       else
+         Status = FAT32CountAvailableClusters(DeviceExt);
+    }
+  Clusters->QuadPart = DeviceExt->AvailableClusters;
+  ExReleaseResourceLite (&DeviceExt->FatResource);
+
+  return Status;
+}
+
+
+
+
+
 NTSTATUS
 FAT12WriteCluster(PDEVICE_EXTENSION DeviceExt,
                  ULONG ClusterToWrite,
-                 ULONG NewValue)
+                 ULONG NewValue,
+                 PULONG OldValue)
 /*
  * FUNCTION: Writes a cluster to the FAT12 physical and in-memory tables
  */
@@ -507,7 +494,7 @@ FAT12WriteCluster(PDEVICE_EXTENSION DeviceExt,
   LARGE_INTEGER Offset;
 
   Offset.QuadPart = 0;
-  if(!CcMapData(DeviceExt->FATFileObject, &Offset, DeviceExt->Boot->FATSectors * BLOCKSIZE, 1, &Context, &BaseAddress))
+  if(!CcMapData(DeviceExt->FATFileObject, &Offset, DeviceExt->FatInfo.FATSectors * BLOCKSIZE, 1, &Context, &BaseAddress))
   {
     return STATUS_UNSUCCESSFUL;
   }
@@ -518,12 +505,14 @@ FAT12WriteCluster(PDEVICE_EXTENSION DeviceExt,
          NewValue, ClusterToWrite, FATOffset);
   if ((ClusterToWrite % 2) == 0)
     {
+      *OldValue = CBlock[FATOffset] + ((CBlock[FATOffset + 1] & 0x0f) << 8);
       CBlock[FATOffset] = NewValue;
       CBlock[FATOffset + 1] &= 0xf0;
       CBlock[FATOffset + 1] |= (NewValue & 0xf00) >> 8;
     }
   else
     {
+      *OldValue = (CBlock[FATOffset] >> 4) + (CBlock[FATOffset + 1] << 4);
       CBlock[FATOffset] &= 0x0f;
       CBlock[FATOffset] |= (NewValue & 0xf) << 4;
       CBlock[FATOffset + 1] = NewValue >> 4;
@@ -538,7 +527,8 @@ FAT12WriteCluster(PDEVICE_EXTENSION DeviceExt,
 NTSTATUS
 FAT16WriteCluster(PDEVICE_EXTENSION DeviceExt,
                  ULONG ClusterToWrite,
-                 ULONG NewValue)
+                 ULONG NewValue,
+                 PULONG OldValue)
 /*
  * FUNCTION: Writes a cluster to the FAT16 physical and in-memory tables
  */
@@ -550,6 +540,7 @@ FAT16WriteCluster(PDEVICE_EXTENSION DeviceExt,
   ULONG ChunkSize;
   PVOID Context;
   LARGE_INTEGER Offset;
+  PUSHORT Cluster;
 
   ChunkSize = CACHEPAGESIZE(DeviceExt);
   FATOffset = ClusterToWrite * 2;
@@ -560,7 +551,9 @@ FAT16WriteCluster(PDEVICE_EXTENSION DeviceExt,
   }
   DPRINT("Writing 0x%x for offset 0x%x 0x%x\n", NewValue, FATOffset,
             ClusterToWrite);
-  *((PUSHORT)(BaseAddress + (FATOffset % ChunkSize))) = NewValue;
+  Cluster = ((PUSHORT)(BaseAddress + (FATOffset % ChunkSize)));
+  *OldValue = *Cluster;
+  *Cluster = NewValue;
   CcSetDirtyPinnedData(Context, NULL);
   CcUnpinData(Context);
   return(STATUS_SUCCESS);
@@ -569,7 +562,8 @@ FAT16WriteCluster(PDEVICE_EXTENSION DeviceExt,
 NTSTATUS
 FAT32WriteCluster(PDEVICE_EXTENSION DeviceExt,
                  ULONG ClusterToWrite,
-                 ULONG NewValue)
+                 ULONG NewValue,
+                 PULONG OldValue)
 /*
  * FUNCTION: Writes a cluster to the FAT32 physical tables
  */
@@ -581,6 +575,7 @@ FAT32WriteCluster(PDEVICE_EXTENSION DeviceExt,
   ULONG ChunkSize;
   PVOID Context;
   LARGE_INTEGER Offset;
+  PULONG Cluster;
 
   ChunkSize = CACHEPAGESIZE(DeviceExt);
 
@@ -592,13 +587,13 @@ FAT32WriteCluster(PDEVICE_EXTENSION DeviceExt,
   }
   DPRINT("Writing 0x%x for offset 0x%x 0x%x\n", NewValue, FATOffset,
             ClusterToWrite);
-  *((PULONG)(BaseAddress + (FATOffset % ChunkSize))) = NewValue & 0x0fffffff;
+  Cluster = ((PULONG)(BaseAddress + (FATOffset % ChunkSize)));
+  *OldValue = *Cluster & 0x0fffffff;
+  *Cluster = (*Cluster & 0xf0000000) | (NewValue & 0x0fffffff);
 
   CcSetDirtyPinnedData(Context, NULL);
   CcUnpinData(Context);
 
-  DPRINT("DeviceExt->Boot->FATSectors %d\n",
-            ((struct _BootSector32 *)DeviceExt->Boot)->FATSectors32);
   return(STATUS_SUCCESS);
 }
 
@@ -612,19 +607,28 @@ WriteCluster(PDEVICE_EXTENSION DeviceExt,
  */
 {
   NTSTATUS Status;
-
-  if (DeviceExt->FatType == FAT16)
+  ULONG OldValue;
+  ExAcquireResourceExclusiveLite (&DeviceExt->FatResource, TRUE);
+  if (DeviceExt->FatInfo.FatType == FAT16)
     {
-      Status = FAT16WriteCluster(DeviceExt, ClusterToWrite, NewValue);
+      Status = FAT16WriteCluster(DeviceExt, ClusterToWrite, NewValue, &OldValue);
     }
-  else if (DeviceExt->FatType == FAT32)
+  else if (DeviceExt->FatInfo.FatType == FAT32)
     {
-      Status = FAT32WriteCluster(DeviceExt, ClusterToWrite, NewValue);
+      Status = FAT32WriteCluster(DeviceExt, ClusterToWrite, NewValue, &OldValue);
     }
   else
     {
-      Status = FAT12WriteCluster(DeviceExt, ClusterToWrite, NewValue);
+      Status = FAT12WriteCluster(DeviceExt, ClusterToWrite, NewValue, &OldValue);
     }
+  if (DeviceExt->AvailableClustersValid)
+       {
+      if (OldValue && NewValue == 0)
+        InterlockedIncrement(&DeviceExt->AvailableClusters);
+      else if (OldValue == 0 && NewValue)
+        InterlockedDecrement(&DeviceExt->AvailableClusters);
+    }
+  ExReleaseResourceLite(&DeviceExt->FatResource);
   return(Status);
 }
 
@@ -636,8 +640,8 @@ ClusterToSector(PDEVICE_EXTENSION DeviceExt,
  *           device
  */
 {
-  return DeviceExt->dataStart +
-    ((Cluster - 2) * DeviceExt->Boot->SectorsPerCluster);
+  return DeviceExt->FatInfo.dataStart +
+    ((Cluster - 2) * DeviceExt->FatInfo.SectorsPerCluster);
 }
 
 NTSTATUS
@@ -654,7 +658,7 @@ VfatRawReadCluster(PDEVICE_EXTENSION DeviceExt,
   if (FirstCluster == 1)
   {
     return VfatReadSectors(DeviceExt->StorageDevice, Cluster,
-                        DeviceExt->Boot->SectorsPerCluster * Count, Buffer);
+                        DeviceExt->FatInfo.SectorsPerCluster * Count, Buffer);
   }
   else
   {
@@ -662,7 +666,7 @@ VfatRawReadCluster(PDEVICE_EXTENSION DeviceExt,
 
     Sector = ClusterToSector(DeviceExt, Cluster);
     return VfatReadSectors(DeviceExt->StorageDevice, Sector,
-                        DeviceExt->Boot->SectorsPerCluster * Count, Buffer);
+                        DeviceExt->FatInfo.SectorsPerCluster * Count, Buffer);
   }
 }
 
@@ -685,14 +689,14 @@ VfatRawWriteCluster(PDEVICE_EXTENSION DeviceExt,
   if (FirstCluster == 1)
   {
     Status = VfatWriteSectors(DeviceExt->StorageDevice, Cluster,
-                          DeviceExt->Boot->SectorsPerCluster * Count, Buffer);
+                          DeviceExt->FatInfo.SectorsPerCluster * Count, Buffer);
   }
   else
   {
     Sector = ClusterToSector(DeviceExt, Cluster);
 
     Status = VfatWriteSectors(DeviceExt->StorageDevice, Sector,
-                               DeviceExt->Boot->SectorsPerCluster * Count, Buffer);
+                               DeviceExt->FatInfo.SectorsPerCluster * Count, Buffer);
   }
   return(Status);
 }
@@ -708,8 +712,8 @@ GetNextCluster(PDEVICE_EXTENSION DeviceExt,
 {
   NTSTATUS Status;
 
-//  DPRINT ("GetNextCluster(DeviceExt %x, CurrentCluster %x)\n",
-//       DeviceExt, CurrentCluster);
+  DPRINT ("GetNextCluster(DeviceExt %x, CurrentCluster %x)\n",
+         DeviceExt, CurrentCluster);
 
   if (!Extend)
   {
@@ -719,7 +723,7 @@ GetNextCluster(PDEVICE_EXTENSION DeviceExt,
   {
     ExAcquireResourceExclusiveLite(&DeviceExt->FatResource, TRUE);
   }
-
+  CHECKPOINT;
   /*
    * If the file hasn't any clusters allocated then we need special
    * handling
@@ -728,16 +732,18 @@ GetNextCluster(PDEVICE_EXTENSION DeviceExt,
   {
     ULONG NewCluster;
 
-    if (DeviceExt->FatType == FAT16)
+    if (DeviceExt->FatInfo.FatType == FAT16)
         {
+          CHECKPOINT;
           Status = FAT16FindAvailableCluster(DeviceExt, &NewCluster);
+          CHECKPOINT;
           if (!NT_SUCCESS(Status))
           {
           ExReleaseResourceLite(&DeviceExt->FatResource);
              return(Status);
           }
         }
-    else if (DeviceExt->FatType == FAT32)
+    else if (DeviceExt->FatInfo.FatType == FAT32)
         {
            Status = FAT32FindAvailableCluster(DeviceExt, &NewCluster);
            if (!NT_SUCCESS(Status))
@@ -767,11 +773,11 @@ GetNextCluster(PDEVICE_EXTENSION DeviceExt,
      return(STATUS_UNSUCCESSFUL);
   }
 
-  if (DeviceExt->FatType == FAT16)
+  if (DeviceExt->FatInfo.FatType == FAT16)
   {
      Status = Fat16GetNextCluster(DeviceExt, CurrentCluster, NextCluster);
   }
-  else if (DeviceExt->FatType == FAT32)
+  else if (DeviceExt->FatInfo.FatType == FAT32)
   {
      Status = Fat32GetNextCluster(DeviceExt, CurrentCluster, NextCluster);
   }
@@ -785,7 +791,7 @@ GetNextCluster(PDEVICE_EXTENSION DeviceExt,
 
      /* We are after last existing cluster, we must add one to file */
      /* Firstly, find the next available open allocation unit */
-     if (DeviceExt->FatType == FAT16)
+     if (DeviceExt->FatInfo.FatType == FAT16)
          {
            Status = FAT16FindAvailableCluster(DeviceExt, &NewCluster);
            if (!NT_SUCCESS(Status))
@@ -794,7 +800,7 @@ GetNextCluster(PDEVICE_EXTENSION DeviceExt,
              return(Status);
            }
          }
-     else if (DeviceExt->FatType == FAT32)
+     else if (DeviceExt->FatInfo.FatType == FAT32)
          {
            Status = FAT32FindAvailableCluster(DeviceExt, &NewCluster);
            if (!NT_SUCCESS(Status))
@@ -839,7 +845,7 @@ GetNextSector(PDEVICE_EXTENSION DeviceExt,
   DPRINT("GetNextSector(DeviceExt %x, CurrentSector %x)\n",
         DeviceExt,
         CurrentSector);
-  if (CurrentSector<DeviceExt->dataStart || ((CurrentSector - DeviceExt->dataStart + 1) % DeviceExt -> Boot -> SectorsPerCluster))
+  if (CurrentSector<DeviceExt->FatInfo.dataStart || ((CurrentSector - DeviceExt->FatInfo.dataStart + 1) % DeviceExt->FatInfo.SectorsPerCluster))
   /* Basically, if the next sequential sector would be on a cluster border, then we'll need to check in the FAT */
     {
       (*NextSector)=CurrentSector+1;
@@ -847,7 +853,7 @@ GetNextSector(PDEVICE_EXTENSION DeviceExt,
     }
   else
     {
-      CurrentSector = (CurrentSector - DeviceExt->dataStart) / DeviceExt -> Boot -> SectorsPerCluster + 2;
+      CurrentSector = (CurrentSector - DeviceExt->FatInfo.dataStart) / DeviceExt->FatInfo.SectorsPerCluster + 2;
 
       Status = GetNextCluster(DeviceExt, CurrentSector, NextSector, Extend);
       if (!NT_SUCCESS(Status))
index 0baee0a..c376156 100644 (file)
@@ -1,4 +1,4 @@
-/* $Id: fcb.c,v 1.13 2002/01/15 21:54:51 hbirr Exp $
+/* $Id: fcb.c,v 1.14 2002/03/18 22:37:12 hbirr Exp $
  *
  *
  * FILE:             fcb.c
@@ -156,7 +156,6 @@ vfatFCBInitializeCache (PVCB  vcb, PVFATFCB  fcb)
 {
   NTSTATUS  status;
   PFILE_OBJECT  fileObject;
-  ULONG  bytesPerCluster;
   ULONG  fileCacheQuantum;
   PVFATCCB  newCCB;
 
@@ -180,9 +179,8 @@ vfatFCBInitializeCache (PVCB  vcb, PVFATFCB  fcb)
   fcb->pDevExt = vcb;
 
 
-  bytesPerCluster = vcb->Boot->SectorsPerCluster * BLOCKSIZE;
-  fileCacheQuantum = (bytesPerCluster >= PAGESIZE) ?
-      bytesPerCluster : PAGESIZE;
+  fileCacheQuantum = (vcb->FatInfo.BytesPerCluster >= PAGESIZE) ?
+      vcb->FatInfo.BytesPerCluster : PAGESIZE;
 
   status = CcRosInitializeFileCache (fileObject,
                                      &fcb->RFCB.Bcb,
@@ -208,25 +206,25 @@ vfatMakeRootFCB(PDEVICE_EXTENSION  pVCB)
 
   FCB = vfatNewFCB(L"\\");
   memset(FCB->entry.Filename, ' ', 11);
-  FCB->entry.FileSize = pVCB->rootDirectorySectors * BLOCKSIZE;
+  FCB->entry.FileSize = pVCB->FatInfo.rootDirectorySectors * BLOCKSIZE;
   FCB->entry.Attrib = FILE_ATTRIBUTE_DIRECTORY;
-  if (pVCB->FatType == FAT32)
+  if (pVCB->FatInfo.FatType == FAT32)
   {
-    CurrentCluster = FirstCluster = ((struct _BootSector32*)(pVCB->Boot))->RootCluster;
+    CurrentCluster = FirstCluster = pVCB->FatInfo.RootCluster;
     FCB->entry.FirstCluster = FirstCluster & 0xffff;
     FCB->entry.FirstClusterHigh = FirstCluster >> 16;
     CurrentCluster = FirstCluster;
 
     while (CurrentCluster != 0xffffffff && NT_SUCCESS(Status))
     {
-      Size += pVCB->BytesPerCluster;
+      Size += pVCB->FatInfo.BytesPerCluster;
       Status = NextCluster (pVCB, NULL, FirstCluster, &CurrentCluster, FALSE);
     }
   }
   else
   {
     FCB->entry.FirstCluster = 1;
-    Size = pVCB->rootDirectorySectors * BLOCKSIZE;
+    Size = pVCB->FatInfo.rootDirectorySectors * BLOCKSIZE;
   }
   FCB->RefCount = 1;
   FCB->dirIndex = 0;
@@ -298,14 +296,14 @@ vfatMakeFCBFromDirEntry(PVCB  vcb,
     FirstCluster = vfatDirEntryGetFirstCluster (vcb, &rcFCB->entry);
     if (FirstCluster == 1)
     {
-      Size = vcb->rootDirectorySectors * BLOCKSIZE;
+      Size = vcb->FatInfo.rootDirectorySectors * BLOCKSIZE;
     }
     else
     {
       CurrentCluster = FirstCluster;
       while (CurrentCluster != 0xffffffff)
       {
-         Size += vcb->BytesPerCluster;
+         Size += vcb->FatInfo.BytesPerCluster;
          Status = NextCluster (vcb, NULL, FirstCluster, &CurrentCluster, FALSE);
       }
     }
@@ -317,7 +315,7 @@ vfatMakeFCBFromDirEntry(PVCB  vcb,
   rcFCB->dirIndex = dirIndex;
   rcFCB->RFCB.FileSize.QuadPart = Size;
   rcFCB->RFCB.ValidDataLength.QuadPart = Size;
-  rcFCB->RFCB.AllocationSize.QuadPart = ROUND_UP(Size, vcb->BytesPerCluster);
+  rcFCB->RFCB.AllocationSize.QuadPart = ROUND_UP(Size, vcb->FatInfo.BytesPerCluster);
 //  DPRINT1("%S %d %d\n", longName, Size, (ULONG)rcFCB->RFCB.AllocationSize.QuadPart);
   vfatFCBInitializeCache (vcb, rcFCB);
   rcFCB->RefCount++;
@@ -353,11 +351,10 @@ vfatAttachFCBToFileObject (PDEVICE_EXTENSION  vcb,
 
   if (!(fcb->Flags & FCB_CACHE_INITIALIZED))
   {
-    ULONG  bytesPerCluster;
     ULONG  fileCacheQuantum;
 
-    bytesPerCluster = vcb->Boot->SectorsPerCluster * BLOCKSIZE;
-    fileCacheQuantum = (bytesPerCluster >= PAGESIZE) ? bytesPerCluster : PAGESIZE;
+    fileCacheQuantum = (vcb->FatInfo.BytesPerCluster >= PAGESIZE) ? 
+                               vcb->FatInfo.BytesPerCluster : PAGESIZE;
     status = CcRosInitializeFileCache (fileObject,
                                        &fcb->RFCB.Bcb,
                                        fileCacheQuantum);
index cb4c67b..f73ffb8 100644 (file)
@@ -1,4 +1,4 @@
-/* $Id: finfo.c,v 1.11 2001/11/02 22:47:36 hbirr Exp $
+/* $Id: finfo.c,v 1.12 2002/03/18 22:37:12 hbirr Exp $
  *
  * COPYRIGHT:        See COPYING in the top level directory
  * PROJECT:          ReactOS kernel
@@ -37,7 +37,7 @@ VfatGetStandardInformation(PVFATFCB FCB,
   DeviceExtension = DeviceObject->DeviceExtension;
   /* PRECONDITION */
   assert (DeviceExtension != NULL);
-  assert (DeviceExtension->BytesPerCluster != 0);
+  assert (DeviceExtension->FatInfo.BytesPerCluster != 0);
   assert (StandardInfo != NULL);
   assert (FCB != NULL);
 
@@ -143,7 +143,7 @@ VfatSetDispositionInformation(PFILE_OBJECT FileObject,
   DPRINT ("FsdSetDispositionInformation()\n");
 
   assert (DeviceExt != NULL);
-  assert (DeviceExt->BytesPerCluster != 0);
+  assert (DeviceExt->FatInfo.BytesPerCluster != 0);
   assert (FCB != NULL);
 
   if (!wcscmp(FCB->PathName, L"\\") || !wcscmp(FCB->ObjectName, L"..")
diff --git a/reactos/drivers/fs/vfat/fsctl.c b/reactos/drivers/fs/vfat/fsctl.c
new file mode 100644 (file)
index 0000000..860402e
--- /dev/null
@@ -0,0 +1,378 @@
+/* $Id: fsctl.c,v 1.1 2002/03/18 22:37:13 hbirr Exp $
+ *
+ * COPYRIGHT:        See COPYING in the top level directory
+ * PROJECT:          ReactOS kernel
+ * FILE:             services/fs/vfat/fsctl.c
+ * PURPOSE:          VFAT Filesystem
+ */
+
+/* INCLUDES *****************************************************************/
+
+#include <ddk/ntddk.h>
+#include <wchar.h>
+
+#define NDEBUG
+#include <debug.h>
+
+#include "vfat.h"
+
+/* FUNCTIONS ****************************************************************/
+
+#define  CACHEPAGESIZE(pDeviceExt) ((pDeviceExt)->FatInfo.BytesPerCluster > PAGESIZE ? \
+                  (pDeviceExt)->FatInfo.BytesPerCluster : PAGESIZE)
+
+
+static NTSTATUS
+VfatHasFileSystem(PDEVICE_OBJECT DeviceToMount,
+                 PBOOLEAN RecognizedFS,
+                 PFATINFO pFatInfo)
+{
+   NTSTATUS Status;
+   PARTITION_INFORMATION PartitionInfo;
+   DISK_GEOMETRY DiskGeometry;
+   FATINFO FatInfo;
+   ULONG Size;
+   ULONG Sectors;
+   struct _BootSector* Boot;
+
+   *RecognizedFS = FALSE;
+
+   Size = sizeof(DISK_GEOMETRY);
+   Status = VfatBlockDeviceIoControl(DeviceToMount,
+                                    IOCTL_DISK_GET_DRIVE_GEOMETRY,
+                                    NULL,
+                                    0,
+                                    &DiskGeometry,
+                                    &Size);
+   if (!NT_SUCCESS(Status))
+   {
+      DPRINT("VfatBlockDeviceIoControl faild (%x)\n", Status);
+      return Status;
+   }
+   if (DiskGeometry.MediaType == FixedMedia)
+   {
+      // We have found a hard disk
+      Size = sizeof(PARTITION_INFORMATION);
+      Status = VfatBlockDeviceIoControl(DeviceToMount,
+                                       IOCTL_DISK_GET_PARTITION_INFO,
+                                       NULL,
+                                       0,
+                                       &PartitionInfo,
+                                       &Size);
+      if (!NT_SUCCESS(Status))
+      {
+         DPRINT1("VfatBlockDeviceIoControl faild (%x)\n", Status);
+         return Status;
+      }
+#ifdef DBG
+      DbgPrint("Partition Information:\n");
+      DbgPrint("StartingOffset      %u\n", PartitionInfo.StartingOffset.QuadPart  / 512);
+      DbgPrint("PartitionLength     %u\n", PartitionInfo.PartitionLength.QuadPart / 512);
+      DbgPrint("HiddenSectors       %u\n", PartitionInfo.HiddenSectors);
+      DbgPrint("PartitionNumber     %u\n", PartitionInfo.PartitionNumber);
+      DbgPrint("PartitionType       %u\n", PartitionInfo.PartitionType);
+      DbgPrint("BootIndicator       %u\n", PartitionInfo.BootIndicator);
+      DbgPrint("RecognizedPartition %u\n", PartitionInfo.RecognizedPartition);
+      DbgPrint("RewritePartition    %u\n", PartitionInfo.RewritePartition);
+#endif
+      if (PartitionInfo.PartitionType == PTDOS3xPrimary  ||
+          PartitionInfo.PartitionType == PTOLDDOS16Bit   ||
+          PartitionInfo.PartitionType == PTDos5xPrimary  ||
+          PartitionInfo.PartitionType == PTWin95FAT32    ||
+          PartitionInfo.PartitionType == PTWin95FAT32LBA ||
+          PartitionInfo.PartitionType == PTWin95FAT16LBA)
+      {
+         *RecognizedFS = TRUE;
+      }
+   }
+   else if (DiskGeometry.MediaType > Unknown && DiskGeometry.MediaType < RemovableMedia)
+   {
+      *RecognizedFS = TRUE;
+   }
+   if (*RecognizedFS == FALSE)
+   {
+      return STATUS_SUCCESS;
+   }
+ReadSector:
+   Boot = ExAllocatePool(NonPagedPool, BLOCKSIZE);
+   if (Boot == NULL)
+   {
+      *RecognizedFS=FALSE;
+      return STATUS_INSUFFICIENT_RESOURCES;
+   }
+   Status = VfatReadSectors(DeviceToMount, 0, 1, (PUCHAR) Boot);
+   if (NT_SUCCESS(Status))
+   {
+      FatInfo.VolumeID = Boot->VolumeID;
+      FatInfo.FATStart = Boot->ReservedSectors;
+      FatInfo.FATCount = Boot->FATCount;
+      FatInfo.FATSectors = Boot->FATSectors ? Boot->FATSectors : ((struct _BootSector32*) Boot)->FATSectors32;
+      FatInfo.BytesPerSector = Boot->BytesPerSector;
+      FatInfo.SectorsPerCluster = Boot->SectorsPerCluster;
+      FatInfo.BytesPerCluster = FatInfo.BytesPerSector * FatInfo.SectorsPerCluster;
+      FatInfo.rootDirectorySectors = ((Boot->RootEntries * 32) + Boot->BytesPerSector - 1) / Boot->BytesPerSector;
+      FatInfo.rootStart = FatInfo.FATStart + FatInfo.FATCount * FatInfo.FATSectors;
+      FatInfo.dataStart = FatInfo.rootStart + FatInfo.rootDirectorySectors;
+      Sectors = Boot->Sectors ? Boot->Sectors : Boot->SectorsHuge;
+      Sectors -= Boot->ReservedSectors + FatInfo.FATCount * FatInfo.FATSectors + FatInfo.rootDirectorySectors;
+      FatInfo.NumberOfClusters = Sectors / Boot->SectorsPerCluster;
+      if (FatInfo.NumberOfClusters < 4085)
+      {
+         DPRINT("FAT12\n");
+         FatInfo.FatType = FAT12;
+      }
+      else if (FatInfo.NumberOfClusters >= 65525)
+      {
+         DPRINT("FAT32\n");
+         FatInfo.FatType = FAT32;
+         FatInfo.RootCluster = ((struct _BootSector32*) Boot)->RootCluster;
+         FatInfo.rootStart = FatInfo.dataStart + ((FatInfo.RootCluster - 2) * FatInfo.SectorsPerCluster);
+         FatInfo.VolumeID = ((struct _BootSector32*) Boot)->VolumeID;
+      }
+      else
+      {
+         DPRINT("FAT16\n");
+         FatInfo.FatType = FAT16;
+      }
+      if (pFatInfo)
+      {
+         *pFatInfo = FatInfo;
+      }
+   }
+   ExFreePool(Boot);
+   return Status;
+}
+
+static NTSTATUS
+VfatMountDevice(PDEVICE_EXTENSION DeviceExt,
+               PDEVICE_OBJECT DeviceToMount)
+/*
+ * FUNCTION: Mounts the device
+ */
+{
+   NTSTATUS Status;
+   BOOLEAN RecognizedFS;
+
+   DPRINT1("Mounting VFAT device...\n");
+
+   Status = VfatHasFileSystem(DeviceToMount, &RecognizedFS, &DeviceExt->FatInfo);
+   if (!NT_SUCCESS(Status))
+   {
+      return(Status);
+   }
+
+   if (DeviceExt->FatInfo.BytesPerCluster >= PAGESIZE &&
+      (DeviceExt->FatInfo.BytesPerCluster % PAGESIZE) != 0)
+   {
+      DbgPrint("(%s:%d) Invalid cluster size\n", __FILE__, __LINE__);
+      KeBugCheck(0);
+   }
+   else if (DeviceExt->FatInfo.BytesPerCluster < PAGESIZE &&
+      (PAGESIZE % DeviceExt->FatInfo.BytesPerCluster) != 0)
+   {
+      DbgPrint("(%s:%d) Invalid cluster size2\n", __FILE__, __LINE__);
+      KeBugCheck(0);
+   }
+
+   return(STATUS_SUCCESS);
+}
+
+
+static NTSTATUS
+VfatMount (PVFAT_IRP_CONTEXT IrpContext)
+/*
+ * FUNCTION: Mount the filesystem
+ */
+{
+   PDEVICE_OBJECT DeviceObject = NULL;
+   PDEVICE_EXTENSION DeviceExt = NULL;
+   BOOLEAN RecognizedFS;
+   NTSTATUS Status;
+   PVFATFCB Fcb = NULL;
+   PVFATCCB Ccb = NULL;
+   LARGE_INTEGER timeout;
+
+   DPRINT("VfatMount(IrpContext %x)\n", IrpContext);
+
+   assert (IrpContext);
+
+   if (IrpContext->DeviceObject != VfatGlobalData->DeviceObject)
+   {
+      Status = STATUS_INVALID_DEVICE_REQUEST;
+      goto ByeBye;
+   }
+
+   Status = VfatHasFileSystem (IrpContext->Stack->Parameters.Mount.DeviceObject, &RecognizedFS, NULL);
+   if (!NT_SUCCESS(Status))
+   {
+      goto ByeBye;
+   }
+
+   if (RecognizedFS == FALSE)
+   {
+      DPRINT("VFAT: Unrecognized Volume\n");
+      Status = STATUS_UNRECOGNIZED_VOLUME;
+      goto ByeBye;
+   }
+
+   DPRINT("VFAT: Recognized volume\n");
+   Status = IoCreateDevice(VfatGlobalData->DriverObject,
+                          sizeof (DEVICE_EXTENSION),
+                          NULL,
+                          FILE_DEVICE_FILE_SYSTEM,
+                          0,
+                          FALSE,
+                          &DeviceObject);
+   if (!NT_SUCCESS(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 = IrpContext->Stack->Parameters.Mount.DeviceObject->Vpb;
+   Status = VfatMountDevice(DeviceExt, IrpContext->Stack->Parameters.Mount.DeviceObject);
+   if (!NT_SUCCESS(Status))
+   {
+      /* FIXME: delete device object */
+      goto ByeBye;
+   }
+
+#ifdef DBG
+   DbgPrint("BytesPerSector:     %d\n", DeviceExt->FatInfo.BytesPerSector);
+   DbgPrint("SectorsPerCluster:  %d\n", DeviceExt->FatInfo.SectorsPerCluster);
+   DbgPrint("FATCount:           %d\n", DeviceExt->FatInfo.FATCount);
+   DbgPrint("FATSectors:         %d\n", DeviceExt->FatInfo.FATSectors);
+   DbgPrint("RootStart:          %d\n", DeviceExt->FatInfo.rootStart);
+   DbgPrint("DataStart:          %d\n", DeviceExt->FatInfo.dataStart);
+   if (DeviceExt->FatInfo.FatType == FAT32)
+   {
+      DbgPrint("RootCluster:        %d\n", DeviceExt->FatInfo.RootCluster);
+   }
+#endif
+   DeviceObject->Vpb->Flags |= VPB_MOUNTED;
+   DeviceExt->StorageDevice = IoAttachDeviceToDeviceStack(DeviceObject, IrpContext->Stack->Parameters.Mount.DeviceObject);
+
+   DeviceExt->FATFileObject = IoCreateStreamFileObject(NULL, DeviceExt->StorageDevice);
+   Fcb = vfatNewFCB(NULL);
+   if (Fcb == NULL)
+   {
+      Status = STATUS_INSUFFICIENT_RESOURCES;
+      goto ByeBye;
+   }
+   Ccb = ExAllocatePoolWithTag (NonPagedPool, sizeof (VFATCCB), TAG_CCB);
+   if (Ccb == NULL)
+   {
+      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;
+   DeviceExt->FATFileObject->PrivateCacheMap = NULL;
+   DeviceExt->FATFileObject->Vpb = DeviceObject->Vpb;
+   Ccb->pFcb = Fcb;
+   Ccb->PtrFileObject = DeviceExt->FATFileObject;
+   Fcb->FileObject = DeviceExt->FATFileObject;
+   Fcb->pDevExt = (PDEVICE_EXTENSION)DeviceExt->StorageDevice;
+
+   Fcb->Flags = FCB_IS_FAT;
+
+   if (DeviceExt->FatInfo.FatType != FAT12)
+   {
+      Fcb->RFCB.FileSize.QuadPart = DeviceExt->FatInfo.FATSectors * BLOCKSIZE;
+      Fcb->RFCB.ValidDataLength.QuadPart = DeviceExt->FatInfo.FATSectors * BLOCKSIZE;
+      Fcb->RFCB.AllocationSize.QuadPart = ROUND_UP(DeviceExt->FatInfo.FATSectors * BLOCKSIZE, CACHEPAGESIZE(DeviceExt));
+      Status = CcRosInitializeFileCache(DeviceExt->FATFileObject, &Fcb->RFCB.Bcb, CACHEPAGESIZE(DeviceExt));
+   }
+   else
+   {
+      Fcb->RFCB.FileSize.QuadPart = DeviceExt->FatInfo.FATSectors * BLOCKSIZE;
+      Fcb->RFCB.ValidDataLength.QuadPart = DeviceExt->FatInfo.FATSectors * BLOCKSIZE;
+      Fcb->RFCB.AllocationSize.QuadPart = 2 * PAGESIZE;
+      Status = CcRosInitializeFileCache(DeviceExt->FATFileObject, &Fcb->RFCB.Bcb, 2 * PAGESIZE);
+   }
+   if (!NT_SUCCESS (Status))
+   {
+      DbgPrint ("CcRosInitializeFileCache failed\n");
+      goto ByeBye;
+   }
+   DeviceExt->LastAvailableCluster = 0;
+   ExInitializeResourceLite(&DeviceExt->DirResource);
+   ExInitializeResourceLite(&DeviceExt->FatResource);
+
+   KeInitializeSpinLock(&DeviceExt->FcbListLock);
+   InitializeListHead(&DeviceExt->FcbListHead);
+
+   /* read serial number */
+   DeviceObject->Vpb->SerialNumber = DeviceExt->FatInfo.VolumeID;
+
+   /* read volume label */
+   ReadVolumeLabel(DeviceExt,  DeviceObject->Vpb);
+
+   Status = STATUS_SUCCESS;
+
+ByeBye:
+
+  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 VfatFileSystemControl(PVFAT_IRP_CONTEXT IrpContext)
+/*
+ * FUNCTION: File system control
+ */
+{
+
+   NTSTATUS Status;
+
+   DPRINT("VfatFileSystemControl(IrpContext %x)\n", IrpContext);
+
+   assert (IrpContext);
+
+   switch (IrpContext->MinorFunction)
+   {
+      case IRP_MN_USER_FS_REQUEST:
+         DPRINT("VFAT FSC: IRP_MN_USER_FS_REQUEST\n");
+        Status = STATUS_INVALID_DEVICE_REQUEST;
+        break;
+
+      case IRP_MN_MOUNT_VOLUME:
+         Status = VfatMount(IrpContext);
+        break;
+
+      case IRP_MN_VERIFY_VOLUME:
+         DPRINT("VFAT FSC: IRP_MN_VERIFY_VOLUME\n");
+        Status = STATUS_INVALID_DEVICE_REQUEST;
+        break;
+
+      default:
+          DPRINT("VFAT FSC: MinorFunction %d\n", IrpContext->MinorFunction);
+          Status = STATUS_INVALID_DEVICE_REQUEST;
+          break;
+   }
+
+   IrpContext->Irp->IoStatus.Status = Status;
+   IrpContext->Irp->IoStatus.Information = 0;
+
+   IoCompleteRequest (IrpContext->Irp, IO_NO_INCREMENT);
+   VfatFreeIrpContext(IrpContext);
+   return (Status);
+}
+
index d42ee5c..1069359 100644 (file)
@@ -1,4 +1,4 @@
-/* $Id: iface.c,v 1.61 2002/02/08 02:57:09 chorns Exp $
+/* $Id: iface.c,v 1.62 2002/03/18 22:37:12 hbirr Exp $
  *
  * COPYRIGHT:        See COPYING in the top level directory
  * PROJECT:          ReactOS kernel
 
 /* GLOBALS *****************************************************************/
 
-#define  CACHEPAGESIZE(pDeviceExt) ((pDeviceExt)->BytesPerCluster > PAGESIZE ? \
-                  (pDeviceExt)->BytesPerCluster : PAGESIZE)
 
-static PDRIVER_OBJECT VfatDriverObject;
+PVFAT_GLOBAL_DATA VfatGlobalData;
 
 /* FUNCTIONS ****************************************************************/
 
-static NTSTATUS
-VfatHasFileSystem(PDEVICE_OBJECT DeviceToMount,
-                 PBOOLEAN RecognizedFS)
-/*
- * FUNCTION: Tests if the device contains a filesystem that can be mounted
- *           by this fsd
- */
-{
-   BootSector *Boot;
-   NTSTATUS Status;
-
-   Boot = ExAllocatePool(NonPagedPool, 512);
-
-   Status = VfatReadSectors(DeviceToMount, 0, 1, (UCHAR *) Boot);
-   if (!NT_SUCCESS(Status))
-     {
-       return(Status);
-     }
-
-   DPRINT("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)
-     {
-       *RecognizedFS = TRUE;
-     }
-   else
-     {
-       *RecognizedFS = FALSE;
-     }
-
-   ExFreePool(Boot);
-
-   return(STATUS_SUCCESS);
-}
-
-
-static NTSTATUS
-VfatMountDevice(PDEVICE_EXTENSION DeviceExt,
-               PDEVICE_OBJECT DeviceToMount)
-/*
- * FUNCTION: Mounts the device
- */
-{
-   NTSTATUS Status;
-
-   DPRINT("Mounting VFAT device...");
-   DPRINT("DeviceExt %x\n", DeviceExt);
-
-   DeviceExt->Boot = ExAllocatePool(NonPagedPool, 512);
-
-   Status = VfatReadSectors(DeviceToMount, 0, 1, (UCHAR *) DeviceExt->Boot);
-   if (!NT_SUCCESS(Status))
-     {
-       return(Status);
-     }
-
-   DeviceExt->FATStart = DeviceExt->Boot->ReservedSectors;
-   DeviceExt->rootDirectorySectors =
-     (DeviceExt->Boot->RootEntries * 32) / DeviceExt->Boot->BytesPerSector;
-   DeviceExt->rootStart =
-     DeviceExt->FATStart +
-     DeviceExt->Boot->FATCount * DeviceExt->Boot->FATSectors;
-   DeviceExt->dataStart =
-     DeviceExt->rootStart + DeviceExt->rootDirectorySectors;
-   DeviceExt->BytesPerSector = DeviceExt->Boot->BytesPerSector;
-   DeviceExt->FATEntriesPerSector = DeviceExt->Boot->BytesPerSector / 32;
-   DeviceExt->BytesPerCluster = DeviceExt->Boot->SectorsPerCluster *
-     DeviceExt->Boot->BytesPerSector;
-
-   if (DeviceExt->BytesPerCluster >= PAGESIZE && 
-       (DeviceExt->BytesPerCluster % PAGESIZE) != 0)
-     {
-       DbgPrint("Invalid cluster size\n");
-       KeBugCheck(0);
-     }
-   else if (DeviceExt->BytesPerCluster < PAGESIZE &&
-           (PAGESIZE % DeviceExt->BytesPerCluster) != 0)
-     {
-       DbgPrint("Invalid cluster size2\n");
-       KeBugCheck(0);
-     }
-
-   if (strncmp (DeviceExt->Boot->SysType, "FAT12", 5) == 0)
-     {
-       DPRINT("FAT12\n");
-       DeviceExt->FatType = FAT12;
-     }
-   else if (strncmp
-           (((struct _BootSector32 *) (DeviceExt->Boot))->SysType, "FAT32",
-           5) == 0)
-     {
-       DPRINT("FAT32\n");
-       DeviceExt->FatType = FAT32;
-       DeviceExt->rootDirectorySectors = DeviceExt->Boot->SectorsPerCluster;
-       DeviceExt->dataStart = DeviceExt->FATStart + DeviceExt->Boot->FATCount
-         * ((struct _BootSector32 *) (DeviceExt->Boot))->FATSectors32;
-       DeviceExt->rootStart = ClusterToSector (DeviceExt,
-         ((struct _BootSector32 *)(DeviceExt->Boot))->RootCluster);
-     }
-   else
-     {
-       DPRINT("FAT16\n");
-       DeviceExt->FatType = FAT16;
-     }
-
-   return(STATUS_SUCCESS);
-}
-
-
-static NTSTATUS
-VfatMount (PVFAT_IRP_CONTEXT IrpContext)
-/*
- * FUNCTION: Mount the filesystem
- */
-{
-  PDEVICE_OBJECT DeviceObject = NULL;
-  PDEVICE_EXTENSION DeviceExt = NULL;
-  BOOLEAN RecognizedFS;
-  NTSTATUS Status;
-  PVFATFCB Fcb = NULL;
-  PVFATCCB Ccb = NULL;
-
-  DPRINT("VfatMount(IrpContext %x)\n", IrpContext);
-
-  assert (IrpContext);
-
-  Status = VfatHasFileSystem (IrpContext->Stack->Parameters.Mount.DeviceObject, &RecognizedFS);
-  if (!NT_SUCCESS(Status))
-  {
-     goto ByeBye;
-  }
-
-  if (RecognizedFS == FALSE)
-  {
-     DPRINT("VFAT: Unrecognized Volume\n");
-     Status = STATUS_UNRECOGNIZED_VOLUME;
-     goto ByeBye;
-  }
-
-  DPRINT("VFAT: Recognized volume\n");
-
-  Status = IoCreateDevice(VfatDriverObject,
-                         sizeof (DEVICE_EXTENSION),
-                         NULL,
-                         FILE_DEVICE_FILE_SYSTEM,
-                         0,
-                         FALSE,
-                         &DeviceObject);
-  if (!NT_SUCCESS(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 = IrpContext->Stack->Parameters.Mount.DeviceObject->Vpb;
-  Status = VfatMountDevice(DeviceExt, IrpContext->Stack->Parameters.Mount.DeviceObject);
-  if (!NT_SUCCESS(Status))
-  {
-    /* FIXME: delete device object */
-    goto ByeBye;
-  }
-
-#ifdef DBG
-  DbgPrint("BytesPerSector:     %d\n", DeviceExt->Boot->BytesPerSector);
-  DbgPrint("SectorsPerCluster:  %d\n", DeviceExt->Boot->SectorsPerCluster);
-  DbgPrint("ReservedSectors:    %d\n", DeviceExt->Boot->ReservedSectors);
-  DbgPrint("FATCount:           %d\n", DeviceExt->Boot->FATCount);
-  DbgPrint("RootEntries:        %d\n", DeviceExt->Boot->RootEntries);
-  DbgPrint("Sectors:            %d\n", DeviceExt->Boot->Sectors);
-  DbgPrint("FATSectors:         %d\n", DeviceExt->Boot->FATSectors);
-  DbgPrint("SectorsPerTrack:    %d\n", DeviceExt->Boot->SectorsPerTrack);
-  DbgPrint("Heads:              %d\n", DeviceExt->Boot->Heads);
-  DbgPrint("HiddenSectors:      %d\n", DeviceExt->Boot->HiddenSectors);
-  DbgPrint("SectorsHuge:        %d\n", DeviceExt->Boot->SectorsHuge);
-  DbgPrint("RootStart:          %d\n", DeviceExt->rootStart);
-  DbgPrint("DataStart:          %d\n", DeviceExt->dataStart);
-  if (DeviceExt->FatType == FAT32)
-    {
-      DbgPrint("FATSectors32:       %d\n",
-              ((struct _BootSector32*)(DeviceExt->Boot))->FATSectors32);
-      DbgPrint("RootCluster:        %d\n",
-              ((struct _BootSector32*)(DeviceExt->Boot))->RootCluster);
-      DbgPrint("FSInfoSector:       %d\n",
-              ((struct _BootSector32*)(DeviceExt->Boot))->FSInfoSector);
-      DbgPrint("BootBackup:         %d\n",
-              ((struct _BootSector32*)(DeviceExt->Boot))->BootBackup);
-    }
-#endif
-  DeviceObject->Vpb->Flags |= VPB_MOUNTED;
-  DeviceExt->StorageDevice = IoAttachDeviceToDeviceStack(DeviceObject, IrpContext->Stack->Parameters.Mount.DeviceObject);
-
-  DeviceExt->FATFileObject = IoCreateStreamFileObject(NULL, DeviceExt->StorageDevice);
-  Fcb = vfatNewFCB(NULL);
-  if (Fcb == NULL)
-  {
-    Status = STATUS_INSUFFICIENT_RESOURCES;
-    goto ByeBye;
-  }
-  Ccb = ExAllocatePoolWithTag (NonPagedPool, sizeof (VFATCCB), TAG_CCB);
-  if (Ccb == NULL)
-  {
-    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;
-  Fcb->pDevExt = (PDEVICE_EXTENSION)DeviceExt->StorageDevice;
-
-  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;
-    Fcb->RFCB.ValidDataLength.QuadPart = ((struct _BootSector32 *)DeviceExt->Boot)->FATSectors32 * BLOCKSIZE;
-    Fcb->RFCB.AllocationSize.QuadPart = ROUND_UP(((struct _BootSector32 *)DeviceExt->Boot)->FATSectors32 * BLOCKSIZE, CACHEPAGESIZE(DeviceExt));
-    Status = CcRosInitializeFileCache(DeviceExt->FATFileObject, &Fcb->RFCB.Bcb, CACHEPAGESIZE(DeviceExt));
-  }
-  else
-  {
-    if (DeviceExt->FatType == FAT16)
-    {
-      Fcb->RFCB.FileSize.QuadPart = DeviceExt->Boot->FATSectors * BLOCKSIZE;
-      Fcb->RFCB.ValidDataLength.QuadPart = DeviceExt->Boot->FATSectors * BLOCKSIZE;
-      Fcb->RFCB.AllocationSize.QuadPart = ROUND_UP(DeviceExt->Boot->FATSectors * BLOCKSIZE, CACHEPAGESIZE(DeviceExt));
-      Status = CcRosInitializeFileCache(DeviceExt->FATFileObject, &Fcb->RFCB.Bcb, CACHEPAGESIZE(DeviceExt));
-    }
-    else
-    {
-      Fcb->RFCB.FileSize.QuadPart = DeviceExt->Boot->FATSectors * BLOCKSIZE;
-      Fcb->RFCB.ValidDataLength.QuadPart = DeviceExt->Boot->FATSectors * BLOCKSIZE;
-      Fcb->RFCB.AllocationSize.QuadPart = 2 * PAGESIZE;
-      Status = CcRosInitializeFileCache(DeviceExt->FATFileObject, &Fcb->RFCB.Bcb, 2 * PAGESIZE);
-    }
-  }
-  if (!NT_SUCCESS (Status))
-  {
-     DbgPrint ("CcRosInitializeFileCache failed\n");
-     goto ByeBye;
-  }
-
-  DeviceExt->LastAvailableCluster = 0;
-  ExInitializeResourceLite(&DeviceExt->DirResource);
-  ExInitializeResourceLite(&DeviceExt->FatResource);
-
-  KeInitializeSpinLock(&DeviceExt->FcbListLock);
-  InitializeListHead(&DeviceExt->FcbListHead);
-
-  /* read serial number */
-  if (DeviceExt->FatType == FAT12 || DeviceExt->FatType == FAT16)
-    DeviceObject->Vpb->SerialNumber =
-      ((struct _BootSector *) (DeviceExt->Boot))->VolumeID;
-  else if (DeviceExt->FatType == FAT32)
-    DeviceObject->Vpb->SerialNumber =
-      ((struct _BootSector32 *) (DeviceExt->Boot))->VolumeID;
-
-  /* read volume label */
-  ReadVolumeLabel(DeviceExt,  DeviceObject->Vpb);
-  Status = STATUS_SUCCESS;
-
-ByeBye:
-
-  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 VfatFileSystemControl(PVFAT_IRP_CONTEXT IrpContext)
-/*
- * FUNCTION: File system control
- */
-{
-
-   NTSTATUS Status;
-
-   DPRINT("VfatFileSystemControl(IrpContext %x)\n", IrpContext);
-
-   assert (IrpContext);
-
-   switch (IrpContext->MinorFunction)
-     {
-       case IRP_MN_USER_FS_REQUEST:
-          DPRINT("VFAT FSC: IRP_MN_USER_FS_REQUEST\n");
-          Status = STATUS_INVALID_DEVICE_REQUEST;
-          break;
-
-       case IRP_MN_MOUNT_VOLUME:
-          Status = VfatMount(IrpContext);
-          break;
-
-       case IRP_MN_VERIFY_VOLUME:
-          DPRINT("VFAT FSC: IRP_MN_VERIFY_VOLUME\n");
-          Status = STATUS_INVALID_DEVICE_REQUEST;
-          break;
-
-       default:
-          DPRINT("VFAT FSC: MinorFunction %d\n", IrpContext->MinorFunction);
-          Status = STATUS_INVALID_DEVICE_REQUEST;
-          break;
-     }
-
-   IrpContext->Irp->IoStatus.Status = Status;
-   IrpContext->Irp->IoStatus.Information = 0;
-
-   IoCompleteRequest (IrpContext->Irp, IO_NO_INCREMENT);
-   return (Status);
-}
-
-
 NTSTATUS STDCALL
-DriverEntry(PDRIVER_OBJECT _DriverObject,
+DriverEntry(PDRIVER_OBJECT DriverObject,
            PUNICODE_STRING RegistryPath)
 /*
  * FUNCTION: Called by the system to initalize the driver
@@ -399,14 +57,12 @@ DriverEntry(PDRIVER_OBJECT _DriverObject,
 
    DPRINT("VFAT 0.0.6\n");
 
-   VfatDriverObject = _DriverObject;
-
    RtlInitUnicodeString(&DeviceName,
                        L"\\Device\\Vfat");
-   Status = IoCreateDevice(VfatDriverObject,
-                          0,
+   Status = IoCreateDevice(DriverObject,
+                          sizeof(VFAT_GLOBAL_DATA),
                           &DeviceName,
-                          FILE_DEVICE_FILE_SYSTEM,
+                          FILE_DEVICE_DISK_FILE_SYSTEM,
                           0,
                           FALSE,
                           &DeviceObject);
@@ -414,32 +70,30 @@ DriverEntry(PDRIVER_OBJECT _DriverObject,
      {
        return (Status);
      }
+   VfatGlobalData = DeviceObject->DeviceExtension;
+   RtlZeroMemory (VfatGlobalData, sizeof(VFAT_GLOBAL_DATA));
+   VfatGlobalData->DriverObject = DriverObject;
+   VfatGlobalData->DeviceObject = DeviceObject;
 
    DeviceObject->Flags = DO_DIRECT_IO;
-   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] =
-     VfatBuildRequest;
-   VfatDriverObject->MajorFunction[IRP_MJ_QUERY_INFORMATION] =
-     VfatBuildRequest;
-   VfatDriverObject->MajorFunction[IRP_MJ_SET_INFORMATION] =
-     VfatBuildRequest;
-   VfatDriverObject->MajorFunction[IRP_MJ_DIRECTORY_CONTROL] =
-     VfatBuildRequest;
-   VfatDriverObject->MajorFunction[IRP_MJ_QUERY_VOLUME_INFORMATION] =
-     VfatBuildRequest;
-   VfatDriverObject->MajorFunction[IRP_MJ_SET_VOLUME_INFORMATION] =
-     VfatBuildRequest;
-   VfatDriverObject->MajorFunction[IRP_MJ_SHUTDOWN] = VfatShutdown;
-   VfatDriverObject->MajorFunction[IRP_MJ_CLEANUP] = VfatBuildRequest;
-
-   VfatDriverObject->DriverUnload = NULL;
+   DriverObject->MajorFunction[IRP_MJ_CLOSE] = VfatBuildRequest;
+   DriverObject->MajorFunction[IRP_MJ_CREATE] = VfatBuildRequest;
+   DriverObject->MajorFunction[IRP_MJ_READ] = VfatBuildRequest;
+   DriverObject->MajorFunction[IRP_MJ_WRITE] = VfatBuildRequest;
+   DriverObject->MajorFunction[IRP_MJ_FILE_SYSTEM_CONTROL] = VfatBuildRequest;
+   DriverObject->MajorFunction[IRP_MJ_QUERY_INFORMATION] = VfatBuildRequest;
+   DriverObject->MajorFunction[IRP_MJ_SET_INFORMATION] = VfatBuildRequest;
+   DriverObject->MajorFunction[IRP_MJ_DIRECTORY_CONTROL] = VfatBuildRequest;
+   DriverObject->MajorFunction[IRP_MJ_QUERY_VOLUME_INFORMATION] = VfatBuildRequest;
+   DriverObject->MajorFunction[IRP_MJ_SET_VOLUME_INFORMATION] = VfatBuildRequest;
+   DriverObject->MajorFunction[IRP_MJ_SHUTDOWN] = VfatShutdown;
+   DriverObject->MajorFunction[IRP_MJ_CLEANUP] = VfatBuildRequest;
+
+   DriverObject->DriverUnload = NULL;
 
    IoRegisterFileSystem(DeviceObject);
-
    return STATUS_SUCCESS;
 }
 
 /* EOF */
+
index 8031aa3..09d9009 100644 (file)
@@ -1,4 +1,4 @@
-# $Id: makefile,v 1.37 2002/01/08 00:49:01 dwelch Exp $
+# $Id: makefile,v 1.38 2002/03/18 22:37:13 hbirr Exp $
 
 PATH_TO_TOP = ../../..
 
@@ -22,7 +22,8 @@ TARGET_OBJECTS = \
   shutdown.o \
   string.o \
   volume.o \
-  misc.o
+  misc.o \
+  fsctl.o
 
 DEP_OBJECTS = $(TARGET_OBJECTS)
 
index af23e51..14c0109 100644 (file)
@@ -1,5 +1,5 @@
 
-/* $Id: rw.c,v 1.38 2002/01/27 03:25:44 dwelch Exp $
+/* $Id: rw.c,v 1.39 2002/03/18 22:37:13 hbirr Exp $
  *
  * COPYRIGHT:        See COPYING in the top level directory
  * PROJECT:          ReactOS kernel
@@ -121,7 +121,7 @@ NextCluster(PDEVICE_EXTENSION DeviceExt,
     }
   if (FirstCluster == 1)
     {
-      (*CurrentCluster) += DeviceExt->Boot->SectorsPerCluster;
+      (*CurrentCluster) += DeviceExt->FatInfo.SectorsPerCluster;
       return(STATUS_SUCCESS);
     }
   else
@@ -176,7 +176,7 @@ OffsetToCluster(PDEVICE_EXTENSION DeviceExt,
   if (Fcb != NULL && Fcb->Flags & FCB_IS_PAGE_FILE)
     {
       ULONG NCluster;
-      ULONG Offset = FileOffset / DeviceExt->BytesPerCluster;
+      ULONG Offset = FileOffset / DeviceExt->FatInfo.BytesPerCluster;
       PULONG FatChain;
       int i;
       if (Fcb->FatChainSize == 0)
@@ -238,14 +238,14 @@ OffsetToCluster(PDEVICE_EXTENSION DeviceExt,
   if (FirstCluster == 1)
     {
       /* root of FAT16 or FAT12 */
-      *Cluster = DeviceExt->rootStart + FileOffset
-       / (DeviceExt->BytesPerCluster) * DeviceExt->Boot->SectorsPerCluster;
+      *Cluster = DeviceExt->FatInfo.rootStart + FileOffset
+       / (DeviceExt->FatInfo.BytesPerCluster) * DeviceExt->FatInfo.SectorsPerCluster;
       return(STATUS_SUCCESS);
     }
   else
     {
       CurrentCluster = FirstCluster;
-      for (i = 0; i < FileOffset / DeviceExt->BytesPerCluster; i++)
+      for (i = 0; i < FileOffset / DeviceExt->FatInfo.BytesPerCluster; i++)
        {
          Status = GetNextCluster (DeviceExt, CurrentCluster, &CurrentCluster,
                                   Extend);
@@ -271,14 +271,14 @@ VfatReadCluster(PDEVICE_EXTENSION DeviceExt,
   PVOID BaseAddress = NULL;
   NTSTATUS Status;
 
-  if (InternalLength == DeviceExt->BytesPerCluster)
+  if (InternalLength == DeviceExt->FatInfo.BytesPerCluster)
   {
     Status = VfatRawReadCluster(DeviceExt, FirstCluster,
                                 Destination, *CurrentCluster, 1);
   }
   else
   {
-    BaseAddress = ExAllocatePool(NonPagedPool, DeviceExt->BytesPerCluster);
+    BaseAddress = ExAllocatePool(NonPagedPool, DeviceExt->FatInfo.BytesPerCluster);
     if (BaseAddress == NULL)
     {
       return(STATUS_NO_MEMORY);
@@ -318,7 +318,7 @@ VfatReadFile (PDEVICE_EXTENSION DeviceExt, PFILE_OBJECT FileObject,
 
   /* PRECONDITION */
   assert (DeviceExt != NULL);
-  assert (DeviceExt->BytesPerCluster != 0);
+  assert (DeviceExt->FatInfo.BytesPerCluster != 0);
   assert (FileObject != NULL);
   assert (FileObject->FsContext2 != NULL);
 
@@ -351,7 +351,7 @@ VfatReadFile (PDEVICE_EXTENSION DeviceExt, PFILE_OBJECT FileObject,
        }
 
       Status = VfatReadSectors(DeviceExt->StorageDevice,
-                              DeviceExt->FATStart + ReadOffset / BLOCKSIZE, 
+                              DeviceExt->FatInfo.FATStart + ReadOffset / BLOCKSIZE, 
                               Length / BLOCKSIZE, Buffer);
       if (NT_SUCCESS(Status))
        {
@@ -388,9 +388,9 @@ VfatReadFile (PDEVICE_EXTENSION DeviceExt, PFILE_OBJECT FileObject,
   if (FirstCluster == 1)
     {
       /* root directory of FAT12 or FAT16 */
-      if (ReadOffset + Length > DeviceExt->rootDirectorySectors * BLOCKSIZE)
+      if (ReadOffset + Length > DeviceExt->FatInfo.rootDirectorySectors * BLOCKSIZE)
        {
-         Length = DeviceExt->rootDirectorySectors * BLOCKSIZE - ReadOffset;
+         Length = DeviceExt->FatInfo.rootDirectorySectors * BLOCKSIZE - ReadOffset;
        }
   }
 
@@ -413,7 +413,7 @@ VfatReadFile (PDEVICE_EXTENSION DeviceExt, PFILE_OBJECT FileObject,
   Status = OffsetToCluster(DeviceExt,
                           Fcb,
                           FirstCluster,
-                          ROUND_DOWN(ReadOffset, DeviceExt->BytesPerCluster),
+                          ROUND_DOWN(ReadOffset, DeviceExt->FatInfo.BytesPerCluster),
                           &CurrentCluster,
                           FALSE);
   if (!NT_SUCCESS(Status))
@@ -424,15 +424,15 @@ VfatReadFile (PDEVICE_EXTENSION DeviceExt, PFILE_OBJECT FileObject,
    * If the read doesn't begin on a chunk boundary then we need special
    * handling
    */
-  if ((ReadOffset % DeviceExt->BytesPerCluster) != 0 )
+  if ((ReadOffset % DeviceExt->FatInfo.BytesPerCluster) != 0 )
     {
-      TempLength = min (Length, DeviceExt->BytesPerCluster - 
-                       (ReadOffset % DeviceExt->BytesPerCluster));
+      TempLength = min (Length, DeviceExt->FatInfo.BytesPerCluster - 
+                       (ReadOffset % DeviceExt->FatInfo.BytesPerCluster));
       Ccb->LastCluster = CurrentCluster;
-      Ccb->LastOffset = ROUND_DOWN(ReadOffset, DeviceExt->BytesPerCluster);
+      Ccb->LastOffset = ROUND_DOWN(ReadOffset, DeviceExt->FatInfo.BytesPerCluster);
       Status = VfatReadCluster(DeviceExt, Fcb, FirstCluster, &CurrentCluster, 
                               Buffer, 
-                              ReadOffset % DeviceExt->BytesPerCluster, 
+                              ReadOffset % DeviceExt->FatInfo.BytesPerCluster, 
                               TempLength);
       if (NT_SUCCESS(Status))
        {
@@ -443,7 +443,7 @@ VfatReadFile (PDEVICE_EXTENSION DeviceExt, PFILE_OBJECT FileObject,
        }
   }
 
-  while (Length >= DeviceExt->BytesPerCluster && 
+  while (Length >= DeviceExt->FatInfo.BytesPerCluster && 
         CurrentCluster != 0xffffffff && NT_SUCCESS(Status))
     {
       StartCluster = CurrentCluster;
@@ -453,25 +453,25 @@ VfatReadFile (PDEVICE_EXTENSION DeviceExt, PFILE_OBJECT FileObject,
       do
        {
          ClusterCount++;
-         BytesDone += DeviceExt->BytesPerCluster;
+         BytesDone += DeviceExt->FatInfo.BytesPerCluster;
          Status = NextCluster(DeviceExt, Fcb, FirstCluster, &CurrentCluster, 
                               FALSE);
        }
       while (StartCluster + ClusterCount == CurrentCluster && 
             NT_SUCCESS(Status) &&
-            Length - BytesDone >= DeviceExt->BytesPerCluster);
+            Length - BytesDone >= DeviceExt->FatInfo.BytesPerCluster);
 
       DPRINT("Count %d, Start %x Next %x\n", ClusterCount, StartCluster, 
             CurrentCluster);
       Ccb->LastCluster = StartCluster + (ClusterCount - 1);
       Ccb->LastOffset = ReadOffset + 
-       (ClusterCount - 1) * DeviceExt->BytesPerCluster;
+       (ClusterCount - 1) * DeviceExt->FatInfo.BytesPerCluster;
       
       Status = VfatRawReadCluster(DeviceExt, FirstCluster, Buffer, 
                                  StartCluster, ClusterCount);
       if (NT_SUCCESS(Status))
        {
-         ClusterCount *=  DeviceExt->BytesPerCluster;
+         ClusterCount *=  DeviceExt->FatInfo.BytesPerCluster;
          (*LengthRead) = (*LengthRead) + ClusterCount;
          Buffer += ClusterCount;
          Length -= ClusterCount;
@@ -485,7 +485,7 @@ VfatReadFile (PDEVICE_EXTENSION DeviceExt, PFILE_OBJECT FileObject,
   if (Length > 0 && CurrentCluster != 0xffffffff && NT_SUCCESS(Status))
     {
       Ccb->LastCluster = CurrentCluster;
-      Ccb->LastOffset = ReadOffset + DeviceExt->BytesPerCluster;
+      Ccb->LastOffset = ReadOffset + DeviceExt->FatInfo.BytesPerCluster;
 
       Status = VfatReadCluster(DeviceExt, Fcb, FirstCluster, &CurrentCluster,
                               Buffer, 0, Length);
@@ -500,19 +500,19 @@ VfatReadFile (PDEVICE_EXTENSION DeviceExt, PFILE_OBJECT FileObject,
 NTSTATUS
 VfatWriteCluster(PDEVICE_EXTENSION DeviceExt,
                 PVFATFCB Fcb,
-                   ULONG StartOffset,
-                   ULONG FirstCluster,
-                   PULONG CurrentCluster,
-                   PVOID Source,
-                   ULONG InternalOffset,
-                   ULONG InternalLength)
+                ULONG StartOffset,
+                ULONG FirstCluster,
+                PULONG CurrentCluster,
+                PVOID Source,
+                ULONG InternalOffset,
+                ULONG InternalLength)
 {
   PVOID BaseAddress;
   NTSTATUS Status;
 
-  if (InternalLength != DeviceExt->BytesPerCluster)
+  if (InternalLength != DeviceExt->FatInfo.BytesPerCluster)
   {
-     BaseAddress = ExAllocatePool(NonPagedPool, DeviceExt->BytesPerCluster);
+     BaseAddress = ExAllocatePool(NonPagedPool, DeviceExt->FatInfo.BytesPerCluster);
      if (BaseAddress == NULL)
      {
        return(STATUS_NO_MEMORY);
@@ -520,7 +520,7 @@ VfatWriteCluster(PDEVICE_EXTENSION DeviceExt,
   }
   else
     BaseAddress = Source;
-  if (InternalLength != DeviceExt->BytesPerCluster)
+  if (InternalLength != DeviceExt->FatInfo.BytesPerCluster)
   {
     /*
      * If the data in the cache isn't valid or we are bypassing the
@@ -531,7 +531,7 @@ VfatWriteCluster(PDEVICE_EXTENSION DeviceExt,
                                *CurrentCluster, 1);
      if (!NT_SUCCESS(Status))
      {
-        if (InternalLength != DeviceExt->BytesPerCluster)
+        if (InternalLength != DeviceExt->FatInfo.BytesPerCluster)
         {
           ExFreePool(BaseAddress);
         }
@@ -545,7 +545,7 @@ VfatWriteCluster(PDEVICE_EXTENSION DeviceExt,
   DPRINT("Writing 0x%x\n", *CurrentCluster);
   Status = VfatRawWriteCluster(DeviceExt, FirstCluster, BaseAddress,
                               *CurrentCluster, 1);
-  if (InternalLength != DeviceExt->BytesPerCluster)
+  if (InternalLength != DeviceExt->FatInfo.BytesPerCluster)
   {
     ExFreePool(BaseAddress);
   }
@@ -611,10 +611,10 @@ VfatWriteFile (PDEVICE_EXTENSION DeviceExt, PFILE_OBJECT FileObject,
       Length = (ULONG)Fcb->RFCB.FileSize.QuadPart - WriteOffset;
     }
 
-    for (Count = 0; Count < DeviceExt->Boot->FATCount; Count++)
+    for (Count = 0; Count < DeviceExt->FatInfo.FATCount; Count++)
     {
       Status = VfatWriteSectors(DeviceExt->StorageDevice,
-                 DeviceExt->FATStart + (Count * (ULONG)Fcb->RFCB.FileSize.QuadPart + WriteOffset) / BLOCKSIZE,
+                 DeviceExt->FatInfo.FATStart + (Count * (ULONG)Fcb->RFCB.FileSize.QuadPart + WriteOffset) / BLOCKSIZE,
                  Length / BLOCKSIZE, Buffer);
       if (!NT_SUCCESS(Status))
       {
@@ -639,7 +639,7 @@ VfatWriteFile (PDEVICE_EXTENSION DeviceExt, PFILE_OBJECT FileObject,
     if (FirstCluster == 1)
     {
       // root directory of FAT12 od FAT16
-      if (WriteOffset + Length > DeviceExt->rootDirectorySectors * BLOCKSIZE)
+      if (WriteOffset + Length > DeviceExt->FatInfo.rootDirectorySectors * BLOCKSIZE)
       {
         DPRINT("Writing over the end of the root directory on FAT12/16\n");
         return STATUS_END_OF_FILE;
@@ -664,7 +664,7 @@ VfatWriteFile (PDEVICE_EXTENSION DeviceExt, PFILE_OBJECT FileObject,
     Status = OffsetToCluster(DeviceExt,
                             Fcb,
                           FirstCluster,
-                          ROUND_DOWN(WriteOffset, DeviceExt->BytesPerCluster),
+                          ROUND_DOWN(WriteOffset, DeviceExt->FatInfo.BytesPerCluster),
                           &CurrentCluster,
                           FALSE);
     if (!NT_SUCCESS(Status) || CurrentCluster == 0xffffffff)
@@ -673,23 +673,24 @@ VfatWriteFile (PDEVICE_EXTENSION DeviceExt, PFILE_OBJECT FileObject,
       return(Status);
     }
     pCcb->LastCluster = CurrentCluster;
-    pCcb->LastOffset = ROUND_DOWN(WriteOffset, DeviceExt->BytesPerCluster);
+    pCcb->LastOffset = ROUND_DOWN(WriteOffset, DeviceExt->FatInfo.BytesPerCluster);
 
     /*
      * If the offset in the cluster doesn't fall on the cluster boundary
      * then we have to write only from the specified offset
      */
     Status = STATUS_SUCCESS;
-    if ((WriteOffset % DeviceExt->BytesPerCluster) != 0)
+    if ((WriteOffset % DeviceExt->FatInfo.BytesPerCluster) != 0)
     {
-      TempLength = min (Length, DeviceExt->BytesPerCluster - (WriteOffset % DeviceExt->BytesPerCluster));
+      TempLength = min (Length, DeviceExt->FatInfo.BytesPerCluster 
+             - (WriteOffset % DeviceExt->FatInfo.BytesPerCluster));
       Status = VfatWriteCluster(DeviceExt,
                                Fcb,
-                             ROUND_DOWN(WriteOffset, DeviceExt->BytesPerCluster),
+                             ROUND_DOWN(WriteOffset, DeviceExt->FatInfo.BytesPerCluster),
                              FirstCluster,
                              &CurrentCluster,
                              Buffer,
-                             WriteOffset % DeviceExt->BytesPerCluster,
+                             WriteOffset % DeviceExt->FatInfo.BytesPerCluster,
                              TempLength);
       if (NT_SUCCESS(Status))
       {
@@ -699,7 +700,8 @@ VfatWriteFile (PDEVICE_EXTENSION DeviceExt, PFILE_OBJECT FileObject,
       }
     }
 
-    while (Length >= DeviceExt->BytesPerCluster && CurrentCluster != 0xffffffff && NT_SUCCESS(Status))
+    while (Length >= DeviceExt->FatInfo.BytesPerCluster && 
+           CurrentCluster != 0xffffffff && NT_SUCCESS(Status))
     {
       StartCluster = CurrentCluster;
       Count = 0;
@@ -710,15 +712,15 @@ VfatWriteFile (PDEVICE_EXTENSION DeviceExt, PFILE_OBJECT FileObject,
         Status = NextCluster(DeviceExt, Fcb, FirstCluster, &CurrentCluster, FALSE);
       }
       while (StartCluster + Count == CurrentCluster && NT_SUCCESS(Status) &&
-        Length - Count * DeviceExt->BytesPerCluster >= DeviceExt->BytesPerCluster);
+        Length - Count * DeviceExt->FatInfo.BytesPerCluster >= DeviceExt->FatInfo.BytesPerCluster);
 
       pCcb->LastCluster = StartCluster + (Count - 1);
-      pCcb->LastOffset = WriteOffset + (Count - 1) * DeviceExt->BytesPerCluster;
+      pCcb->LastOffset = WriteOffset + (Count - 1) * DeviceExt->FatInfo.BytesPerCluster;
 
       Status = VfatRawWriteCluster(DeviceExt, FirstCluster, Buffer, StartCluster, Count);
       if (NT_SUCCESS(Status))
       {
-        Count *=  DeviceExt->BytesPerCluster;
+        Count *=  DeviceExt->FatInfo.BytesPerCluster;
         Buffer += Count;
         Length -= Count;
         WriteOffset += Count;
@@ -796,7 +798,7 @@ NTSTATUS vfatExtendSpace (PDEVICE_EXTENSION pDeviceExt, PFILE_OBJECT pFileObject
   pFcb = ((PVFATCCB) (pFileObject->FsContext2))->pFcb;
 
   DPRINT ("New Size %d,  AllocationSize %d,  BytesPerCluster %d\n",  NewSize,
-    (ULONG)pFcb->RFCB.AllocationSize.QuadPart, pDeviceExt->BytesPerCluster);
+    (ULONG)pFcb->RFCB.AllocationSize.QuadPart, pDeviceExt->FatInfo.BytesPerCluster);
 
   FirstCluster = CurrentCluster = vfatDirEntryGetFirstCluster (pDeviceExt, &pFcb->entry);
 
@@ -817,7 +819,7 @@ NTSTATUS vfatExtendSpace (PDEVICE_EXTENSION pDeviceExt, PFILE_OBJECT pFileObject
     else
     {
       Status = OffsetToCluster(pDeviceExt, pFcb, FirstCluster,
-                 pFcb->RFCB.AllocationSize.QuadPart - pDeviceExt->BytesPerCluster,
+                 pFcb->RFCB.AllocationSize.QuadPart - pDeviceExt->FatInfo.BytesPerCluster,
                  &CurrentCluster, FALSE);
       if (!NT_SUCCESS(Status))
       {
@@ -839,7 +841,7 @@ NTSTATUS vfatExtendSpace (PDEVICE_EXTENSION pDeviceExt, PFILE_OBJECT pFileObject
     }
 
     Status = OffsetToCluster(pDeviceExt, pFcb, FirstCluster,
-               ROUND_DOWN(NewSize-1, pDeviceExt->BytesPerCluster),
+               ROUND_DOWN(NewSize-1, pDeviceExt->FatInfo.BytesPerCluster),
                &NewCluster, TRUE);
     if (!NT_SUCCESS(Status) || NewCluster == 0xffffffff)
     {
@@ -864,10 +866,10 @@ NTSTATUS vfatExtendSpace (PDEVICE_EXTENSION pDeviceExt, PFILE_OBJECT pFileObject
     if (pFcb->RFCB.AllocationSize.QuadPart == 0)
     {
       pFcb->entry.FirstCluster = FirstCluster;
-      if(pDeviceExt->FatType == FAT32)
+      if(pDeviceExt->FatInfo.FatType == FAT32)
         pFcb->entry.FirstClusterHigh = FirstCluster >> 16;
     }
-    pFcb->RFCB.AllocationSize.QuadPart = ROUND_UP(NewSize, pDeviceExt->BytesPerCluster);
+    pFcb->RFCB.AllocationSize.QuadPart = ROUND_UP(NewSize, pDeviceExt->FatInfo.BytesPerCluster);
     if (pFcb->entry.Attrib & FILE_ATTRIBUTE_DIRECTORY)
     {
       pFcb->RFCB.FileSize.QuadPart = pFcb->RFCB.AllocationSize.QuadPart;
index 880b4ef..f87c9ba 100644 (file)
@@ -1,4 +1,4 @@
-/* $Id: vfat.h,v 1.39 2002/02/05 21:31:03 hbirr Exp $ */
+/* $Id: vfat.h,v 1.40 2002/03/18 22:37:13 hbirr Exp $ */
 
 #include <ddk/ntifs.h>
 
@@ -61,12 +61,13 @@ struct _BootBackupSector
 
 typedef struct _BootSector BootSector;
 
-struct _FATDirEntry {
+struct _FATDirEntry
+{
   unsigned char  Filename[8], Ext[3], Attrib, Res[2];
   unsigned short CreationTime,CreationDate,AccessDate;
-  unsigned short FirstClusterHigh;// higher
-  unsigned short UpdateTime;//time create/update
-  unsigned short UpdateDate;//date create/update
+  unsigned short FirstClusterHigh;                      // higher
+  unsigned short UpdateTime;                            //time create/update
+  unsigned short UpdateDate;                            //date create/update
   unsigned short FirstCluster;
   unsigned long  FileSize;
 } __attribute__((packed));
@@ -76,13 +77,13 @@ typedef struct _FATDirEntry FATDirEntry, FAT_DIR_ENTRY, *PFAT_DIR_ENTRY;
 struct _slot
 {
   unsigned char id;               // sequence number for slot
-  WCHAR  name0_4[5];      // first 5 characters in name
+  WCHAR  name0_4[5];              // first 5 characters in name
   unsigned char attr;             // attribute byte
   unsigned char reserved;         // always 0
   unsigned char alias_checksum;   // checksum for 8.3 alias
-  WCHAR  name5_10[6];     // 6 more characters in name
+  WCHAR  name5_10[6];             // 6 more characters in name
   unsigned char start[2];         // starting cluster number
-  WCHAR  name11_12[2];     // last 2 characters in name
+  WCHAR  name11_12[2];            // last 2 characters in name
 } __attribute__((packed));
 
 
@@ -94,6 +95,27 @@ typedef struct _slot slot;
 #define FAT12 (2)
 #define FAT32 (3)
 
+#define VCB_VOLUME_LOCKED       0x0001
+#define VCB_DISMOUNT_PENDING    0x0002
+
+typedef struct
+{
+  ULONG VolumeID;
+  ULONG FATStart;
+  ULONG FATCount;
+  ULONG FATSectors;
+  ULONG rootDirectorySectors;
+  ULONG rootStart;
+  ULONG dataStart;
+  ULONG RootCluster;
+  ULONG SectorsPerCluster;
+  ULONG BytesPerSector;
+  ULONG BytesPerCluster;
+  ULONG NumberOfClusters;
+  ULONG FatType;
+}
+FATINFO, *PFATINFO;
+
 typedef struct
 {
   ERESOURCE DirResource;
@@ -104,15 +126,23 @@ typedef struct
 
   PDEVICE_OBJECT StorageDevice;
   PFILE_OBJECT FATFileObject;
-  BootSector *Boot;
-  int rootDirectorySectors, FATStart, rootStart, dataStart;
-  int BytesPerSector;
-  int FATEntriesPerSector, FATUnit;
-  ULONG BytesPerCluster;
-  ULONG FatType;
+  FATINFO FatInfo;
   ULONG LastAvailableCluster;
-  ULONG NumberOfClusters;
-} DEVICE_EXTENSION, *PDEVICE_EXTENSION, VCB, *PVCB;
+  ULONG AvailableClusters;
+  BOOLEAN AvailableClustersValid;
+  ULONG Flags;
+}
+DEVICE_EXTENSION, *PDEVICE_EXTENSION, VCB, *PVCB;
+
+typedef struct
+{
+  PDRIVER_OBJECT DriverObject;
+  PDEVICE_OBJECT DeviceObject;
+  ULONG Flags;
+}
+VFAT_GLOBAL_DATA, *PVFAT_GLOBAL_DATA;
+
+extern PVFAT_GLOBAL_DATA VfatGlobalData;
 
 #define FCB_CACHE_INITIALIZED   0x0001
 #define FCB_DELETE_PENDING      0x0002
@@ -137,11 +167,13 @@ typedef struct _VFATFCB
   ULONG dirIndex;
   ERESOURCE PagingIoResource;
   ERESOURCE MainResource;
+  ULONG TimerCount;
 
   /* Structure members used only for paging files. */
   ULONG FatChainSize;
   PULONG FatChain;
-} VFATFCB, *PVFATFCB;
+}
+VFATFCB, *PVFATFCB;
 
 typedef struct _VFATCCB
 {
@@ -156,7 +188,8 @@ typedef struct _VFATCCB
   ULONG LastCluster;
   ULONG LastOffset;
 
-} VFATCCB, *PVFATCCB;
+}
+VFATCCB, *PVFATCCB;
 
 #define TAG(A, B, C, D) (ULONG)(((A)<<0) + ((B)<<8) + ((C)<<16) + ((D)<<24))
 
@@ -169,14 +202,16 @@ typedef struct __DOSTIME
    WORD        Second:5;
    WORD        Minute:6;
    WORD Hour:5;
-} DOSTIME, *PDOSTIME;
+}
+DOSTIME, *PDOSTIME;
 
 typedef struct __DOSDATE
 {
    WORD        Day:5;
    WORD        Month:4;
    WORD Year:5;
-} DOSDATE, *PDOSDATE;
+}
+DOSDATE, *PDOSDATE;
 
 #define IRPCONTEXT_CANWAIT  0x0001
 
@@ -194,216 +229,299 @@ typedef struct
 }
 VFAT_IRP_CONTEXT, *PVFAT_IRP_CONTEXT;
 
+/*  ------------------------------------------------------  shutdown.c  */
+
+NTSTATUS STDCALL VfatShutdown (PDEVICE_OBJECT DeviceObject,
+                               PIRP Irp);
+
+/*  --------------------------------------------------------  volume.c  */
+
+NTSTATUS VfatQueryVolumeInformation (PVFAT_IRP_CONTEXT IrpContext);
+
+NTSTATUS VfatSetVolumeInformation (PVFAT_IRP_CONTEXT IrpContext);
+
+/*  ------------------------------------------------------  blockdev.c  */
+
+NTSTATUS VfatReadSectors(IN PDEVICE_OBJECT pDeviceObject,
+                         IN ULONG DiskSector,
+                         IN ULONG SectorCount,
+                         IN PUCHAR Buffer);
+
+NTSTATUS VfatWriteSectors(IN PDEVICE_OBJECT pDeviceObject,
+                          IN ULONG DiskSector,
+                          IN ULONG SectorCount,
+                          IN PUCHAR Buffer);
+
+NTSTATUS VfatBlockDeviceIoControl (IN PDEVICE_OBJECT DeviceObject,
+                                  IN ULONG CtlCode,
+                                  IN PVOID InputBuffer,
+                                  IN ULONG InputBufferSize,
+                                  IN OUT PVOID OutputBuffer, 
+                                  IN OUT PULONG pOutputBufferSize);
+
+/*  -----------------------------------------------------------  dir.c  */
 
-/* functions called by i/o manager : */
-NTSTATUS STDCALL
-DriverEntry(PDRIVER_OBJECT _DriverObject,PUNICODE_STRING RegistryPath);
 NTSTATUS VfatDirectoryControl (PVFAT_IRP_CONTEXT);
-NTSTATUS VfatRead (PVFAT_IRP_CONTEXT);
-NTSTATUS VfatWrite (PVFAT_IRP_CONTEXT);
-NTSTATUS VfatCreate (PVFAT_IRP_CONTEXT);
-NTSTATUS VfatClose (PVFAT_IRP_CONTEXT);
-NTSTATUS VfatFileSystemControl (PVFAT_IRP_CONTEXT);
-NTSTATUS VfatQueryInformation (PVFAT_IRP_CONTEXT);
-NTSTATUS VfatSetInformation (PVFAT_IRP_CONTEXT);
-NTSTATUS VfatCleanup (PVFAT_IRP_CONTEXT);
-NTSTATUS STDCALL
-VfatShutdown(PDEVICE_OBJECT DeviceObject, PIRP Irp);
-NTSTATUS VfatQueryVolumeInformation (PVFAT_IRP_CONTEXT);
-NTSTATUS VfatSetVolumeInformation (PVFAT_IRP_CONTEXT);
-
-
-NTSTATUS
-NextCluster(PDEVICE_EXTENSION DeviceExt,
-           PVFATFCB Fcb,
-           ULONG FirstCluster,
-           PULONG CurrentCluster,
-           BOOLEAN Extend);
-
-/* internal functions in blockdev.c */
-NTSTATUS
-VfatReadSectors(IN PDEVICE_OBJECT pDeviceObject,
-               IN ULONG   DiskSector,
-               IN ULONG       SectorCount,
-               IN UCHAR*       Buffer);
-
-NTSTATUS
-VfatWriteSectors(IN PDEVICE_OBJECT pDeviceObject,
-                IN ULONG   DiskSector,
-                IN ULONG        SectorCount,
-                IN UCHAR*      Buffer);
-
-/* internal functions in dir.c : */
-BOOL FsdDosDateTimeToFileTime(WORD wDosDate,WORD wDosTime, TIME *FileTime);
-BOOL FsdFileTimeToDosDateTime(TIME *FileTime,WORD *pwDosDate,WORD *pwDosTime);
-
-/* internal functions in iface.c : */
-NTSTATUS 
-FindFile(PDEVICE_EXTENSION DeviceExt, PVFATFCB Fcb,
-        PVFATFCB Parent, PWSTR FileToFind,ULONG *StartSector,ULONG *Entry);
-NTSTATUS 
-VfatCloseFile(PDEVICE_EXTENSION DeviceExt, PFILE_OBJECT FileObject);
-NTSTATUS 
-VfatOpenFile(PDEVICE_EXTENSION DeviceExt, PFILE_OBJECT FileObject, 
-           PWSTR FileName);
-NTSTATUS 
-VfatReadFile(PDEVICE_EXTENSION DeviceExt, PFILE_OBJECT FileObject,
-            PVOID Buffer, ULONG Length, ULONG ReadOffset,
-             PULONG LengthRead, ULONG NoCache);
-NTSTATUS
-VfatWriteFile(PDEVICE_EXTENSION DeviceExt, PFILE_OBJECT FileObject,
-              PVOID Buffer, ULONG Length, ULONG WriteOffset, BOOLEAN NoCache, BOOLEAN PageIo);
-NTSTATUS
-GetNextWriteCluster(PDEVICE_EXTENSION DeviceExt, 
-                   ULONG FirstCluster,
-                   ULONG CurrentCluster,
-                   PULONG NextCluster);
-BOOLEAN 
-IsDeletedEntry(PVOID Block, ULONG Offset);
-BOOLEAN 
-IsLastEntry(PVOID Block, ULONG Offset);
-wchar_t* 
-vfat_wcsncpy(wchar_t * dest, const wchar_t *src,size_t wcount);
-
-/* internal functions in dirwr.c */
-NTSTATUS 
-addEntry(PDEVICE_EXTENSION DeviceExt,
-        PFILE_OBJECT pFileObject,ULONG RequestedOptions,UCHAR ReqAttr);
-NTSTATUS 
-updEntry(PDEVICE_EXTENSION DeviceExt,PFILE_OBJECT pFileObject);
-NTSTATUS
-delEntry(PDEVICE_EXTENSION, PFILE_OBJECT);
 
-/*
- * String functions
- */
-VOID 
-vfat_initstr(wchar_t *wstr, ULONG wsize);
-wchar_t* 
-vfat_wcsncat(wchar_t * dest, const wchar_t * src,size_t wstart, size_t wcount);
-wchar_t* 
-vfat_wcsncpy(wchar_t * dest, const wchar_t *src,size_t wcount);
-wchar_t* 
-vfat_movstr(wchar_t *src, ULONG dpos, ULONG spos, ULONG len);
-BOOLEAN 
-wstrcmpi(PWSTR s1, PWSTR s2);
-BOOLEAN
-wstrcmpjoki(PWSTR s1, PWSTR s2);
-PWCHAR  vfatGetNextPathElement (PWCHAR  pFileName);
-void  vfatWSubString (PWCHAR pTarget, const PWCHAR pSource, size_t pLength);
+BOOL FsdDosDateTimeToFileTime (WORD wDosDate,
+                               WORD wDosTime,
+                               TIME *FileTime);
+
+BOOL FsdFileTimeToDosDateTime (TIME *FileTime,
+                               WORD *pwDosDate,
+                               WORD *pwDosTime);
+
+/*  --------------------------------------------------------  create.c  */
+
+NTSTATUS VfatCreate (PVFAT_IRP_CONTEXT IrpContext);
+
+NTSTATUS VfatOpenFile (PDEVICE_EXTENSION DeviceExt,
+                       PFILE_OBJECT FileObject,
+                       PWSTR FileName);
+
+NTSTATUS FindFile (PDEVICE_EXTENSION DeviceExt,
+                   PVFATFCB Fcb,
+                   PVFATFCB Parent,
+                   PWSTR FileToFind,
+                   PULONG pDirIndex,
+                   PULONG pDirIndex2);
+
+VOID vfat8Dot3ToString (PCHAR pBasename,
+                        PCHAR pExtension,
+                        PWSTR pName);
+
+NTSTATUS ReadVolumeLabel(PDEVICE_EXTENSION DeviceExt,
+                         PVPB Vpb);
+
+BOOLEAN IsDeletedEntry (PVOID Block,
+                        ULONG Offset);
+
+BOOLEAN IsLastEntry (PVOID Block,
+                     ULONG Offset);
+
+/*  ---------------------------------------------------------  close.c  */
+
+NTSTATUS VfatClose (PVFAT_IRP_CONTEXT IrpContext);
+
+NTSTATUS VfatCloseFile(PDEVICE_EXTENSION DeviceExt,
+                       PFILE_OBJECT FileObject);
+
+/*  -------------------------------------------------------  cleanup.c  */
+
+NTSTATUS VfatCleanup (PVFAT_IRP_CONTEXT IrpContext);
+
+/*  ---------------------------------------------------------  fsctl.c  */
+
+NTSTATUS VfatFileSystemControl (PVFAT_IRP_CONTEXT IrpContext);
+
+/*  ---------------------------------------------------------  finfo.c  */
+
+NTSTATUS VfatQueryInformation (PVFAT_IRP_CONTEXT IrpContext);
+
+NTSTATUS VfatSetInformation (PVFAT_IRP_CONTEXT IrpContext);
+
+/*  ---------------------------------------------------------  iface.c  */
+
+NTSTATUS STDCALL DriverEntry (PDRIVER_OBJECT DriverObject,
+                              PUNICODE_STRING RegistryPath);
+
+/*  ---------------------------------------------------------  dirwr.c  */
+
+NTSTATUS addEntry (PDEVICE_EXTENSION DeviceExt,
+                   PFILE_OBJECT pFileObject,
+                   ULONG RequestedOptions,UCHAR ReqAttr);
+
+NTSTATUS updEntry (PDEVICE_EXTENSION DeviceExt,
+                   PFILE_OBJECT pFileObject);
+
+NTSTATUS delEntry(PDEVICE_EXTENSION,
+                  PFILE_OBJECT);
+
+/*  --------------------------------------------------------  string.c  */
+
+VOID vfat_initstr (wchar_t *wstr,
+                   ULONG wsize);
+
+wchar_t* vfat_wcsncat (wchar_t * dest,
+                       const wchar_t * src,
+                       size_t wstart,
+                       size_t wcount);
+
+wchar_t* vfat_wcsncpy (wchar_t * dest,
+                       const wchar_t *src,
+                       size_t wcount);
+
+wchar_t* vfat_movstr (wchar_t *src,
+                      ULONG dpos,
+                      ULONG spos,
+                      ULONG len);
+
+BOOLEAN wstrcmpi (PWSTR s1,
+                  PWSTR s2);
+
+BOOLEAN wstrcmpjoki (PWSTR s1,
+                     PWSTR s2);
+
+PWCHAR vfatGetNextPathElement (PWCHAR  pFileName);
+
+VOID vfatWSubString (PWCHAR pTarget,
+                     const PWCHAR pSource,
+                     size_t pLength);
+
 BOOL  vfatIsFileNameValid (PWCHAR pFileName);
 
-/*
- * functions from fat.c
- */
-NTSTATUS
-OffsetToCluster(PDEVICE_EXTENSION DeviceExt, 
-               PVFATFCB Fcb,
-               ULONG FirstCluster, 
-               ULONG FileOffset,
-               PULONG Cluster,
-               BOOLEAN Extend);
-ULONG
-ClusterToSector(PDEVICE_EXTENSION DeviceExt,
-               ULONG Cluster);
-NTSTATUS
-GetNextCluster(PDEVICE_EXTENSION DeviceExt,
-              ULONG CurrentCluster,
-              PULONG NextCluster,
-              BOOLEAN Extend);
-NTSTATUS
-GetNextSector(PDEVICE_EXTENSION DeviceExt,
-             ULONG CurrentSector,
-             PULONG NextSector,
-             BOOLEAN Extend);
-NTSTATUS
-VfatRawReadCluster(PDEVICE_EXTENSION DeviceExt,
-                  ULONG FirstCluster,
-                  PVOID Buffer,
-                  ULONG Cluster,
-           ULONG Count);
-NTSTATUS
-VfatRawWriteCluster(PDEVICE_EXTENSION DeviceExt,
-                   ULONG FirstCluster,
-                   PVOID Buffer,
-                   ULONG Cluster,
-            ULONG Count);
-NTSTATUS
-FAT12CountAvailableClusters(PDEVICE_EXTENSION DeviceExt,
-                           PLARGE_INTEGER Clusters);
-NTSTATUS
-FAT16CountAvailableClusters(PDEVICE_EXTENSION DeviceExt,
-                           PLARGE_INTEGER Clusters);
-NTSTATUS
-FAT32CountAvailableClusters(PDEVICE_EXTENSION DeviceExt,
-                           PLARGE_INTEGER Clusters);
-NTSTATUS
-WriteCluster(PDEVICE_EXTENSION DeviceExt,
-            ULONG ClusterToWrite,
-            ULONG NewValue);
-
-/*  ---------------------------------------------------------  create.c  */
-
-void  vfat8Dot3ToString (PCHAR pBasename, PCHAR pExtension, PWSTR pName);
-NTSTATUS
-ReadVolumeLabel(PDEVICE_EXTENSION DeviceExt, PVPB Vpb);
-NTSTATUS
-VfatOpenFile(PDEVICE_EXTENSION DeviceExt,
-            PFILE_OBJECT FileObject,
-            PWSTR FileName);
-
-/*  -----------------------------------------------  DirEntry Functions  */
+/*  -----------------------------------------------------------  fat.c  */
+
+NTSTATUS OffsetToCluster (PDEVICE_EXTENSION DeviceExt,
+                          PVFATFCB Fcb,
+                          ULONG FirstCluster,
+                          ULONG FileOffset,
+                          PULONG Cluster,
+                          BOOLEAN Extend);
+
+ULONG ClusterToSector (PDEVICE_EXTENSION DeviceExt,
+                       ULONG Cluster);
+
+NTSTATUS GetNextCluster (PDEVICE_EXTENSION DeviceExt,
+                         ULONG CurrentCluster,
+                         PULONG NextCluster,
+                         BOOLEAN Extend);
+
+NTSTATUS GetNextSector (PDEVICE_EXTENSION DeviceExt,
+                        ULONG CurrentSector,
+                        PULONG NextSector,
+                        BOOLEAN Extend);
+
+NTSTATUS VfatRawReadCluster (PDEVICE_EXTENSION DeviceExt,
+                             ULONG FirstCluster,
+                             PVOID Buffer,
+                             ULONG Cluster,
+                             ULONG Count);
+
+NTSTATUS VfatRawWriteCluster (PDEVICE_EXTENSION DeviceExt,
+                              ULONG FirstCluster,
+                              PVOID Buffer,
+                              ULONG Cluster,
+                              ULONG Count);
+
+NTSTATUS CountAvailableClusters (PDEVICE_EXTENSION DeviceExt,
+                                 PLARGE_INTEGER Clusters);
+
+/*  ------------------------------------------------------  direntry.c  */
 
 ULONG  vfatDirEntryGetFirstCluster (PDEVICE_EXTENSION  pDeviceExt,
                                     PFAT_DIR_ENTRY  pDirEntry);
+
 BOOL  vfatIsDirEntryDeleted (FATDirEntry * pFatDirEntry);
+
 BOOL  vfatIsDirEntryVolume (FATDirEntry * pFatDirEntry);
+
 BOOL  vfatIsDirEntryEndMarker (FATDirEntry * pFatDirEntry);
-void  vfatGetDirEntryName (PFAT_DIR_ENTRY pDirEntry,  PWSTR  pEntryName);
+
+VOID vfatGetDirEntryName (PFAT_DIR_ENTRY pDirEntry,
+                          PWSTR  pEntryName);
+
 NTSTATUS  vfatGetNextDirEntry (PDEVICE_EXTENSION  pDeviceExt,
                                PVFATFCB  pDirectoryFCB,
                                ULONG * pDirectoryIndex,
                                PWSTR pLongFileName,
                                PFAT_DIR_ENTRY pDirEntry);
 
-/*  -----------------------------------------------------  FCB Functions */
-
-PVFATFCB  vfatNewFCB (PWCHAR pFileName);
-void  vfatDestroyFCB (PVFATFCB  pFCB);
-void  vfatGrabFCB (PDEVICE_EXTENSION  pVCB,  PVFATFCB  pFCB);
-void  vfatReleaseFCB (PDEVICE_EXTENSION  pVCB,  PVFATFCB  pFCB);
-void  vfatAddFCBToTable (PDEVICE_EXTENSION  pVCB,  
-                         PVFATFCB  pFCB);
-PVFATFCB  vfatGrabFCBFromTable (PDEVICE_EXTENSION  pDeviceExt, 
-                                PWSTR  pFileName);
-PVFATFCB  vfatMakeRootFCB (PDEVICE_EXTENSION  pVCB);
-PVFATFCB  vfatOpenRootFCB (PDEVICE_EXTENSION  pVCB);
-BOOL  vfatFCBIsDirectory (PDEVICE_EXTENSION pVCB, PVFATFCB FCB);
-NTSTATUS  vfatAttachFCBToFileObject (PDEVICE_EXTENSION  vcb, 
-                                     PVFATFCB  fcb,
-                                     PFILE_OBJECT  fileObject);
-NTSTATUS  vfatDirFindFile (PDEVICE_EXTENSION  pVCB, 
-                           PVFATFCB  parentFCB,
-                           PWSTR  elementName,
-                           PVFATFCB * fileFCB);
-NTSTATUS  vfatGetFCBForFile (PDEVICE_EXTENSION  pVCB,
-                             PVFATFCB  *pParentFCB, 
-                             PVFATFCB  *pFCB, 
-                             const PWSTR  pFileName);
-NTSTATUS vfatMakeFCBFromDirEntry(PVCB  vcb,
-                                            PVFATFCB  directoryFCB,
-                                            PWSTR  longName,
-                                            PFAT_DIR_ENTRY  dirEntry,
-                                 ULONG dirIndex,
-                                            PVFATFCB * fileFCB);
-
-/*  -------------------------------------------------------------  rw.c  */
-
-NTSTATUS vfatExtendSpace (PDEVICE_EXTENSION pDeviceExt, PFILE_OBJECT pFileObject, ULONG NewSize);
-
-/*  ------------------------------------------------------------- misc.c */
+/*  -----------------------------------------------------------  fcb.c  */
+
+PVFATFCB vfatNewFCB (PWCHAR pFileName);
+
+VOID vfatDestroyFCB (PVFATFCB  pFCB);
+
+VOID vfatGrabFCB (PDEVICE_EXTENSION  pVCB,
+                  PVFATFCB  pFCB);
+
+VOID vfatReleaseFCB (PDEVICE_EXTENSION  pVCB,
+                     PVFATFCB  pFCB);
+
+VOID vfatAddFCBToTable (PDEVICE_EXTENSION  pVCB,
+                        PVFATFCB  pFCB);
+
+PVFATFCB vfatGrabFCBFromTable (PDEVICE_EXTENSION  pDeviceExt,
+                               PWSTR  pFileName);
+
+PVFATFCB vfatMakeRootFCB (PDEVICE_EXTENSION  pVCB);
+
+PVFATFCB vfatOpenRootFCB (PDEVICE_EXTENSION  pVCB);
+
+BOOL vfatFCBIsDirectory (PDEVICE_EXTENSION pVCB,
+                         PVFATFCB FCB);
+
+NTSTATUS vfatAttachFCBToFileObject (PDEVICE_EXTENSION  vcb,
+                                    PVFATFCB  fcb,
+                                    PFILE_OBJECT  fileObject);
+
+NTSTATUS vfatDirFindFile (PDEVICE_EXTENSION  pVCB,
+                          PVFATFCB  parentFCB,
+                          PWSTR  elementName,
+                          PVFATFCB * fileFCB);
+
+NTSTATUS vfatGetFCBForFile (PDEVICE_EXTENSION  pVCB,
+                            PVFATFCB  *pParentFCB,
+                            PVFATFCB  *pFCB,
+                            const PWSTR  pFileName);
+
+NTSTATUS vfatMakeFCBFromDirEntry (PVCB  vcb,
+                                  PVFATFCB  directoryFCB,
+                                  PWSTR  longName,
+                                  PFAT_DIR_ENTRY  dirEntry,
+                                  ULONG dirIndex,
+                                  PVFATFCB * fileFCB);
+
+/*  ------------------------------------------------------------  rw.c  */
+
+NTSTATUS VfatRead (PVFAT_IRP_CONTEXT IrpContext);
+
+NTSTATUS VfatWrite (PVFAT_IRP_CONTEXT IrpContext);
+
+NTSTATUS vfatExtendSpace (PDEVICE_EXTENSION pDeviceExt,
+                          PFILE_OBJECT pFileObject,
+                          ULONG NewSize);
+/*
+NTSTATUS VfatWriteFile (PDEVICE_EXTENSION DeviceExt,
+                        PFILE_OBJECT FileObject,
+                        PVOID Buffer,
+                        ULONG Length,
+                        ULONG WriteOffset,
+                        BOOLEAN NoCache,
+                        BOOLEAN PageIo);
+
+
+NTSTATUS VfatReadFile (PDEVICE_EXTENSION DeviceExt,
+                       PFILE_OBJECT FileObject,
+                       PVOID Buffer, ULONG Length,
+                       ULONG ReadOffset,
+                       PULONG LengthRead,
+                       ULONG NoCache);
+*/
+
+NTSTATUS NextCluster(PDEVICE_EXTENSION DeviceExt,
+                     PVFATFCB Fcb,
+                     ULONG FirstCluster,
+                     PULONG CurrentCluster,
+                     BOOLEAN Extend);
+
+/*  -----------------------------------------------------------  misc.c  */
+
 NTSTATUS VfatQueueRequest(PVFAT_IRP_CONTEXT IrpContext);
-PVFAT_IRP_CONTEXT VfatAllocateIrpContext(PDEVICE_OBJECT DeviceObject, PIRP Irp);
+
+PVFAT_IRP_CONTEXT VfatAllocateIrpContext(PDEVICE_OBJECT DeviceObject,
+                                         PIRP Irp);
+
 VOID VfatFreeIrpContext(PVFAT_IRP_CONTEXT IrpContext);
-NTSTATUS STDCALL VfatBuildRequest (PDEVICE_OBJECT DeviceObject, PIRP Irp);
 
+NTSTATUS STDCALL VfatBuildRequest (PDEVICE_OBJECT DeviceObject,
+                                   PIRP Irp);
+/*
+PVOID VfatGetUserBuffer(IN PIRP);
+
+NTSTATUS VfatLockUserBuffer(IN PIRP, IN ULONG,
+                            IN LOCK_OPERATION);
+*/
+
+/* EOF */
index 2044bff..c22ded3 100644 (file)
@@ -1,4 +1,4 @@
-/* $Id: volume.c,v 1.14 2001/11/02 22:47:36 hbirr Exp $
+/* $Id: volume.c,v 1.15 2002/03/18 22:37:13 hbirr Exp $
  *
  * COPYRIGHT:        See COPYING in the top level directory
  * PROJECT:          ReactOS kernel
@@ -62,29 +62,39 @@ FsdGetFsVolumeInformation(PDEVICE_OBJECT DeviceObject,
 
 
 static NTSTATUS
-FsdGetFsAttributeInformation(PFILE_FS_ATTRIBUTE_INFORMATION FsAttributeInfo,
+FsdGetFsAttributeInformation(PDEVICE_EXTENSION DeviceExt,
+                            PFILE_FS_ATTRIBUTE_INFORMATION FsAttributeInfo,
                             PULONG BufferLength)
 {
+  ULONG Length = DeviceExt->FatInfo.FatType == FAT32 ? 10 : 6;
+
   DPRINT("FsdGetFsAttributeInformation()\n");
   DPRINT("FsAttributeInfo = %p\n", FsAttributeInfo);
   DPRINT("BufferLength %lu\n", *BufferLength);
-  DPRINT("Required length %lu\n", (sizeof(FILE_FS_ATTRIBUTE_INFORMATION) + 6));
+  DPRINT("Required length %lu\n", (sizeof(FILE_FS_ATTRIBUTE_INFORMATION) + Length));
 
   if (*BufferLength < sizeof (FILE_FS_ATTRIBUTE_INFORMATION))
     return STATUS_INFO_LENGTH_MISMATCH;
 
-  if (*BufferLength < (sizeof(FILE_FS_ATTRIBUTE_INFORMATION) + 6))
+  if (*BufferLength < (sizeof(FILE_FS_ATTRIBUTE_INFORMATION) + Length))
     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");
+  FsAttributeInfo->FileSystemNameLength = Length;
+  if (DeviceExt->FatInfo.FatType == FAT32)
+  {
+    memcpy(FsAttributeInfo->FileSystemName, L"FAT32", 10);
+  }
+  else
+  {
+    memcpy(FsAttributeInfo->FileSystemName, L"FAT", 6);
+  }
 
   DPRINT("Finished FsdGetFsAttributeInformation()\n");
 
-  *BufferLength -= (sizeof(FILE_FS_ATTRIBUTE_INFORMATION) + 6);
+  *BufferLength -= (sizeof(FILE_FS_ATTRIBUTE_INFORMATION) + Length);
   DPRINT("BufferLength %lu\n", *BufferLength);
 
   return(STATUS_SUCCESS);
@@ -106,35 +116,11 @@ FsdGetFsSizeInformation(PDEVICE_OBJECT DeviceObject,
     return(STATUS_BUFFER_OVERFLOW);
 
   DeviceExt = DeviceObject->DeviceExtension;
+  Status = CountAvailableClusters(DeviceExt, &FsSizeInfo->AvailableAllocationUnits);
 
-  if (DeviceExt->FatType == FAT32)
-    {
-      struct _BootSector32 *BootSect =
-       (struct _BootSector32 *) DeviceExt->Boot;
-
-      FsSizeInfo->TotalAllocationUnits.QuadPart = ((BootSect->Sectors ? BootSect->Sectors : BootSect->SectorsHuge)-DeviceExt->dataStart)/BootSect->SectorsPerCluster;
-
-      Status = FAT32CountAvailableClusters(DeviceExt,
-                                          &FsSizeInfo->AvailableAllocationUnits);
-
-      FsSizeInfo->SectorsPerAllocationUnit = BootSect->SectorsPerCluster;
-      FsSizeInfo->BytesPerSector = BootSect->BytesPerSector;
-    }
-  else
-    {
-      struct _BootSector *BootSect = (struct _BootSector *) DeviceExt->Boot;
-
-      FsSizeInfo->TotalAllocationUnits.QuadPart = ((BootSect->Sectors ? BootSect->Sectors : BootSect->SectorsHuge)-DeviceExt->dataStart)/BootSect->SectorsPerCluster;
-
-      if (DeviceExt->FatType == FAT16)
-       Status = FAT16CountAvailableClusters(DeviceExt,
-                                            &FsSizeInfo->AvailableAllocationUnits);
-      else
-       Status = FAT12CountAvailableClusters(DeviceExt,
-                                            &FsSizeInfo->AvailableAllocationUnits);
-      FsSizeInfo->SectorsPerAllocationUnit = BootSect->SectorsPerCluster;
-      FsSizeInfo->BytesPerSector = BootSect->BytesPerSector;
-    }
+  FsSizeInfo->TotalAllocationUnits.QuadPart = DeviceExt->FatInfo.NumberOfClusters;
+  FsSizeInfo->SectorsPerAllocationUnit = DeviceExt->FatInfo.SectorsPerCluster;
+  FsSizeInfo->BytesPerSector = DeviceExt->FatInfo.BytesPerSector;
 
   DPRINT("Finished FsdGetFsSizeInformation()\n");
   if (NT_SUCCESS(Status))
@@ -216,7 +202,8 @@ NTSTATUS VfatQueryVolumeInformation(PVFAT_IRP_CONTEXT IrpContext)
       break;
 
     case FileFsAttributeInformation:
-      RC = FsdGetFsAttributeInformation(SystemBuffer,
+      RC = FsdGetFsAttributeInformation(IrpContext->DeviceObject->DeviceExtension,
+                                       SystemBuffer,
                                        &BufferLength);
       break;