diff --git a/src/dll/fsop.c b/src/dll/fsop.c index 99644cca..7a1088bd 100644 --- a/src/dll/fsop.c +++ b/src/dll/fsop.c @@ -906,7 +906,11 @@ FSP_API NTSTATUS FspFileSystemOpFileSystemControl(FSP_FILE_SYSTEM *FileSystem, (PVOID)Request->Req.FileSystemControl.UserContext, (PWSTR)Request->Buffer, ReparseData, &Size); if (NT_SUCCESS(Result)) + { + Response->Size = (UINT16)(sizeof *Response + Size); + Response->Rsp.FileSystemControl.Buffer.Offset = 0; Response->Rsp.FileSystemControl.Buffer.Size = (UINT16)Size; + } } break; case FSCTL_SET_REPARSE_POINT: @@ -937,7 +941,7 @@ FSP_API NTSTATUS FspFileSystemOpFileSystemControl(FSP_FILE_SYSTEM *FileSystem, break; } - return STATUS_SUCCESS; + return Result; } FSP_API NTSTATUS FspFileSystemOpQuerySecurity(FSP_FILE_SYSTEM *FileSystem, diff --git a/src/sys/fsctl.c b/src/sys/fsctl.c index 1728b036..86fe7839 100644 --- a/src/sys/fsctl.c +++ b/src/sys/fsctl.c @@ -174,24 +174,24 @@ static NTSTATUS FspFsvolFileSystemControlReparsePoint( ; } } + + FspFileNodeAcquireExclusive(FileNode, Full); } else { - if (0 != InputBuffer || 0 != InputBufferLength || - 0 == OutputBuffer || 0 == OutputBufferLength) + if (0 == OutputBuffer || 0 == OutputBufferLength) return STATUS_INVALID_PARAMETER; - Result = FspBufferUserBuffer(Irp, OutputBufferLength, IoWriteAccess); - if (!NT_SUCCESS(Result)) - return Result; + /* + * NtFsControlFile (IopXxxControlFile) will setup Irp->AssociatedIrp.SystemBuffer + * with enough space for either InputBufferLength or OutputBufferLength. There is + * no need to call FspBufferUserBuffer ourselves. + */ + + FspFileNodeAcquireShared(FileNode, Full); } - if (IsWrite) - FspFileNodeAcquireExclusive(FileNode, Full); - else - FspFileNodeAcquireShared(FileNode, Full); - - Result = FspIopCreateRequestEx(Irp, &FileNode->FileName, InputBufferLength, + Result = FspIopCreateRequestEx(Irp, &FileNode->FileName, IsWrite ? InputBufferLength : 0, FspFsvolFileSystemControlRequestFini, &Request); if (!NT_SUCCESS(Result)) { @@ -225,12 +225,12 @@ static NTSTATUS FspFsvolFileSystemControlReparsePointComplete( { PAGED_CODE(); - if (!IsWrite) + if (IsWrite) return STATUS_SUCCESS; NTSTATUS Result; PIO_STACK_LOCATION IrpSp = IoGetCurrentIrpStackLocation(Irp); - PVOID OutputBuffer = Irp->AssociatedIrp.SystemBuffer; /* see FspBufferUserBuffer call */ + PVOID OutputBuffer = Irp->AssociatedIrp.SystemBuffer; ULONG OutputBufferLength = IrpSp->Parameters.FileSystemControl.OutputBufferLength; if (Response->Buffer + Response->Rsp.FileSystemControl.Buffer.Offset + @@ -302,6 +302,7 @@ NTSTATUS FspFsvolFileSystemControlComplete( FSP_FILE_NODE *FileNode = FileObject->FsContext; FSP_FSCTL_TRANSACT_REQ *Request = FspIrpRequest(Irp); + Result = STATUS_INVALID_DEVICE_REQUEST; switch (IrpSp->MinorFunction) { case IRP_MN_USER_FS_REQUEST: @@ -314,18 +315,12 @@ NTSTATUS FspFsvolFileSystemControlComplete( case FSCTL_DELETE_REPARSE_POINT: Result = FspFsvolFileSystemControlReparsePointComplete(Irp, Response, TRUE); break; - default: - ASSERT(0); - Result = STATUS_INVALID_PARAMETER; - break; } break; - default: - ASSERT(0); - Result = STATUS_INVALID_PARAMETER; - break; } + ASSERT(STATUS_INVALID_DEVICE_REQUEST != Result); + FspIopRequestContext(Request, RequestFileNode) = 0; FspFileNodeReleaseOwner(FileNode, Full, Request);