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