*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;
{
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,
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;
/* 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)
/* Cleanup */
if (DeviceExt && DeviceExt->FATFileObject)
ObDereferenceObject (DeviceExt->FATFileObject);
+ if (DeviceExt && DeviceExt->SpareVPB)
+ ExFreePoolWithTag(DeviceExt->SpareVPB, TAG_VFAT);
if (Fcb)
vfatDestroyFCB(Fcb);
if (Ccb)
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
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))
{
/* Mark we're being dismounted */
DeviceExt->Flags |= VCB_DISMOUNT_PENDING;
+#ifndef ENABLE_SWAPOUT
IrpContext->DeviceObject->Vpb->Flags &= ~VPB_MOUNTED;
+#endif
ExReleaseResourceLite(&DeviceExt->FatResource);
break;
}
- IrpContext->Irp->IoStatus.Status = Status;
-
- IoCompleteRequest(IrpContext->Irp, IO_NO_INCREMENT);
- VfatFreeIrpContext(IrpContext);
return Status;
}