diff --git a/src/dll/fuse/fuse.c b/src/dll/fuse/fuse.c index 6b3e90b0..3079ced6 100644 --- a/src/dll/fuse/fuse.c +++ b/src/dll/fuse/fuse.c @@ -603,12 +603,14 @@ FSP_FUSE_API struct fuse *fsp_fuse_new(struct fsp_fuse_env *env, if (!opt_data.set_FileInfoTimeout && opt_data.set_attr_timeout) opt_data.VolumeParams.FileInfoTimeout = opt_data.set_attr_timeout * 1000; opt_data.VolumeParams.CaseSensitiveSearch = TRUE; + opt_data.VolumeParams.CasePreservedNames = TRUE; opt_data.VolumeParams.PersistentAcls = TRUE; opt_data.VolumeParams.ReparsePoints = TRUE; opt_data.VolumeParams.ReparsePointsAccessCheck = FALSE; opt_data.VolumeParams.NamedStreams = FALSE; opt_data.VolumeParams.ReadOnlyVolume = FALSE; opt_data.VolumeParams.PostCleanupWhenModifiedOnly = TRUE; + opt_data.VolumeParams.PassQueryDirectoryFileName = TRUE; opt_data.VolumeParams.UmFileContextIsUserContext2 = TRUE; if (L'\0' == opt_data.VolumeParams.FileSystemName[0]) memcpy(opt_data.VolumeParams.FileSystemName, L"FUSE", 5 * sizeof(WCHAR)); diff --git a/src/dll/fuse/fuse_intf.c b/src/dll/fuse/fuse_intf.c index 4f5b6b92..a901ccc6 100644 --- a/src/dll/fuse/fuse_intf.c +++ b/src/dll/fuse/fuse_intf.c @@ -1757,6 +1757,63 @@ static NTSTATUS fsp_fuse_intf_ReadDirectory(FSP_FILE_SYSTEM *FileSystem, return STATUS_SUCCESS; } +static NTSTATUS fsp_fuse_intf_GetDirInfoByName(FSP_FILE_SYSTEM *FileSystem, + PVOID FileNode, PWSTR FileName, + FSP_FSCTL_DIR_INFO *DirInfo) +{ + struct fuse *f = FileSystem->UserContext; + struct fsp_fuse_file_desc *filedesc = FileNode; + char *PosixName = 0; + char PosixPath[FSP_FSCTL_TRANSACT_PATH_SIZEMAX / sizeof(WCHAR)]; + int ParentLength, FSlashLength, PosixNameLength; + UINT32 Uid, Gid, Mode; + NTSTATUS Result; + + Result = FspPosixMapWindowsToPosixPath(FileName, &PosixName); + if (!NT_SUCCESS(Result)) + { + Result = STATUS_OBJECT_NAME_NOT_FOUND; //Result? + goto exit; + } + + ParentLength = lstrlenA(filedesc->PosixPath); + FSlashLength = 1 < ParentLength; + PosixNameLength = lstrlenA(PosixName); + if (FSP_FSCTL_TRANSACT_PATH_SIZEMAX <= (ParentLength + FSlashLength + PosixNameLength) * sizeof(WCHAR)) + { + Result = STATUS_OBJECT_NAME_NOT_FOUND; //STATUS_OBJECT_NAME_INVALID? + goto exit; + } + + memcpy(PosixPath, filedesc->PosixPath, ParentLength); + memcpy(PosixPath + ParentLength, "/", FSlashLength); + memcpy(PosixPath + ParentLength + FSlashLength, PosixName, PosixNameLength + 1); + + Result = fsp_fuse_intf_GetFileInfoEx(FileSystem, PosixPath, 0, + &Uid, &Gid, &Mode, &DirInfo->FileInfo); + if (!NT_SUCCESS(Result)) + { + Result = STATUS_OBJECT_NAME_NOT_FOUND; //Result? + goto exit; + } + + /* + * FUSE does not do FileName normalization; so just return the FileName as given to us! + */ + + //memset(DirInfo->Padding, 0, sizeof DirInfo->Padding); + DirInfo->Size = (UINT16)(sizeof(FSP_FSCTL_DIR_INFO) + lstrlenW(FileName) * sizeof(WCHAR)); + memcpy(DirInfo->FileNameBuf, FileName, DirInfo->Size - sizeof(FSP_FSCTL_DIR_INFO)); + + Result = STATUS_SUCCESS; + +exit: + if (0 != PosixName) + FspPosixDeletePath(PosixName); + + return Result; +} + static NTSTATUS fsp_fuse_intf_ResolveReparsePoints(FSP_FILE_SYSTEM *FileSystem, PWSTR FileName, UINT32 ReparsePointIndex, BOOLEAN ResolveLastPathComponent, PIO_STATUS_BLOCK PIoStatus, PVOID Buffer, PSIZE_T PSize) @@ -2030,6 +2087,8 @@ FSP_FILE_SYSTEM_INTERFACE fsp_fuse_intf = fsp_fuse_intf_GetReparsePoint, fsp_fuse_intf_SetReparsePoint, fsp_fuse_intf_DeleteReparsePoint, + 0, + fsp_fuse_intf_GetDirInfoByName, }; /*