# HG changeset patch # User alanb # Date 1249026268 -3600 # Node ID 3dd3615c174857ff78396d45cc084684f8fd43f2 # Parent e3af585364e7bd586a0bf9a9a61fcb84f0602673 6867101: Path.checkAccess fails with sharing violation on special files such as pagefile.sys Reviewed-by: sherman diff -r e3af585364e7 -r 3dd3615c1748 jdk/src/windows/classes/sun/nio/fs/WindowsConstants.java --- a/jdk/src/windows/classes/sun/nio/fs/WindowsConstants.java Wed Jul 29 21:45:52 2009 -0700 +++ b/jdk/src/windows/classes/sun/nio/fs/WindowsConstants.java Fri Jul 31 08:44:28 2009 +0100 @@ -92,6 +92,7 @@ public static final int ERROR_INVALID_DATA = 13; public static final int ERROR_NOT_SAME_DEVICE = 17; public static final int ERROR_NOT_READY = 21; + public static final int ERROR_SHARING_VIOLATION = 32; public static final int ERROR_FILE_EXISTS = 80; public static final int ERROR_INVALID_PARAMATER = 87; public static final int ERROR_DISK_FULL = 112; diff -r e3af585364e7 -r 3dd3615c1748 jdk/src/windows/classes/sun/nio/fs/WindowsFileAttributes.java --- a/jdk/src/windows/classes/sun/nio/fs/WindowsFileAttributes.java Wed Jul 29 21:45:52 2009 -0700 +++ b/jdk/src/windows/classes/sun/nio/fs/WindowsFileAttributes.java Fri Jul 31 08:44:28 2009 +0100 @@ -299,6 +299,9 @@ throws WindowsException { if (!ensureAccurateMetadata) { + WindowsException firstException = null; + + // GetFileAttributesEx is the fastest way to read the attributes NativeBuffer buffer = NativeBuffers.getNativeBuffer(SIZEOF_FILE_ATTRIBUTE_DATA); try { @@ -310,9 +313,39 @@ .getInt(address + OFFSETOF_FILE_ATTRIBUTE_DATA_ATTRIBUTES); if ((fileAttrs & FILE_ATTRIBUTE_REPARSE_POINT) == 0) return fromFileAttributeData(address, 0); + } catch (WindowsException x) { + if (x.lastError() != ERROR_SHARING_VIOLATION) + throw x; + firstException = x; } finally { buffer.release(); } + + // For sharing violations, fallback to FindFirstFile if the file + // is not a root directory. + if (firstException != null) { + String search = path.getPathForWin32Calls(); + char last = search.charAt(search.length() -1); + if (last == ':' || last == '\\') + throw firstException; + buffer = getBufferForFindData(); + try { + long handle = FindFirstFile(search, buffer.address()); + FindClose(handle); + WindowsFileAttributes attrs = fromFindData(buffer.address()); + // FindFirstFile does not follow sym links. Even if + // followLinks is false, there isn't sufficient information + // in the WIN32_FIND_DATA structure to know if the reparse + // point is a sym link. + if (attrs.isReparsePoint()) + throw firstException; + return attrs; + } catch (WindowsException ignore) { + throw firstException; + } finally { + buffer.release(); + } + } } // file is reparse point so need to open file to get attributes diff -r e3af585364e7 -r 3dd3615c1748 jdk/test/java/nio/file/Path/Misc.java --- a/jdk/test/java/nio/file/Path/Misc.java Wed Jul 29 21:45:52 2009 -0700 +++ b/jdk/test/java/nio/file/Path/Misc.java Fri Jul 31 08:44:28 2009 +0100 @@ -22,7 +22,7 @@ */ /* @test - * @bug 4313887 6838333 + * @bug 4313887 6838333 6866804 * @summary Unit test for java.nio.file.Path for miscellenous methods not * covered by other tests * @library .. @@ -107,6 +107,28 @@ dir.checkAccess(AccessMode.READ, AccessMode.WRITE); /** + * Test: Check access to all files in all root directories. + * (A useful test on Windows for special files such as pagefile.sys) + */ + for (Path root: FileSystems.getDefault().getRootDirectories()) { + DirectoryStream stream; + try { + stream = root.newDirectoryStream(); + } catch (IOException x) { + continue; // skip root directories that aren't accessible + } + try { + for (Path entry: stream) { + try { + entry.checkAccess(); + } catch (AccessDeniedException ignore) { } + } + } finally { + stream.close(); + } + } + + /** * Test: File does not exist */ Path doesNotExist = dir.resolve("thisDoesNotExists");