mirror of
https://github.com/winfsp/winfsp.git
synced 2025-06-08 13:02:10 -05:00
Major refactoring: WIP
This commit is contained in:
parent
00c812e380
commit
7a12fe0713
@ -28,6 +28,7 @@ static NTSTATUS FspFsctlCleanup(
|
|||||||
{
|
{
|
||||||
PAGED_CODE();
|
PAGED_CODE();
|
||||||
|
|
||||||
|
if (0 != IrpSp->FileObject->FsContext2)
|
||||||
FspVolumeDelete(DeviceObject, Irp, IrpSp);
|
FspVolumeDelete(DeviceObject, Irp, IrpSp);
|
||||||
|
|
||||||
Irp->IoStatus.Information = 0;
|
Irp->IoStatus.Information = 0;
|
||||||
|
@ -282,6 +282,9 @@ static NTSTATUS FspFsvolDeviceInit(PDEVICE_OBJECT DeviceObject)
|
|||||||
RtlZeroMemory(FsvolDeviceExtension->SwapVpb, sizeof *FsvolDeviceExtension->SwapVpb);
|
RtlZeroMemory(FsvolDeviceExtension->SwapVpb, sizeof *FsvolDeviceExtension->SwapVpb);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* initialize our delete lock */
|
||||||
|
ExInitializeResourceLite(&FsvolDeviceExtension->DeleteResource);
|
||||||
|
|
||||||
/* setup our Ioq and expiration fields */
|
/* setup our Ioq and expiration fields */
|
||||||
FspIoqInitialize(&FsvolDeviceExtension->Ioq, FspIopCompleteCanceledIrp);
|
FspIoqInitialize(&FsvolDeviceExtension->Ioq, FspIopCompleteCanceledIrp);
|
||||||
KeInitializeSpinLock(&FsvolDeviceExtension->ExpirationLock);
|
KeInitializeSpinLock(&FsvolDeviceExtension->ExpirationLock);
|
||||||
@ -348,6 +351,9 @@ static VOID FspFsvolDeviceFini(PDEVICE_OBJECT DeviceObject)
|
|||||||
if (0 != FsvolDeviceExtension->FsvrtDeviceObject)
|
if (0 != FsvolDeviceExtension->FsvrtDeviceObject)
|
||||||
ObDereferenceObject(FsvolDeviceExtension->FsvrtDeviceObject);
|
ObDereferenceObject(FsvolDeviceExtension->FsvrtDeviceObject);
|
||||||
|
|
||||||
|
/* finalize our delete lock */
|
||||||
|
ExDeleteResourceLite(&FsvolDeviceExtension->DeleteResource);
|
||||||
|
|
||||||
/* free the spare VPB if we still have it */
|
/* free the spare VPB if we still have it */
|
||||||
if (0 != FsvolDeviceExtension->SwapVpb)
|
if (0 != FsvolDeviceExtension->SwapVpb)
|
||||||
FspFreeExternal(FsvolDeviceExtension->SwapVpb);
|
FspFreeExternal(FsvolDeviceExtension->SwapVpb);
|
||||||
|
@ -368,9 +368,9 @@ typedef struct
|
|||||||
PDEVICE_OBJECT FsctlDeviceObject;
|
PDEVICE_OBJECT FsctlDeviceObject;
|
||||||
PDEVICE_OBJECT FsvrtDeviceObject;
|
PDEVICE_OBJECT FsvrtDeviceObject;
|
||||||
HANDLE MupHandle;
|
HANDLE MupHandle;
|
||||||
BOOLEAN DeletePending;
|
|
||||||
PVPB SwapVpb;
|
PVPB SwapVpb;
|
||||||
FSP_WORK_ITEM_WITH_DELAY DeleteVolumeWorkItem;
|
FSP_WORK_ITEM_WITH_DELAY DeleteVolumeWorkItem;
|
||||||
|
ERESOURCE DeleteResource;
|
||||||
FSP_FSCTL_VOLUME_PARAMS VolumeParams;
|
FSP_FSCTL_VOLUME_PARAMS VolumeParams;
|
||||||
FSP_IOQ Ioq;
|
FSP_IOQ Ioq;
|
||||||
KSPIN_LOCK ExpirationLock;
|
KSPIN_LOCK ExpirationLock;
|
||||||
|
255
src/sys/volume.c
255
src/sys/volume.c
@ -10,6 +10,7 @@ NTSTATUS FspVolumeCreate(
|
|||||||
PDEVICE_OBJECT FsctlDeviceObject, PIRP Irp, PIO_STACK_LOCATION IrpSp);
|
PDEVICE_OBJECT FsctlDeviceObject, PIRP Irp, PIO_STACK_LOCATION IrpSp);
|
||||||
VOID FspVolumeDelete(
|
VOID FspVolumeDelete(
|
||||||
PDEVICE_OBJECT FsctlDeviceObject, PIRP Irp, PIO_STACK_LOCATION IrpSp);
|
PDEVICE_OBJECT FsctlDeviceObject, PIRP Irp, PIO_STACK_LOCATION IrpSp);
|
||||||
|
static WORKER_THREAD_ROUTINE FspVolumeDeleteDelayed;
|
||||||
NTSTATUS FspVolumeMount(
|
NTSTATUS FspVolumeMount(
|
||||||
PDEVICE_OBJECT FsctlDeviceObject, PIRP Irp, PIO_STACK_LOCATION IrpSp);
|
PDEVICE_OBJECT FsctlDeviceObject, PIRP Irp, PIO_STACK_LOCATION IrpSp);
|
||||||
NTSTATUS FspVolumeGetName(
|
NTSTATUS FspVolumeGetName(
|
||||||
@ -24,6 +25,7 @@ NTSTATUS FspVolumeWork(
|
|||||||
#ifdef ALLOC_PRAGMA
|
#ifdef ALLOC_PRAGMA
|
||||||
#pragma alloc_text(PAGE, FspVolumeCreate)
|
#pragma alloc_text(PAGE, FspVolumeCreate)
|
||||||
#pragma alloc_text(PAGE, FspVolumeDelete)
|
#pragma alloc_text(PAGE, FspVolumeDelete)
|
||||||
|
#pragma alloc_text(PAGE, FspVolumeDeleteDelayed)
|
||||||
#pragma alloc_text(PAGE, FspVolumeMount)
|
#pragma alloc_text(PAGE, FspVolumeMount)
|
||||||
#pragma alloc_text(PAGE, FspVolumeGetName)
|
#pragma alloc_text(PAGE, FspVolumeGetName)
|
||||||
#pragma alloc_text(PAGE, FspVolumeTransact)
|
#pragma alloc_text(PAGE, FspVolumeTransact)
|
||||||
@ -154,6 +156,119 @@ VOID FspVolumeDelete(
|
|||||||
PDEVICE_OBJECT FsctlDeviceObject, PIRP Irp, PIO_STACK_LOCATION IrpSp)
|
PDEVICE_OBJECT FsctlDeviceObject, PIRP Irp, PIO_STACK_LOCATION IrpSp)
|
||||||
{
|
{
|
||||||
PAGED_CODE();
|
PAGED_CODE();
|
||||||
|
|
||||||
|
ASSERT(IRP_MJ_CLEANUP == IrpSp->MajorFunction);
|
||||||
|
ASSERT(0 != IrpSp->FileObject->FsContext2);
|
||||||
|
|
||||||
|
PDEVICE_OBJECT FsvolDeviceObject = IrpSp->FileObject->FsContext2;
|
||||||
|
FSP_FSVOL_DEVICE_EXTENSION *FsvolDeviceExtension = FspFsvolDeviceExtension(FsvolDeviceObject);
|
||||||
|
|
||||||
|
/* acquire our DeleteResource */
|
||||||
|
ExAcquireResourceExclusiveLite(&FsvolDeviceExtension->DeleteResource, TRUE);
|
||||||
|
|
||||||
|
/* stop the I/O queue */
|
||||||
|
FspIoqStop(&FsvolDeviceExtension->Ioq);
|
||||||
|
|
||||||
|
/* do we have a virtual disk device or a MUP handle? */
|
||||||
|
if (0 != FsvolDeviceExtension->FsvrtDeviceObject)
|
||||||
|
{
|
||||||
|
PDEVICE_OBJECT FsvrtDeviceObject = FsvolDeviceExtension->FsvrtDeviceObject;
|
||||||
|
PVPB OldVpb;
|
||||||
|
KIRQL Irql;
|
||||||
|
BOOLEAN DeleteVpb = FALSE;
|
||||||
|
BOOLEAN DeleteDly = FALSE;
|
||||||
|
LARGE_INTEGER DelayTimeout;
|
||||||
|
|
||||||
|
/* swap the virtual disk device VPB with the preallocated one */
|
||||||
|
#pragma prefast(push)
|
||||||
|
#pragma prefast(disable:28175, "We are a filesystem: ok to access Vpb")
|
||||||
|
IoAcquireVpbSpinLock(&Irql);
|
||||||
|
OldVpb = FsvrtDeviceObject->Vpb;
|
||||||
|
if (0 != OldVpb)
|
||||||
|
{
|
||||||
|
FsvrtDeviceObject->Vpb = FsvolDeviceExtension->SwapVpb;
|
||||||
|
FsvrtDeviceObject->Vpb->Size = sizeof *FsvrtDeviceObject->Vpb;
|
||||||
|
FsvrtDeviceObject->Vpb->Type = IO_TYPE_VPB;
|
||||||
|
FsvrtDeviceObject->Vpb->Flags = FlagOn(OldVpb->Flags, VPB_REMOVE_PENDING);
|
||||||
|
FsvrtDeviceObject->Vpb->RealDevice = OldVpb->RealDevice;
|
||||||
|
FsvrtDeviceObject->Vpb->RealDevice->Vpb = FsvrtDeviceObject->Vpb;
|
||||||
|
DeleteVpb = 0 == OldVpb->ReferenceCount;
|
||||||
|
DeleteDly = 2 <= OldVpb->ReferenceCount;
|
||||||
|
}
|
||||||
|
IoReleaseVpbSpinLock(Irql);
|
||||||
|
if (DeleteVpb)
|
||||||
|
{
|
||||||
|
/* no more references to the old VPB; delete now! */
|
||||||
|
FspFreeExternal(OldVpb);
|
||||||
|
FsvolDeviceExtension->SwapVpb = 0;
|
||||||
|
}
|
||||||
|
else if (!DeleteDly)
|
||||||
|
{
|
||||||
|
/* there is only the reference from FspVolumeMount */
|
||||||
|
FspFreeExternal(OldVpb);
|
||||||
|
FsvolDeviceExtension->SwapVpb = 0;
|
||||||
|
FspDeviceRelease(FsvolDeviceObject);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
/* keep VPB around for delayed delete */
|
||||||
|
FsvolDeviceExtension->SwapVpb = OldVpb;
|
||||||
|
#pragma prefast(pop)
|
||||||
|
|
||||||
|
/* release the virtual disk and volume device objects */
|
||||||
|
FspDeviceRelease(FsvrtDeviceObject);
|
||||||
|
FspDeviceRelease(FsvolDeviceObject);
|
||||||
|
|
||||||
|
/* are we doing delayed delete of VPB and volume device object? */
|
||||||
|
if (DeleteDly)
|
||||||
|
{
|
||||||
|
DelayTimeout.QuadPart = 300/*ms*/ * -10000;
|
||||||
|
FspInitializeWorkItemWithDelay(&FsvolDeviceExtension->DeleteVolumeWorkItem,
|
||||||
|
FspVolumeDeleteDelayed, FsvolDeviceObject);
|
||||||
|
FspQueueWorkItemWithDelay(&FsvolDeviceExtension->DeleteVolumeWorkItem, DelayTimeout);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if (0 != FsvolDeviceExtension->MupHandle)
|
||||||
|
{
|
||||||
|
HANDLE MupHandle = FsvolDeviceExtension->MupHandle;
|
||||||
|
|
||||||
|
FsRtlDeregisterUncProvider(MupHandle);
|
||||||
|
FsvolDeviceExtension->MupHandle = 0;
|
||||||
|
|
||||||
|
/* release the volume device object */
|
||||||
|
FspDeviceRelease(FsvolDeviceObject);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* release the DeleteResource */
|
||||||
|
ExReleaseResourceLite(&FsvolDeviceExtension->DeleteResource);
|
||||||
|
}
|
||||||
|
|
||||||
|
static VOID FspVolumeDeleteDelayed(PVOID Context)
|
||||||
|
{
|
||||||
|
PAGED_CODE();
|
||||||
|
|
||||||
|
PDEVICE_OBJECT FsvolDeviceObject = Context;
|
||||||
|
FSP_FSVOL_DEVICE_EXTENSION *FsvolDeviceExtension = FspFsvolDeviceExtension(FsvolDeviceObject);
|
||||||
|
KIRQL Irql;
|
||||||
|
BOOLEAN DeleteVpb = FALSE;
|
||||||
|
LARGE_INTEGER DelayTimeout;
|
||||||
|
|
||||||
|
IoAcquireVpbSpinLock(&Irql);
|
||||||
|
ASSERT(0 != FsvolDeviceExtension->SwapVpb->ReferenceCount);
|
||||||
|
DeleteVpb = 1 == FsvolDeviceExtension->SwapVpb->ReferenceCount;
|
||||||
|
if (DeleteVpb)
|
||||||
|
FsvolDeviceExtension->SwapVpb->ReferenceCount = 0;
|
||||||
|
IoReleaseVpbSpinLock(Irql);
|
||||||
|
if (DeleteVpb)
|
||||||
|
{
|
||||||
|
FspFreeExternal(FsvolDeviceExtension->SwapVpb);
|
||||||
|
FsvolDeviceExtension->SwapVpb = 0;
|
||||||
|
FspDeviceRelease(FsvolDeviceObject);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
DelayTimeout.QuadPart = 300/*ms*/ * -10000;
|
||||||
|
FspQueueWorkItemWithDelay(&FsvolDeviceExtension->DeleteVolumeWorkItem, DelayTimeout);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
NTSTATUS FspVolumeMount(
|
NTSTATUS FspVolumeMount(
|
||||||
@ -185,13 +300,17 @@ NTSTATUS FspVolumeMount(
|
|||||||
{
|
{
|
||||||
FsvolDeviceObject = DeviceObjects[i];
|
FsvolDeviceObject = DeviceObjects[i];
|
||||||
FsvolDeviceExtension = FspFsvolDeviceExtension(FsvolDeviceObject);
|
FsvolDeviceExtension = FspFsvolDeviceExtension(FsvolDeviceObject);
|
||||||
if (FsvolDeviceExtension->FsvrtDeviceObject == FsvrtDeviceObject &&
|
if (FsvolDeviceExtension->FsvrtDeviceObject == FsvrtDeviceObject)
|
||||||
!FsvolDeviceExtension->DeletePending)
|
{
|
||||||
|
ExAcquireResourceExclusiveLite(&FsvolDeviceExtension->DeleteResource, TRUE);
|
||||||
|
if (!FspIoqStopped(&FsvolDeviceExtension->Ioq))
|
||||||
{
|
{
|
||||||
Result = STATUS_SUCCESS;
|
Result = STATUS_SUCCESS;
|
||||||
/* break out of the loop without FspDeviceRelease on the volume device! */
|
/* break out of the loop without FspDeviceRelease or DeleteResource release! */
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
ExReleaseResourceLite(&FsvolDeviceExtension->DeleteResource);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
FspDeviceRelease(DeviceObjects[i]);
|
FspDeviceRelease(DeviceObjects[i]);
|
||||||
}
|
}
|
||||||
@ -201,9 +320,11 @@ NTSTATUS FspVolumeMount(
|
|||||||
return Result;
|
return Result;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* At this point the volume device object we are going to use in the VPB has been FspDeviceRetain'ed.
|
* At this point the volume device object we are going to use in the VPB
|
||||||
* We also increment the VPB's ReferenceCount so that we can do a delayed delete of the volume device
|
* has been FspDeviceRetain'ed and the volume DeleteResource has been acquired.
|
||||||
* later on.
|
* We will increment the VPB's ReferenceCount so that we can do a delayed delete
|
||||||
|
* of the volume device later on. Once done with the VPB we can release the
|
||||||
|
* DeleteResource. [The volume device remains FspDeviceRetain'ed!]
|
||||||
*/
|
*/
|
||||||
ASSERT(0 != FsvolDeviceObject && 0 != FsvolDeviceExtension);
|
ASSERT(0 != FsvolDeviceObject && 0 != FsvolDeviceExtension);
|
||||||
IoAcquireVpbSpinLock(&Irql);
|
IoAcquireVpbSpinLock(&Irql);
|
||||||
@ -212,6 +333,9 @@ NTSTATUS FspVolumeMount(
|
|||||||
Vpb->SerialNumber = FsvolDeviceExtension->VolumeParams.SerialNumber;
|
Vpb->SerialNumber = FsvolDeviceExtension->VolumeParams.SerialNumber;
|
||||||
IoReleaseVpbSpinLock(Irql);
|
IoReleaseVpbSpinLock(Irql);
|
||||||
|
|
||||||
|
/* done with mounting; release the DeleteResource */
|
||||||
|
ExReleaseResourceLite(&FsvolDeviceExtension->DeleteResource);
|
||||||
|
|
||||||
Irp->IoStatus.Information = 0;
|
Irp->IoStatus.Information = 0;
|
||||||
return STATUS_SUCCESS;
|
return STATUS_SUCCESS;
|
||||||
}
|
}
|
||||||
@ -271,125 +395,6 @@ NTSTATUS FspVolumeWork(
|
|||||||
}
|
}
|
||||||
|
|
||||||
#if 0
|
#if 0
|
||||||
VOID FspFsctlDeleteVolume(
|
|
||||||
PDEVICE_OBJECT DeviceObject, PIRP Irp, PIO_STACK_LOCATION IrpSp)
|
|
||||||
{
|
|
||||||
/* performed during IRP_MJ_CLEANUP! */
|
|
||||||
PAGED_CODE();
|
|
||||||
|
|
||||||
PDEVICE_OBJECT FsvolDeviceObject;
|
|
||||||
FSP_FSVOL_DEVICE_EXTENSION *FsvolDeviceExtension;
|
|
||||||
|
|
||||||
FsvolDeviceObject = FspFsvolDeviceObjectFromFileObject(IrpSp->FileObject);
|
|
||||||
if (0 == FsvolDeviceObject)
|
|
||||||
return;
|
|
||||||
FsvolDeviceExtension = FspFsvolDeviceExtension(FsvolDeviceObject);
|
|
||||||
|
|
||||||
/* mark the volume device as pending delete */
|
|
||||||
FsvolDeviceExtension->DeletePending = TRUE;
|
|
||||||
|
|
||||||
/* stop the I/O queue */
|
|
||||||
FspIoqStop(&FsvolDeviceExtension->Ioq);
|
|
||||||
|
|
||||||
/* do we have a virtual disk device or a MUP handle? */
|
|
||||||
if (0 != FsvolDeviceExtension->FsvrtDeviceObject)
|
|
||||||
{
|
|
||||||
PDEVICE_OBJECT FsvrtDeviceObject = FsvolDeviceExtension->FsvrtDeviceObject;
|
|
||||||
PVPB OldVpb;
|
|
||||||
KIRQL Irql;
|
|
||||||
BOOLEAN DeleteVpb = FALSE;
|
|
||||||
BOOLEAN DeleteDly = FALSE;
|
|
||||||
LARGE_INTEGER DelayTimeout;
|
|
||||||
|
|
||||||
/* swap the virtual disk device VPB with the preallocated one */
|
|
||||||
#pragma prefast(push)
|
|
||||||
#pragma prefast(disable:28175, "We are a filesystem: ok to access Vpb")
|
|
||||||
IoAcquireVpbSpinLock(&Irql);
|
|
||||||
OldVpb = FsvrtDeviceObject->Vpb;
|
|
||||||
if (0 != OldVpb)
|
|
||||||
{
|
|
||||||
FsvrtDeviceObject->Vpb = FsvolDeviceExtension->SwapVpb;
|
|
||||||
FsvrtDeviceObject->Vpb->Size = sizeof *FsvrtDeviceObject->Vpb;
|
|
||||||
FsvrtDeviceObject->Vpb->Type = IO_TYPE_VPB;
|
|
||||||
FsvrtDeviceObject->Vpb->Flags = FlagOn(OldVpb->Flags, VPB_REMOVE_PENDING);
|
|
||||||
FsvrtDeviceObject->Vpb->RealDevice = OldVpb->RealDevice;
|
|
||||||
FsvrtDeviceObject->Vpb->RealDevice->Vpb = FsvrtDeviceObject->Vpb;
|
|
||||||
DeleteVpb = 0 == OldVpb->ReferenceCount;
|
|
||||||
DeleteDly = 2 <= OldVpb->ReferenceCount;
|
|
||||||
}
|
|
||||||
IoReleaseVpbSpinLock(Irql);
|
|
||||||
if (DeleteVpb)
|
|
||||||
{
|
|
||||||
/* no more references to the old VPB; delete now! */
|
|
||||||
FspFreeExternal(OldVpb);
|
|
||||||
FsvolDeviceExtension->SwapVpb = 0;
|
|
||||||
}
|
|
||||||
else if (!DeleteDly)
|
|
||||||
{
|
|
||||||
/* there is only the reference from IRP_MN_MOUNT_VOLUME */
|
|
||||||
FspFreeExternal(OldVpb);
|
|
||||||
FsvolDeviceExtension->SwapVpb = 0;
|
|
||||||
FspDeviceRelease(FsvolDeviceObject);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
/* keep VPB around for delayed delete */
|
|
||||||
FsvolDeviceExtension->SwapVpb = OldVpb;
|
|
||||||
#pragma prefast(pop)
|
|
||||||
|
|
||||||
/* release the virtual disk and volume device objects */
|
|
||||||
FspDeviceRelease(FsvrtDeviceObject);
|
|
||||||
FspDeviceRelease(FsvolDeviceObject);
|
|
||||||
|
|
||||||
/* are we doing delayed delete of VPB and volume device object? */
|
|
||||||
if (DeleteDly)
|
|
||||||
{
|
|
||||||
DelayTimeout.QuadPart = 300/*ms*/ * -10000;
|
|
||||||
FspInitializeWorkItemWithDelay(&FsvolDeviceExtension->DeleteVolumeWorkItem,
|
|
||||||
FspFsctlDeleteVolumeDelayed, FsvolDeviceObject);
|
|
||||||
FspQueueWorkItemWithDelay(&FsvolDeviceExtension->DeleteVolumeWorkItem, DelayTimeout);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else if (0 != FsvolDeviceExtension->MupHandle)
|
|
||||||
{
|
|
||||||
HANDLE MupHandle = FsvolDeviceExtension->MupHandle;
|
|
||||||
|
|
||||||
FsRtlDeregisterUncProvider(MupHandle);
|
|
||||||
FsvolDeviceExtension->MupHandle = 0;
|
|
||||||
|
|
||||||
/* release the volume device object */
|
|
||||||
FspDeviceRelease(FsvolDeviceObject);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
static VOID FspFsctlDeleteVolumeDelayed(PVOID Context)
|
|
||||||
{
|
|
||||||
PAGED_CODE();
|
|
||||||
|
|
||||||
PDEVICE_OBJECT FsvolDeviceObject = Context;
|
|
||||||
FSP_FSVOL_DEVICE_EXTENSION *FsvolDeviceExtension = FspFsvolDeviceExtension(FsvolDeviceObject);
|
|
||||||
KIRQL Irql;
|
|
||||||
BOOLEAN DeleteVpb = FALSE;
|
|
||||||
LARGE_INTEGER DelayTimeout;
|
|
||||||
|
|
||||||
IoAcquireVpbSpinLock(&Irql);
|
|
||||||
ASSERT(0 != FsvolDeviceExtension->SwapVpb->ReferenceCount);
|
|
||||||
DeleteVpb = 1 == FsvolDeviceExtension->SwapVpb->ReferenceCount;
|
|
||||||
if (DeleteVpb)
|
|
||||||
FsvolDeviceExtension->SwapVpb->ReferenceCount = 0;
|
|
||||||
IoReleaseVpbSpinLock(Irql);
|
|
||||||
if (DeleteVpb)
|
|
||||||
{
|
|
||||||
FspFreeExternal(FsvolDeviceExtension->SwapVpb);
|
|
||||||
FsvolDeviceExtension->SwapVpb = 0;
|
|
||||||
FspDeviceRelease(FsvolDeviceObject);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
DelayTimeout.QuadPart = 300/*ms*/ * -10000;
|
|
||||||
FspQueueWorkItemWithDelay(&FsvolDeviceExtension->DeleteVolumeWorkItem, DelayTimeout);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
static NTSTATUS FspFsctlTransact(
|
static NTSTATUS FspFsctlTransact(
|
||||||
PDEVICE_OBJECT DeviceObject, PIRP Irp, PIO_STACK_LOCATION IrpSp)
|
PDEVICE_OBJECT DeviceObject, PIRP Irp, PIO_STACK_LOCATION IrpSp)
|
||||||
{
|
{
|
||||||
|
Loading…
x
Reference in New Issue
Block a user