mirror of
https://github.com/winfsp/winfsp.git
synced 2025-04-23 00:43:00 -05:00
Major refactoring: WIP
This commit is contained in:
parent
e59e4d20d7
commit
a4ac4fd169
@ -29,7 +29,7 @@ extern const __declspec(selectany) GUID FspFsvrtDeviceClassGuid =
|
|||||||
#define FSP_FSCTL_CREATE \
|
#define FSP_FSCTL_CREATE \
|
||||||
CTL_CODE(FILE_DEVICE_FILE_SYSTEM, 0x800 + 'C', METHOD_BUFFERED, FILE_ANY_ACCESS)
|
CTL_CODE(FILE_DEVICE_FILE_SYSTEM, 0x800 + 'C', METHOD_BUFFERED, FILE_ANY_ACCESS)
|
||||||
#define FSP_FSCTL_TRANSACT \
|
#define FSP_FSCTL_TRANSACT \
|
||||||
CTL_CODE(FILE_DEVICE_FILE_SYSTEM, 0x800 + 'T', METHOD_BUFFERED, FILE_ANY_ACCESS)
|
CTL_CODE(FILE_DEVICE_FILE_SYSTEM, 0x800 + 'T', METHOD_OUT_DIRECT, FILE_ANY_ACCESS)
|
||||||
|
|
||||||
#define FSP_FSCTL_CREATE_BUFFER_SIZEMIN 128
|
#define FSP_FSCTL_CREATE_BUFFER_SIZEMIN 128
|
||||||
#define FSP_FSCTL_TRANSACT_REQ_BUFFER_SIZEMIN 16384 /* checked by driver! */
|
#define FSP_FSCTL_TRANSACT_REQ_BUFFER_SIZEMIN 16384 /* checked by driver! */
|
||||||
|
105
src/sys/fsctl.c
105
src/sys/fsctl.c
@ -73,7 +73,7 @@ static NTSTATUS FspFsctlCreateVolume(
|
|||||||
ULONG InputBufferLength = IrpSp->Parameters.FileSystemControl.InputBufferLength;
|
ULONG InputBufferLength = IrpSp->Parameters.FileSystemControl.InputBufferLength;
|
||||||
ULONG OutputBufferLength = IrpSp->Parameters.FileSystemControl.OutputBufferLength;
|
ULONG OutputBufferLength = IrpSp->Parameters.FileSystemControl.OutputBufferLength;
|
||||||
PVOID SystemBuffer = Irp->AssociatedIrp.SystemBuffer;
|
PVOID SystemBuffer = Irp->AssociatedIrp.SystemBuffer;
|
||||||
if (sizeof(FSP_FSCTL_VOLUME_PARAMS) > InputBufferLength || 0 == SystemBuffer)
|
if (0 == SystemBuffer || sizeof(FSP_FSCTL_VOLUME_PARAMS) > InputBufferLength)
|
||||||
return STATUS_INVALID_PARAMETER;
|
return STATUS_INVALID_PARAMETER;
|
||||||
if (FSP_FSCTL_CREATE_BUFFER_SIZEMIN > OutputBufferLength)
|
if (FSP_FSCTL_CREATE_BUFFER_SIZEMIN > OutputBufferLength)
|
||||||
return STATUS_BUFFER_TOO_SMALL;
|
return STATUS_BUFFER_TOO_SMALL;
|
||||||
@ -368,7 +368,6 @@ static NTSTATUS FspFsctlTransact(
|
|||||||
{
|
{
|
||||||
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;
|
||||||
@ -381,29 +380,54 @@ static NTSTATUS FspFsctlTransact(
|
|||||||
return STATUS_BUFFER_TOO_SMALL;
|
return STATUS_BUFFER_TOO_SMALL;
|
||||||
|
|
||||||
NTSTATUS Result;
|
NTSTATUS Result;
|
||||||
FSP_FSVRT_DEVICE_EXTENSION *FsvrtDeviceExtension = FspFsvrtDeviceExtension(DeviceObject);
|
PDEVICE_OBJECT FsvolDeviceObject = 0;
|
||||||
PUINT8 SystemBufferEnd;
|
|
||||||
|
FSP_FSCTL_FILE_CONTEXT2 *FsContext2 = IrpSp->FileObject->FsContext2;
|
||||||
|
ExAcquireFastMutex(&FsContext2->FastMutex);
|
||||||
|
try
|
||||||
|
{
|
||||||
|
/* check to see if we already have a volume */
|
||||||
|
FsvolDeviceObject = FsContext2->FsvolDeviceObject;
|
||||||
|
if (0 != FsvolDeviceObject)
|
||||||
|
{
|
||||||
|
BOOLEAN Success; (VOID)Success;
|
||||||
|
|
||||||
|
/* this must succeed because our volume device exists until IRP_MJ_CLEANUP */
|
||||||
|
Success = FspDeviceRetain(FsvolDeviceObject);
|
||||||
|
ASSERT(Success);
|
||||||
|
|
||||||
|
Result = STATUS_SUCCESS;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
Result = STATUS_ACCESS_DENIED;
|
||||||
|
}
|
||||||
|
finally
|
||||||
|
{
|
||||||
|
ExReleaseFastMutex(&FsContext2->FastMutex);
|
||||||
|
}
|
||||||
|
if (!NT_SUCCESS(Result))
|
||||||
|
return Result;
|
||||||
|
|
||||||
|
FSP_FSVOL_DEVICE_EXTENSION *FsvolDeviceExtension = FspFsvolDeviceExtension(FsvolDeviceObject);
|
||||||
|
PVOID MdlBuffer;
|
||||||
|
PUINT8 BufferEnd;
|
||||||
FSP_FSCTL_TRANSACT_RSP *Response, *NextResponse;
|
FSP_FSCTL_TRANSACT_RSP *Response, *NextResponse;
|
||||||
FSP_FSCTL_TRANSACT_REQ *Request, *PendingIrpRequest;
|
FSP_FSCTL_TRANSACT_REQ *Request, *PendingIrpRequest;
|
||||||
PIRP ProcessIrp, PendingIrp;
|
PIRP ProcessIrp, PendingIrp;
|
||||||
LARGE_INTEGER Timeout;
|
LARGE_INTEGER Timeout;
|
||||||
|
|
||||||
/* access check */
|
try
|
||||||
Result = FspSecuritySubjectContextAccessCheck(
|
{
|
||||||
FsvrtDeviceExtension->SecurityDescriptorBuf, FILE_WRITE_DATA, Irp->RequestorMode);
|
|
||||||
if (!NT_SUCCESS(Result))
|
|
||||||
return Result;
|
|
||||||
|
|
||||||
/* process any user-mode file system responses */
|
/* process any user-mode file system responses */
|
||||||
Response = SystemBuffer;
|
Response = SystemBuffer;
|
||||||
SystemBufferEnd = (PUINT8)SystemBuffer + InputBufferLength;
|
BufferEnd = (PUINT8)SystemBuffer + InputBufferLength;
|
||||||
for (;;)
|
for (;;)
|
||||||
{
|
{
|
||||||
NextResponse = FspFsctlTransactConsumeResponse(Response, SystemBufferEnd);
|
NextResponse = FspFsctlTransactConsumeResponse(Response, BufferEnd);
|
||||||
if (0 == NextResponse)
|
if (0 == NextResponse)
|
||||||
break;
|
break;
|
||||||
|
|
||||||
ProcessIrp = FspIoqEndProcessingIrp(&FsvrtDeviceExtension->Ioq, (UINT_PTR)Response->Hint);
|
ProcessIrp = FspIoqEndProcessingIrp(&FsvolDeviceExtension->Ioq, (UINT_PTR)Response->Hint);
|
||||||
if (0 == ProcessIrp)
|
if (0 == ProcessIrp)
|
||||||
/* either IRP was canceled or a bogus Hint was provided */
|
/* either IRP was canceled or a bogus Hint was provided */
|
||||||
continue;
|
continue;
|
||||||
@ -413,25 +437,38 @@ static NTSTATUS FspFsctlTransact(
|
|||||||
Response = NextResponse;
|
Response = NextResponse;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* try to get a pointer to the output buffer */
|
||||||
|
MdlBuffer = MmGetSystemAddressForMdlSafe(Irp->MdlAddress, NormalPagePriority);
|
||||||
|
if (0 == MdlBuffer)
|
||||||
|
{
|
||||||
|
Irp->IoStatus.Information = 0;
|
||||||
|
Result = STATUS_SUCCESS;
|
||||||
|
goto exit;
|
||||||
|
}
|
||||||
|
|
||||||
/* wait for an IRP to arrive */
|
/* wait for an IRP to arrive */
|
||||||
KeQuerySystemTime(&Timeout);
|
KeQuerySystemTime(&Timeout);
|
||||||
Timeout.QuadPart += FsvrtDeviceExtension->VolumeParams.TransactTimeout * 10000;
|
Timeout.QuadPart += FsvolDeviceExtension->VolumeParams.TransactTimeout * 10000;
|
||||||
/* convert millis to nanos and add to absolute time */
|
/* convert millis to nanos and add to absolute time */
|
||||||
while (0 == (PendingIrp = FspIoqNextPendingIrp(&FsvrtDeviceExtension->Ioq, &Timeout)))
|
while (0 == (PendingIrp = FspIoqNextPendingIrp(&FsvolDeviceExtension->Ioq, &Timeout)))
|
||||||
{
|
{
|
||||||
if (FspIoqStopped(&FsvrtDeviceExtension->Ioq))
|
if (FspIoqStopped(&FsvolDeviceExtension->Ioq))
|
||||||
return STATUS_CANCELLED;
|
{
|
||||||
|
Result = STATUS_CANCELLED;
|
||||||
|
goto exit;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
if (FspIoqTimeout == PendingIrp)
|
if (FspIoqTimeout == PendingIrp)
|
||||||
{
|
{
|
||||||
Irp->IoStatus.Information = 0;
|
Irp->IoStatus.Information = 0;
|
||||||
return STATUS_SUCCESS;
|
Result = STATUS_SUCCESS;
|
||||||
|
goto exit;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* send any pending IRP's to the user-mode file system */
|
/* send any pending IRP's to the user-mode file system */
|
||||||
Request = SystemBuffer;
|
Request = MdlBuffer;
|
||||||
SystemBufferEnd = (PUINT8)SystemBuffer + OutputBufferLength;
|
BufferEnd = (PUINT8)MdlBuffer + OutputBufferLength;
|
||||||
ASSERT(FspFsctlTransactCanProduceRequest(Request, SystemBufferEnd));
|
ASSERT(FspFsctlTransactCanProduceRequest(Request, BufferEnd));
|
||||||
for (;;)
|
for (;;)
|
||||||
{
|
{
|
||||||
PendingIrpRequest = FspIrpRequest(PendingIrp);
|
PendingIrpRequest = FspIrpRequest(PendingIrp);
|
||||||
@ -444,7 +481,7 @@ static NTSTATUS FspFsctlTransact(
|
|||||||
RtlCopyMemory(Request, PendingIrpRequest, PendingIrpRequest->Size);
|
RtlCopyMemory(Request, PendingIrpRequest, PendingIrpRequest->Size);
|
||||||
Request = FspFsctlTransactProduceRequest(Request, PendingIrpRequest->Size);
|
Request = FspFsctlTransactProduceRequest(Request, PendingIrpRequest->Size);
|
||||||
|
|
||||||
if (!FspIoqStartProcessingIrp(&FsvrtDeviceExtension->Ioq, PendingIrp))
|
if (!FspIoqStartProcessingIrp(&FsvolDeviceExtension->Ioq, PendingIrp))
|
||||||
{
|
{
|
||||||
/*
|
/*
|
||||||
* This can only happen if the Ioq was stopped. Abandon everything
|
* This can only happen if the Ioq was stopped. Abandon everything
|
||||||
@ -452,28 +489,34 @@ static NTSTATUS FspFsctlTransact(
|
|||||||
* queues of the Ioq will be cancelled during FspIoqStop(). We must
|
* queues of the Ioq will be cancelled during FspIoqStop(). We must
|
||||||
* also cancel the PendingIrp we have in our hands.
|
* also cancel the PendingIrp we have in our hands.
|
||||||
*/
|
*/
|
||||||
ASSERT(FspIoqStopped(&FsvrtDeviceExtension->Ioq));
|
ASSERT(FspIoqStopped(&FsvolDeviceExtension->Ioq));
|
||||||
FspIopCompleteIrp(PendingIrp, STATUS_CANCELLED);
|
FspIopCompleteIrp(PendingIrp, STATUS_CANCELLED);
|
||||||
return STATUS_CANCELLED;
|
Result = STATUS_CANCELLED;
|
||||||
|
goto exit;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* check that we have enough space before pulling the next pending IRP off the queue */
|
/* check that we have enough space before pulling the next pending IRP off the queue */
|
||||||
if (!FspFsctlTransactCanProduceRequest(Request, SystemBufferEnd))
|
if (!FspFsctlTransactCanProduceRequest(Request, BufferEnd))
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
PendingIrp = FspIoqNextPendingIrp(&FsvrtDeviceExtension->Ioq, 0);
|
PendingIrp = FspIoqNextPendingIrp(&FsvolDeviceExtension->Ioq, 0);
|
||||||
if (0 == PendingIrp)
|
if (0 == PendingIrp)
|
||||||
break;
|
break;
|
||||||
|
|
||||||
}
|
}
|
||||||
Irp->IoStatus.Information = (PUINT8)Request - (PUINT8)SystemBuffer;
|
|
||||||
|
|
||||||
return STATUS_SUCCESS;
|
Irp->IoStatus.Information = (PUINT8)Request - (PUINT8)MdlBuffer;
|
||||||
|
Result = STATUS_SUCCESS;
|
||||||
|
|
||||||
#else
|
exit:;
|
||||||
return STATUS_INVALID_DEVICE_REQUEST;
|
}
|
||||||
#endif
|
finally
|
||||||
|
{
|
||||||
|
FspDeviceRelease(FsvolDeviceObject);
|
||||||
|
}
|
||||||
|
|
||||||
|
return Result;
|
||||||
}
|
}
|
||||||
|
|
||||||
static NTSTATUS FspFsvolFileSystemControl(
|
static NTSTATUS FspFsvolFileSystemControl(
|
||||||
|
Loading…
x
Reference in New Issue
Block a user