From ab2dbf2a681c49e8564c73c619629c46dc600792 Mon Sep 17 00:00:00 2001 From: Alan Bateman Date: Thu, 6 Aug 2026 12:05:18 +0000 Subject: [PATCH] 8389112: (fs) BasicFileAttributes::isDirectory returns false for directory in OneDrive over SMB (win) Reviewed-by: jpai --- .../classes/sun/nio/fs/WindowsConstants.java | 3 ++ .../sun/nio/fs/WindowsFileAttributes.java | 54 ++++++++++++------- 2 files changed, 39 insertions(+), 18 deletions(-) diff --git a/src/java.base/windows/classes/sun/nio/fs/WindowsConstants.java b/src/java.base/windows/classes/sun/nio/fs/WindowsConstants.java index d8056f6f2fb..2c91bb01773 100644 --- a/src/java.base/windows/classes/sun/nio/fs/WindowsConstants.java +++ b/src/java.base/windows/classes/sun/nio/fs/WindowsConstants.java @@ -75,6 +75,9 @@ class WindowsConstants { public static final int IO_REPARSE_TAG_AF_UNIX = 0x80000023; public static final int IO_REPARSE_TAG_MOUNT_POINT = 0xA0000003; public static final int IO_REPARSE_TAG_SYMLINK = 0xA000000C; + public static final int IO_REPARSE_TAG_DEDUP = 0x80000013; + public static final int IO_REPARSE_TAG_CLOUD = 0x9000001A; + public static final int IO_REPARSE_TAG_CLOUD_MASK = 0x0000F000; public static final int MAXIMUM_REPARSE_DATA_BUFFER_SIZE = 16 * 1024; public static final int SYMBOLIC_LINK_FLAG_DIRECTORY = 0x1; public static final int SYMBOLIC_LINK_FLAG_ALLOW_UNPRIVILEGED_CREATE = 0x2; diff --git a/src/java.base/windows/classes/sun/nio/fs/WindowsFileAttributes.java b/src/java.base/windows/classes/sun/nio/fs/WindowsFileAttributes.java index 31ea68645ef..0b938bde54c 100644 --- a/src/java.base/windows/classes/sun/nio/fs/WindowsFileAttributes.java +++ b/src/java.base/windows/classes/sun/nio/fs/WindowsFileAttributes.java @@ -487,39 +487,57 @@ class WindowsFileAttributes } boolean isDirectoryLink() { - return isSymbolicLink() && ((fileAttrs & FILE_ATTRIBUTE_DIRECTORY) != 0); + return ((fileAttrs & FILE_ATTRIBUTE_DIRECTORY) != 0) + && isReparsePoint() + && (reparseTag == IO_REPARSE_TAG_SYMLINK); } boolean isDirectoryJunction() { - return reparseTag == IO_REPARSE_TAG_MOUNT_POINT; + return ((fileAttrs & FILE_ATTRIBUTE_DIRECTORY) != 0) + && isReparsePoint() + && (reparseTag == IO_REPARSE_TAG_MOUNT_POINT); + } + + boolean isUnixDomainSocket() { + return isReparsePoint() && (reparseTag == IO_REPARSE_TAG_AF_UNIX); } @Override public boolean isSymbolicLink() { - return reparseTag == IO_REPARSE_TAG_SYMLINK; - } - - boolean isUnixDomainSocket() { - return reparseTag == IO_REPARSE_TAG_AF_UNIX; + return isReparsePoint() && (reparseTag == IO_REPARSE_TAG_SYMLINK); } @Override public boolean isDirectory() { - return ((fileAttrs & FILE_ATTRIBUTE_DIRECTORY) != 0 && - (fileAttrs & FILE_ATTRIBUTE_REPARSE_POINT) == 0); - } - - @Override - public boolean isOther() { - if (isSymbolicLink()) - return false; - // return true if device or reparse point - return ((fileAttrs & (FILE_ATTRIBUTE_DEVICE | FILE_ATTRIBUTE_REPARSE_POINT)) != 0); + return ((fileAttrs & FILE_ATTRIBUTE_DIRECTORY) != 0) + && !isSymbolicLink() + && !isDirectoryJunction(); } @Override public boolean isRegularFile() { - return !isSymbolicLink() && !isDirectory() && !isOther(); + if ((fileAttrs & FILE_ATTRIBUTE_DIRECTORY) != 0) + return false; + if ((fileAttrs & FILE_ATTRIBUTE_DEVICE) != 0) + return false; + if (!isReparsePoint()) + return true; + + // deduplicated file + if (reparseTag == IO_REPARSE_TAG_DEDUP) + return true; + + // file in cloud storage (Microsoft defines a range of tags for this) + if ((reparseTag & ~IO_REPARSE_TAG_CLOUD_MASK) == IO_REPARSE_TAG_CLOUD) + return true; + + // socket file or other non-directory reparse point + return false; + } + + @Override + public boolean isOther() { + return !isRegularFile() && !isDirectory() && !isSymbolicLink(); } @Override