[FASTFAT]
[reactos.git] / reactos / drivers / filesystems / fastfat / fsctl.c
index ab9d3af..873b0fc 100644 (file)
@@ -121,16 +121,6 @@ VfatHasFileSystem(
             *RecognizedFS = TRUE;
         }
     }
-    else if (DiskGeometry.MediaType == Unknown)
-    {
-        /*
-         * Floppy disk driver can return Unknown as media type if it
-         * doesn't know yet what floppy in the drive really is. This is
-         * perfectly correct to do under Windows.
-         */
-        *RecognizedFS = TRUE;
-        DiskGeometry.BytesPerSector = 512;
-    }
     else
     {
         *RecognizedFS = TRUE;
@@ -429,7 +419,6 @@ VfatMount(
     {
         HashTableSize = 65537; // 65536 = 64 * 1024;
     }
-    HashTableSize = FCB_HASH_TABLE_SIZE;
     DPRINT("VFAT: Recognized volume\n");
     Status = IoCreateDevice(VfatGlobalData->DriverObject,
                             ROUND_UP(sizeof (DEVICE_EXTENSION), sizeof(ULONG)) + sizeof(HASHENTRY*) * HashTableSize,
@@ -447,6 +436,7 @@ VfatMount(
     RtlZeroMemory(DeviceExt, ROUND_UP(sizeof(DEVICE_EXTENSION), sizeof(ULONG)) + sizeof(HASHENTRY*) * HashTableSize);
     DeviceExt->FcbHashTable = (HASHENTRY**)((ULONG_PTR)DeviceExt + ROUND_UP(sizeof(DEVICE_EXTENSION), sizeof(ULONG)));
     DeviceExt->HashTableSize = HashTableSize;
+    DeviceExt->VolumeDevice = DeviceObject;
 
     /* use same vpb as device disk */
     DeviceObject->Vpb = Vpb;
@@ -521,6 +511,14 @@ VfatMount(
     /* Initialize this resource early ... it's used in VfatCleanup */
     ExInitializeResourceLite(&DeviceExt->DirResource);
 
+    DeviceExt->IoVPB = DeviceObject->Vpb;
+    DeviceExt->SpareVPB = ExAllocatePoolWithTag(NonPagedPool, sizeof(VPB), TAG_VFAT);
+    if (DeviceExt->SpareVPB == NULL)
+    {
+        Status = STATUS_INSUFFICIENT_RESOURCES;
+        goto ByeBye;
+    }
+
     DeviceExt->FATFileObject = IoCreateStreamFileObject(NULL, DeviceExt->StorageDevice);
     Fcb = vfatNewFCB(DeviceExt, &NameU);
     if (Fcb == NULL)
@@ -622,6 +620,8 @@ ByeBye:
         /* Cleanup */
         if (DeviceExt && DeviceExt->FATFileObject)
             ObDereferenceObject (DeviceExt->FATFileObject);
+        if (DeviceExt && DeviceExt->SpareVPB)
+            ExFreePoolWithTag(DeviceExt->SpareVPB, TAG_VFAT);
         if (Fcb)
             vfatDestroyFCB(Fcb);
         if (Ccb)
@@ -865,14 +865,16 @@ VfatLockOrUnlockVolume(
 {
     PFILE_OBJECT FileObject;
     PDEVICE_EXTENSION DeviceExt;
+    PVFATFCB Fcb;
 
     DPRINT("VfatLockOrUnlockVolume(%p, %d)\n", IrpContext, Lock);
 
     DeviceExt = IrpContext->DeviceExt;
     FileObject = IrpContext->FileObject;
+    Fcb = FileObject->FsContext;
 
     /* Only allow locking with the volume open */
-    if (FileObject->FsContext != DeviceExt->VolumeFcb)
+    if (!(Fcb->Flags & FCB_IS_VOLUME))
     {
         return STATUS_ACCESS_DENIED;
     }
@@ -911,10 +913,14 @@ VfatDismountVolume(
     PDEVICE_EXTENSION DeviceExt;
     PLIST_ENTRY NextEntry;
     PVFATFCB Fcb;
+    PFILE_OBJECT FileObject;
+    ULONG eocMark;
+    NTSTATUS Status;
 
     DPRINT("VfatDismountVolume(%p)\n", IrpContext);
 
     DeviceExt = IrpContext->DeviceExt;
+    FileObject = IrpContext->FileObject;
 
     /* We HAVE to be locked. Windows also allows dismount with no lock
      * but we're here mainly for 1st stage, so KISS
@@ -935,31 +941,21 @@ VfatDismountVolume(
 
     ExAcquireResourceExclusiveLite(&DeviceExt->FatResource, TRUE);
 
-    /* Browse all the available FCBs first, and force data writing to disk */
-    for (NextEntry = DeviceExt->FcbListHead.Flink;
-         NextEntry != &DeviceExt->FcbListHead;
-         NextEntry = NextEntry->Flink)
+    if (DeviceExt->VolumeFcb->Flags & VCB_CLEAR_DIRTY)
     {
-        Fcb = CONTAINING_RECORD(NextEntry, VFATFCB, FcbListEntry);
-
-        ExAcquireResourceExclusiveLite(&Fcb->MainResource, TRUE);
-        ExAcquireResourceExclusiveLite(&Fcb->PagingIoResource, TRUE);
-
-        if (Fcb->FileObject)
+        /* Set clean shutdown bit */
+        Status = GetNextCluster(DeviceExt, 1, &eocMark);
+        if (NT_SUCCESS(Status))
         {
-            if (Fcb->Flags & FCB_IS_DIRTY)
-            {
-                VfatUpdateEntry(Fcb);
-            }
-
-            CcPurgeCacheSection(Fcb->FileObject->SectionObjectPointer, NULL, 0, FALSE);
-            CcUninitializeCacheMap(Fcb->FileObject, &Fcb->RFCB.FileSize, NULL);
+            eocMark |= DeviceExt->CleanShutBitMask;
+            if (NT_SUCCESS(WriteCluster(DeviceExt, 1, eocMark)))
+                DeviceExt->VolumeFcb->Flags &= ~VCB_IS_DIRTY;
         }
-
-        ExReleaseResourceLite(&Fcb->PagingIoResource);
-        ExReleaseResourceLite(&Fcb->MainResource);
     }
 
+    /* Flush volume & files */
+    VfatFlushVolume(DeviceExt, (PVFATFCB)FileObject->FsContext);
+
     /* Rebrowse the FCB in order to free them now */
     while (!IsListEmpty(&DeviceExt->FcbListHead))
     {
@@ -970,7 +966,9 @@ VfatDismountVolume(
 
     /* Mark we're being dismounted */
     DeviceExt->Flags |= VCB_DISMOUNT_PENDING;
+#ifndef ENABLE_SWAPOUT
     IrpContext->DeviceObject->Vpb->Flags &= ~VPB_MOUNTED;
+#endif
 
     ExReleaseResourceLite(&DeviceExt->FatResource);
 
@@ -1057,9 +1055,5 @@ VfatFileSystemControl(
             break;
     }
 
-    IrpContext->Irp->IoStatus.Status = Status;
-
-    IoCompleteRequest(IrpContext->Irp, IO_NO_INCREMENT);
-    VfatFreeIrpContext(IrpContext);
     return Status;
 }