/* 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)
FsRtlNotifyInitializeSync(&DeviceExt->NotifySync);
InitializeListHead(&DeviceExt->NotifyList);
- DPRINT1("Mount success\n");
+ DPRINT("Mount success\n");
Status = STATUS_SUCCESS;
/* 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;
- DPRINT1("VfatLockOrUnlockVolume(%p, %d)\n", IrpContext, Lock);
+ 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;
}
PVFAT_IRP_CONTEXT IrpContext)
{
PDEVICE_EXTENSION DeviceExt;
+ PLIST_ENTRY NextEntry;
+ PVFATFCB Fcb;
+ PFILE_OBJECT FileObject;
- DPRINT1("VfatDismountVolume(%p)\n", IrpContext);
+ 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
+ */
if (!(DeviceExt->Flags & VCB_VOLUME_LOCKED))
{
return STATUS_ACCESS_DENIED;
}
- UNIMPLEMENTED;
- return STATUS_NOT_IMPLEMENTED;
+ /* Race condition? */
+ if (DeviceExt->Flags & VCB_DISMOUNT_PENDING)
+ {
+ return STATUS_VOLUME_DISMOUNTED;
+ }
+
+ /* Notify we'll dismount. Pass that point there's no reason we fail */
+ FsRtlNotifyVolumeEvent(IrpContext->Stack->FileObject, FSRTL_VOLUME_DISMOUNT);
+
+ ExAcquireResourceExclusiveLite(&DeviceExt->FatResource, TRUE);
+
+ /* Flush volume & files */
+ VfatFlushVolume(DeviceExt, (PVFATFCB)FileObject->FsContext);
+
+ /* Rebrowse the FCB in order to free them now */
+ while (!IsListEmpty(&DeviceExt->FcbListHead))
+ {
+ NextEntry = RemoveHeadList(&DeviceExt->FcbListHead);
+ Fcb = CONTAINING_RECORD(NextEntry, VFATFCB, FcbListEntry);
+ vfatDestroyFCB(Fcb);
+ }
+
+ /* Mark we're being dismounted */
+ DeviceExt->Flags |= VCB_DISMOUNT_PENDING;
+ IrpContext->DeviceObject->Vpb->Flags &= ~VPB_MOUNTED;
+
+ ExReleaseResourceLite(&DeviceExt->FatResource);
+
+ /* Release a few resources and quit, we're done */
+ ExDeleteResourceLite(&DeviceExt->DirResource);
+ ExDeleteResourceLite(&DeviceExt->FatResource);
+ ObDereferenceObject(DeviceExt->FATFileObject);
+
+ return STATUS_SUCCESS;
}
/*