microsoft / ProjFS-Managed-API

A managed-code API for the Windows Projected File System
Other
142 stars 34 forks source link

DirectoryEnumerationResults.Add symlink override is incompatible with EnumerateFileSystemInfos on .NET Framework #81

Closed yerudako closed 2 years ago

yerudako commented 2 years ago

Context: Symlink support is being added in #73. The DirectoryEnumerationResults.Add method calls PrjFillDirEntryBuffer2 native API method. For certain environment/symlink combinations, such as ones in these tests, PrjFillDirEntryBuffer2 returns ERROR_INSUFFICIENT_BUFFER for the first enumeration element.

It is expected of the provider to return ERROR_INSUFFICIENT_BUFFER as a callback result if the error happened on the first enumeration element. SimpleManagedProvider is an example of a provider doing this according to the guidelines.

Issue: ERROR_INSUFFICIENT_BUFFER result coming from an enumeration callback is handled correctly in .NET Core, but not .NET Framework.

• Framework is using FindFirstFile()/FindNextFile(). There is no handling in the enumerator for buffer size results, in fact those functions’ doc pages do not discuss INSUFFICIENT_BUFFER as a possible result. • NetCore is using NtQueryDirectoryFile() and related APIs, using resizing buffers.

.NET Framework: directoryinfo.cs (microsoft.com) filesystemenumerable.cs (microsoft.com) .NET Core: FileSystemEnumerator.Windows: runtime/FileSystemEnumerator.Windows.cs· dotnet/runtime (github.com) FILE_FULL_DIR_INFORMATION derived from calling ntdll.dll : runtime/Interop.FILE_FULL_DIR_INFORMATION.cs dotnet/runtime (github.com)

Workaround: .NET Framework 4.8 clients should not use the Add override with the symlink target. If the symlink support is needed, .NET Core runtime could be used instead.

cgallred commented 2 years ago

This turned out to be a bug in the sample SimpleProvider application provoked by different behavior between .NET Framework and .NET Core. Clients of either version can use the Add override with the symlink target.