mirror of
https://github.com/openjdk/jdk.git
synced 2026-03-01 03:30:34 +00:00
250 lines
8.3 KiB
Java
250 lines
8.3 KiB
Java
/*
|
|
* Copyright (c) 2008, 2019, 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 sun.nio.fs;
|
|
|
|
import java.nio.file.*;
|
|
import java.nio.file.attribute.*;
|
|
import java.io.IOException;
|
|
|
|
import static sun.nio.fs.WindowsConstants.*;
|
|
import static sun.nio.fs.WindowsNativeDispatcher.*;
|
|
|
|
/**
|
|
* Windows implementation of FileStore.
|
|
*/
|
|
|
|
class WindowsFileStore
|
|
extends FileStore
|
|
{
|
|
private final String root;
|
|
private final VolumeInformation volInfo;
|
|
private final int volType;
|
|
private final String displayName; // returned by toString
|
|
|
|
private WindowsFileStore(String root) throws WindowsException {
|
|
assert root.charAt(root.length()-1) == '\\';
|
|
this.root = root;
|
|
this.volInfo = GetVolumeInformation(root);
|
|
this.volType = GetDriveType(root);
|
|
|
|
// file store "display name" is the volume name if available
|
|
String vol = volInfo.volumeName();
|
|
if (!vol.isEmpty()) {
|
|
this.displayName = vol;
|
|
} else {
|
|
// TBD - should we map all types? Does this need to be localized?
|
|
this.displayName = (volType == DRIVE_REMOVABLE) ? "Removable Disk" : "";
|
|
}
|
|
}
|
|
|
|
static WindowsFileStore create(String root, boolean ignoreNotReady)
|
|
throws IOException
|
|
{
|
|
try {
|
|
return new WindowsFileStore(root);
|
|
} catch (WindowsException x) {
|
|
if (ignoreNotReady && x.lastError() == ERROR_NOT_READY)
|
|
return null;
|
|
x.rethrowAsIOException(root);
|
|
return null; // keep compiler happy
|
|
}
|
|
}
|
|
|
|
static WindowsFileStore create(WindowsPath file) throws IOException {
|
|
try {
|
|
// if the file is a link then GetVolumePathName returns the
|
|
// volume that the link is on so we need to call it with the
|
|
// final target
|
|
String target = WindowsLinkSupport.getFinalPath(file, true);
|
|
try {
|
|
return createFromPath(target);
|
|
} catch (WindowsException e) {
|
|
if (e.lastError() != ERROR_DIR_NOT_ROOT)
|
|
throw e;
|
|
target = WindowsLinkSupport.getFinalPath(file);
|
|
if (target == null)
|
|
throw new FileSystemException(file.getPathForExceptionMessage(),
|
|
null, "Couldn't resolve path");
|
|
return createFromPath(target);
|
|
}
|
|
} catch (WindowsException x) {
|
|
x.rethrowAsIOException(file);
|
|
return null; // keep compiler happy
|
|
}
|
|
}
|
|
|
|
private static WindowsFileStore createFromPath(String target) throws WindowsException {
|
|
String root = GetVolumePathName(target);
|
|
return new WindowsFileStore(root);
|
|
}
|
|
|
|
VolumeInformation volumeInformation() {
|
|
return volInfo;
|
|
}
|
|
|
|
int volumeType() {
|
|
return volType;
|
|
}
|
|
|
|
@Override
|
|
public String name() {
|
|
return volInfo.volumeName(); // "SYSTEM", "DVD-RW", ...
|
|
}
|
|
|
|
@Override
|
|
public String type() {
|
|
return volInfo.fileSystemName(); // "FAT", "NTFS", ...
|
|
}
|
|
|
|
@Override
|
|
public boolean isReadOnly() {
|
|
return ((volInfo.flags() & FILE_READ_ONLY_VOLUME) != 0);
|
|
}
|
|
|
|
// read the free space info
|
|
private DiskFreeSpace readDiskFreeSpaceEx() throws IOException {
|
|
try {
|
|
return GetDiskFreeSpaceEx(root);
|
|
} catch (WindowsException x) {
|
|
x.rethrowAsIOException(root);
|
|
return null;
|
|
}
|
|
}
|
|
|
|
private DiskFreeSpace readDiskFreeSpace() throws IOException {
|
|
try {
|
|
return GetDiskFreeSpace(root);
|
|
} catch (WindowsException x) {
|
|
x.rethrowAsIOException(root);
|
|
return null;
|
|
}
|
|
}
|
|
|
|
@Override
|
|
public long getTotalSpace() throws IOException {
|
|
long space = readDiskFreeSpaceEx().totalNumberOfBytes();
|
|
return space >= 0 ? space : Long.MAX_VALUE;
|
|
}
|
|
|
|
@Override
|
|
public long getUsableSpace() throws IOException {
|
|
long space = readDiskFreeSpaceEx().freeBytesAvailable();
|
|
return space >= 0 ? space : Long.MAX_VALUE;
|
|
}
|
|
|
|
@Override
|
|
public long getUnallocatedSpace() throws IOException {
|
|
long space = readDiskFreeSpaceEx().freeBytesAvailable();
|
|
return space >= 0 ? space : Long.MAX_VALUE;
|
|
}
|
|
|
|
@Override
|
|
public long getBlockSize() throws IOException {
|
|
return readDiskFreeSpace().bytesPerSector();
|
|
}
|
|
|
|
@Override
|
|
public <V extends FileStoreAttributeView> V getFileStoreAttributeView(Class<V> type) {
|
|
if (type == null)
|
|
throw new NullPointerException();
|
|
return (V) null;
|
|
}
|
|
|
|
@Override
|
|
public Object getAttribute(String attribute) throws IOException {
|
|
// standard
|
|
if (attribute.equals("totalSpace"))
|
|
return getTotalSpace();
|
|
if (attribute.equals("usableSpace"))
|
|
return getUsableSpace();
|
|
if (attribute.equals("unallocatedSpace"))
|
|
return getUnallocatedSpace();
|
|
if (attribute.equals("bytesPerSector"))
|
|
return getBlockSize();
|
|
// windows specific for testing purposes
|
|
if (attribute.equals("volume:vsn"))
|
|
return volInfo.volumeSerialNumber();
|
|
if (attribute.equals("volume:isRemovable"))
|
|
return volType == DRIVE_REMOVABLE;
|
|
if (attribute.equals("volume:isCdrom"))
|
|
return volType == DRIVE_CDROM;
|
|
throw new UnsupportedOperationException("'" + attribute + "' not recognized");
|
|
}
|
|
|
|
@Override
|
|
public boolean supportsFileAttributeView(Class<? extends FileAttributeView> type) {
|
|
if (type == null)
|
|
throw new NullPointerException();
|
|
if (type == BasicFileAttributeView.class || type == DosFileAttributeView.class)
|
|
return true;
|
|
if (type == AclFileAttributeView.class || type == FileOwnerAttributeView.class)
|
|
return ((volInfo.flags() & FILE_PERSISTENT_ACLS) != 0);
|
|
if (type == UserDefinedFileAttributeView.class)
|
|
return ((volInfo.flags() & FILE_NAMED_STREAMS) != 0);
|
|
return false;
|
|
}
|
|
|
|
@Override
|
|
public boolean supportsFileAttributeView(String name) {
|
|
if (name.equals("basic") || name.equals("dos"))
|
|
return true;
|
|
if (name.equals("acl"))
|
|
return supportsFileAttributeView(AclFileAttributeView.class);
|
|
if (name.equals("owner"))
|
|
return supportsFileAttributeView(FileOwnerAttributeView.class);
|
|
if (name.equals("user"))
|
|
return supportsFileAttributeView(UserDefinedFileAttributeView.class);
|
|
return false;
|
|
}
|
|
|
|
@Override
|
|
public boolean equals(Object ob) {
|
|
if (ob == this)
|
|
return true;
|
|
if (!(ob instanceof WindowsFileStore))
|
|
return false;
|
|
WindowsFileStore other = (WindowsFileStore)ob;
|
|
return root.equals(other.root);
|
|
}
|
|
|
|
@Override
|
|
public int hashCode() {
|
|
return root.hashCode();
|
|
}
|
|
|
|
@Override
|
|
public String toString() {
|
|
StringBuilder sb = new StringBuilder(displayName);
|
|
if (sb.length() > 0)
|
|
sb.append(" ");
|
|
sb.append("(");
|
|
// drop trailing slash
|
|
sb.append(root.subSequence(0, root.length()-1));
|
|
sb.append(")");
|
|
return sb.toString();
|
|
}
|
|
}
|