Major refactoring: WIP

This commit is contained in:
Bill Zissimopoulos 2015-12-20 14:23:58 -08:00
parent e08e44d5f9
commit 7ef68a6688
3 changed files with 129 additions and 144 deletions

View File

@ -33,11 +33,12 @@ static NTSTATUS FspFsctlCreate(
PAGED_CODE(); PAGED_CODE();
FSP_FSCTL_FILE_CONTEXT2 *FsContext2; FSP_FSCTL_FILE_CONTEXT2 *FsContext2;
FsContext2 = FspAlloc(sizeof *FsContext2); FsContext2 = FspAllocNonPaged(sizeof *FsContext2);
if (0 == FsContext2) if (0 == FsContext2)
return STATUS_INSUFFICIENT_RESOURCES; return STATUS_INSUFFICIENT_RESOURCES;
RtlZeroMemory(FsContext2, sizeof *FsContext2); RtlZeroMemory(FsContext2, sizeof *FsContext2);
ExInitializeFastMutex(&FsContext2->FastMutex);
IrpSp->FileObject->FsContext2 = FsContext2; IrpSp->FileObject->FsContext2 = FsContext2;
Irp->IoStatus.Information = FILE_OPENED; Irp->IoStatus.Information = FILE_OPENED;

View File

@ -411,6 +411,7 @@ VOID FspDeviceDeleteAll(VOID);
/* fsctl file objects */ /* fsctl file objects */
typedef struct typedef struct
{ {
FAST_MUTEX FastMutex;
PDEVICE_OBJECT FsvolDeviceObject; PDEVICE_OBJECT FsvolDeviceObject;
} FSP_FSCTL_FILE_CONTEXT2; } FSP_FSCTL_FILE_CONTEXT2;

View File

@ -69,7 +69,6 @@ static NTSTATUS FspFsctlCreateVolume(
{ {
PAGED_CODE(); PAGED_CODE();
#if 0
/* check parameters */ /* check parameters */
ULONG InputBufferLength = IrpSp->Parameters.FileSystemControl.InputBufferLength; ULONG InputBufferLength = IrpSp->Parameters.FileSystemControl.InputBufferLength;
ULONG OutputBufferLength = IrpSp->Parameters.FileSystemControl.OutputBufferLength; ULONG OutputBufferLength = IrpSp->Parameters.FileSystemControl.OutputBufferLength;
@ -114,24 +113,22 @@ static NTSTATUS FspFsctlCreateVolume(
Guid.Data4[4], Guid.Data4[5], Guid.Data4[6], Guid.Data4[7]); Guid.Data4[4], Guid.Data4[5], Guid.Data4[6], Guid.Data4[7]);
ASSERT(NT_SUCCESS(Result)); ASSERT(NT_SUCCESS(Result));
FSP_DEVICE_EXTENSION *DeviceExtension = FspDeviceExtension(DeviceObject); FSP_FSCTL_FILE_CONTEXT2 *FsContext2 = IrpSp->FileObject->FsContext2;
ExAcquireResourceExclusiveLite(&DeviceExtension->Resource, TRUE); ExAcquireFastMutex(&FsContext2->FastMutex);
try try
{ {
HANDLE MupHandle = 0; /* check to see if we already have a volume */
PDEVICE_OBJECT FsvrtDeviceObject = 0; if (0 != FsContext2->FsvolDeviceObject)
PDEVICE_OBJECT FsvolDeviceObject;
FSP_FSVOL_DEVICE_EXTENSION *FsvolDeviceExtension;
BOOLEAN Inserted;
/* quick check to see if we already have a volume */
FsvolDeviceObject = FspDeviceLookupContext(DeviceObject, (UINT_PTR)IrpSp->FileObject);
if (0 != FsvolDeviceObject)
{ {
Result = STATUS_ACCESS_DENIED; Result = STATUS_ACCESS_DENIED;
goto exit; goto exit;
} }
HANDLE MupHandle = 0;
PDEVICE_OBJECT FsvrtDeviceObject = 0;
PDEVICE_OBJECT FsvolDeviceObject;
FSP_FSVOL_DEVICE_EXTENSION *FsvolDeviceExtension;
/* create the volume (and virtual disk) device(s) */ /* create the volume (and virtual disk) device(s) */
Result = FspDeviceCreate(FspFsvolDeviceExtensionKind, 0, Result = FspDeviceCreate(FspFsvolDeviceExtensionKind, 0,
DeviceObject->DeviceType, DeviceObject->DeviceType,
@ -175,9 +172,7 @@ static NTSTATUS FspFsctlCreateVolume(
} }
/* associate the new volume device with our file object */ /* associate the new volume device with our file object */
FspDeviceInsertContext(DeviceObject, (UINT_PTR)IrpSp->FileObject, FsvolDeviceObject, FsContext2->FsvolDeviceObject = FsvolDeviceObject;
&FsvolDeviceExtension->ElementStorage, &Inserted);
ASSERT(Inserted);
Irp->IoStatus.Information = DeviceName.Length + sizeof(WCHAR); Irp->IoStatus.Information = DeviceName.Length + sizeof(WCHAR);
Result = STATUS_SUCCESS; Result = STATUS_SUCCESS;
@ -186,13 +181,10 @@ static NTSTATUS FspFsctlCreateVolume(
} }
finally finally
{ {
ExReleaseResourceLite(&DeviceExtension->Resource); ExReleaseFastMutex(&FsContext2->FastMutex);
} }
return Result; return Result;
#else
return STATUS_INVALID_DEVICE_REQUEST;
#endif
} }
static NTSTATUS FspFsctlMountVolume( static NTSTATUS FspFsctlMountVolume(
@ -200,51 +192,51 @@ static NTSTATUS FspFsctlMountVolume(
{ {
PAGED_CODE(); PAGED_CODE();
#if 0
NTSTATUS Result; NTSTATUS Result;
FSP_DEVICE_EXTENSION *DeviceExtension = FspDeviceExtension(DeviceObject);
ExAcquireResourceExclusiveLite(&DeviceExtension->Resource, TRUE);
try
{
PVPB Vpb = IrpSp->Parameters.MountVolume.Vpb; PVPB Vpb = IrpSp->Parameters.MountVolume.Vpb;
PDEVICE_OBJECT FsvrtDeviceObject = IrpSp->Parameters.MountVolume.DeviceObject; PDEVICE_OBJECT FsvrtDeviceObject = IrpSp->Parameters.MountVolume.DeviceObject;
PDEVICE_OBJECT FsvolDeviceObject; PDEVICE_OBJECT FsvolDeviceObject = 0;
FSP_FSVOL_DEVICE_EXTENSION *FsvolDeviceExtension; FSP_FSVOL_DEVICE_EXTENSION *FsvolDeviceExtension = 0;
PDEVICE_OBJECT *DeviceObjects = 0;
ULONG DeviceObjectCount = 0;
KIRQL Irql;
/* quick check to see if we already have a volume */ /* check the passed in device object; it must be our own and not marked delete pending */
FsvolDeviceObject = FspDeviceLookupContext(DeviceObject, (UINT_PTR)IrpSp->FileObject); Result = FspDeviceCopyList(&DeviceObjects, &DeviceObjectCount);
if (0 != FsvolDeviceObject) if (NT_SUCCESS(Result))
{ {
Result = STATUS_UNRECOGNIZED_VOLUME; Result = STATUS_UNRECOGNIZED_VOLUME;
goto exit; for (ULONG i = 0; DeviceObjectCount > i; i++)
} if (FspDeviceRetain(DeviceObjects[i]))
{
if (FspFsvolDeviceExtensionKind == FspDeviceExtension(DeviceObjects[i])->Kind)
{
FsvolDeviceObject = DeviceObjects[i];
FsvolDeviceExtension = FspFsvolDeviceExtension(FsvolDeviceObject); FsvolDeviceExtension = FspFsvolDeviceExtension(FsvolDeviceObject);
if (FsvolDeviceExtension->DeletePending || if (FsvolDeviceExtension->FsvrtDeviceObject == FsvrtDeviceObject &&
FsvolDeviceExtension->FsvrtDeviceObject != FsvrtDeviceObject) !FsvolDeviceExtension->DeletePending)
{ {
Result = STATUS_UNRECOGNIZED_VOLUME; Result = STATUS_SUCCESS;
goto exit; break;
} }
}
FspDeviceRelease(DeviceObjects[i]);
}
FspDeviceDeleteList(DeviceObjects, DeviceObjectCount);
}
if (!NT_SUCCESS(Result))
return Result;
/* our volume device object has been FspDeviceRetain'ed */
ASSERT(0 != FsvolDeviceObject && 0 != FsvolDeviceExtension);
IoAcquireVpbSpinLock(&Irql);
Vpb->ReferenceCount++;
Vpb->DeviceObject = FsvolDeviceObject; Vpb->DeviceObject = FsvolDeviceObject;
Vpb->SerialNumber = FsvolDeviceExtension->VolumeParams.SerialNumber; Vpb->SerialNumber = FsvolDeviceExtension->VolumeParams.SerialNumber;
IoReleaseVpbSpinLock(Irql);
Irp->IoStatus.Information = 0; Irp->IoStatus.Information = 0;
Result = STATUS_SUCCESS; return STATUS_SUCCESS;
exit:;
}
finally
{
ExReleaseResourceLite(&DeviceExtension->Resource);
}
return Result;
#else
return STATUS_INVALID_DEVICE_REQUEST;
#endif
} }
VOID FspFsctlDeleteVolume( VOID FspFsctlDeleteVolume(
@ -253,24 +245,17 @@ VOID FspFsctlDeleteVolume(
/* performed during IRP_MJ_CLEANUP! */ /* performed during IRP_MJ_CLEANUP! */
PAGED_CODE(); PAGED_CODE();
#if 0 FSP_FSCTL_FILE_CONTEXT2 *FsContext2 = IrpSp->FileObject->FsContext2;
PDEVICE_OBJECT FsvolDeviceObject = 0; PDEVICE_OBJECT FsvolDeviceObject = 0;
FSP_DEVICE_EXTENSION *DeviceExtension = FspDeviceExtension(DeviceObject); /*
ExAcquireResourceExclusiveLite(&DeviceExtension->Resource, TRUE); * Check to see if we have a volume. There is no need to protect this
try * access in FsContext2->FastMutex, because we are called during IRP_MJ_CLEANUP.
{ */
FsvolDeviceObject = FspDeviceLookupContext(DeviceObject, (UINT_PTR)IrpSp->FileObject); FsvolDeviceObject = FsContext2->FsvolDeviceObject;
if (0 != FsvolDeviceObject) if (0 == FsvolDeviceObject)
FspDeviceDeleteContext(DeviceObject, (UINT_PTR)IrpSp->FileObject, 0); return;
}
finally
{
ExReleaseResourceLite(&DeviceExtension->Resource);
}
if (0 != FsvolDeviceObject)
{
FSP_FSVOL_DEVICE_EXTENSION *FsvolDeviceExtension = FspFsvolDeviceExtension(FsvolDeviceObject); FSP_FSVOL_DEVICE_EXTENSION *FsvolDeviceExtension = FspFsvolDeviceExtension(FsvolDeviceObject);
/* mark the volume device as pending delete */ /* mark the volume device as pending delete */
@ -286,7 +271,7 @@ VOID FspFsctlDeleteVolume(
PVPB OldVpb; PVPB OldVpb;
KIRQL Irql; KIRQL Irql;
BOOLEAN DeleteVpb = FALSE; BOOLEAN DeleteVpb = FALSE;
BOOLEAN DeleteDelayed = FALSE; BOOLEAN DeleteDly = FALSE;
LARGE_INTEGER DelayTimeout; LARGE_INTEGER DelayTimeout;
/* swap the virtual disk device VPB with the preallocated one */ /* swap the virtual disk device VPB with the preallocated one */
@ -303,23 +288,25 @@ VOID FspFsctlDeleteVolume(
FsvrtDeviceObject->Vpb->RealDevice = OldVpb->RealDevice; FsvrtDeviceObject->Vpb->RealDevice = OldVpb->RealDevice;
FsvrtDeviceObject->Vpb->RealDevice->Vpb = FsvrtDeviceObject->Vpb; FsvrtDeviceObject->Vpb->RealDevice->Vpb = FsvrtDeviceObject->Vpb;
DeleteVpb = 0 == OldVpb->ReferenceCount; DeleteVpb = 0 == OldVpb->ReferenceCount;
DeleteDelayed = !DeleteVpb; DeleteDly = 2 <= OldVpb->ReferenceCount;
if (DeleteDelayed)
{
/* keep VPB around for delayed delete */
OldVpb->ReferenceCount++;
FsvolDeviceExtension->SwapVpb = OldVpb;
}
else
FsvolDeviceExtension->SwapVpb = 0;
} }
IoReleaseVpbSpinLock(Irql); IoReleaseVpbSpinLock(Irql);
if (DeleteDelayed) if (DeleteVpb)
/* keep volume device object around for delayed delete */ {
FspDeviceRetain(FsvolDeviceObject);
else if (DeleteVpb)
/* no more references to the old VPB; delete now! */ /* no more references to the old VPB; delete now! */
FspFreeExternal(OldVpb); 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) #pragma prefast(pop)
/* release the virtual disk and volume device objects */ /* release the virtual disk and volume device objects */
@ -327,7 +314,7 @@ VOID FspFsctlDeleteVolume(
FspDeviceRelease(FsvolDeviceObject); FspDeviceRelease(FsvolDeviceObject);
/* are we doing delayed delete of VPB and volume device object? */ /* are we doing delayed delete of VPB and volume device object? */
if (DeleteDelayed) if (DeleteDly)
{ {
DelayTimeout.QuadPart = 300/*ms*/ * -10000; DelayTimeout.QuadPart = 300/*ms*/ * -10000;
FspInitializeWorkItemWithDelay(&FsvolDeviceExtension->DeleteVolumeWorkItem, FspInitializeWorkItemWithDelay(&FsvolDeviceExtension->DeleteVolumeWorkItem,
@ -340,20 +327,17 @@ VOID FspFsctlDeleteVolume(
HANDLE MupHandle = FsvolDeviceExtension->MupHandle; HANDLE MupHandle = FsvolDeviceExtension->MupHandle;
FsRtlDeregisterUncProvider(MupHandle); FsRtlDeregisterUncProvider(MupHandle);
FsvolDeviceExtension->MupHandle = 0;
/* release the volume device object */ /* release the volume device object */
FspDeviceRelease(FsvolDeviceObject); FspDeviceRelease(FsvolDeviceObject);
} }
}
#endif
} }
static VOID FspFsctlDeleteVolumeDelayed(PVOID Context) static VOID FspFsctlDeleteVolumeDelayed(PVOID Context)
{ {
PAGED_CODE(); PAGED_CODE();
#if 0
PDEVICE_OBJECT FsvolDeviceObject = Context; PDEVICE_OBJECT FsvolDeviceObject = Context;
FSP_FSVOL_DEVICE_EXTENSION *FsvolDeviceExtension = FspFsvolDeviceExtension(FsvolDeviceObject); FSP_FSVOL_DEVICE_EXTENSION *FsvolDeviceExtension = FspFsvolDeviceExtension(FsvolDeviceObject);
KIRQL Irql; KIRQL Irql;
@ -377,7 +361,6 @@ static VOID FspFsctlDeleteVolumeDelayed(PVOID Context)
DelayTimeout.QuadPart = 300/*ms*/ * -10000; DelayTimeout.QuadPart = 300/*ms*/ * -10000;
FspQueueWorkItemWithDelay(&FsvolDeviceExtension->DeleteVolumeWorkItem, DelayTimeout); FspQueueWorkItemWithDelay(&FsvolDeviceExtension->DeleteVolumeWorkItem, DelayTimeout);
} }
#endif
} }
static NTSTATUS FspFsctlTransact( static NTSTATUS FspFsctlTransact(