1 // Licensed to the .NET Foundation under one or more agreements. 2 // The .NET Foundation licenses this file to you under the MIT license. 3 // See the LICENSE file in the project root for more information. 4 5 using System.Collections.Generic; 6 using System.Security; 7 8 namespace System.IO 9 { 10 public sealed partial class DriveInfo 11 { GetDrives()12 public static DriveInfo[] GetDrives() 13 { 14 string[] mountPoints = Interop.Sys.GetAllMountPoints(); 15 DriveInfo[] info = new DriveInfo[mountPoints.Length]; 16 for (int i = 0; i < info.Length; i++) 17 { 18 info[i] = new DriveInfo(mountPoints[i]); 19 } 20 21 return info; 22 } 23 NormalizeDriveName(string driveName)24 private static string NormalizeDriveName(string driveName) 25 { 26 if (driveName.Contains("\0")) 27 { 28 throw new ArgumentException(SR.Format(SR.Arg_InvalidDriveChars, driveName), nameof(driveName)); 29 } 30 if (driveName.Length == 0) 31 { 32 throw new ArgumentException(SR.Arg_MustBeNonEmptyDriveName, nameof(driveName)); 33 } 34 return driveName; 35 } 36 37 public DriveType DriveType 38 { 39 get 40 { 41 DriveType type; 42 int result = Interop.Sys.GetFormatInfoForMountPoint(Name, out type); 43 if (result == 0) 44 { 45 return type; 46 } 47 else 48 { 49 Interop.ErrorInfo errorInfo = Interop.Sys.GetLastErrorInfo(); 50 51 // This is one of the few properties that doesn't throw on failure, 52 // instead returning a value from the enum. 53 switch (errorInfo.Error) 54 { 55 case Interop.Error.ELOOP: 56 case Interop.Error.ENAMETOOLONG: 57 case Interop.Error.ENOENT: 58 case Interop.Error.ENOTDIR: 59 return DriveType.NoRootDirectory; 60 default: 61 return DriveType.Unknown; 62 } 63 } 64 } 65 } 66 67 public string DriveFormat 68 { 69 get 70 { 71 string format = string.Empty; 72 CheckStatfsResultAndThrowIfNecessary(Interop.Sys.GetFormatInfoForMountPoint(Name, out format)); 73 return format; 74 } 75 } 76 77 public long AvailableFreeSpace 78 { 79 get 80 { 81 Interop.Sys.MountPointInformation mpi = default(Interop.Sys.MountPointInformation); 82 CheckStatfsResultAndThrowIfNecessary(Interop.Sys.GetSpaceInfoForMountPoint(Name, out mpi)); 83 return checked((long)mpi.AvailableFreeSpace); 84 } 85 } 86 87 public long TotalFreeSpace 88 { 89 get 90 { 91 Interop.Sys.MountPointInformation mpi = default(Interop.Sys.MountPointInformation); 92 CheckStatfsResultAndThrowIfNecessary(Interop.Sys.GetSpaceInfoForMountPoint(Name, out mpi)); 93 return checked((long)mpi.TotalFreeSpace); 94 } 95 } 96 97 public long TotalSize 98 { 99 get 100 { 101 Interop.Sys.MountPointInformation mpi = default(Interop.Sys.MountPointInformation); 102 CheckStatfsResultAndThrowIfNecessary(Interop.Sys.GetSpaceInfoForMountPoint(Name, out mpi)); 103 return checked((long)mpi.TotalSize); 104 } 105 } 106 107 public string VolumeLabel 108 { 109 get 110 { 111 return Name; 112 } 113 set 114 { 115 throw new PlatformNotSupportedException(); 116 } 117 } 118 119 // ----------------------------- 120 // ---- PAL layer ends here ---- 121 // ----------------------------- 122 CheckStatfsResultAndThrowIfNecessary(int result)123 private void CheckStatfsResultAndThrowIfNecessary(int result) 124 { 125 if (result != 0) 126 { 127 var errorInfo = Interop.Sys.GetLastErrorInfo(); 128 if (errorInfo.Error == Interop.Error.ENOENT) 129 { 130 throw new DriveNotFoundException(SR.Format(SR.IO_DriveNotFound_Drive, Name)); // match Win32 131 } 132 else 133 { 134 throw Interop.GetExceptionForIoErrno(errorInfo, isDirectory: true); 135 } 136 } 137 } 138 } 139 } 140