This commit is contained in:
Bill Zissimopoulos 2015-11-30 10:07:56 -08:00
parent 7c3d69f63b
commit 427f8a20e6
3 changed files with 106 additions and 67 deletions

View File

@ -22,6 +22,7 @@ static NTSTATUS FspFsvolDeviceInit(PDEVICE_OBJECT DeviceObject);
static VOID FspFsvolDeviceFini(PDEVICE_OBJECT DeviceObject);
BOOLEAN FspDeviceRetain(PDEVICE_OBJECT DeviceObject);
VOID FspDeviceRelease(PDEVICE_OBJECT DeviceObject);
BOOLEAN FspDeviceDeleted(PDEVICE_OBJECT DeviceObject);
NTSTATUS FspDeviceCopyList(
PDEVICE_OBJECT **PDeviceObjects, PULONG PDeviceObjectCount);
VOID FspDeviceDeleteList(
@ -240,6 +241,22 @@ VOID FspDeviceRelease(PDEVICE_OBJECT DeviceObject)
FspDeviceDelete(DeviceObject);
}
BOOLEAN FspDeviceDeleted(PDEVICE_OBJECT DeviceObject)
{
// !PAGED_CODE();
BOOLEAN Result;
FSP_DEVICE_EXTENSION *DeviceExtension;
KIRQL Irql;
DeviceExtension = FspDeviceExtension(DeviceObject);
KeAcquireSpinLock(&DeviceExtension->SpinLock, &Irql);
Result = 0 == DeviceExtension->RefCount;
KeReleaseSpinLock(&DeviceExtension->SpinLock, Irql);
return Result;
}
NTSTATUS FspDeviceCopyList(
PDEVICE_OBJECT **PDeviceObjects, PULONG PDeviceObjectCount)
{

View File

@ -309,6 +309,7 @@ NTSTATUS FspDeviceCreate(UINT32 Kind, ULONG ExtraSize,
VOID FspDeviceDelete(PDEVICE_OBJECT DeviceObject);
BOOLEAN FspDeviceRetain(PDEVICE_OBJECT DeviceObject);
VOID FspDeviceRelease(PDEVICE_OBJECT DeviceObject);
BOOLEAN FspDeviceDeleted(PDEVICE_OBJECT DeviceObject);
NTSTATUS FspDeviceCopyList(
PDEVICE_OBJECT **PDeviceObjects, PULONG PDeviceObjectCount);
VOID FspDeviceDeleteList(

View File

@ -111,25 +111,30 @@ static NTSTATUS FspFsctlMountVolume(
NTSTATUS Result;
FSP_FSCTL_DEVICE_EXTENSION *FsctlDeviceExtension = FspFsctlDeviceExtension(DeviceObject);
FSP_FSVRT_DEVICE_EXTENSION *FsvrtDeviceExtension;
FSP_FSVOL_DEVICE_EXTENSION *FsvolDeviceExtension;
ExAcquireResourceExclusiveLite(&FsctlDeviceExtension->Base.Resource, TRUE);
try
{
PVPB Vpb = IrpSp->Parameters.MountVolume.Vpb;
PDEVICE_OBJECT FsvrtDeviceObject = Vpb->RealDevice;
PDEVICE_OBJECT FsvolDeviceObject;
FSP_FSVRT_DEVICE_EXTENSION *FsvrtDeviceExtension;
FSP_FSVOL_DEVICE_EXTENSION *FsvolDeviceExtension;
/* check the passed in volume object; it must be one of our own */
Result = FspDeviceOwned(FsvrtDeviceObject);
if (!NT_SUCCESS(Result))
{
if (STATUS_NO_SUCH_DEVICE == Result)
return STATUS_UNRECOGNIZED_VOLUME;
else
return Result;
Result = STATUS_UNRECOGNIZED_VOLUME;
goto exit;
}
if (FspDeviceDeleted(FsvrtDeviceObject) ||
FILE_DEVICE_VIRTUAL_DISK != FsvrtDeviceObject->DeviceType)
{
Result = STATUS_UNRECOGNIZED_VOLUME;
goto exit;
}
if (FILE_DEVICE_VIRTUAL_DISK != FsvrtDeviceObject->DeviceType)
return STATUS_UNRECOGNIZED_VOLUME;
ExAcquireResourceExclusiveLite(&FsctlDeviceExtension->Base.Resource, TRUE);
/* create the file system device object */
Result = FspDeviceCreate(FspFsvolDeviceExtensionKind, 0,
@ -148,7 +153,12 @@ static NTSTATUS FspFsctlMountVolume(
Irp->IoStatus.Information = 0;
}
exit:;
}
finally
{
ExReleaseResourceLite(&FsctlDeviceExtension->Base.Resource);
}
return Result;
}
@ -158,21 +168,23 @@ static NTSTATUS FspFsvrtDeleteVolume(
{
PAGED_CODE();
NTSTATUS Result;
FSP_FSVRT_DEVICE_EXTENSION *FsvrtDeviceExtension =
FspFsvrtDeviceExtension(DeviceObject);
FSP_FSVRT_DEVICE_EXTENSION *FsvrtDeviceExtension = FspFsvrtDeviceExtension(DeviceObject);
FSP_FSCTL_DEVICE_EXTENSION *FsctlDeviceExtension =
FspFsctlDeviceExtension(FsvrtDeviceExtension->FsctlDeviceObject);
ExAcquireResourceExclusiveLite(&FsctlDeviceExtension->Base.Resource, TRUE);
try
{
NTSTATUS Result;
PVPB OldVpb;
BOOLEAN FreeVpb = FALSE;
KIRQL Irql;
/* access check */
Result = FspSecuritySubjectContextAccessCheck(
FsvrtDeviceExtension->SecurityDescriptorBuf, FILE_WRITE_DATA, Irp->RequestorMode);
if (!NT_SUCCESS(Result))
return Result;
ExAcquireResourceExclusiveLite(&FsctlDeviceExtension->Base.Resource, TRUE);
goto exit;
/* stop the I/O queue */
FspIoqStop(&FsvrtDeviceExtension->Ioq);
@ -182,7 +194,7 @@ static NTSTATUS FspFsvrtDeleteVolume(
#pragma prefast(disable:28175, "We are a filesystem: ok to access Vpb")
IoAcquireVpbSpinLock(&Irql);
OldVpb = DeviceObject->Vpb;
if (0 != OldVpb)
if (0 != OldVpb && 0 != FsvrtDeviceExtension->SwapVpb)
{
DeviceObject->Vpb = FsvrtDeviceExtension->SwapVpb;
DeviceObject->Vpb->Size = sizeof *DeviceObject->Vpb;
@ -191,17 +203,26 @@ static NTSTATUS FspFsvrtDeleteVolume(
DeviceObject->Vpb->RealDevice = OldVpb->RealDevice;
DeviceObject->Vpb->RealDevice->Vpb = DeviceObject->Vpb;
FsvrtDeviceExtension->SwapVpb = 0;
FreeVpb = 0 == OldVpb->ReferenceCount;
}
IoReleaseVpbSpinLock(Irql);
if (FreeVpb)
ExFreePool(OldVpb);
#pragma prefast(pop)
/* release the file system device and virtual volume objects */
PDEVICE_OBJECT FsvolDeviceObject = FsvrtDeviceExtension->FsvolDeviceObject;
FsvrtDeviceExtension->FsvolDeviceObject = 0;
if (0 != FsvolDeviceObject)
FspDeviceRelease(FsvolDeviceObject);
FspDeviceRelease(DeviceObject);
exit:;
}
finally
{
ExReleaseResourceLite(&FsctlDeviceExtension->Base.Resource);
}
return STATUS_SUCCESS;
}