Skip to content
Open
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -336,6 +336,11 @@ internal FileHandleType GetFileTypeCore()
{
Interop.Kernel32.FileTypes.FILE_TYPE_CHAR => FileHandleType.CharacterDevice,
Interop.Kernel32.FileTypes.FILE_TYPE_PIPE => GetPipeOrSocketType(),
// GetFileType can return FILE_TYPE_DISK for regular files, directories and symbolic links.
// However, when Path is not null, it means that the handle was created by SafeFileHandle.Open
// which does not allow opening directories or symbolic links (it resolves them).
// That is why we can skip the extra check performed by GetDiskBasedType.
Interop.Kernel32.FileTypes.FILE_TYPE_DISK when Path is not null => FileHandleType.RegularFile,
Comment on lines +341 to +343
Copy link

Copilot AI Mar 19, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The new fast-path assumes Path is not null implies the handle can't be a directory or a symlink, but SafeFileHandle.Open passes through FileOptions and FileStreamHelpers.ValidateArguments explicitly allows (FileOptions)0x02000000 (FILE_FLAG_BACKUP_SEMANTICS). With that flag, CreateFile can successfully open directory handles while still setting _path, so this switch arm would misclassify such handles as RegularFile (making Type/CanSeek incorrect). Consider narrowing the fast-path to cases where FILE_FLAG_BACKUP_SEMANTICS is not set (or otherwise proving directories can’t be opened) and adjust the comment accordingly.

Suggested change
// which does not allow opening directories or symbolic links (it resolves them).
// That is why we can skip the extra check performed by GetDiskBasedType.
Interop.Kernel32.FileTypes.FILE_TYPE_DISK when Path is not null => FileHandleType.RegularFile,
// which does not allow opening directories or symbolic links (it resolves them) unless
// FILE_FLAG_BACKUP_SEMANTICS (0x02000000) is specified in FileOptions to allow opening directories.
// When backup semantics are not used, we can skip the extra check performed by GetDiskBasedType.
Interop.Kernel32.FileTypes.FILE_TYPE_DISK when Path is not null && (GetFileOptions() & (FileOptions)0x02000000) == 0 => FileHandleType.RegularFile,

Copilot uses AI. Check for mistakes.
Interop.Kernel32.FileTypes.FILE_TYPE_DISK => GetDiskBasedType(),
_ => FileHandleType.Unknown
};
Expand Down
Loading