X-Git-Url: https://git.reactos.org/?p=reactos.git;a=blobdiff_plain;f=reactos%2Fdrivers%2Ffilesystems%2Ffastfat%2Fmisc.c;h=751514d34f57dee525c05aa97d1f91b01d1b7a25;hp=ddd547ff8feb5797dbcefacd1bf2582edc5ab5a3;hb=0440330ea68f6de151bce4b553f7e6b26deb6451;hpb=545615df47dbc7dc64e85bdbdb85cfce1965fcc6 diff --git a/reactos/drivers/filesystems/fastfat/misc.c b/reactos/drivers/filesystems/fastfat/misc.c index ddd547ff8fe..751514d34f5 100644 --- a/reactos/drivers/filesystems/fastfat/misc.c +++ b/reactos/drivers/filesystems/fastfat/misc.c @@ -312,3 +312,90 @@ VfatLockUserBuffer( return STATUS_SUCCESS; } + +BOOLEAN +VfatCheckForDismount( + IN PDEVICE_EXTENSION DeviceExt, + IN BOOLEAN Create) +{ + KIRQL OldIrql; + PVPB Vpb; + BOOLEAN Delete; + + DPRINT1("VfatCheckForDismount(%p, %u)\n", DeviceExt, Create); + + /* Lock VPB */ + IoAcquireVpbSpinLock(&OldIrql); + + /* Reference it and check if a create is being done */ + Vpb = DeviceExt->IoVPB; + if (Vpb->ReferenceCount != Create) + { + /* Copy the VPB to our local own to prepare later dismount */ + if (DeviceExt->SpareVPB != NULL) + { + RtlZeroMemory(DeviceExt->SpareVPB, sizeof(VPB)); + DeviceExt->SpareVPB->Type = IO_TYPE_VPB; + DeviceExt->SpareVPB->Size = sizeof(VPB); + DeviceExt->SpareVPB->RealDevice = DeviceExt->IoVPB->RealDevice; + DeviceExt->SpareVPB->DeviceObject = NULL; + DeviceExt->SpareVPB->Flags = DeviceExt->IoVPB->Flags & VPB_REMOVE_PENDING; + DeviceExt->IoVPB->RealDevice->Vpb = DeviceExt->SpareVPB; + DeviceExt->SpareVPB = NULL; + DeviceExt->IoVPB->Flags |= VPB_PERSISTENT; + } + + /* Don't do anything */ + Delete = FALSE; + } + else + { + /* Otherwise, delete the volume */ + Delete = TRUE; + + /* Check if it has a VPB and unmount it */ + if (Vpb->RealDevice->Vpb == Vpb) + { + Vpb->DeviceObject = NULL; + Vpb->Flags &= ~VPB_MOUNTED; + } + } + + /* Release lock and return status */ + IoReleaseVpbSpinLock(OldIrql); + + /* If we were to delete, delete volume */ + if (Delete) + { + PVPB DelVpb; + + /* If we have a local VPB, we'll have to delete it + * but we won't dismount us - something went bad before + */ + if (DeviceExt->SpareVPB) + { + DelVpb = DeviceExt->SpareVPB; + } + /* Otherwise, dismount our device if possible */ + else + { + if (DeviceExt->IoVPB->ReferenceCount) + { + ObfDereferenceObject(DeviceExt->StorageDevice); + IoDeleteDevice(DeviceExt->VolumeDevice); + return Delete; + } + + DelVpb = DeviceExt->IoVPB; + } + + /* Delete any of the available VPB and dismount */ + ExFreePool(DelVpb); + ObfDereferenceObject(DeviceExt->StorageDevice); + IoDeleteDevice(DeviceExt->VolumeDevice); + + return Delete; + } + + return Delete; +}