sys: FspFsvrtDeleteVolume

This commit is contained in:
Bill Zissimopoulos 2015-11-29 14:52:27 -08:00
parent 8cb508d3e4
commit ed64b3078c
3 changed files with 68 additions and 24 deletions

View File

@ -103,6 +103,11 @@ static VOID FspFsvrtDeviceDeleteObject(PDEVICE_OBJECT DeviceObject)
{ {
PAGED_CODE(); PAGED_CODE();
FSP_FSVRT_DEVICE_EXTENSION *FsvrtDeviceExtension = FspFsvrtDeviceExtension(DeviceObject);
if (0 != FsvrtDeviceExtension->SwapVpb)
ExFreePoolWithTag(FsvrtDeviceExtension->SwapVpb, FSP_TAG);
IoDeleteDevice(DeviceObject); IoDeleteDevice(DeviceObject);
} }
@ -110,11 +115,6 @@ static VOID FspFsvolDeviceDeleteObject(PDEVICE_OBJECT DeviceObject)
{ {
PAGED_CODE(); PAGED_CODE();
FSP_FSVOL_DEVICE_EXTENSION *FsvolDeviceExtension = FspFsvolDeviceExtension(DeviceObject);
if (0 != FsvolDeviceExtension->SwapVpb)
ExFreePoolWithTag(FsvolDeviceExtension->SwapVpb, FSP_TAG);
IoDeleteDevice(DeviceObject); IoDeleteDevice(DeviceObject);
} }

View File

@ -257,13 +257,13 @@ typedef struct
PDEVICE_OBJECT FsctlDeviceObject; PDEVICE_OBJECT FsctlDeviceObject;
FSP_FSCTL_VOLUME_PARAMS VolumeParams; FSP_FSCTL_VOLUME_PARAMS VolumeParams;
FSP_IOQ Ioq; FSP_IOQ Ioq;
PVPB SwapVpb;
UINT8 SecurityDescriptorBuf[]; UINT8 SecurityDescriptorBuf[];
} FSP_FSVRT_DEVICE_EXTENSION; } FSP_FSVRT_DEVICE_EXTENSION;
typedef struct typedef struct
{ {
FSP_DEVICE_EXTENSION Base; FSP_DEVICE_EXTENSION Base;
PDEVICE_OBJECT FsvrtDeviceObject; PDEVICE_OBJECT FsvrtDeviceObject;
PVPB SwapVpb;
} FSP_FSVOL_DEVICE_EXTENSION; } FSP_FSVOL_DEVICE_EXTENSION;
static inline static inline
FSP_DEVICE_EXTENSION *FspDeviceExtension(PDEVICE_OBJECT DeviceObject) FSP_DEVICE_EXTENSION *FspDeviceExtension(PDEVICE_OBJECT DeviceObject)

View File

@ -55,19 +55,33 @@ static NTSTATUS FspFsctlCreateVolume(
return STATUS_BUFFER_TOO_SMALL; return STATUS_BUFFER_TOO_SMALL;
NTSTATUS Result; NTSTATUS Result;
PVOID SecurityDescriptorBuf = 0;
PVPB SwapVpb = 0;
/* create volume guid */ /* create volume guid */
GUID Guid; GUID Guid;
Result = FspCreateGuid(&Guid); Result = FspCreateGuid(&Guid);
if (!NT_SUCCESS(Result)) if (!NT_SUCCESS(Result))
return Result; goto exit;
/* copy the security descriptor from the system buffer to a temporary one */ /* copy the security descriptor from the system buffer to a temporary one */
PVOID SecurityDescriptorBuf = ExAllocatePoolWithTag(PagedPool, SecurityDescriptorSize, FSP_TAG); SecurityDescriptorBuf = ExAllocatePoolWithTag(PagedPool, SecurityDescriptorSize, FSP_TAG);
if (0 == SecurityDescriptorBuf) if (0 == SecurityDescriptorBuf)
return STATUS_INSUFFICIENT_RESOURCES; {
Result = STATUS_INSUFFICIENT_RESOURCES;
goto exit;
}
RtlCopyMemory(SecurityDescriptorBuf, SecurityDescriptor, SecurityDescriptorSize); RtlCopyMemory(SecurityDescriptorBuf, SecurityDescriptor, SecurityDescriptorSize);
/* preallocate swap VPB */
SwapVpb = ExAllocatePoolWithTag(NonPagedPool, sizeof *SwapVpb, FSP_TAG);
if (0 == SwapVpb)
{
Result = STATUS_INSUFFICIENT_RESOURCES;
goto exit;
}
RtlZeroMemory(SwapVpb, sizeof *SwapVpb);
/* create the virtual volume device */ /* create the virtual volume device */
PDEVICE_OBJECT FsvrtDeviceObject; PDEVICE_OBJECT FsvrtDeviceObject;
UNICODE_STRING DeviceSddl; UNICODE_STRING DeviceSddl;
@ -92,14 +106,21 @@ static NTSTATUS FspFsctlCreateVolume(
FsvrtDeviceExtension->FsctlDeviceObject = DeviceObject; FsvrtDeviceExtension->FsctlDeviceObject = DeviceObject;
FsvrtDeviceExtension->VolumeParams = *Params; FsvrtDeviceExtension->VolumeParams = *Params;
FspIoqInitialize(&FsvrtDeviceExtension->Ioq); FspIoqInitialize(&FsvrtDeviceExtension->Ioq);
FsvrtDeviceExtension->SwapVpb = SwapVpb;
RtlCopyMemory(FspFsvrtDeviceExtension(FsvrtDeviceObject)->SecurityDescriptorBuf, RtlCopyMemory(FspFsvrtDeviceExtension(FsvrtDeviceObject)->SecurityDescriptorBuf,
SecurityDescriptorBuf, SecurityDescriptorSize); SecurityDescriptorBuf, SecurityDescriptorSize);
ClearFlag(FsvrtDeviceObject->Flags, DO_DEVICE_INITIALIZING); ClearFlag(FsvrtDeviceObject->Flags, DO_DEVICE_INITIALIZING);
Irp->IoStatus.Information = DeviceName.Length + 1; Irp->IoStatus.Information = DeviceName.Length + 1;
SwapVpb = 0;
} }
exit:
/* free the temporary security descriptor */ /* free the temporary security descriptor */
ExFreePoolWithTag(SecurityDescriptorBuf, FSP_TAG); if (0 != SecurityDescriptorBuf)
ExFreePoolWithTag(SecurityDescriptorBuf, FSP_TAG);
/* free swap VPB if we failed */
if (0 != SwapVpb)
ExFreePoolWithTag(SwapVpb, FSP_TAG);
return Result; return Result;
} }
@ -111,7 +132,6 @@ static NTSTATUS FspFsctlMountVolume(
NTSTATUS Result; NTSTATUS Result;
PVPB Vpb = IrpSp->Parameters.MountVolume.Vpb; PVPB Vpb = IrpSp->Parameters.MountVolume.Vpb;
PVPB SwapVpb = 0;
PDEVICE_OBJECT FsvrtDeviceObject = Vpb->RealDevice; PDEVICE_OBJECT FsvrtDeviceObject = Vpb->RealDevice;
PDEVICE_OBJECT FsvolDeviceObject; PDEVICE_OBJECT FsvolDeviceObject;
@ -127,14 +147,9 @@ static NTSTATUS FspFsctlMountVolume(
if (FILE_DEVICE_VIRTUAL_DISK != FsvrtDeviceObject->DeviceType) if (FILE_DEVICE_VIRTUAL_DISK != FsvrtDeviceObject->DeviceType)
return STATUS_UNRECOGNIZED_VOLUME; return STATUS_UNRECOGNIZED_VOLUME;
/* preallocate swap VPB */ ExAcquireResourceExclusiveLite(&FspFsctlDeviceExtension(DeviceObject)->Resource, TRUE);
SwapVpb = ExAllocatePoolWithTag(NonPagedPool, sizeof *SwapVpb, FSP_TAG);
if (0 == SwapVpb)
return STATUS_INSUFFICIENT_RESOURCES;
RtlZeroMemory(SwapVpb, sizeof *Vpb);
/* create the file system device object */ /* create the file system device object */
ExAcquireResourceExclusiveLite(&FspFsctlDeviceExtension(DeviceObject)->Resource, TRUE);
Result = IoCreateDevice(DeviceObject->DriverObject, Result = IoCreateDevice(DeviceObject->DriverObject,
sizeof(FSP_FSVOL_DEVICE_EXTENSION), 0, DeviceObject->DeviceType, sizeof(FSP_FSVOL_DEVICE_EXTENSION), 0, DeviceObject->DeviceType,
0, FALSE, 0, FALSE,
@ -147,18 +162,12 @@ static NTSTATUS FspFsctlMountVolume(
FSP_FSVOL_DEVICE_EXTENSION *FsvolDeviceExtension = FspFsvolDeviceExtension(FsvolDeviceObject); FSP_FSVOL_DEVICE_EXTENSION *FsvolDeviceExtension = FspFsvolDeviceExtension(FsvolDeviceObject);
FsvolDeviceExtension->Base.Kind = FspFsvolDeviceExtensionKind; FsvolDeviceExtension->Base.Kind = FspFsvolDeviceExtensionKind;
FsvolDeviceExtension->FsvrtDeviceObject = FsvrtDeviceObject; FsvolDeviceExtension->FsvrtDeviceObject = FsvrtDeviceObject;
FsvolDeviceExtension->SwapVpb = SwapVpb;
ClearFlag(FsvolDeviceObject->Flags, DO_DEVICE_INITIALIZING); ClearFlag(FsvolDeviceObject->Flags, DO_DEVICE_INITIALIZING);
Vpb->VolumeLabelLength = 0;
Vpb->DeviceObject = FsvolDeviceObject; Vpb->DeviceObject = FsvolDeviceObject;
Irp->IoStatus.Information = 0; Irp->IoStatus.Information = 0;
SwapVpb = 0;
} }
ExReleaseResourceLite(&FspFsctlDeviceExtension(DeviceObject)->Resource);
/* free swap VPB if we failed */ ExReleaseResourceLite(&FspFsctlDeviceExtension(DeviceObject)->Resource);
if (0 != SwapVpb)
ExFreePoolWithTag(SwapVpb, FSP_TAG);
return Result; return Result;
} }
@ -177,6 +186,41 @@ static NTSTATUS FspFsvrtDeleteVolume(
if (!NT_SUCCESS(Result)) if (!NT_SUCCESS(Result))
return Result; return Result;
ExAcquireResourceExclusiveLite(&FspFsctlDeviceExtension(DeviceObject)->Resource, TRUE);
/* stop the I/O queue */
FspIoqStop(&FsvrtDeviceExtension->Ioq);
/* swap the preallocated VPB */
PVPB OldVpb;
KIRQL Irql;
IoAcquireVpbSpinLock(&Irql);
OldVpb = DeviceObject->Vpb;
if (0 != OldVpb)
{
DeviceObject->Vpb = FsvrtDeviceExtension->SwapVpb;
DeviceObject->Vpb->Size = sizeof *DeviceObject->Vpb;
DeviceObject->Vpb->Type = IO_TYPE_VPB;
DeviceObject->Vpb->Flags = FlagOn(OldVpb->Flags, VPB_REMOVE_PENDING);
DeviceObject->Vpb->RealDevice = OldVpb->RealDevice;
DeviceObject->Vpb->RealDevice->Vpb = DeviceObject->Vpb;
FsvrtDeviceExtension->SwapVpb = 0;
}
IoReleaseVpbSpinLock(Irql);
/* delete the file system device object */
if (0 != OldVpb && 0 != OldVpb->DeviceObject &&
FspDeviceOwned(DeviceObject->DriverObject, OldVpb->DeviceObject))
{
ASSERT(FspFsvolDeviceExtensionKind == FspDeviceExtension(OldVpb->DeviceObject)->Kind);
FspDeviceDeleteObject(OldVpb->DeviceObject);
}
/* delete the virtual volume device */
FspDeviceDeleteObject(DeviceObject);
ExReleaseResourceLite(&FspFsctlDeviceExtension(DeviceObject)->Resource);
return STATUS_INVALID_DEVICE_REQUEST; return STATUS_INVALID_DEVICE_REQUEST;
} }