1 /* 2 * Copyright (c) 2008, 2011, Oracle and/or its affiliates. All rights reserved. 3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 4 * 5 * This code is free software; you can redistribute it and/or modify it 6 * under the terms of the GNU General Public License version 2 only, as 7 * published by the Free Software Foundation. Oracle designates this 8 * particular file as subject to the "Classpath" exception as provided 9 * by Oracle in the LICENSE file that accompanied this code. 10 * 11 * This code is distributed in the hope that it will be useful, but WITHOUT 12 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 13 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 14 * version 2 for more details (a copy is included in the LICENSE file that 15 * accompanied this code). 16 * 17 * You should have received a copy of the GNU General Public License version 18 * 2 along with this work; if not, write to the Free Software Foundation, 19 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 20 * 21 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 22 * or visit www.oracle.com if you need additional information or have any 23 * questions. 24 */ 25 26 package sun.nio.fs; 27 28 import java.nio.file.*; 29 import java.nio.file.attribute.*; 30 import java.io.IOException; 31 32 import static sun.nio.fs.WindowsConstants.*; 33 import static sun.nio.fs.WindowsNativeDispatcher.*; 34 35 /** 36 * Windows implementation of FileStore. 37 */ 38 39 class WindowsFileStore 40 extends FileStore 41 { 42 private final String root; 43 private final VolumeInformation volInfo; 44 private final int volType; 45 private final String displayName; // returned by toString 46 47 private WindowsFileStore(String root) throws WindowsException { 48 assert root.charAt(root.length()-1) == '\\'; 49 this.root = root; 50 this.volInfo = GetVolumeInformation(root); 51 this.volType = GetDriveType(root); 52 53 // file store "display name" is the volume name if available 54 String vol = volInfo.volumeName(); 55 if (vol.length() > 0) { 56 this.displayName = vol; 57 } else { 58 // TBD - should we map all types? Does this need to be localized? 59 this.displayName = (volType == DRIVE_REMOVABLE) ? "Removable Disk" : ""; 60 } 61 } 62 63 static WindowsFileStore create(String root, boolean ignoreNotReady) 64 throws IOException 65 { 66 try { 67 return new WindowsFileStore(root); 68 } catch (WindowsException x) { 69 if (ignoreNotReady && x.lastError() == ERROR_NOT_READY) 70 return null; 71 x.rethrowAsIOException(root); 72 return null; // keep compiler happy 73 } 74 } 75 76 static WindowsFileStore create(WindowsPath file) throws IOException { 77 try { 78 // if the file is a link then GetVolumePathName returns the 79 // volume that the link is on so we need to call it with the 80 // final target 81 String target = WindowsLinkSupport.getFinalPath(file, true); 82 try { 83 return createFromPath(target); 84 } catch (WindowsException e) { 85 if (e.lastError() != ERROR_DIR_NOT_ROOT) 86 throw e; 87 target = WindowsLinkSupport.getFinalPath(file); 88 if (target == null) 89 throw new FileSystemException(file.getPathForExceptionMessage(), 90 null, "Couldn't resolve path"); 91 return createFromPath(target); 92 } 93 } catch (WindowsException x) { 94 x.rethrowAsIOException(file); 95 return null; // keep compiler happy 96 } 97 } 98 99 private static WindowsFileStore createFromPath(String target) throws WindowsException { 100 String root = GetVolumePathName(target); 101 return new WindowsFileStore(root); 102 } 103 104 VolumeInformation volumeInformation() { 105 return volInfo; 106 } 107 108 int volumeType() { 109 return volType; 110 } 111 112 @Override 113 public String name() { 114 return volInfo.volumeName(); // "SYSTEM", "DVD-RW", ... 115 } 116 117 @Override 118 public String type() { 119 return volInfo.fileSystemName(); // "FAT", "NTFS", ... 120 } 121 122 @Override 123 public boolean isReadOnly() { 124 return ((volInfo.flags() & FILE_READ_ONLY_VOLUME) != 0); 125 } 126 127 // read the free space info 128 private DiskFreeSpace readDiskFreeSpace() throws IOException { 129 try { 130 return GetDiskFreeSpaceEx(root); 131 } catch (WindowsException x) { 132 x.rethrowAsIOException(root); 133 return null; 134 } 135 } 136 137 @Override 138 public long getTotalSpace() throws IOException { 139 return readDiskFreeSpace().totalNumberOfBytes(); 140 } 141 142 @Override 143 public long getUsableSpace() throws IOException { 144 return readDiskFreeSpace().freeBytesAvailable(); 145 } 146 147 @Override 148 public long getUnallocatedSpace() throws IOException { 149 return readDiskFreeSpace().freeBytesAvailable(); 150 } 151 152 @Override 153 public <V extends FileStoreAttributeView> V getFileStoreAttributeView(Class<V> type) { 154 if (type == null) 155 throw new NullPointerException(); 156 return (V) null; 157 } 158 159 @Override 160 public Object getAttribute(String attribute) throws IOException { 161 // standard 162 if (attribute.equals("totalSpace")) 163 return getTotalSpace(); 164 if (attribute.equals("usableSpace")) 165 return getUsableSpace(); 166 if (attribute.equals("unallocatedSpace")) 167 return getUnallocatedSpace(); 168 // windows specific for testing purposes 169 if (attribute.equals("volume:vsn")) 170 return volInfo.volumeSerialNumber(); 171 if (attribute.equals("volume:isRemovable")) 172 return volType == DRIVE_REMOVABLE; 173 if (attribute.equals("volume:isCdrom")) 174 return volType == DRIVE_CDROM; 175 throw new UnsupportedOperationException("'" + attribute + "' not recognized"); 176 } 177 178 @Override 179 public boolean supportsFileAttributeView(Class<? extends FileAttributeView> type) { 180 if (type == null) 181 throw new NullPointerException(); 182 if (type == BasicFileAttributeView.class || type == DosFileAttributeView.class) 183 return true; 184 if (type == AclFileAttributeView.class || type == FileOwnerAttributeView.class) 185 return ((volInfo.flags() & FILE_PERSISTENT_ACLS) != 0); 186 if (type == UserDefinedFileAttributeView.class) 187 return ((volInfo.flags() & FILE_NAMED_STREAMS) != 0); 188 return false; 189 } 190 191 @Override 192 public boolean supportsFileAttributeView(String name) { 193 if (name.equals("basic") || name.equals("dos")) 194 return true; 195 if (name.equals("acl")) 196 return supportsFileAttributeView(AclFileAttributeView.class); 197 if (name.equals("owner")) 198 return supportsFileAttributeView(FileOwnerAttributeView.class); 199 if (name.equals("user")) 200 return supportsFileAttributeView(UserDefinedFileAttributeView.class); 201 return false; 202 } 203 204 @Override 205 public boolean equals(Object ob) { 206 if (ob == this) 207 return true; 208 if (!(ob instanceof WindowsFileStore)) 209 return false; 210 WindowsFileStore other = (WindowsFileStore)ob; 211 return root.equals(other.root); 212 } 213 214 @Override 215 public int hashCode() { 216 return root.hashCode(); 217 } 218 219 @Override 220 public String toString() { 221 StringBuilder sb = new StringBuilder(displayName); 222 if (sb.length() > 0) 223 sb.append(" "); 224 sb.append("("); 225 // drop trailing slash 226 sb.append(root.subSequence(0, root.length()-1)); 227 sb.append(")"); 228 return sb.toString(); 229 } 230 }