diff --git a/jdk/make/java/java/Makefile b/jdk/make/java/java/Makefile index 6693a8224b7..b2d1c5ab091 100644 --- a/jdk/make/java/java/Makefile +++ b/jdk/make/java/java/Makefile @@ -1,5 +1,5 @@ # -# Copyright (c) 1997, 2011, Oracle and/or its affiliates. All rights reserved. +# Copyright (c) 1997, 2012, Oracle and/or its affiliates. All rights reserved. # DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. # # This code is free software; you can redistribute it and/or modify it @@ -64,13 +64,11 @@ include FILES_java.gmk include Exportedfiles.gmk ifeq ($(PLATFORM),windows) -FILES_java += java/io/Win32FileSystem.java \ - java/io/WinNTFileSystem.java \ +FILES_java += java/io/WinNTFileSystem.java \ java/util/prefs/WindowsPreferences.java \ java/util/prefs/WindowsPreferencesFactory.java FILES_c += ProcessImpl_md.c \ - Win32FileSystem_md.c \ WinNTFileSystem_md.c \ canonicalize_md.c \ dirent_md.c \ diff --git a/jdk/makefiles/CompileNativeLibraries.gmk b/jdk/makefiles/CompileNativeLibraries.gmk index 5a3be46cb22..4962b40a2f1 100644 --- a/jdk/makefiles/CompileNativeLibraries.gmk +++ b/jdk/makefiles/CompileNativeLibraries.gmk @@ -209,7 +209,6 @@ ifeq ($(OPENJDK_TARGET_OS),windows) else LIBJAVA_EXCLUDE_FILES += \ ProcessImpl_md.c \ - Win32FileSystem_md.c \ WinNTFileSystem_md.c \ dirent_md.c \ WindowsPreferences.c \ diff --git a/jdk/src/windows/classes/java/io/Win32FileSystem.java b/jdk/src/windows/classes/java/io/Win32FileSystem.java deleted file mode 100644 index 4040c128fb1..00000000000 --- a/jdk/src/windows/classes/java/io/Win32FileSystem.java +++ /dev/null @@ -1,608 +0,0 @@ -/* - * Copyright (c) 1998, 2010, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. Oracle designates this - * particular file as subject to the "Classpath" exception as provided - * by Oracle in the LICENSE file that accompanied this code. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - */ - -package java.io; - -import java.security.AccessController; -import java.util.Locale; -import sun.security.action.GetPropertyAction; - - -class Win32FileSystem extends FileSystem { - - private final char slash; - private final char altSlash; - private final char semicolon; - - public Win32FileSystem() { - slash = AccessController.doPrivileged( - new GetPropertyAction("file.separator")).charAt(0); - semicolon = AccessController.doPrivileged( - new GetPropertyAction("path.separator")).charAt(0); - altSlash = (this.slash == '\\') ? '/' : '\\'; - } - - private boolean isSlash(char c) { - return (c == '\\') || (c == '/'); - } - - private boolean isLetter(char c) { - return ((c >= 'a') && (c <= 'z')) || ((c >= 'A') && (c <= 'Z')); - } - - private String slashify(String p) { - if ((p.length() > 0) && (p.charAt(0) != slash)) return slash + p; - else return p; - } - - - /* -- Normalization and construction -- */ - - public char getSeparator() { - return slash; - } - - public char getPathSeparator() { - return semicolon; - } - - /* A normal Win32 pathname contains no duplicate slashes, except possibly - for a UNC prefix, and does not end with a slash. It may be the empty - string. Normalized Win32 pathnames have the convenient property that - the length of the prefix almost uniquely identifies the type of the path - and whether it is absolute or relative: - - 0 relative to both drive and directory - 1 drive-relative (begins with '\\') - 2 absolute UNC (if first char is '\\'), - else directory-relative (has form "z:foo") - 3 absolute local pathname (begins with "z:\\") - */ - - private int normalizePrefix(String path, int len, StringBuffer sb) { - int src = 0; - while ((src < len) && isSlash(path.charAt(src))) src++; - char c; - if ((len - src >= 2) - && isLetter(c = path.charAt(src)) - && path.charAt(src + 1) == ':') { - /* Remove leading slashes if followed by drive specifier. - This hack is necessary to support file URLs containing drive - specifiers (e.g., "file://c:/path"). As a side effect, - "/c:/path" can be used as an alternative to "c:/path". */ - sb.append(c); - sb.append(':'); - src += 2; - } else { - src = 0; - if ((len >= 2) - && isSlash(path.charAt(0)) - && isSlash(path.charAt(1))) { - /* UNC pathname: Retain first slash; leave src pointed at - second slash so that further slashes will be collapsed - into the second slash. The result will be a pathname - beginning with "\\\\" followed (most likely) by a host - name. */ - src = 1; - sb.append(slash); - } - } - return src; - } - - /* Normalize the given pathname, whose length is len, starting at the given - offset; everything before this offset is already normal. */ - private String normalize(String path, int len, int off) { - if (len == 0) return path; - if (off < 3) off = 0; /* Avoid fencepost cases with UNC pathnames */ - int src; - char slash = this.slash; - StringBuffer sb = new StringBuffer(len); - - if (off == 0) { - /* Complete normalization, including prefix */ - src = normalizePrefix(path, len, sb); - } else { - /* Partial normalization */ - src = off; - sb.append(path.substring(0, off)); - } - - /* Remove redundant slashes from the remainder of the path, forcing all - slashes into the preferred slash */ - while (src < len) { - char c = path.charAt(src++); - if (isSlash(c)) { - while ((src < len) && isSlash(path.charAt(src))) src++; - if (src == len) { - /* Check for trailing separator */ - int sn = sb.length(); - if ((sn == 2) && (sb.charAt(1) == ':')) { - /* "z:\\" */ - sb.append(slash); - break; - } - if (sn == 0) { - /* "\\" */ - sb.append(slash); - break; - } - if ((sn == 1) && (isSlash(sb.charAt(0)))) { - /* "\\\\" is not collapsed to "\\" because "\\\\" marks - the beginning of a UNC pathname. Even though it is - not, by itself, a valid UNC pathname, we leave it as - is in order to be consistent with the win32 APIs, - which treat this case as an invalid UNC pathname - rather than as an alias for the root directory of - the current drive. */ - sb.append(slash); - break; - } - /* Path does not denote a root directory, so do not append - trailing slash */ - break; - } else { - sb.append(slash); - } - } else { - sb.append(c); - } - } - - String rv = sb.toString(); - return rv; - } - - /* Check that the given pathname is normal. If not, invoke the real - normalizer on the part of the pathname that requires normalization. - This way we iterate through the whole pathname string only once. */ - public String normalize(String path) { - int n = path.length(); - char slash = this.slash; - char altSlash = this.altSlash; - char prev = 0; - for (int i = 0; i < n; i++) { - char c = path.charAt(i); - if (c == altSlash) - return normalize(path, n, (prev == slash) ? i - 1 : i); - if ((c == slash) && (prev == slash) && (i > 1)) - return normalize(path, n, i - 1); - if ((c == ':') && (i > 1)) - return normalize(path, n, 0); - prev = c; - } - if (prev == slash) return normalize(path, n, n - 1); - return path; - } - - public int prefixLength(String path) { - char slash = this.slash; - int n = path.length(); - if (n == 0) return 0; - char c0 = path.charAt(0); - char c1 = (n > 1) ? path.charAt(1) : 0; - if (c0 == slash) { - if (c1 == slash) return 2; /* Absolute UNC pathname "\\\\foo" */ - return 1; /* Drive-relative "\\foo" */ - } - if (isLetter(c0) && (c1 == ':')) { - if ((n > 2) && (path.charAt(2) == slash)) - return 3; /* Absolute local pathname "z:\\foo" */ - return 2; /* Directory-relative "z:foo" */ - } - return 0; /* Completely relative */ - } - - public String resolve(String parent, String child) { - int pn = parent.length(); - if (pn == 0) return child; - int cn = child.length(); - if (cn == 0) return parent; - - String c = child; - int childStart = 0; - int parentEnd = pn; - - if ((cn > 1) && (c.charAt(0) == slash)) { - if (c.charAt(1) == slash) { - /* Drop prefix when child is a UNC pathname */ - childStart = 2; - } else { - /* Drop prefix when child is drive-relative */ - childStart = 1; - - } - if (cn == childStart) { // Child is double slash - if (parent.charAt(pn - 1) == slash) - return parent.substring(0, pn - 1); - return parent; - } - } - - if (parent.charAt(pn - 1) == slash) - parentEnd--; - - int strlen = parentEnd + cn - childStart; - char[] theChars = null; - if (child.charAt(childStart) == slash) { - theChars = new char[strlen]; - parent.getChars(0, parentEnd, theChars, 0); - child.getChars(childStart, cn, theChars, parentEnd); - } else { - theChars = new char[strlen + 1]; - parent.getChars(0, parentEnd, theChars, 0); - theChars[parentEnd] = slash; - child.getChars(childStart, cn, theChars, parentEnd + 1); - } - return new String(theChars); - } - - public String getDefaultParent() { - return ("" + slash); - } - - public String fromURIPath(String path) { - String p = path; - if ((p.length() > 2) && (p.charAt(2) == ':')) { - // "/c:/foo" --> "c:/foo" - p = p.substring(1); - // "c:/foo/" --> "c:/foo", but "c:/" --> "c:/" - if ((p.length() > 3) && p.endsWith("/")) - p = p.substring(0, p.length() - 1); - } else if ((p.length() > 1) && p.endsWith("/")) { - // "/foo/" --> "/foo" - p = p.substring(0, p.length() - 1); - } - return p; - } - - - - /* -- Path operations -- */ - - public boolean isAbsolute(File f) { - int pl = f.getPrefixLength(); - return (((pl == 2) && (f.getPath().charAt(0) == slash)) - || (pl == 3)); - } - - protected native String getDriveDirectory(int drive); - - private static String[] driveDirCache = new String[26]; - - private static int driveIndex(char d) { - if ((d >= 'a') && (d <= 'z')) return d - 'a'; - if ((d >= 'A') && (d <= 'Z')) return d - 'A'; - return -1; - } - - private String getDriveDirectory(char drive) { - int i = driveIndex(drive); - if (i < 0) return null; - String s = driveDirCache[i]; - if (s != null) return s; - s = getDriveDirectory(i + 1); - driveDirCache[i] = s; - return s; - } - - private String getUserPath() { - /* For both compatibility and security, - we must look this up every time */ - return normalize(System.getProperty("user.dir")); - } - - private String getDrive(String path) { - int pl = prefixLength(path); - return (pl == 3) ? path.substring(0, 2) : null; - } - - public String resolve(File f) { - String path = f.getPath(); - int pl = f.getPrefixLength(); - if ((pl == 2) && (path.charAt(0) == slash)) - return path; /* UNC */ - if (pl == 3) - return path; /* Absolute local */ - if (pl == 0) - return getUserPath() + slashify(path); /* Completely relative */ - if (pl == 1) { /* Drive-relative */ - String up = getUserPath(); - String ud = getDrive(up); - if (ud != null) return ud + path; - return up + path; /* User dir is a UNC path */ - } - if (pl == 2) { /* Directory-relative */ - String up = getUserPath(); - String ud = getDrive(up); - if ((ud != null) && path.startsWith(ud)) - return up + slashify(path.substring(2)); - char drive = path.charAt(0); - String dir = getDriveDirectory(drive); - String np; - if (dir != null) { - /* When resolving a directory-relative path that refers to a - drive other than the current drive, insist that the caller - have read permission on the result */ - String p = drive + (':' + dir + slashify(path.substring(2))); - SecurityManager security = System.getSecurityManager(); - try { - if (security != null) security.checkRead(p); - } catch (SecurityException x) { - /* Don't disclose the drive's directory in the exception */ - throw new SecurityException("Cannot resolve path " + path); - } - return p; - } - return drive + ":" + slashify(path.substring(2)); /* fake it */ - } - throw new InternalError("Unresolvable path: " + path); - } - - // Caches for canonicalization results to improve startup performance. - // The first cache handles repeated canonicalizations of the same path - // name. The prefix cache handles repeated canonicalizations within the - // same directory, and must not create results differing from the true - // canonicalization algorithm in canonicalize_md.c. For this reason the - // prefix cache is conservative and is not used for complex path names. - private ExpiringCache cache = new ExpiringCache(); - private ExpiringCache prefixCache = new ExpiringCache(); - - public String canonicalize(String path) throws IOException { - // If path is a drive letter only then skip canonicalization - int len = path.length(); - if ((len == 2) && - (isLetter(path.charAt(0))) && - (path.charAt(1) == ':')) { - char c = path.charAt(0); - if ((c >= 'A') && (c <= 'Z')) - return path; - return "" + ((char) (c-32)) + ':'; - } else if ((len == 3) && - (isLetter(path.charAt(0))) && - (path.charAt(1) == ':') && - (path.charAt(2) == '\\')) { - char c = path.charAt(0); - if ((c >= 'A') && (c <= 'Z')) - return path; - return "" + ((char) (c-32)) + ':' + '\\'; - } - if (!useCanonCaches) { - return canonicalize0(path); - } else { - String res = cache.get(path); - if (res == null) { - String dir = null; - String resDir = null; - if (useCanonPrefixCache) { - dir = parentOrNull(path); - if (dir != null) { - resDir = prefixCache.get(dir); - if (resDir != null) { - // Hit only in prefix cache; full path is canonical, - // but we need to get the canonical name of the file - // in this directory to get the appropriate capitalization - String filename = path.substring(1 + dir.length()); - res = canonicalizeWithPrefix(resDir, filename); - cache.put(dir + File.separatorChar + filename, res); - } - } - } - if (res == null) { - res = canonicalize0(path); - cache.put(path, res); - if (useCanonPrefixCache && dir != null) { - resDir = parentOrNull(res); - if (resDir != null) { - File f = new File(res); - if (f.exists() && !f.isDirectory()) { - prefixCache.put(dir, resDir); - } - } - } - } - } - return res; - } - } - - protected native String canonicalize0(String path) - throws IOException; - protected String canonicalizeWithPrefix(String canonicalPrefix, - String filename) throws IOException - { - return canonicalizeWithPrefix0(canonicalPrefix, - canonicalPrefix + File.separatorChar + filename); - } - // Run the canonicalization operation assuming that the prefix - // (everything up to the last filename) is canonical; just gets - // the canonical name of the last element of the path - protected native String canonicalizeWithPrefix0(String canonicalPrefix, - String pathWithCanonicalPrefix) - throws IOException; - // Best-effort attempt to get parent of this path; used for - // optimization of filename canonicalization. This must return null for - // any cases where the code in canonicalize_md.c would throw an - // exception or otherwise deal with non-simple pathnames like handling - // of "." and "..". It may conservatively return null in other - // situations as well. Returning null will cause the underlying - // (expensive) canonicalization routine to be called. - static String parentOrNull(String path) { - if (path == null) return null; - char sep = File.separatorChar; - char altSep = '/'; - int last = path.length() - 1; - int idx = last; - int adjacentDots = 0; - int nonDotCount = 0; - while (idx > 0) { - char c = path.charAt(idx); - if (c == '.') { - if (++adjacentDots >= 2) { - // Punt on pathnames containing . and .. - return null; - } - if (nonDotCount == 0) { - // Punt on pathnames ending in a . - return null; - } - } else if (c == sep) { - if (adjacentDots == 1 && nonDotCount == 0) { - // Punt on pathnames containing . and .. - return null; - } - if (idx == 0 || - idx >= last - 1 || - path.charAt(idx - 1) == sep || - path.charAt(idx - 1) == altSep) { - // Punt on pathnames containing adjacent slashes - // toward the end - return null; - } - return path.substring(0, idx); - } else if (c == altSep) { - // Punt on pathnames containing both backward and - // forward slashes - return null; - } else if (c == '*' || c == '?') { - // Punt on pathnames containing wildcards - return null; - } else { - ++nonDotCount; - adjacentDots = 0; - } - --idx; - } - return null; - } - - - /* -- Attribute accessors -- */ - - public native int getBooleanAttributes(File f); - public native boolean checkAccess(File f, int access); - public native long getLastModifiedTime(File f); - public native long getLength(File f); - public native boolean setPermission(File f, int access, boolean enable, boolean owneronly); - - /* -- File operations -- */ - - public native boolean createFileExclusively(String path) - throws IOException; - public boolean delete(File f) { - // Keep canonicalization caches in sync after file deletion - // and renaming operations. Could be more clever than this - // (i.e., only remove/update affected entries) but probably - // not worth it since these entries expire after 30 seconds - // anyway. - cache.clear(); - prefixCache.clear(); - return delete0(f); - } - protected native boolean delete0(File f); - public native String[] list(File f); - public native boolean createDirectory(File f); - public boolean rename(File f1, File f2) { - // Keep canonicalization caches in sync after file deletion - // and renaming operations. Could be more clever than this - // (i.e., only remove/update affected entries) but probably - // not worth it since these entries expire after 30 seconds - // anyway. - cache.clear(); - prefixCache.clear(); - return rename0(f1, f2); - } - protected native boolean rename0(File f1, File f2); - public native boolean setLastModifiedTime(File f, long time); - public native boolean setReadOnly(File f); - - - /* -- Filesystem interface -- */ - - private boolean access(String path) { - try { - SecurityManager security = System.getSecurityManager(); - if (security != null) security.checkRead(path); - return true; - } catch (SecurityException x) { - return false; - } - } - - private static native int listRoots0(); - - public File[] listRoots() { - int ds = listRoots0(); - int n = 0; - for (int i = 0; i < 26; i++) { - if (((ds >> i) & 1) != 0) { - if (!access((char)('A' + i) + ":" + slash)) - ds &= ~(1 << i); - else - n++; - } - } - File[] fs = new File[n]; - int j = 0; - char slash = this.slash; - for (int i = 0; i < 26; i++) { - if (((ds >> i) & 1) != 0) - fs[j++] = new File((char)('A' + i) + ":" + slash); - } - return fs; - } - - - /* -- Disk usage -- */ - public long getSpace(File f, int t) { - if (f.exists()) { - File file = (f.isDirectory() ? f : f.getParentFile()); - return getSpace0(file, t); - } - return 0; - } - - private native long getSpace0(File f, int t); - - - /* -- Basic infrastructure -- */ - - public int compare(File f1, File f2) { - return f1.getPath().compareToIgnoreCase(f2.getPath()); - } - - public int hashCode(File f) { - /* Could make this more efficient: String.hashCodeIgnoreCase */ - return f.getPath().toLowerCase(Locale.ENGLISH).hashCode() ^ 1234321; - } - - - private static native void initIDs(); - - static { - initIDs(); - } - -} diff --git a/jdk/src/windows/classes/java/io/WinNTFileSystem.java b/jdk/src/windows/classes/java/io/WinNTFileSystem.java index 5ad2eeb5be4..caa47f80c08 100644 --- a/jdk/src/windows/classes/java/io/WinNTFileSystem.java +++ b/jdk/src/windows/classes/java/io/WinNTFileSystem.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2001, 2006, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2001, 2012, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -23,34 +23,601 @@ * questions. */ -/* - */ - package java.io; +import java.security.AccessController; +import java.util.Locale; +import sun.security.action.GetPropertyAction; + /** * Unicode-aware FileSystem for Windows NT/2000. * * @author Konstantin Kladko * @since 1.4 */ -class WinNTFileSystem extends Win32FileSystem { +class WinNTFileSystem extends FileSystem { - protected native String canonicalize0(String path) - throws IOException; - protected native String canonicalizeWithPrefix0(String canonicalPrefix, - String pathWithCanonicalPrefix) - throws IOException; + private final char slash; + private final char altSlash; + private final char semicolon; + + public WinNTFileSystem() { + slash = AccessController.doPrivileged( + new GetPropertyAction("file.separator")).charAt(0); + semicolon = AccessController.doPrivileged( + new GetPropertyAction("path.separator")).charAt(0); + altSlash = (this.slash == '\\') ? '/' : '\\'; + } + + private boolean isSlash(char c) { + return (c == '\\') || (c == '/'); + } + + private boolean isLetter(char c) { + return ((c >= 'a') && (c <= 'z')) || ((c >= 'A') && (c <= 'Z')); + } + + private String slashify(String p) { + if ((p.length() > 0) && (p.charAt(0) != slash)) return slash + p; + else return p; + } + + /* -- Normalization and construction -- */ + + @Override + public char getSeparator() { + return slash; + } + + @Override + public char getPathSeparator() { + return semicolon; + } + + /* Check that the given pathname is normal. If not, invoke the real + normalizer on the part of the pathname that requires normalization. + This way we iterate through the whole pathname string only once. */ + @Override + public String normalize(String path) { + int n = path.length(); + char slash = this.slash; + char altSlash = this.altSlash; + char prev = 0; + for (int i = 0; i < n; i++) { + char c = path.charAt(i); + if (c == altSlash) + return normalize(path, n, (prev == slash) ? i - 1 : i); + if ((c == slash) && (prev == slash) && (i > 1)) + return normalize(path, n, i - 1); + if ((c == ':') && (i > 1)) + return normalize(path, n, 0); + prev = c; + } + if (prev == slash) return normalize(path, n, n - 1); + return path; + } + + /* Normalize the given pathname, whose length is len, starting at the given + offset; everything before this offset is already normal. */ + private String normalize(String path, int len, int off) { + if (len == 0) return path; + if (off < 3) off = 0; /* Avoid fencepost cases with UNC pathnames */ + int src; + char slash = this.slash; + StringBuffer sb = new StringBuffer(len); + + if (off == 0) { + /* Complete normalization, including prefix */ + src = normalizePrefix(path, len, sb); + } else { + /* Partial normalization */ + src = off; + sb.append(path.substring(0, off)); + } + + /* Remove redundant slashes from the remainder of the path, forcing all + slashes into the preferred slash */ + while (src < len) { + char c = path.charAt(src++); + if (isSlash(c)) { + while ((src < len) && isSlash(path.charAt(src))) src++; + if (src == len) { + /* Check for trailing separator */ + int sn = sb.length(); + if ((sn == 2) && (sb.charAt(1) == ':')) { + /* "z:\\" */ + sb.append(slash); + break; + } + if (sn == 0) { + /* "\\" */ + sb.append(slash); + break; + } + if ((sn == 1) && (isSlash(sb.charAt(0)))) { + /* "\\\\" is not collapsed to "\\" because "\\\\" marks + the beginning of a UNC pathname. Even though it is + not, by itself, a valid UNC pathname, we leave it as + is in order to be consistent with the win32 APIs, + which treat this case as an invalid UNC pathname + rather than as an alias for the root directory of + the current drive. */ + sb.append(slash); + break; + } + /* Path does not denote a root directory, so do not append + trailing slash */ + break; + } else { + sb.append(slash); + } + } else { + sb.append(c); + } + } + + String rv = sb.toString(); + return rv; + } + + /* A normal Win32 pathname contains no duplicate slashes, except possibly + for a UNC prefix, and does not end with a slash. It may be the empty + string. Normalized Win32 pathnames have the convenient property that + the length of the prefix almost uniquely identifies the type of the path + and whether it is absolute or relative: + + 0 relative to both drive and directory + 1 drive-relative (begins with '\\') + 2 absolute UNC (if first char is '\\'), + else directory-relative (has form "z:foo") + 3 absolute local pathname (begins with "z:\\") + */ + private int normalizePrefix(String path, int len, StringBuffer sb) { + int src = 0; + while ((src < len) && isSlash(path.charAt(src))) src++; + char c; + if ((len - src >= 2) + && isLetter(c = path.charAt(src)) + && path.charAt(src + 1) == ':') { + /* Remove leading slashes if followed by drive specifier. + This hack is necessary to support file URLs containing drive + specifiers (e.g., "file://c:/path"). As a side effect, + "/c:/path" can be used as an alternative to "c:/path". */ + sb.append(c); + sb.append(':'); + src += 2; + } else { + src = 0; + if ((len >= 2) + && isSlash(path.charAt(0)) + && isSlash(path.charAt(1))) { + /* UNC pathname: Retain first slash; leave src pointed at + second slash so that further slashes will be collapsed + into the second slash. The result will be a pathname + beginning with "\\\\" followed (most likely) by a host + name. */ + src = 1; + sb.append(slash); + } + } + return src; + } + + @Override + public int prefixLength(String path) { + char slash = this.slash; + int n = path.length(); + if (n == 0) return 0; + char c0 = path.charAt(0); + char c1 = (n > 1) ? path.charAt(1) : 0; + if (c0 == slash) { + if (c1 == slash) return 2; /* Absolute UNC pathname "\\\\foo" */ + return 1; /* Drive-relative "\\foo" */ + } + if (isLetter(c0) && (c1 == ':')) { + if ((n > 2) && (path.charAt(2) == slash)) + return 3; /* Absolute local pathname "z:\\foo" */ + return 2; /* Directory-relative "z:foo" */ + } + return 0; /* Completely relative */ + } + + @Override + public String resolve(String parent, String child) { + int pn = parent.length(); + if (pn == 0) return child; + int cn = child.length(); + if (cn == 0) return parent; + + String c = child; + int childStart = 0; + int parentEnd = pn; + + if ((cn > 1) && (c.charAt(0) == slash)) { + if (c.charAt(1) == slash) { + /* Drop prefix when child is a UNC pathname */ + childStart = 2; + } else { + /* Drop prefix when child is drive-relative */ + childStart = 1; + + } + if (cn == childStart) { // Child is double slash + if (parent.charAt(pn - 1) == slash) + return parent.substring(0, pn - 1); + return parent; + } + } + + if (parent.charAt(pn - 1) == slash) + parentEnd--; + + int strlen = parentEnd + cn - childStart; + char[] theChars = null; + if (child.charAt(childStart) == slash) { + theChars = new char[strlen]; + parent.getChars(0, parentEnd, theChars, 0); + child.getChars(childStart, cn, theChars, parentEnd); + } else { + theChars = new char[strlen + 1]; + parent.getChars(0, parentEnd, theChars, 0); + theChars[parentEnd] = slash; + child.getChars(childStart, cn, theChars, parentEnd + 1); + } + return new String(theChars); + } + + @Override + public String getDefaultParent() { + return ("" + slash); + } + + @Override + public String fromURIPath(String path) { + String p = path; + if ((p.length() > 2) && (p.charAt(2) == ':')) { + // "/c:/foo" --> "c:/foo" + p = p.substring(1); + // "c:/foo/" --> "c:/foo", but "c:/" --> "c:/" + if ((p.length() > 3) && p.endsWith("/")) + p = p.substring(0, p.length() - 1); + } else if ((p.length() > 1) && p.endsWith("/")) { + // "/foo/" --> "/foo" + p = p.substring(0, p.length() - 1); + } + return p; + } + + /* -- Path operations -- */ + + @Override + public boolean isAbsolute(File f) { + int pl = f.getPrefixLength(); + return (((pl == 2) && (f.getPath().charAt(0) == slash)) + || (pl == 3)); + } + + @Override + public String resolve(File f) { + String path = f.getPath(); + int pl = f.getPrefixLength(); + if ((pl == 2) && (path.charAt(0) == slash)) + return path; /* UNC */ + if (pl == 3) + return path; /* Absolute local */ + if (pl == 0) + return getUserPath() + slashify(path); /* Completely relative */ + if (pl == 1) { /* Drive-relative */ + String up = getUserPath(); + String ud = getDrive(up); + if (ud != null) return ud + path; + return up + path; /* User dir is a UNC path */ + } + if (pl == 2) { /* Directory-relative */ + String up = getUserPath(); + String ud = getDrive(up); + if ((ud != null) && path.startsWith(ud)) + return up + slashify(path.substring(2)); + char drive = path.charAt(0); + String dir = getDriveDirectory(drive); + String np; + if (dir != null) { + /* When resolving a directory-relative path that refers to a + drive other than the current drive, insist that the caller + have read permission on the result */ + String p = drive + (':' + dir + slashify(path.substring(2))); + SecurityManager security = System.getSecurityManager(); + try { + if (security != null) security.checkRead(p); + } catch (SecurityException x) { + /* Don't disclose the drive's directory in the exception */ + throw new SecurityException("Cannot resolve path " + path); + } + return p; + } + return drive + ":" + slashify(path.substring(2)); /* fake it */ + } + throw new InternalError("Unresolvable path: " + path); + } + + private String getUserPath() { + /* For both compatibility and security, + we must look this up every time */ + return normalize(System.getProperty("user.dir")); + } + + private String getDrive(String path) { + int pl = prefixLength(path); + return (pl == 3) ? path.substring(0, 2) : null; + } + + private static String[] driveDirCache = new String[26]; + + private static int driveIndex(char d) { + if ((d >= 'a') && (d <= 'z')) return d - 'a'; + if ((d >= 'A') && (d <= 'Z')) return d - 'A'; + return -1; + } + + private native String getDriveDirectory(int drive); + + private String getDriveDirectory(char drive) { + int i = driveIndex(drive); + if (i < 0) return null; + String s = driveDirCache[i]; + if (s != null) return s; + s = getDriveDirectory(i + 1); + driveDirCache[i] = s; + return s; + } + + // Caches for canonicalization results to improve startup performance. + // The first cache handles repeated canonicalizations of the same path + // name. The prefix cache handles repeated canonicalizations within the + // same directory, and must not create results differing from the true + // canonicalization algorithm in canonicalize_md.c. For this reason the + // prefix cache is conservative and is not used for complex path names. + private ExpiringCache cache = new ExpiringCache(); + private ExpiringCache prefixCache = new ExpiringCache(); + + @Override + public String canonicalize(String path) throws IOException { + // If path is a drive letter only then skip canonicalization + int len = path.length(); + if ((len == 2) && + (isLetter(path.charAt(0))) && + (path.charAt(1) == ':')) { + char c = path.charAt(0); + if ((c >= 'A') && (c <= 'Z')) + return path; + return "" + ((char) (c-32)) + ':'; + } else if ((len == 3) && + (isLetter(path.charAt(0))) && + (path.charAt(1) == ':') && + (path.charAt(2) == '\\')) { + char c = path.charAt(0); + if ((c >= 'A') && (c <= 'Z')) + return path; + return "" + ((char) (c-32)) + ':' + '\\'; + } + if (!useCanonCaches) { + return canonicalize0(path); + } else { + String res = cache.get(path); + if (res == null) { + String dir = null; + String resDir = null; + if (useCanonPrefixCache) { + dir = parentOrNull(path); + if (dir != null) { + resDir = prefixCache.get(dir); + if (resDir != null) { + /* + * Hit only in prefix cache; full path is canonical, + * but we need to get the canonical name of the file + * in this directory to get the appropriate + * capitalization + */ + String filename = path.substring(1 + dir.length()); + res = canonicalizeWithPrefix(resDir, filename); + cache.put(dir + File.separatorChar + filename, res); + } + } + } + if (res == null) { + res = canonicalize0(path); + cache.put(path, res); + if (useCanonPrefixCache && dir != null) { + resDir = parentOrNull(res); + if (resDir != null) { + File f = new File(res); + if (f.exists() && !f.isDirectory()) { + prefixCache.put(dir, resDir); + } + } + } + } + } + return res; + } + } + + private native String canonicalize0(String path) + throws IOException; + + private String canonicalizeWithPrefix(String canonicalPrefix, + String filename) throws IOException + { + return canonicalizeWithPrefix0(canonicalPrefix, + canonicalPrefix + File.separatorChar + filename); + } + + // Run the canonicalization operation assuming that the prefix + // (everything up to the last filename) is canonical; just gets + // the canonical name of the last element of the path + private native String canonicalizeWithPrefix0(String canonicalPrefix, + String pathWithCanonicalPrefix) + throws IOException; + + // Best-effort attempt to get parent of this path; used for + // optimization of filename canonicalization. This must return null for + // any cases where the code in canonicalize_md.c would throw an + // exception or otherwise deal with non-simple pathnames like handling + // of "." and "..". It may conservatively return null in other + // situations as well. Returning null will cause the underlying + // (expensive) canonicalization routine to be called. + private static String parentOrNull(String path) { + if (path == null) return null; + char sep = File.separatorChar; + char altSep = '/'; + int last = path.length() - 1; + int idx = last; + int adjacentDots = 0; + int nonDotCount = 0; + while (idx > 0) { + char c = path.charAt(idx); + if (c == '.') { + if (++adjacentDots >= 2) { + // Punt on pathnames containing . and .. + return null; + } + if (nonDotCount == 0) { + // Punt on pathnames ending in a . + return null; + } + } else if (c == sep) { + if (adjacentDots == 1 && nonDotCount == 0) { + // Punt on pathnames containing . and .. + return null; + } + if (idx == 0 || + idx >= last - 1 || + path.charAt(idx - 1) == sep || + path.charAt(idx - 1) == altSep) { + // Punt on pathnames containing adjacent slashes + // toward the end + return null; + } + return path.substring(0, idx); + } else if (c == altSep) { + // Punt on pathnames containing both backward and + // forward slashes + return null; + } else if (c == '*' || c == '?') { + // Punt on pathnames containing wildcards + return null; + } else { + ++nonDotCount; + adjacentDots = 0; + } + --idx; + } + return null; + } /* -- Attribute accessors -- */ + @Override public native int getBooleanAttributes(File f); + + @Override public native boolean checkAccess(File f, int access); + + @Override public native long getLastModifiedTime(File f); + + @Override public native long getLength(File f); - public native boolean setPermission(File f, int access, boolean enable, boolean owneronly); + @Override + public native boolean setPermission(File f, int access, boolean enable, + boolean owneronly); + /* -- File operations -- */ + + @Override + public native boolean createFileExclusively(String path) + throws IOException; + + @Override + public native String[] list(File f); + + @Override + public native boolean createDirectory(File f); + + @Override + public native boolean setLastModifiedTime(File f, long time); + + @Override + public native boolean setReadOnly(File f); + + @Override + public boolean delete(File f) { + // Keep canonicalization caches in sync after file deletion + // and renaming operations. Could be more clever than this + // (i.e., only remove/update affected entries) but probably + // not worth it since these entries expire after 30 seconds + // anyway. + cache.clear(); + prefixCache.clear(); + return delete0(f); + } + + private native boolean delete0(File f); + + @Override + public boolean rename(File f1, File f2) { + // Keep canonicalization caches in sync after file deletion + // and renaming operations. Could be more clever than this + // (i.e., only remove/update affected entries) but probably + // not worth it since these entries expire after 30 seconds + // anyway. + cache.clear(); + prefixCache.clear(); + return rename0(f1, f2); + } + + private native boolean rename0(File f1, File f2); + + /* -- Filesystem interface -- */ + + @Override + public File[] listRoots() { + int ds = listRoots0(); + int n = 0; + for (int i = 0; i < 26; i++) { + if (((ds >> i) & 1) != 0) { + if (!access((char)('A' + i) + ":" + slash)) + ds &= ~(1 << i); + else + n++; + } + } + File[] fs = new File[n]; + int j = 0; + char slash = this.slash; + for (int i = 0; i < 26; i++) { + if (((ds >> i) & 1) != 0) + fs[j++] = new File((char)('A' + i) + ":" + slash); + } + return fs; + } + + private static native int listRoots0(); + + private boolean access(String path) { + try { + SecurityManager security = System.getSecurityManager(); + if (security != null) security.checkRead(path); + return true; + } catch (SecurityException x) { + return false; + } + } + + /* -- Disk usage -- */ + + @Override public long getSpace(File f, int t) { if (f.exists()) { return getSpace0(f, t); @@ -60,20 +627,22 @@ class WinNTFileSystem extends Win32FileSystem { private native long getSpace0(File f, int t); - /* -- File operations -- */ + /* -- Basic infrastructure -- */ + + @Override + public int compare(File f1, File f2) { + return f1.getPath().compareToIgnoreCase(f2.getPath()); + } + + @Override + public int hashCode(File f) { + /* Could make this more efficient: String.hashCodeIgnoreCase */ + return f.getPath().toLowerCase(Locale.ENGLISH).hashCode() ^ 1234321; + } - public native boolean createFileExclusively(String path) - throws IOException; - protected native boolean delete0(File f); - public native String[] list(File f); - public native boolean createDirectory(File f); - protected native boolean rename0(File f1, File f2); - public native boolean setLastModifiedTime(File f, long time); - public native boolean setReadOnly(File f); - protected native String getDriveDirectory(int drive); private static native void initIDs(); static { - initIDs(); + initIDs(); } } diff --git a/jdk/src/windows/native/java/io/FileSystem_md.c b/jdk/src/windows/native/java/io/FileSystem_md.c index a56c5b5d2a8..bd813e7dbf0 100644 --- a/jdk/src/windows/native/java/io/FileSystem_md.c +++ b/jdk/src/windows/native/java/io/FileSystem_md.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 1998, 2001, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1998, 2012, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -27,16 +27,8 @@ #include "jni.h" #include "jni_util.h" -extern jboolean onNT; -extern void initializeWindowsVersion(); - JNIEXPORT jobject JNICALL Java_java_io_FileSystem_getFileSystem(JNIEnv *env, jclass ignored) { - initializeWindowsVersion(); - if (onNT) { - return JNU_NewObjectByName(env, "java/io/WinNTFileSystem", "()V"); - } else { - return JNU_NewObjectByName(env, "java/io/Win32FileSystem", "()V"); - } + return JNU_NewObjectByName(env, "java/io/WinNTFileSystem", "()V"); } diff --git a/jdk/src/windows/native/java/io/Win32FileSystem_md.c b/jdk/src/windows/native/java/io/Win32FileSystem_md.c deleted file mode 100644 index 91c086c48b9..00000000000 --- a/jdk/src/windows/native/java/io/Win32FileSystem_md.c +++ /dev/null @@ -1,509 +0,0 @@ -/* - * Copyright (c) 1998, 2006, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. Oracle designates this - * particular file as subject to the "Classpath" exception as provided - * by Oracle in the LICENSE file that accompanied this code. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - */ - -#include -#include -#include -#include -#include -#include -#include - -#include "jvm.h" -#include "jni.h" -#include "jni_util.h" -#include "jlong.h" -#include "io_util.h" -#include "dirent_md.h" -#include "java_io_FileSystem.h" - -/* This macro relies upon the fact that JNU_GetStringPlatformChars always makes - a copy of the string */ - -#define WITH_NATIVE_PATH(env, object, id, var) \ - WITH_FIELD_PLATFORM_STRING(env, object, id, var) \ - JVM_NativePath((char *)var); - -#define END_NATIVE_PATH(env, var) END_PLATFORM_STRING(env, var) - - -static struct { - jfieldID path; -} ids; - -JNIEXPORT void JNICALL -Java_java_io_Win32FileSystem_initIDs(JNIEnv *env, jclass cls) -{ - jclass fileClass = (*env)->FindClass(env, "java/io/File"); - if (!fileClass) return; - ids.path = (*env)->GetFieldID(env, fileClass, - "path", "Ljava/lang/String;"); -} - - -/* -- Path operations -- */ - - -extern int canonicalize(char *path, const char *out, int len); -extern int canonicalizeWithPrefix(const char* canonicalPrefix, const char *pathWithCanonicalPrefix, char *out, int len); - -JNIEXPORT jstring JNICALL -Java_java_io_Win32FileSystem_canonicalize0(JNIEnv *env, jobject this, - jstring pathname) -{ - jstring rv = NULL; - - WITH_PLATFORM_STRING(env, pathname, path) { - char canonicalPath[JVM_MAXPATHLEN]; - if (canonicalize(JVM_NativePath((char *)path), - canonicalPath, JVM_MAXPATHLEN) < 0) { - JNU_ThrowIOExceptionWithLastError(env, "Bad pathname"); - } else { - rv = JNU_NewStringPlatform(env, canonicalPath); - } - } END_PLATFORM_STRING(env, path); - return rv; -} - - -JNIEXPORT jstring JNICALL -Java_java_io_Win32FileSystem_canonicalizeWithPrefix0(JNIEnv *env, jobject this, - jstring canonicalPrefixString, - jstring pathWithCanonicalPrefixString) -{ - jstring rv = NULL; - char canonicalPath[JVM_MAXPATHLEN]; - - WITH_PLATFORM_STRING(env, canonicalPrefixString, canonicalPrefix) { - WITH_PLATFORM_STRING(env, pathWithCanonicalPrefixString, pathWithCanonicalPrefix) { - if (canonicalizeWithPrefix(canonicalPrefix, - pathWithCanonicalPrefix, - canonicalPath, JVM_MAXPATHLEN) < 0) { - JNU_ThrowIOExceptionWithLastError(env, "Bad pathname"); - } else { - rv = JNU_NewStringPlatform(env, canonicalPath); - } - } END_PLATFORM_STRING(env, pathWithCanonicalPrefix); - } END_PLATFORM_STRING(env, canonicalPrefix); - return rv; -} - - - -/* -- Attribute accessors -- */ - -/* Check whether or not the file name in "path" is a Windows reserved - device name (CON, PRN, AUX, NUL, COM[1-9], LPT[1-9]) based on the - returned result from GetFullPathName. If the file name in the path - is indeed a reserved device name GetFuulPathName returns - "\\.\[ReservedDeviceName]". - */ -BOOL isReservedDeviceName(const char* path) { -#define BUFSIZE 9 - char buf[BUFSIZE]; - char *lpf = NULL; - DWORD retLen = GetFullPathName(path, - BUFSIZE, - buf, - &lpf); - if ((retLen == BUFSIZE - 1 || retLen == BUFSIZE - 2) && - buf[0] == '\\' && buf[1] == '\\' && - buf[2] == '.' && buf[3] == '\\') { - char* dname = _strupr(buf + 4); - if (strcmp(dname, "CON") == 0 || - strcmp(dname, "PRN") == 0 || - strcmp(dname, "AUX") == 0 || - strcmp(dname, "NUL") == 0) - return TRUE; - if ((strncmp(dname, "COM", 3) == 0 || - strncmp(dname, "LPT", 3) == 0) && - dname[3] - '0' > 0 && - dname[3] - '0' <= 9) - return TRUE; - } - return FALSE; -} - -JNIEXPORT jint JNICALL -Java_java_io_Win32FileSystem_getBooleanAttributes(JNIEnv *env, jobject this, - jobject file) -{ - jint rv = 0; - - WITH_NATIVE_PATH(env, file, ids.path, path) { - WIN32_FILE_ATTRIBUTE_DATA wfad; - if (!isReservedDeviceName(path) && - GetFileAttributesEx(path, GetFileExInfoStandard, &wfad)) { - rv = (java_io_FileSystem_BA_EXISTS - | ((wfad.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) - ? java_io_FileSystem_BA_DIRECTORY - : java_io_FileSystem_BA_REGULAR) - | ((wfad.dwFileAttributes & FILE_ATTRIBUTE_HIDDEN) - ? java_io_FileSystem_BA_HIDDEN : 0)); - } - } END_NATIVE_PATH(env, path); - return rv; -} - - -JNIEXPORT jboolean JNICALL -Java_java_io_Win32FileSystem_checkAccess(JNIEnv *env, jobject this, - jobject file, jint a) -{ - jboolean rv = JNI_FALSE; - int mode; - switch (a) { - case java_io_FileSystem_ACCESS_READ: - case java_io_FileSystem_ACCESS_EXECUTE: - mode = 4; - break; - case java_io_FileSystem_ACCESS_WRITE: - mode = 2; - break; - default: assert(0); - } - WITH_NATIVE_PATH(env, file, ids.path, path) { - if (access(path, mode) == 0) { - rv = JNI_TRUE; - } - } END_NATIVE_PATH(env, path); - return rv; -} - -JNIEXPORT jboolean JNICALL -Java_java_io_Win32FileSystem_setPermission(JNIEnv *env, jobject this, - jobject file, - jint access, - jboolean enable, - jboolean owneronly) -{ - jboolean rv = JNI_FALSE; - if (access == java_io_FileSystem_ACCESS_READ || - access == java_io_FileSystem_ACCESS_EXECUTE) { - return enable; - } - WITH_NATIVE_PATH(env, file, ids.path, path) { - DWORD a; - a = GetFileAttributes(path); - if (a != INVALID_FILE_ATTRIBUTES) { - if (enable) - a = a & ~FILE_ATTRIBUTE_READONLY; - else - a = a | FILE_ATTRIBUTE_READONLY; - if (SetFileAttributes(path, a)) - rv = JNI_TRUE; - } - } END_NATIVE_PATH(env, path); - return rv; -} - -JNIEXPORT jlong JNICALL -Java_java_io_Win32FileSystem_getLastModifiedTime(JNIEnv *env, jobject this, - jobject file) -{ - jlong rv = 0; - WITH_NATIVE_PATH(env, file, ids.path, path) { - /* Win95, Win98, WinME */ - WIN32_FIND_DATA fd; - jlong temp = 0; - LARGE_INTEGER modTime; - HANDLE h = FindFirstFile(path, &fd); - if (h != INVALID_HANDLE_VALUE) { - FindClose(h); - modTime.LowPart = (DWORD) fd.ftLastWriteTime.dwLowDateTime; - modTime.HighPart = (LONG) fd.ftLastWriteTime.dwHighDateTime; - rv = modTime.QuadPart / 10000; - rv -= 11644473600000; - } - } END_NATIVE_PATH(env, path); - return rv; -} - -JNIEXPORT jlong JNICALL -Java_java_io_Win32FileSystem_getLength(JNIEnv *env, jobject this, - jobject file) -{ - jlong rv = 0; - - WITH_NATIVE_PATH(env, file, ids.path, path) { - struct _stati64 sb; - if (_stati64(path, &sb) == 0) { - rv = sb.st_size; - } - } END_NATIVE_PATH(env, path); - return rv; -} - - -/* -- File operations -- */ - - -JNIEXPORT jboolean JNICALL -Java_java_io_Win32FileSystem_createFileExclusively(JNIEnv *env, jclass cls, - jstring pathname) -{ - jboolean rv = JNI_FALSE; - DWORD a; - - WITH_PLATFORM_STRING(env, pathname, path) { - int orv; - int error; - JVM_NativePath((char *)path); - orv = JVM_Open(path, JVM_O_RDWR | JVM_O_CREAT | JVM_O_EXCL, 0666); - if (orv < 0) { - if (orv != JVM_EEXIST) { - error = GetLastError(); - - // If a directory by the named path already exists, - // return false (behavior of solaris and linux) instead of - // throwing an exception - a = GetFileAttributes(path); - - if ((a == INVALID_FILE_ATTRIBUTES) || - !(a & FILE_ATTRIBUTE_DIRECTORY)) { - SetLastError(error); - JNU_ThrowIOExceptionWithLastError(env, path); - } - } - } else { - JVM_Close(orv); - rv = JNI_TRUE; - } - } END_PLATFORM_STRING(env, path); - return rv; -} - - -static int -removeFileOrDirectory(const char *path) /* Returns 0 on success */ -{ - DWORD a; - - SetFileAttributes(path, 0); - a = GetFileAttributes(path); - if (a == INVALID_FILE_ATTRIBUTES) { - return 1; - } else if (a & FILE_ATTRIBUTE_DIRECTORY) { - return !RemoveDirectory(path); - } else { - return !DeleteFile(path); - } -} - - -JNIEXPORT jboolean JNICALL -Java_java_io_Win32FileSystem_delete0(JNIEnv *env, jobject this, - jobject file) -{ - jboolean rv = JNI_FALSE; - - WITH_NATIVE_PATH(env, file, ids.path, path) { - if (removeFileOrDirectory(path) == 0) { - rv = JNI_TRUE; - } - } END_NATIVE_PATH(env, path); - return rv; -} - - -/* ## Clean this up to use direct Win32 calls */ - -JNIEXPORT jobjectArray JNICALL -Java_java_io_Win32FileSystem_list(JNIEnv *env, jobject this, - jobject file) -{ - DIR *dir; - struct dirent *ptr; - int len, maxlen; - jobjectArray rv, old; - - WITH_NATIVE_PATH(env, file, ids.path, path) { - dir = opendir(path); - } END_NATIVE_PATH(env, path); - if (dir == NULL) return NULL; - - /* Allocate an initial String array */ - len = 0; - maxlen = 16; - rv = (*env)->NewObjectArray(env, maxlen, JNU_ClassString(env), NULL); - if (rv == NULL) goto error; - - /* Scan the directory */ - while ((ptr = readdir(dir)) != NULL) { - jstring name; - if (!strcmp(ptr->d_name, ".") || !strcmp(ptr->d_name, "..")) - continue; - if (len == maxlen) { - old = rv; - rv = (*env)->NewObjectArray(env, maxlen <<= 1, - JNU_ClassString(env), NULL); - if (rv == NULL) goto error; - if (JNU_CopyObjectArray(env, rv, old, len) < 0) goto error; - (*env)->DeleteLocalRef(env, old); - } - name = JNU_NewStringPlatform(env, ptr->d_name); - if (name == NULL) goto error; - (*env)->SetObjectArrayElement(env, rv, len++, name); - (*env)->DeleteLocalRef(env, name); - } - closedir(dir); - - /* Copy the final results into an appropriately-sized array */ - old = rv; - rv = (*env)->NewObjectArray(env, len, JNU_ClassString(env), NULL); - if (rv == NULL) goto error; - if (JNU_CopyObjectArray(env, rv, old, len) < 0) goto error; - return rv; - - error: - closedir(dir); - return NULL; -} - - -JNIEXPORT jboolean JNICALL -Java_java_io_Win32FileSystem_createDirectory(JNIEnv *env, jobject this, - jobject file) -{ - jboolean rv = JNI_FALSE; - - WITH_NATIVE_PATH(env, file, ids.path, path) { - if (mkdir(path) == 0) { - rv = JNI_TRUE; - } - } END_NATIVE_PATH(env, path); - return rv; -} - - -JNIEXPORT jboolean JNICALL -Java_java_io_Win32FileSystem_rename0(JNIEnv *env, jobject this, - jobject from, jobject to) -{ - jboolean rv = JNI_FALSE; - - WITH_NATIVE_PATH(env, from, ids.path, fromPath) { - WITH_NATIVE_PATH(env, to, ids.path, toPath) { - if (rename(fromPath, toPath) == 0) { - rv = JNI_TRUE; - } - } END_NATIVE_PATH(env, toPath); - } END_NATIVE_PATH(env, fromPath); - return rv; -} - - -JNIEXPORT jboolean JNICALL -Java_java_io_Win32FileSystem_setLastModifiedTime(JNIEnv *env, jobject this, - jobject file, jlong time) -{ - jboolean rv = JNI_FALSE; - - WITH_NATIVE_PATH(env, file, ids.path, path) { - HANDLE h; - h = CreateFile(path, GENERIC_WRITE, 0, NULL, OPEN_EXISTING, - FILE_ATTRIBUTE_NORMAL | FILE_FLAG_BACKUP_SEMANTICS, 0); - if (h != INVALID_HANDLE_VALUE) { - LARGE_INTEGER modTime; - FILETIME t; - modTime.QuadPart = (time + 11644473600000L) * 10000L; - t.dwLowDateTime = (DWORD)modTime.LowPart; - t.dwHighDateTime = (DWORD)modTime.HighPart; - if (SetFileTime(h, NULL, NULL, &t)) { - rv = JNI_TRUE; - } - CloseHandle(h); - } - } END_NATIVE_PATH(env, path); - - return rv; -} - - -JNIEXPORT jboolean JNICALL -Java_java_io_Win32FileSystem_setReadOnly(JNIEnv *env, jobject this, - jobject file) -{ - jboolean rv = JNI_FALSE; - - WITH_NATIVE_PATH(env, file, ids.path, path) { - DWORD a; - a = GetFileAttributes(path); - if (a != INVALID_FILE_ATTRIBUTES) { - if (SetFileAttributes(path, a | FILE_ATTRIBUTE_READONLY)) - rv = JNI_TRUE; - } - } END_NATIVE_PATH(env, path); - return rv; -} - - -/* -- Filesystem interface -- */ - - -JNIEXPORT jobject JNICALL -Java_java_io_Win32FileSystem_getDriveDirectory(JNIEnv *env, jclass ignored, - jint drive) -{ - char buf[_MAX_PATH]; - char *p = _getdcwd(drive, buf, sizeof(buf)); - if (p == NULL) return NULL; - if (isalpha(*p) && (p[1] == ':')) p += 2; - return JNU_NewStringPlatform(env, p); -} - - -JNIEXPORT jint JNICALL -Java_java_io_Win32FileSystem_listRoots0(JNIEnv *env, jclass ignored) -{ - return GetLogicalDrives(); -} - -JNIEXPORT jlong JNICALL -Java_java_io_Win32FileSystem_getSpace0(JNIEnv *env, jobject this, - jobject file, jint t) -{ - jlong rv = 0L; - - WITH_NATIVE_PATH(env, file, ids.path, path) { - ULARGE_INTEGER totalSpace, freeSpace, usableSpace; - if (GetDiskFreeSpaceEx(path, &usableSpace, &totalSpace, &freeSpace)) { - switch(t) { - case java_io_FileSystem_SPACE_TOTAL: - rv = long_to_jlong(totalSpace.QuadPart); - break; - case java_io_FileSystem_SPACE_FREE: - rv = long_to_jlong(freeSpace.QuadPart); - break; - case java_io_FileSystem_SPACE_USABLE: - rv = long_to_jlong(usableSpace.QuadPart); - break; - default: - assert(0); - } - } - } END_NATIVE_PATH(env, path); - return rv; -} diff --git a/jdk/src/windows/native/java/io/WinNTFileSystem_md.c b/jdk/src/windows/native/java/io/WinNTFileSystem_md.c index 7d978294367..96f9f138b92 100644 --- a/jdk/src/windows/native/java/io/WinNTFileSystem_md.c +++ b/jdk/src/windows/native/java/io/WinNTFileSystem_md.c @@ -828,6 +828,12 @@ Java_java_io_WinNTFileSystem_getDriveDirectory(JNIEnv *env, jobject this, return ret; } +JNIEXPORT jint JNICALL +Java_java_io_WinNTFileSystem_listRoots0(JNIEnv *env, jclass ignored) +{ + return GetLogicalDrives(); +} + JNIEXPORT jlong JNICALL Java_java_io_WinNTFileSystem_getSpace0(JNIEnv *env, jobject this, jobject file, jint t) diff --git a/jdk/src/windows/native/java/io/io_util_md.c b/jdk/src/windows/native/java/io/io_util_md.c index 787617e4895..2f0e74fc171 100644 --- a/jdk/src/windows/native/java/io/io_util_md.c +++ b/jdk/src/windows/native/java/io/io_util_md.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2001, 2011, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2001, 2012, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -40,22 +40,8 @@ #include #include -extern jboolean onNT = JNI_FALSE; - static DWORD MAX_INPUT_EVENTS = 2000; -void -initializeWindowsVersion() { - OSVERSIONINFO ver; - ver.dwOSVersionInfoSize = sizeof(ver); - GetVersionEx(&ver); - if (ver.dwPlatformId == VER_PLATFORM_WIN32_NT) { - onNT = JNI_TRUE; - } else { - onNT = JNI_FALSE; - } -} - /* If this returns NULL then an exception is pending */ WCHAR* fileToNTPath(JNIEnv *env, jobject file, jfieldID id) { @@ -247,27 +233,21 @@ winFileHandleOpen(JNIEnv *env, jstring path, int flags) const DWORD flagsAndAttributes = maybeWriteThrough | maybeDeleteOnClose; HANDLE h = NULL; - if (onNT) { - WCHAR *pathbuf = pathToNTPath(env, path, JNI_TRUE); - if (pathbuf == NULL) { - /* Exception already pending */ - return -1; - } - h = CreateFileW( - pathbuf, /* Wide char path name */ - access, /* Read and/or write permission */ - sharing, /* File sharing flags */ - NULL, /* Security attributes */ - disposition, /* creation disposition */ - flagsAndAttributes, /* flags and attributes */ - NULL); - free(pathbuf); - } else { - WITH_PLATFORM_STRING(env, path, _ps) { - h = CreateFile(_ps, access, sharing, NULL, disposition, - flagsAndAttributes, NULL); - } END_PLATFORM_STRING(env, _ps); + WCHAR *pathbuf = pathToNTPath(env, path, JNI_TRUE); + if (pathbuf == NULL) { + /* Exception already pending */ + return -1; } + h = CreateFileW( + pathbuf, /* Wide char path name */ + access, /* Read and/or write permission */ + sharing, /* File sharing flags */ + NULL, /* Security attributes */ + disposition, /* creation disposition */ + flagsAndAttributes, /* flags and attributes */ + NULL); + free(pathbuf); + if (h == INVALID_HANDLE_VALUE) { int error = GetLastError(); if (error == ERROR_TOO_MANY_OPEN_FILES) { diff --git a/jdk/src/windows/native/java/lang/ProcessImpl_md.c b/jdk/src/windows/native/java/lang/ProcessImpl_md.c index ed14eeba1be..dfa59f99efd 100644 --- a/jdk/src/windows/native/java/lang/ProcessImpl_md.c +++ b/jdk/src/windows/native/java/lang/ProcessImpl_md.c @@ -40,72 +40,6 @@ */ #define PIPE_SIZE (4096+24) -char * -extractExecutablePath(JNIEnv *env, char *source) -{ - char *p, *r; - - /* If no spaces, then use entire thing */ - if ((p = strchr(source, ' ')) == NULL) - return source; - - /* If no quotes, or quotes after space, return up to space */ - if (((r = strchr(source, '"')) == NULL) || (r > p)) { - *p = 0; - return source; - } - - /* Quotes before space, return up to space after next quotes */ - p = strchr(r, '"'); - if ((p = strchr(p, ' ')) == NULL) - return source; - *p = 0; - return source; -} - -DWORD -selectProcessFlag(JNIEnv *env, jstring cmd0) -{ - char buf[MAX_PATH]; - DWORD newFlag = 0; - char *exe, *p, *name; - unsigned char buffer[2]; - long headerLoc = 0; - int fd = 0; - - exe = (char *)JNU_GetStringPlatformChars(env, cmd0, 0); - exe = extractExecutablePath(env, exe); - - if (exe != NULL) { - if ((p = strchr(exe, '\\')) == NULL) { - SearchPath(NULL, exe, ".exe", MAX_PATH, buf, &name); - } else { - p = strrchr(exe, '\\'); - *p = 0; - p++; - SearchPath(exe, p, ".exe", MAX_PATH, buf, &name); - } - } - - fd = _open(buf, _O_RDONLY); - if (fd > 0) { - _read(fd, buffer, 2); - if (buffer[0] == 'M' && buffer[1] == 'Z') { - _lseek(fd, 60L, SEEK_SET); - _read(fd, buffer, 2); - headerLoc = (long)buffer[1] << 8 | (long)buffer[0]; - _lseek(fd, headerLoc, SEEK_SET); - _read(fd, buffer, 2); - if (buffer[0] == 'P' && buffer[1] == 'E') { - newFlag = DETACHED_PROCESS; - } - } - _close(fd); - } - JNU_ReleaseStringPlatformChars(env, cmd0, exe); - return newFlag; -} - static void win32Error(JNIEnv *env, const char *functionName) { @@ -151,15 +85,8 @@ Java_java_lang_ProcessImpl_create(JNIEnv *env, jclass ignored, const jchar* penvBlock = NULL; jlong *handles = NULL; jlong ret = 0; - OSVERSIONINFO ver; - jboolean onNT = JNI_FALSE; DWORD processFlag; - ver.dwOSVersionInfoSize = sizeof(ver); - GetVersionEx(&ver); - if (ver.dwPlatformId == VER_PLATFORM_WIN32_NT) - onNT = JNI_TRUE; - assert(cmd != NULL); pcmd = (*env)->GetStringChars(env, cmd, NULL); if (pcmd == NULL) goto Catch; @@ -229,10 +156,7 @@ Java_java_lang_ProcessImpl_create(JNIEnv *env, jclass ignored, } SetHandleInformation(si.hStdError, HANDLE_FLAG_INHERIT, TRUE); - if (onNT) - processFlag = CREATE_NO_WINDOW | CREATE_UNICODE_ENVIRONMENT; - else - processFlag = selectProcessFlag(env, cmd) | CREATE_UNICODE_ENVIRONMENT; + processFlag = CREATE_NO_WINDOW | CREATE_UNICODE_ENVIRONMENT; ret = CreateProcessW(0, /* executable name */ (LPWSTR)pcmd, /* command line */ 0, /* process security attribute */ diff --git a/jdk/src/windows/native/java/util/TimeZone_md.c b/jdk/src/windows/native/java/util/TimeZone_md.c index d29558c2924..57d4b526ba6 100644 --- a/jdk/src/windows/native/java/util/TimeZone_md.c +++ b/jdk/src/windows/native/java/util/TimeZone_md.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 1999, 2010, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1999, 2012, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -65,8 +65,6 @@ static void *keyNames[] = { #define STANDARD_NAME 0 #define STD_NAME 2 -static int isNT = FALSE; /* TRUE if it is NT. */ - /* * Calls RegQueryValueEx() to get the value for the specified key. If * the platform is NT, 2000 or XP, it calls the Unicode @@ -95,12 +93,10 @@ getValueInRegistry(HKEY hKey, int len; *typePtr = 0; - if (isNT) { - ret = RegQueryValueExW(hKey, (WCHAR *) keyNames[keyIndex], NULL, - typePtr, buf, bufLengthPtr); - if (ret == ERROR_SUCCESS && *typePtr == REG_SZ) { - return ret; - } + ret = RegQueryValueExW(hKey, (WCHAR *) keyNames[keyIndex], NULL, + typePtr, buf, bufLengthPtr); + if (ret == ERROR_SUCCESS && *typePtr == REG_SZ) { + return ret; } valSize = sizeof(val); @@ -180,8 +176,7 @@ static int getWinTimeZone(char *winZoneName, char *winMapID) */ ver.dwOSVersionInfoSize = sizeof(ver); GetVersionEx(&ver); - isNT = ver.dwPlatformId == VER_PLATFORM_WIN32_NT; - isVista = isNT && ver.dwMajorVersion >= 6; + isVista = ver.dwMajorVersion >= 6; ret = RegOpenKeyEx(HKEY_LOCAL_MACHINE, WIN_CURRENT_TZ_KEY, 0, KEY_READ, (PHKEY)&hKey); diff --git a/jdk/test/java/io/pathNames/win32/bug6344646.java b/jdk/test/java/io/pathNames/win32/bug6344646.java index d39dd40cf36..30f5aa25e49 100644 --- a/jdk/test/java/io/pathNames/win32/bug6344646.java +++ b/jdk/test/java/io/pathNames/win32/bug6344646.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2005, 2011, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2005, 2012, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -23,7 +23,7 @@ /* @test * @bug 6344646 - * @summary tests that Win32FileSystem.hashCode() uses + * @summary tests that WinNTFileSystem.hashCode() uses * locale independent case mapping. */