Path: blob/master/src/java.base/windows/classes/sun/nio/fs/WindowsFileSystem.java
41139 views
/*1* Copyright (c) 2008, 2021, Oracle and/or its affiliates. All rights reserved.2* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.3*4* This code is free software; you can redistribute it and/or modify it5* under the terms of the GNU General Public License version 2 only, as6* published by the Free Software Foundation. Oracle designates this7* particular file as subject to the "Classpath" exception as provided8* by Oracle in the LICENSE file that accompanied this code.9*10* This code is distributed in the hope that it will be useful, but WITHOUT11* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or12* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License13* version 2 for more details (a copy is included in the LICENSE file that14* accompanied this code).15*16* You should have received a copy of the GNU General Public License version17* 2 along with this work; if not, write to the Free Software Foundation,18* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.19*20* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA21* or visit www.oracle.com if you need additional information or have any22* questions.23*/2425package sun.nio.fs;2627import java.nio.file.*;28import java.nio.file.attribute.*;29import java.nio.file.spi.*;30import java.util.*;31import java.util.regex.Pattern;32import java.io.IOException;3334class WindowsFileSystem35extends FileSystem36{37private final WindowsFileSystemProvider provider;3839// default directory (is absolute), and default root40private final String defaultDirectory;41private final String defaultRoot;4243// package-private44WindowsFileSystem(WindowsFileSystemProvider provider,45String dir)46{47this.provider = provider;4849// parse default directory and check it is absolute50WindowsPathParser.Result result = WindowsPathParser.parse(dir);5152if ((result.type() != WindowsPathType.ABSOLUTE) &&53(result.type() != WindowsPathType.UNC))54throw new AssertionError("Default directory is not an absolute path");55this.defaultDirectory = result.path();56this.defaultRoot = result.root();57}5859// package-private60String defaultDirectory() {61return defaultDirectory;62}6364String defaultRoot() {65return defaultRoot;66}6768@Override69public FileSystemProvider provider() {70return provider;71}7273@Override74public String getSeparator() {75return "\\";76}7778@Override79public boolean isOpen() {80return true;81}8283@Override84public boolean isReadOnly() {85return false;86}8788@Override89public void close() throws IOException {90throw new UnsupportedOperationException();91}9293@Override94public Iterable<Path> getRootDirectories() {95int drives = 0;96try {97drives = WindowsNativeDispatcher.GetLogicalDrives();98} catch (WindowsException x) {99// shouldn't happen100throw new AssertionError(x.getMessage());101}102103// iterate over roots, ignoring those that the security manager denies104ArrayList<Path> result = new ArrayList<>();105@SuppressWarnings("removal")106SecurityManager sm = System.getSecurityManager();107for (int i = 0; i <= 25; i++) { // 0->A, 1->B, 2->C...108if ((drives & (1 << i)) != 0) {109StringBuilder sb = new StringBuilder(3);110sb.append((char)('A' + i));111sb.append(":\\");112String root = sb.toString();113if (sm != null) {114try {115sm.checkRead(root);116} catch (SecurityException x) {117continue;118}119}120result.add(WindowsPath.createFromNormalizedPath(this, root));121}122}123return Collections.unmodifiableList(result);124}125126/**127* Iterator returned by getFileStores method.128*/129private class FileStoreIterator implements Iterator<FileStore> {130private final Iterator<Path> roots;131private FileStore next;132133FileStoreIterator() {134this.roots = getRootDirectories().iterator();135}136137private FileStore readNext() {138assert Thread.holdsLock(this);139for (;;) {140if (!roots.hasNext())141return null;142WindowsPath root = (WindowsPath)roots.next();143// ignore if security manager denies access144try {145root.checkRead();146} catch (SecurityException x) {147continue;148}149try {150FileStore fs = WindowsFileStore.create(root.toString(), true);151if (fs != null)152return fs;153} catch (IOException ioe) {154// skip it155}156}157}158159@Override160public synchronized boolean hasNext() {161if (next != null)162return true;163next = readNext();164return next != null;165}166167@Override168public synchronized FileStore next() {169if (next == null)170next = readNext();171if (next == null) {172throw new NoSuchElementException();173} else {174FileStore result = next;175next = null;176return result;177}178}179180@Override181public void remove() {182throw new UnsupportedOperationException();183}184}185186@Override187public Iterable<FileStore> getFileStores() {188@SuppressWarnings("removal")189SecurityManager sm = System.getSecurityManager();190if (sm != null) {191try {192sm.checkPermission(new RuntimePermission("getFileStoreAttributes"));193} catch (SecurityException se) {194return Collections.emptyList();195}196}197return new Iterable<FileStore>() {198public Iterator<FileStore> iterator() {199return new FileStoreIterator();200}201};202}203204// supported views205private static final Set<String> supportedFileAttributeViews = Collections206.unmodifiableSet(new HashSet<String>(Arrays.asList("basic", "dos", "acl", "owner", "user")));207208@Override209public Set<String> supportedFileAttributeViews() {210return supportedFileAttributeViews;211}212213@Override214public final Path getPath(String first, String... more) {215Objects.requireNonNull(first);216String path;217if (more.length == 0) {218path = first;219} else {220StringBuilder sb = new StringBuilder();221sb.append(first);222for (String segment: more) {223if (!segment.isEmpty()) {224if (sb.length() > 0)225sb.append('\\');226sb.append(segment);227}228}229path = sb.toString();230}231return WindowsPath.parse(this, path);232}233234@Override235public UserPrincipalLookupService getUserPrincipalLookupService() {236return LookupService.instance;237}238239private static class LookupService {240static final UserPrincipalLookupService instance =241new UserPrincipalLookupService() {242@Override243public UserPrincipal lookupPrincipalByName(String name)244throws IOException245{246return WindowsUserPrincipals.lookup(name);247}248@Override249public GroupPrincipal lookupPrincipalByGroupName(String group)250throws IOException251{252UserPrincipal user = WindowsUserPrincipals.lookup(group);253if (!(user instanceof GroupPrincipal))254throw new UserPrincipalNotFoundException(group);255return (GroupPrincipal)user;256}257};258}259260@Override261public PathMatcher getPathMatcher(String syntaxAndInput) {262int pos = syntaxAndInput.indexOf(':');263if (pos <= 0 || pos == syntaxAndInput.length())264throw new IllegalArgumentException();265String syntax = syntaxAndInput.substring(0, pos);266String input = syntaxAndInput.substring(pos+1);267268String expr;269if (syntax.equalsIgnoreCase(GLOB_SYNTAX)) {270expr = Globs.toWindowsRegexPattern(input);271} else {272if (syntax.equalsIgnoreCase(REGEX_SYNTAX)) {273expr = input;274} else {275throw new UnsupportedOperationException("Syntax '" + syntax +276"' not recognized");277}278}279280// match in unicode_case_insensitive281final Pattern pattern = Pattern.compile(expr,282Pattern.CASE_INSENSITIVE | Pattern.UNICODE_CASE);283284// return matcher285return new PathMatcher() {286@Override287public boolean matches(Path path) {288return pattern.matcher(path.toString()).matches();289}290};291}292private static final String GLOB_SYNTAX = "glob";293private static final String REGEX_SYNTAX = "regex";294295@Override296public WatchService newWatchService()297throws IOException298{299return new WindowsWatchService(this);300}301}302303304