6867101: Path.checkAccess fails with sharing violation on special files such as pagefile.sys
Reviewed-by: sherman
--- 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;
--- 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
--- 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<Path> 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");