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)
{
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;
}
PDEVICE_EXTENSION DeviceExt;
PLIST_ENTRY NextEntry;
PVFATFCB Fcb;
+ PFILE_OBJECT FileObject;
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)
- {
- Fcb = CONTAINING_RECORD(NextEntry, VFATFCB, FcbListEntry);
-
- ExAcquireResourceExclusiveLite(&Fcb->MainResource, TRUE);
- ExAcquireResourceExclusiveLite(&Fcb->PagingIoResource, TRUE);
-
- if (Fcb->FileObject)
- {
- if (Fcb->Flags & FCB_IS_DIRTY)
- {
- VfatUpdateEntry(Fcb);
- }
-
- CcPurgeCacheSection(Fcb->FileObject->SectionObjectPointer, NULL, 0, FALSE);
- CcUninitializeCacheMap(Fcb->FileObject, &Fcb->RFCB.FileSize, NULL);
- }
-
- 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;
- IrpContext->DeviceObject->Vpb->Flags &= ~VPB_MOUNTED;
ExReleaseResourceLite(&DeviceExt->FatResource);