diff --git a/src/sys/device.c b/src/sys/device.c index 353ad298..0a26cdb4 100644 --- a/src/sys/device.c +++ b/src/sys/device.c @@ -635,7 +635,8 @@ PVOID FspFsvolDeviceEnumerateContextByName(PDEVICE_OBJECT DeviceObject, PUNICODE if (0 != Result && FspFileNameIsPrefix(FileName, Result->FileName, CaseInsensitive, 0) && FileName->Length < Result->FileName->Length && - '\\' == Result->FileName->Buffer[FileName->Length / sizeof(WCHAR)]) + (L'\\' == Result->FileName->Buffer[FileName->Length / sizeof(WCHAR)] || + L':' == Result->FileName->Buffer[FileName->Length / sizeof(WCHAR)])) return Result->Context; else return 0; diff --git a/src/sys/file.c b/src/sys/file.c index 963fce61..b6245ce4 100644 --- a/src/sys/file.c +++ b/src/sys/file.c @@ -1033,7 +1033,7 @@ VOID FspFileNodeRename(FSP_FILE_NODE *FileNode, PUNICODE_STRING NewFileName) FSP_FILE_NODE *DescendantFileNodeArray[16], **DescendantFileNodes; ULONG DescendantFileNodeCount, DescendantFileNodeIndex; FSP_DEVICE_CONTEXT_BY_NAME_TABLE_RESTART_KEY RestartKey; - BOOLEAN Deleted, Inserted; + BOOLEAN Deleted, Inserted, AcquireForeign; USHORT FileNameLength; PWSTR ExternalFileName; @@ -1085,7 +1085,9 @@ VOID FspFileNodeRename(FSP_FILE_NODE *FileNode, PUNICODE_STRING NewFileName) DescendantFileNode = DescendantFileNodes[DescendantFileNodeIndex]; ASSERT(DescendantFileNode->FileName.Length >= FileNameLength); - if (0 != DescendantFileNodeIndex) + AcquireForeign = DescendantFileNode->FileName.Length > FileNameLength && + L'\\' == DescendantFileNode->FileName.Buffer[FileNameLength / sizeof(WCHAR)]; + if (AcquireForeign) FspFileNodeAcquireExclusiveForeign(DescendantFileNode); FspFsvolDeviceDeleteContextByName(FsvolDeviceObject, &DescendantFileNode->FileName, &Deleted); @@ -1115,7 +1117,7 @@ VOID FspFileNodeRename(FSP_FILE_NODE *FileNode, PUNICODE_STRING NewFileName) &DescendantFileNode->ContextByNameElementStorage, &Inserted); ASSERT(Inserted); - if (0 != DescendantFileNodeIndex) + if (AcquireForeign) FspFileNodeReleaseForeign(DescendantFileNode); } diff --git a/tst/winfsp-tests/stream-tests.c b/tst/winfsp-tests/stream-tests.c index 4f85294d..947d35d2 100644 --- a/tst/winfsp-tests/stream-tests.c +++ b/tst/winfsp-tests/stream-tests.c @@ -1393,7 +1393,7 @@ static void stream_rename_flipflop_dotest(ULONG Flags, PWSTR Prefix, ULONG FileI { void *memfs = memfs_start_ex(Flags, FileInfoTimeout); - HANDLE Handle, Mappings[80]; + HANDLE Handle, Mappings[80], DirStreamMapping; BOOL Success; WCHAR FilePath[MAX_PATH]; WCHAR FilePath2[MAX_PATH]; @@ -1408,6 +1408,16 @@ static void stream_rename_flipflop_dotest(ULONG Flags, PWSTR Prefix, ULONG FileI Success = CreateDirectoryW(FilePath, 0); ASSERT(Success); + StringCbPrintfW(FilePath, sizeof FilePath, L"%s%s\\short:dirstrm", + Prefix ? L"" : L"\\\\?\\GLOBALROOT", Prefix ? Prefix : memfs_volumename(memfs)); + Handle = CreateFileW(FilePath, GENERIC_ALL, 0, 0, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, 0); + ASSERT(INVALID_HANDLE_VALUE != Handle); + DirStreamMapping = CreateFileMappingW(Handle, 0, PAGE_READWRITE, + 0, SystemInfo.dwAllocationGranularity, 0); + ASSERT(0 != DirStreamMapping); + Success = CloseHandle(Handle); + ASSERT(Success); + StringCbPrintfW(FilePath, sizeof FilePath, L"%s%s\\short\\subdir", Prefix ? L"" : L"\\\\?\\GLOBALROOT", Prefix ? Prefix : memfs_volumename(memfs)); Success = CreateDirectoryW(FilePath, 0); @@ -1452,6 +1462,9 @@ static void stream_rename_flipflop_dotest(ULONG Flags, PWSTR Prefix, ULONG FileI ASSERT(Success); } + Success = CloseHandle(DirStreamMapping); + ASSERT(Success); + for (ULONG j = 1; NumMappings >= j; j++) { if (NumMappings / 2 >= j)