diff --git a/inc/winfsp/winfsp.h b/inc/winfsp/winfsp.h index 0101f87c..e6b92fb8 100644 --- a/inc/winfsp/winfsp.h +++ b/inc/winfsp/winfsp.h @@ -600,7 +600,8 @@ typedef struct _FSP_FILE_SYSTEM_INTERFACE * Offset within the directory to read from. The kernel does not interpret this value * which is used solely by the file system to locate directory entries. However the * special value 0 indicates that the read should start from the first entries. The first - * two entries returned by ReadDirectory should always be the "." and ".." entries. + * two entries returned by ReadDirectory should always be the "." and ".." entries, + * except for the root directory which does not have these entries. * @param Length * Length of data to read. * @param Pattern diff --git a/src/dll/fuse/fuse_intf.c b/src/dll/fuse/fuse_intf.c index d137f3ea..2ad4eef8 100644 --- a/src/dll/fuse/fuse_intf.c +++ b/src/dll/fuse/fuse_intf.c @@ -1735,6 +1735,15 @@ static NTSTATUS fsp_fuse_intf_ReadDirectory(FSP_FILE_SYSTEM *FileSystem, if (sizeof(struct fsp_fuse_dirinfo) > di->Size) break; + if ('/' == filedesc->PosixPath[0] && '\0' == filedesc->PosixPath[1]) + { + /* if this is the root directory do not add the dot entries */ + + if ('.' == di->PosixNameBuf[0] && ('\0' == di->PosixNameBuf[1] || + ('.' == di->PosixNameBuf[1] && '\0' == di->PosixNameBuf[2]))) + continue; + } + if (!di->FileInfoValid) { if (0 == PosixPath) diff --git a/tst/memfs/memfs.cpp b/tst/memfs/memfs.cpp index 3c1ad48e..bd257acc 100644 --- a/tst/memfs/memfs.cpp +++ b/tst/memfs/memfs.cpp @@ -1150,15 +1150,20 @@ static NTSTATUS ReadDirectory(FSP_FILE_SYSTEM *FileSystem, Context.PBytesTransferred = PBytesTransferred; Context.OffsetFound = FALSE; - if (0 == Offset) - if (!AddDirInfo(FileNode, L".", Buffer, Length, PBytesTransferred)) - return STATUS_SUCCESS; - if (0 == Offset || FileNode->FileInfo.IndexNumber == Offset) + if (L'\0' != FileNode->FileName[1]) { - Context.OffsetFound = FileNode->FileInfo.IndexNumber == Context.Offset; + /* if this is not the root directory add the dot entries */ - if (!AddDirInfo(ParentNode, L"..", Buffer, Length, PBytesTransferred)) - return STATUS_SUCCESS; + if (0 == Offset) + if (!AddDirInfo(FileNode, L".", Buffer, Length, PBytesTransferred)) + return STATUS_SUCCESS; + if (0 == Offset || FileNode->FileInfo.IndexNumber == Offset) + { + Context.OffsetFound = FileNode->FileInfo.IndexNumber == Context.Offset; + + if (!AddDirInfo(ParentNode, L"..", Buffer, Length, PBytesTransferred)) + return STATUS_SUCCESS; + } } if (MemfsFileNodeMapEnumerateChildren(Memfs->FileNodeMap, FileNode, ReadDirectoryEnumFn, &Context)) diff --git a/tst/winfsp-tests/dirctl-test.c b/tst/winfsp-tests/dirctl-test.c index fb36a3f9..3c4df4b0 100644 --- a/tst/winfsp-tests/dirctl-test.c +++ b/tst/winfsp-tests/dirctl-test.c @@ -48,6 +48,33 @@ static void querydir_dotest(ULONG Flags, PWSTR Prefix, ULONG FileInfoTimeout, UL DWORD times[2]; times[0] = GetTickCount(); + if (-1 != Flags) + { + StringCbPrintfW(FilePath, sizeof FilePath, L"%s%s\\*", + Prefix ? L"" : L"\\\\?\\GLOBALROOT", Prefix ? Prefix : memfs_volumename(memfs)); + Handle = FindFirstFileW(FilePath, &FindData); + ASSERT(INVALID_HANDLE_VALUE != Handle); + + FileCount = 0; + do + { + ASSERT( + 0 == mywcscmp(FindData.cFileName, 4, L"file", 4) || + 0 == mywcscmp(FindData.cFileName, 3, L"dir", 3)); + + FileCount++; + + if (0 < SleepTimeout && 5 == FileCount) + Sleep(SleepTimeout); + } while (FindNextFileW(Handle, &FindData)); + ASSERT(ERROR_NO_MORE_FILES == GetLastError()); + + ASSERT(110 == FileCount); + + Success = FindClose(Handle); + ASSERT(Success); + } + StringCbPrintfW(FilePath, sizeof FilePath, L"%s%s\\dir5\\*", Prefix ? L"" : L"\\\\?\\GLOBALROOT", Prefix ? Prefix : memfs_volumename(memfs)); Handle = FindFirstFileW(FilePath, &FindData);