Win32FileSystem.java revision 3261
3261N/A * Copyright (c) 1998, 2010, Oracle and/or its affiliates. All rights reserved. 0N/A * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 0N/A * This code is free software; you can redistribute it and/or modify it 0N/A * under the terms of the GNU General Public License version 2 only, as 2362N/A * published by the Free Software Foundation. Oracle designates this 0N/A * particular file as subject to the "Classpath" exception as provided 2362N/A * by Oracle in the LICENSE file that accompanied this code. 0N/A * This code is distributed in the hope that it will be useful, but WITHOUT 0N/A * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 0N/A * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 0N/A * version 2 for more details (a copy is included in the LICENSE file that 0N/A * accompanied this code). 0N/A * You should have received a copy of the GNU General Public License version 0N/A * 2 along with this work; if not, write to the Free Software Foundation, 0N/A * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 2362N/A * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 2362N/A * or visit www.oracle.com if you need additional information or have any 0N/A return (c ==
'\\') || (c ==
'/');
0N/A return ((c >=
'a') && (c <=
'z')) || ((c >=
'A') && (c <=
'Z'));
0N/A /* -- Normalization and construction -- */ 0N/A /* A normal Win32 pathname contains no duplicate slashes, except possibly 0N/A for a UNC prefix, and does not end with a slash. It may be the empty 0N/A string. Normalized Win32 pathnames have the convenient property that 0N/A the length of the prefix almost uniquely identifies the type of the path 0N/A and whether it is absolute or relative: 0N/A 0 relative to both drive and directory 0N/A 1 drive-relative (begins with '\\') 0N/A 2 absolute UNC (if first char is '\\'), 0N/A else directory-relative (has form "z:foo") 0N/A 3 absolute local pathname (begins with "z:\\") 0N/A /* Remove leading slashes if followed by drive specifier. 0N/A This hack is necessary to support file URLs containing drive 0N/A specifiers (e.g., "file://c:/path"). As a side effect, 0N/A "/c:/path" can be used as an alternative to "c:/path". */ 0N/A /* UNC pathname: Retain first slash; leave src pointed at 0N/A second slash so that further slashes will be collapsed 0N/A into the second slash. The result will be a pathname 0N/A beginning with "\\\\" followed (most likely) by a host 0N/A /* Normalize the given pathname, whose length is len, starting at the given 0N/A offset; everything before this offset is already normal. */ 0N/A if (
off <
3)
off =
0;
/* Avoid fencepost cases with UNC pathnames */ 0N/A /* Complete normalization, including prefix */ 0N/A /* Partial normalization */ 0N/A /* Remove redundant slashes from the remainder of the path, forcing all 0N/A slashes into the preferred slash */ 0N/A /* Check for trailing separator */ 0N/A /* "\\\\" is not collapsed to "\\" because "\\\\" marks 0N/A the beginning of a UNC pathname. Even though it is 0N/A not, by itself, a valid UNC pathname, we leave it as 0N/A is in order to be consistent with the win32 APIs, 0N/A which treat this case as an invalid UNC pathname 0N/A rather than as an alias for the root directory of 0N/A the current drive. */ 0N/A /* Path does not denote a root directory, so do not append 0N/A /* Check that the given pathname is normal. If not, invoke the real 0N/A normalizer on the part of the pathname that requires normalization. 0N/A This way we iterate through the whole pathname string only once. */ 0N/A for (
int i =
0; i < n; i++) {
0N/A if ((c ==
':') && (i >
1))
0N/A if (n ==
0)
return 0;
0N/A if (
c1 ==
slash)
return 2;
/* Absolute UNC pathname "\\\\foo" */ 0N/A return 1;
/* Drive-relative "\\foo" */ 0N/A return 3;
/* Absolute local pathname "z:\\foo" */ 0N/A return 2;
/* Directory-relative "z:foo" */ 0N/A return 0;
/* Completely relative */ 0N/A /* Drop prefix when child is a UNC pathname */ 0N/A /* Drop prefix when child is drive-relative */ 0N/A // "/c:/foo" --> "c:/foo" 0N/A // "c:/foo/" --> "c:/foo", but "c:/" --> "c:/" 0N/A // "/foo/" --> "/foo" 0N/A /* -- Path operations -- */ 0N/A if ((d >=
'a') && (d <=
'z'))
return d -
'a';
0N/A if ((d >=
'A') && (d <=
'Z'))
return d -
'A';
0N/A /* For both compatibility and security, 0N/A we must look this up every time */ 0N/A if (
pl ==
1) {
/* Drive-relative */ 0N/A return up +
path;
/* User dir is a UNC path */ 0N/A if (
pl ==
2) {
/* Directory-relative */ 0N/A /* When resolving a directory-relative path that refers to a 0N/A drive other than the current drive, insist that the caller 0N/A have read permission on the result */ 0N/A /* Don't disclose the drive's directory in the exception */ 0N/A // Caches for canonicalization results to improve startup performance. 0N/A // The first cache handles repeated canonicalizations of the same path 0N/A // name. The prefix cache handles repeated canonicalizations within the 0N/A // same directory, and must not create results differing from the true 0N/A // canonicalization algorithm in canonicalize_md.c. For this reason the 0N/A // prefix cache is conservative and is not used for complex path names. 0N/A // If path is a drive letter only then skip canonicalization 0N/A if ((c >=
'A') && (c <=
'Z'))
0N/A return "" + ((
char) (c-
32)) +
':';
0N/A if ((c >=
'A') && (c <=
'Z'))
0N/A return "" + ((
char) (c-
32)) +
':' +
'\\';
0N/A // Hit only in prefix cache; full path is canonical, 0N/A // but we need to get the canonical name of the file 0N/A // in this directory to get the appropriate capitalization 0N/A // Run the canonicalization operation assuming that the prefix 0N/A // (everything up to the last filename) is canonical; just gets 0N/A // the canonical name of the last element of the path 0N/A // Best-effort attempt to get parent of this path; used for 0N/A // optimization of filename canonicalization. This must return null for 0N/A // any cases where the code in canonicalize_md.c would throw an 0N/A // exception or otherwise deal with non-simple pathnames like handling 0N/A // of "." and "..". It may conservatively return null in other 0N/A // situations as well. Returning null will cause the underlying 0N/A // (expensive) canonicalization routine to be called. 0N/A // Punt on pathnames containing . and .. 0N/A // Punt on pathnames ending in a . 0N/A // Punt on pathnames containing . and .. 0N/A // Punt on pathnames containing adjacent slashes 0N/A // Punt on pathnames containing both backward and 0N/A }
else if (c ==
'*' || c ==
'?') {
0N/A // Punt on pathnames containing wildcards 0N/A /* -- Attribute accessors -- */ 0N/A /* -- File operations -- */ 0N/A // Keep canonicalization caches in sync after file deletion 0N/A // and renaming operations. Could be more clever than this 0N/A // not worth it since these entries expire after 30 seconds 0N/A // Keep canonicalization caches in sync after file deletion 0N/A // and renaming operations. Could be more clever than this 0N/A // not worth it since these entries expire after 30 seconds 0N/A /* -- Filesystem interface -- */ 0N/A for (
int i =
0; i <
26; i++) {
0N/A if (((
ds >> i) &
1) !=
0) {
0N/A for (
int i =
0; i <
26; i++) {
0N/A if (((
ds >> i) &
1) !=
0)
0N/A /* -- Disk usage -- */ 0N/A /* -- Basic infrastructure -- */ 0N/A /* Could make this more efficient: String.hashCodeIgnoreCase */