diff --git a/src/dll/fsop.c b/src/dll/fsop.c index 2e8163f5..91f30b72 100644 --- a/src/dll/fsop.c +++ b/src/dll/fsop.c @@ -1139,11 +1139,16 @@ static NTSTATUS FspFileSystemOpQueryDirectory_GetDirInfoByName(FSP_FILE_SYSTEM * { Result = FileSystem->Interface->GetDirInfoByName(FileSystem, FileContext, FileName, DirInfo); - if (!NT_SUCCESS(Result)) - return Result; - - if (FspFileSystemAddDirInfo(DirInfo, Buffer, Length, PBytesTransferred)) + if (NT_SUCCESS(Result)) + { + if (FspFileSystemAddDirInfo(DirInfo, Buffer, Length, PBytesTransferred)) + FspFileSystemAddDirInfo(0, Buffer, Length, PBytesTransferred); + } + else if (STATUS_OBJECT_NAME_NOT_FOUND == Result) + { + Result = STATUS_SUCCESS; FspFileSystemAddDirInfo(0, Buffer, Length, PBytesTransferred); + } } else { diff --git a/tst/memfs/memfs.cpp b/tst/memfs/memfs.cpp index 1b67310e..b54bab0e 100644 --- a/tst/memfs/memfs.cpp +++ b/tst/memfs/memfs.cpp @@ -42,6 +42,11 @@ FSP_FSCTL_STATIC_ASSERT(MEMFS_MAX_PATH > MAX_PATH, */ #define MEMFS_NAMED_STREAMS +/* + * Define the MEMFS_DIRINFO_BY_NAME macro to include GetDirInfoByName. + */ +#define MEMFS_DIRINFO_BY_NAME + /* * Define the DEBUG_BUFFER_CHECK macro on Windows 8 or above. This includes * a check for the Write buffer to ensure that it is read-only. @@ -1443,6 +1448,48 @@ static NTSTATUS ReadDirectory(FSP_FILE_SYSTEM *FileSystem, return STATUS_SUCCESS; } +#if defined(MEMFS_DIRINFO_BY_NAME) +static NTSTATUS GetDirInfoByName(FSP_FILE_SYSTEM *FileSystem, + PVOID ParentNode0, PWSTR FileName, + FSP_FSCTL_DIR_INFO *DirInfo) +{ + MEMFS *Memfs = (MEMFS *)FileSystem->UserContext; + MEMFS_FILE_NODE *ParentNode = (MEMFS_FILE_NODE *)ParentNode0; + MEMFS_FILE_NODE *FileNode; + WCHAR FileNameBuf[MEMFS_MAX_PATH]; + size_t ParentLength, BSlashLength, FileNameLength; + WCHAR Root[2] = L"\\"; + PWSTR Remain, Suffix; + + ParentLength = wcslen(ParentNode->FileName); + BSlashLength = 1 < ParentLength; + FileNameLength = wcslen(FileName); + if (MEMFS_MAX_PATH <= ParentLength + BSlashLength + FileNameLength) + return STATUS_OBJECT_NAME_NOT_FOUND; //STATUS_OBJECT_NAME_INVALID? + + memcpy(FileNameBuf, ParentNode->FileName, ParentLength * sizeof(WCHAR)); + memcpy(FileNameBuf + ParentLength, L"\\", BSlashLength * sizeof(WCHAR)); + memcpy(FileNameBuf + ParentLength + BSlashLength, FileName, (FileNameLength + 1) * sizeof(WCHAR)); + + FileName = FileNameBuf; + + FileNode = MemfsFileNodeMapGet(Memfs->FileNodeMap, FileName); + if (0 == FileNode) + return STATUS_OBJECT_NAME_NOT_FOUND; + + FspPathSuffix(FileNode->FileName, &Remain, &Suffix, Root); + FileName = Suffix; + FspPathCombine(FileNode->FileName, Suffix); + + //memset(DirInfo->Padding, 0, sizeof DirInfo->Padding); + DirInfo->Size = (UINT16)(sizeof(FSP_FSCTL_DIR_INFO) + wcslen(FileName) * sizeof(WCHAR)); + DirInfo->FileInfo = FileNode->FileInfo; + memcpy(DirInfo->FileNameBuf, FileName, DirInfo->Size - sizeof(FSP_FSCTL_DIR_INFO)); + + return STATUS_SUCCESS; +} +#endif + #if defined(MEMFS_REPARSE_POINTS) static NTSTATUS ResolveReparsePoints(FSP_FILE_SYSTEM *FileSystem, PWSTR FileName, UINT32 ReparsePointIndex, BOOLEAN ResolveLastPathComponent, @@ -1683,6 +1730,11 @@ static FSP_FILE_SYSTEM_INTERFACE MemfsInterface = #else 0, #endif +#if defined(MEMFS_DIRINFO_BY_NAME) + GetDirInfoByName, +#else + 0, +#endif }; /* @@ -1759,6 +1811,9 @@ NTSTATUS MemfsCreateFunnel( VolumeParams.NamedStreams = 1; #endif VolumeParams.PostCleanupWhenModifiedOnly = 1; +#if defined(MEMFS_DIRINFO_BY_NAME) + VolumeParams.PassQueryDirectoryFileName = 1; +#endif if (0 != VolumePrefix) wcscpy_s(VolumeParams.Prefix, sizeof VolumeParams.Prefix / sizeof(WCHAR), VolumePrefix); wcscpy_s(VolumeParams.FileSystemName, sizeof VolumeParams.FileSystemName / sizeof(WCHAR),