diff --git a/src/sys/device.c b/src/sys/device.c index 848864c8..bd45915f 100644 --- a/src/sys/device.c +++ b/src/sys/device.c @@ -410,6 +410,7 @@ static NTSTATUS FspFsvolDeviceInit(PDEVICE_OBJECT DeviceObject) FsvolDeviceExtension->InitDoneStat = 1; /* initialize our context table */ + ExInitializeResourceLite(&FsvolDeviceExtension->VolumeDeleteResource); ExInitializeResourceLite(&FsvolDeviceExtension->FileRenameResource); ExInitializeResourceLite(&FsvolDeviceExtension->ContextTableResource); InitializeListHead(&FsvolDeviceExtension->ContextList); @@ -495,6 +496,7 @@ static VOID FspFsvolDeviceFini(PDEVICE_OBJECT DeviceObject) ExDeleteResourceLite(&FsvolDeviceExtension->ContextTableResource); ExDeleteResourceLite(&FsvolDeviceExtension->FileRenameResource); + ExDeleteResourceLite(&FsvolDeviceExtension->VolumeDeleteResource); } /* is there a virtual disk? */ diff --git a/src/sys/driver.h b/src/sys/driver.h index c1a34cae..0348f17b 100644 --- a/src/sys/driver.h +++ b/src/sys/driver.h @@ -1211,6 +1211,8 @@ typedef struct KSPIN_LOCK ExpirationLock; WORK_QUEUE_ITEM ExpirationWorkItem; BOOLEAN ExpirationInProgress; + ERESOURCE VolumeDeleteResource; + BOOLEAN VolumeDeleted; ERESOURCE FileRenameResource; ERESOURCE ContextTableResource; LIST_ENTRY ContextList; diff --git a/src/sys/volume.c b/src/sys/volume.c index 6928d065..b0390dd3 100644 --- a/src/sys/volume.c +++ b/src/sys/volume.c @@ -369,6 +369,9 @@ VOID FspVolumeDelete( ULONG FileNodeCount, Index; NTSTATUS Result; + ExAcquireResourceExclusiveLite(&FsvolDeviceExtension->VolumeDeleteResource, TRUE); + FsvolDeviceExtension->VolumeDeleted = TRUE; + /* * If we have an fsvrt that is a mountdev, finalize it now! Finalizing a mountdev * involves interaction with the MountManager, which tries to open our devices. @@ -403,6 +406,8 @@ VOID FspVolumeDelete( FspFileNodeDeleteList(FileNodes, FileNodeCount); } + ExReleaseResourceLite(&FsvolDeviceExtension->VolumeDeleteResource); + FspDeviceDereference(FsvolDeviceObject); } @@ -1184,6 +1189,14 @@ NTSTATUS FspVolumeNotify( if (!FspDeviceReference(FsvolDeviceObject)) return STATUS_CANCELLED; + FSP_FSVOL_DEVICE_EXTENSION *FsvolDeviceExtension = FspFsvolDeviceExtension(FsvolDeviceObject); + ExAcquireResourceSharedLite(&FsvolDeviceExtension->VolumeDeleteResource, TRUE); + if (FsvolDeviceExtension->VolumeDeleted) + { + Result = STATUS_CANCELLED; + goto fail; + } + NotifyWorkItem = FspAllocNonPaged( FIELD_OFFSET(FSP_VOLUME_NOTIFY_WORK_ITEM, InputBuffer) + InputBufferLength); if (0 == NotifyWorkItem) @@ -1205,6 +1218,9 @@ NTSTATUS FspVolumeNotify( goto fail; } + ExSetResourceOwnerPointer(&FsvolDeviceExtension->VolumeDeleteResource, + (PVOID)((UINT_PTR)NotifyWorkItem | 3)); + ExInitializeWorkItem(&NotifyWorkItem->WorkItem, FspVolumeNotifyWork, NotifyWorkItem); NotifyWorkItem->FsvolDeviceObject = FsvolDeviceObject; @@ -1216,6 +1232,8 @@ fail: if (0 != NotifyWorkItem) FspFree(NotifyWorkItem); + ExReleaseResourceLite(&FsvolDeviceExtension->VolumeDeleteResource); + FspDeviceDereference(FsvolDeviceObject); return Result; @@ -1365,6 +1383,9 @@ static VOID FspVolumeNotifyWork(PVOID NotifyWorkItem0) ExReleaseFastMutex(&FsvolDeviceExtension->VolumeNotifyMutex); } + ExReleaseResourceForThreadLite(&FsvolDeviceExtension->VolumeDeleteResource, + (ERESOURCE_THREAD)((UINT_PTR)NotifyWorkItem | 3)); + FspDeviceDereference(FsvolDeviceObject); FsRtlExitFileSystem();