mirror of
https://github.com/reactos/reactos.git
synced 2024-12-28 18:15:11 +00:00
[FASTFAT]
Implement some kind of volume dismount in FastFAT (ie, implement VfatDismountVolume()) This is not fully perfect situation, but it does most of the job (+ leaking a few things). So far, this is not dramatic as its main use is for 1st stage. This will have to be improved later on. CORE-8732 #comment Can you retest please? svn path=/trunk/; revision=65173
This commit is contained in:
parent
2f120e9e6d
commit
c1bbc436cb
1 changed files with 61 additions and 2 deletions
|
@ -909,18 +909,77 @@ VfatDismountVolume(
|
|||
PVFAT_IRP_CONTEXT IrpContext)
|
||||
{
|
||||
PDEVICE_EXTENSION DeviceExt;
|
||||
PLIST_ENTRY NextEntry;
|
||||
PVFATFCB Fcb;
|
||||
|
||||
DPRINT1("VfatDismountVolume(%p)\n", IrpContext);
|
||||
|
||||
DeviceExt = IrpContext->DeviceExt;
|
||||
|
||||
/* 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);
|
||||
|
||||
/* 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);
|
||||
}
|
||||
|
||||
/* 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;
|
||||
}
|
||||
|
||||
/*
|
||||
|
|
Loading…
Reference in a new issue