diff --git a/inc/winfsp/fsctl.h b/inc/winfsp/fsctl.h index 1d05e760..7dfbc13c 100644 --- a/inc/winfsp/fsctl.h +++ b/inc/winfsp/fsctl.h @@ -63,6 +63,7 @@ extern const __declspec(selectany) GUID FspFsvrtDeviceClassGuid = #define FSP_FSCTL_TRANSACT_REQ_SIZEMAX (4096 - 64) /* 64: size for internal request header */ #define FSP_FSCTL_TRANSACT_RSP_SIZEMAX (4096 - 64) /* symmetry! */ +#define FSP_FSCTL_TRANSACT_RSP_BUFFER_SIZEMAX (FSP_FSCTL_TRANSACT_RSP_SIZEMAX - sizeof(FSP_FSCTL_TRANSACT_RSP)) #define FSP_FSCTL_TRANSACT_BATCH_BUFFER_SIZEMIN 16384 #define FSP_FSCTL_TRANSACT_BUFFER_SIZEMIN FSP_FSCTL_TRANSACT_REQ_SIZEMAX diff --git a/inc/winfsp/winfsp.h b/inc/winfsp/winfsp.h index a598ad54..e8d8969b 100644 --- a/inc/winfsp/winfsp.h +++ b/inc/winfsp/winfsp.h @@ -675,9 +675,9 @@ typedef struct _FSP_FILE_SYSTEM_INTERFACE * The name of the file or directory to have its reparse points resolved. * @param ReparsePointIndex * The index of the first reparse point within FileName. - * @param OpenReparsePoint - * If TRUE, the last path component of FileName should not be resolved, even - * if it is a reparse point that can be resolved. If FALSE, all path components + * @param ResolveLastPathComponent + * If FALSE, the last path component of FileName should not be resolved, even + * if it is a reparse point that can be resolved. If TRUE, all path components * should be resolved if possible. * @param PIoStatus * Pointer to storage that will receive the status to return to the FSD. When @@ -694,7 +694,7 @@ typedef struct _FSP_FILE_SYSTEM_INTERFACE * STATUS_REPARSE or error code. */ NTSTATUS (*ResolveReparsePoints)(FSP_FILE_SYSTEM *FileSystem, - PWSTR FileName, UINT32 ReparsePointIndex, BOOLEAN OpenReparsePoint, + PWSTR FileName, UINT32 ReparsePointIndex, BOOLEAN ResolveLastPathComponent, PIO_STATUS_BLOCK PIoStatus, PVOID Buffer, PSIZE_T PSize); /** * Get reparse point. @@ -1101,9 +1101,9 @@ FSP_API BOOLEAN FspFileSystemFindReparsePoint(FSP_FILE_SYSTEM *FileSystem, * The name of the file or directory to have its reparse points resolved. * @param ReparsePointIndex * The index of the first reparse point within FileName. - * @param OpenReparsePoint - * If TRUE, the last path component of FileName should not be resolved, even - * if it is a reparse point that can be resolved. If FALSE, all path components + * @param ResolveLastPathComponent + * If FALSE, the last path component of FileName should not be resolved, even + * if it is a reparse point that can be resolved. If TRUE, all path components * should be resolved if possible. * @param PIoStatus * Pointer to storage that will receive the status to return to the FSD. When @@ -1126,7 +1126,7 @@ FSP_API NTSTATUS FspFileSystemResolveReparsePoints(FSP_FILE_SYSTEM *FileSystem, FSP_FILE_SYSTEM *FileSystem, PVOID Context, PWSTR FileName, BOOLEAN IsDirectory, PVOID Buffer, PSIZE_T PSize), PVOID Context, - PWSTR FileName, UINT32 ReparsePointIndex, BOOLEAN OpenReparsePoint, + PWSTR FileName, UINT32 ReparsePointIndex, BOOLEAN ResolveLastPathComponent, PIO_STATUS_BLOCK PIoStatus, PVOID Buffer, PSIZE_T PSize); /** * Test whether reparse data can be replaced. diff --git a/src/dll/fsop.c b/src/dll/fsop.c index 7a1088bd..ff6a09a3 100644 --- a/src/dll/fsop.c +++ b/src/dll/fsop.c @@ -103,11 +103,11 @@ NTSTATUS FspFileSystemCallResolveReparsePoints(FSP_FILE_SYSTEM *FileSystem, if (0 != FileSystem->Interface->ResolveReparsePoints) { memset(&IoStatus, 0, sizeof IoStatus); - Size = FSP_FSCTL_TRANSACT_RSP_SIZEMAX - FIELD_OFFSET(FSP_FSCTL_TRANSACT_RSP, Buffer); + Size = FSP_FSCTL_TRANSACT_RSP_BUFFER_SIZEMAX; Result = FileSystem->Interface->ResolveReparsePoints(FileSystem, (PWSTR)Request->Buffer, ReparsePointIndex, - !!(Request->Req.Create.CreateOptions & FILE_OPEN_REPARSE_POINT), + !(Request->Req.Create.CreateOptions & FILE_OPEN_REPARSE_POINT), &IoStatus, Response->Buffer, &Size); @@ -116,6 +116,7 @@ NTSTATUS FspFileSystemCallResolveReparsePoints(FSP_FILE_SYSTEM *FileSystem, Result = STATUS_REPARSE; Response->IoStatus.Information = (UINT32)IoStatus.Information; + Response->Size = (UINT16)(sizeof *Response + Size); if (0/*IO_REPARSE*/ == IoStatus.Information) { Response->Rsp.Create.Reparse.FileName.Offset = 0; @@ -901,7 +902,7 @@ FSP_API NTSTATUS FspFileSystemOpFileSystemControl(FSP_FILE_SYSTEM *FileSystem, ReparseData = (PREPARSE_DATA_BUFFER)Response->Buffer; memset(ReparseData, 0, sizeof *ReparseData); - Size = FSP_FSCTL_TRANSACT_RSP_SIZEMAX - FIELD_OFFSET(FSP_FSCTL_TRANSACT_RSP, Buffer); + Size = FSP_FSCTL_TRANSACT_RSP_BUFFER_SIZEMAX; Result = FileSystem->Interface->GetReparsePoint(FileSystem, Request, (PVOID)Request->Req.FileSystemControl.UserContext, (PWSTR)Request->Buffer, ReparseData, &Size); @@ -1055,7 +1056,7 @@ FSP_API NTSTATUS FspFileSystemResolveReparsePoints(FSP_FILE_SYSTEM *FileSystem, FSP_FILE_SYSTEM *FileSystem, PVOID Context, PWSTR FileName, BOOLEAN IsDirectory, PVOID Buffer, PSIZE_T PSize), PVOID Context, - PWSTR FileName, UINT32 ReparsePointIndex, BOOLEAN OpenReparsePoint, + PWSTR FileName, UINT32 ReparsePointIndex, BOOLEAN ResolveLastPathComponent, PIO_STATUS_BLOCK PIoStatus, PVOID Buffer, PSIZE_T PSize) { WCHAR c, *p, *lastp; @@ -1090,9 +1091,9 @@ FSP_API NTSTATUS FspFileSystemResolveReparsePoints(FSP_FILE_SYSTEM *FileSystem, { if (L'\0' == *p) { - if (!OpenReparsePoint) + if (!ResolveLastPathComponent) goto exit; - OpenReparsePoint = FALSE; + ResolveLastPathComponent = FALSE; break; } p++; @@ -1157,7 +1158,7 @@ FSP_API NTSTATUS FspFileSystemResolveReparsePoints(FSP_FILE_SYSTEM *FileSystem, { /* not a symlink; return the full reparse point! */ if (Size > *PSize) - return STATUS_OBJECT_NAME_INVALID; + return STATUS_IO_REPARSE_DATA_INVALID; memcpy(Buffer, ReparseData, Size); goto no_symlink_exit; diff --git a/src/dll/fuse/fuse_intf.c b/src/dll/fuse/fuse_intf.c index 6db17c1f..e757a017 100644 --- a/src/dll/fuse/fuse_intf.c +++ b/src/dll/fuse/fuse_intf.c @@ -1877,11 +1877,11 @@ exit: } static NTSTATUS fsp_fuse_intf_ResolveReparsePoints(FSP_FILE_SYSTEM *FileSystem, - PWSTR FileName, UINT32 ReparsePointIndex, BOOLEAN OpenReparsePoint, + PWSTR FileName, UINT32 ReparsePointIndex, BOOLEAN ResolveLastPathComponent, PIO_STATUS_BLOCK PIoStatus, PVOID Buffer, PSIZE_T PSize) { return FspFileSystemResolveReparsePoints(FileSystem, fsp_fuse_intf_GetReparsePointByName, 0, - FileName, ReparsePointIndex, OpenReparsePoint, + FileName, ReparsePointIndex, ResolveLastPathComponent, PIoStatus, Buffer, PSize); } diff --git a/src/sys/iop.c b/src/sys/iop.c index cdc1f68f..ec562c2b 100644 --- a/src/sys/iop.c +++ b/src/sys/iop.c @@ -227,7 +227,7 @@ VOID FspIopCompleteIrpEx(PIRP Irp, NTSTATUS Result, BOOLEAN DeviceDereference) /* get the device object out of the IRP before completion */ PDEVICE_OBJECT DeviceObject = IoGetCurrentIrpStackLocation(Irp)->DeviceObject; - if (STATUS_SUCCESS != Result && STATUS_BUFFER_OVERFLOW != Result) + if (STATUS_SUCCESS != Result && STATUS_REPARSE != Result && STATUS_BUFFER_OVERFLOW != Result) Irp->IoStatus.Information = 0; Irp->IoStatus.Status = Result; IoCompleteRequest(Irp, FSP_IO_INCREMENT); diff --git a/tst/memfs/memfs.cpp b/tst/memfs/memfs.cpp index 487cf815..25d6a28d 100644 --- a/tst/memfs/memfs.cpp +++ b/tst/memfs/memfs.cpp @@ -945,11 +945,11 @@ static NTSTATUS ReadDirectory(FSP_FILE_SYSTEM *FileSystem, } static NTSTATUS ResolveReparsePoints(FSP_FILE_SYSTEM *FileSystem, - PWSTR FileName, UINT32 ReparsePointIndex, BOOLEAN OpenReparsePoint, + PWSTR FileName, UINT32 ReparsePointIndex, BOOLEAN ResolveLastPathComponent, PIO_STATUS_BLOCK PIoStatus, PVOID Buffer, PSIZE_T PSize) { return FspFileSystemResolveReparsePoints(FileSystem, GetReparsePointByName, 0, - FileName, ReparsePointIndex, OpenReparsePoint, + FileName, ReparsePointIndex, ResolveLastPathComponent, PIoStatus, Buffer, PSize); }