mirror of
https://github.com/winfsp/winfsp.git
synced 2025-04-23 08:53:01 -05:00
Major refactoring: WIP
This commit is contained in:
parent
e08e44d5f9
commit
7ef68a6688
@ -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;
|
||||||
|
@ -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;
|
||||||
|
|
||||||
|
269
src/sys/fsctl.c
269
src/sys/fsctl.c
@ -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;
|
||||||
|
PVPB Vpb = IrpSp->Parameters.MountVolume.Vpb;
|
||||||
|
PDEVICE_OBJECT FsvrtDeviceObject = IrpSp->Parameters.MountVolume.DeviceObject;
|
||||||
|
PDEVICE_OBJECT FsvolDeviceObject = 0;
|
||||||
|
FSP_FSVOL_DEVICE_EXTENSION *FsvolDeviceExtension = 0;
|
||||||
|
PDEVICE_OBJECT *DeviceObjects = 0;
|
||||||
|
ULONG DeviceObjectCount = 0;
|
||||||
|
KIRQL Irql;
|
||||||
|
|
||||||
FSP_DEVICE_EXTENSION *DeviceExtension = FspDeviceExtension(DeviceObject);
|
/* check the passed in device object; it must be our own and not marked delete pending */
|
||||||
ExAcquireResourceExclusiveLite(&DeviceExtension->Resource, TRUE);
|
Result = FspDeviceCopyList(&DeviceObjects, &DeviceObjectCount);
|
||||||
try
|
if (NT_SUCCESS(Result))
|
||||||
{
|
{
|
||||||
PVPB Vpb = IrpSp->Parameters.MountVolume.Vpb;
|
Result = STATUS_UNRECOGNIZED_VOLUME;
|
||||||
PDEVICE_OBJECT FsvrtDeviceObject = IrpSp->Parameters.MountVolume.DeviceObject;
|
for (ULONG i = 0; DeviceObjectCount > i; i++)
|
||||||
PDEVICE_OBJECT FsvolDeviceObject;
|
if (FspDeviceRetain(DeviceObjects[i]))
|
||||||
FSP_FSVOL_DEVICE_EXTENSION *FsvolDeviceExtension;
|
{
|
||||||
|
if (FspFsvolDeviceExtensionKind == FspDeviceExtension(DeviceObjects[i])->Kind)
|
||||||
/* quick check to see if we already have a volume */
|
{
|
||||||
FsvolDeviceObject = FspDeviceLookupContext(DeviceObject, (UINT_PTR)IrpSp->FileObject);
|
FsvolDeviceObject = DeviceObjects[i];
|
||||||
if (0 != FsvolDeviceObject)
|
FsvolDeviceExtension = FspFsvolDeviceExtension(FsvolDeviceObject);
|
||||||
{
|
if (FsvolDeviceExtension->FsvrtDeviceObject == FsvrtDeviceObject &&
|
||||||
Result = STATUS_UNRECOGNIZED_VOLUME;
|
!FsvolDeviceExtension->DeletePending)
|
||||||
goto exit;
|
{
|
||||||
}
|
Result = STATUS_SUCCESS;
|
||||||
|
break;
|
||||||
FsvolDeviceExtension = FspFsvolDeviceExtension(FsvolDeviceObject);
|
}
|
||||||
if (FsvolDeviceExtension->DeletePending ||
|
}
|
||||||
FsvolDeviceExtension->FsvrtDeviceObject != FsvrtDeviceObject)
|
FspDeviceRelease(DeviceObjects[i]);
|
||||||
{
|
}
|
||||||
Result = STATUS_UNRECOGNIZED_VOLUME;
|
FspDeviceDeleteList(DeviceObjects, DeviceObjectCount);
|
||||||
goto exit;
|
|
||||||
}
|
|
||||||
|
|
||||||
Vpb->DeviceObject = FsvolDeviceObject;
|
|
||||||
Vpb->SerialNumber = FsvolDeviceExtension->VolumeParams.SerialNumber;
|
|
||||||
|
|
||||||
Irp->IoStatus.Information = 0;
|
|
||||||
Result = STATUS_SUCCESS;
|
|
||||||
|
|
||||||
exit:;
|
|
||||||
}
|
|
||||||
finally
|
|
||||||
{
|
|
||||||
ExReleaseResourceLite(&DeviceExtension->Resource);
|
|
||||||
}
|
}
|
||||||
|
if (!NT_SUCCESS(Result))
|
||||||
|
return Result;
|
||||||
|
|
||||||
return Result;
|
/* our volume device object has been FspDeviceRetain'ed */
|
||||||
#else
|
ASSERT(0 != FsvolDeviceObject && 0 != FsvolDeviceExtension);
|
||||||
return STATUS_INVALID_DEVICE_REQUEST;
|
IoAcquireVpbSpinLock(&Irql);
|
||||||
#endif
|
Vpb->ReferenceCount++;
|
||||||
|
Vpb->DeviceObject = FsvolDeviceObject;
|
||||||
|
Vpb->SerialNumber = FsvolDeviceExtension->VolumeParams.SerialNumber;
|
||||||
|
IoReleaseVpbSpinLock(Irql);
|
||||||
|
|
||||||
|
Irp->IoStatus.Information = 0;
|
||||||
|
return STATUS_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
VOID FspFsctlDeleteVolume(
|
VOID FspFsctlDeleteVolume(
|
||||||
@ -253,107 +245,99 @@ 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 = FsContext2->FsvolDeviceObject;
|
||||||
|
if (0 == FsvolDeviceObject)
|
||||||
|
return;
|
||||||
|
|
||||||
|
FSP_FSVOL_DEVICE_EXTENSION *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)
|
||||||
{
|
{
|
||||||
FsvolDeviceObject = FspDeviceLookupContext(DeviceObject, (UINT_PTR)IrpSp->FileObject);
|
PDEVICE_OBJECT FsvrtDeviceObject = FsvolDeviceExtension->FsvrtDeviceObject;
|
||||||
if (0 != FsvolDeviceObject)
|
PVPB OldVpb;
|
||||||
FspDeviceDeleteContext(DeviceObject, (UINT_PTR)IrpSp->FileObject, 0);
|
KIRQL Irql;
|
||||||
}
|
BOOLEAN DeleteVpb = FALSE;
|
||||||
finally
|
BOOLEAN DeleteDly = FALSE;
|
||||||
{
|
LARGE_INTEGER DelayTimeout;
|
||||||
ExReleaseResourceLite(&DeviceExtension->Resource);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (0 != FsvolDeviceObject)
|
/* swap the virtual disk device VPB with the preallocated one */
|
||||||
{
|
|
||||||
FSP_FSVOL_DEVICE_EXTENSION *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 DeleteDelayed = FALSE;
|
|
||||||
LARGE_INTEGER DelayTimeout;
|
|
||||||
|
|
||||||
/* swap the virtual disk device VPB with the preallocated one */
|
|
||||||
#pragma prefast(push)
|
#pragma prefast(push)
|
||||||
#pragma prefast(disable:28175, "We are a filesystem: ok to access Vpb")
|
#pragma prefast(disable:28175, "We are a filesystem: ok to access Vpb")
|
||||||
IoAcquireVpbSpinLock(&Irql);
|
IoAcquireVpbSpinLock(&Irql);
|
||||||
OldVpb = FsvrtDeviceObject->Vpb;
|
OldVpb = FsvrtDeviceObject->Vpb;
|
||||||
if (0 != OldVpb)
|
if (0 != OldVpb)
|
||||||
{
|
{
|
||||||
FsvrtDeviceObject->Vpb = FsvolDeviceExtension->SwapVpb;
|
FsvrtDeviceObject->Vpb = FsvolDeviceExtension->SwapVpb;
|
||||||
FsvrtDeviceObject->Vpb->Size = sizeof *FsvrtDeviceObject->Vpb;
|
FsvrtDeviceObject->Vpb->Size = sizeof *FsvrtDeviceObject->Vpb;
|
||||||
FsvrtDeviceObject->Vpb->Type = IO_TYPE_VPB;
|
FsvrtDeviceObject->Vpb->Type = IO_TYPE_VPB;
|
||||||
FsvrtDeviceObject->Vpb->Flags = FlagOn(OldVpb->Flags, VPB_REMOVE_PENDING);
|
FsvrtDeviceObject->Vpb->Flags = FlagOn(OldVpb->Flags, VPB_REMOVE_PENDING);
|
||||||
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)
|
}
|
||||||
{
|
IoReleaseVpbSpinLock(Irql);
|
||||||
/* keep VPB around for delayed delete */
|
if (DeleteVpb)
|
||||||
OldVpb->ReferenceCount++;
|
{
|
||||||
FsvolDeviceExtension->SwapVpb = OldVpb;
|
/* no more references to the old VPB; delete now! */
|
||||||
}
|
FspFreeExternal(OldVpb);
|
||||||
else
|
FsvolDeviceExtension->SwapVpb = 0;
|
||||||
FsvolDeviceExtension->SwapVpb = 0;
|
}
|
||||||
}
|
else if (!DeleteDly)
|
||||||
IoReleaseVpbSpinLock(Irql);
|
{
|
||||||
if (DeleteDelayed)
|
/* there is only the reference from IRP_MN_MOUNT_VOLUME */
|
||||||
/* keep volume device object around for delayed delete */
|
FspFreeExternal(OldVpb);
|
||||||
FspDeviceRetain(FsvolDeviceObject);
|
FsvolDeviceExtension->SwapVpb = 0;
|
||||||
else if (DeleteVpb)
|
FspDeviceRelease(FsvolDeviceObject);
|
||||||
/* no more references to the old VPB; delete now! */
|
}
|
||||||
FspFreeExternal(OldVpb);
|
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 */
|
||||||
FspDeviceRelease(FsvrtDeviceObject);
|
FspDeviceRelease(FsvrtDeviceObject);
|
||||||
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;
|
|
||||||
FspInitializeWorkItemWithDelay(&FsvolDeviceExtension->DeleteVolumeWorkItem,
|
|
||||||
FspFsctlDeleteVolumeDelayed, FsvolDeviceObject);
|
|
||||||
FspQueueWorkItemWithDelay(&FsvolDeviceExtension->DeleteVolumeWorkItem, DelayTimeout);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else if (0 != FsvolDeviceExtension->MupHandle)
|
|
||||||
{
|
{
|
||||||
HANDLE MupHandle = FsvolDeviceExtension->MupHandle;
|
DelayTimeout.QuadPart = 300/*ms*/ * -10000;
|
||||||
|
FspInitializeWorkItemWithDelay(&FsvolDeviceExtension->DeleteVolumeWorkItem,
|
||||||
FsRtlDeregisterUncProvider(MupHandle);
|
FspFsctlDeleteVolumeDelayed, FsvolDeviceObject);
|
||||||
|
FspQueueWorkItemWithDelay(&FsvolDeviceExtension->DeleteVolumeWorkItem, DelayTimeout);
|
||||||
/* release the volume device object */
|
|
||||||
FspDeviceRelease(FsvolDeviceObject);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
#endif
|
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)
|
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(
|
||||||
|
Loading…
x
Reference in New Issue
Block a user