mirror of
				https://github.com/winfsp/winfsp.git
				synced 2025-11-03 20:48:08 -06:00 
			
		
		
		
	Major refactoring: WIP
This commit is contained in:
		@@ -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(
 | 
				
			||||||
 
 | 
				
			|||||||
		Reference in New Issue
	
	Block a user