Merge pull request #796 from alesliehughes/master
[mono.git] / mcs / class / corlib / System.IO / DriveInfo.cs
index d421ea4254be738a5b1768cb3d712adb2c3b0c8e..6c4c7eee87ce0b3a2563058aeed2b769b3bcff3c 100644 (file)
 // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
 //
 
-#if NET_2_0
 using System;
-using System.Collections;
+using System.Collections.Generic;
 using System.Text;
 using System.Runtime.Serialization;
+using System.Runtime.CompilerServices;
 using System.Runtime.InteropServices;
 
 namespace System.IO {
        [SerializableAttribute] 
        [ComVisibleAttribute(true)] 
        public sealed class DriveInfo : ISerializable {
-               _DriveType _drive_type;
-               DriveType drive_type;
                string drive_format;
                string path;
 
-               DriveInfo (_DriveType _drive_type, string path, string fstype)
+               DriveInfo (string path, string fstype)
                {
-                       this._drive_type = _drive_type;
                        this.drive_format = fstype;
                        this.path = path;
-
-                       this.drive_type = ToDriveType (_drive_type, fstype);
                }
 
                public DriveInfo (string driveName)
                {
-                       DriveInfo [] drives = GetDrives ();
+                       if (!Environment.IsUnix) {
+                               if (driveName == null || driveName.Length == 0)
+                                       throw new ArgumentException ("The drive name is null or empty", "driveName");
+
+                               if (driveName.Length >= 2 && driveName [1] != ':')
+                                       throw new ArgumentException ("Invalid drive name", "driveName");
 
+                               // Convert the path to a standard format so we can find it later.
+                               driveName = String.Concat (Char.ToUpperInvariant (driveName [0]).ToString (), ":\\");
+                       }
+
+                       DriveInfo [] drives = GetDrives ();
                        foreach (DriveInfo d in drives){
                                if (d.path == driveName){
                                        this.path = d.path;
-                                       this.drive_type = d.drive_type;
                                        this.drive_format = d.drive_format;
                                        this.path = d.path;
-                                       this._drive_type = d._drive_type;
                                        return;
                                }
                        }
                        throw new ArgumentException ("The drive name does not exist", "driveName");
                }
                
-               enum _DriveType {
-                       GenericUnix,
-                       Linux,
-                       Windows,
+               static void GetDiskFreeSpace (string path, out ulong availableFreeSpace, out ulong totalSize, out ulong totalFreeSpace)
+               {
+                       MonoIOError error;
+                       if (!GetDiskFreeSpaceInternal (path, out availableFreeSpace, out totalSize, out totalFreeSpace, out error))
+                               throw MonoIO.GetException (path, error);
                }
-               
-               [MonoTODO("Always returns infinite")]
+
                public long AvailableFreeSpace {
                        get {
-                               if (DriveType == DriveType.CDRom || DriveType == DriveType.Ram || DriveType == DriveType.Unknown)
-                                       return 0;
-                               return Int64.MaxValue;
+                               ulong availableFreeSpace;
+                               ulong totalSize;
+                               ulong totalFreeSpace;
+
+                               GetDiskFreeSpace (path, out availableFreeSpace, out totalSize, out totalFreeSpace);
+                               return availableFreeSpace > long.MaxValue ?  long.MaxValue : (long) availableFreeSpace;
                        }
                }
 
-               [MonoTODO("Always returns infinite")]
                public long TotalFreeSpace {
                        get {
-                               if (DriveType == DriveType.CDRom || DriveType == DriveType.Ram || DriveType == DriveType.Unknown)
-                                       return 0;
-                               return Int64.MaxValue;
+                               ulong availableFreeSpace;
+                               ulong totalSize;
+                               ulong totalFreeSpace;
+
+                               GetDiskFreeSpace (path, out availableFreeSpace, out totalSize, out totalFreeSpace);
+                               return totalFreeSpace > long.MaxValue ?  long.MaxValue : (long) totalFreeSpace;
                        }
                }
 
-               [MonoTODO("Always returns infinite")]
                public long TotalSize {
                        get {
-                               return Int64.MaxValue;
+                               ulong availableFreeSpace;
+                               ulong totalSize;
+                               ulong totalFreeSpace;
+
+                               GetDiskFreeSpace (path, out availableFreeSpace, out totalSize, out totalFreeSpace);
+                               return totalSize > long.MaxValue ?  long.MaxValue : (long) totalSize;
                        }
                }
 
-               [MonoTODO ("Currently only works on Mono/Unix")]
+               [MonoTODO ("Currently get only works on Mono/Unix; set not implemented")]
                public string VolumeLabel {
                        get {
-                               if (_drive_type != _DriveType.Windows)
-                                       return path;
-                               else
-                                       return path;
+                               return path;
+                       }
+                       set {
+                               throw new NotImplementedException ();
                        }
                }
                
@@ -110,52 +122,9 @@ namespace System.IO {
                        }
                }
 
-               static DriveType ToDriveType (_DriveType drive_type, string drive_format)
-               {
-                       if (drive_type == _DriveType.Linux){
-                               switch (drive_format){
-                               case "tmpfs":
-                               case "ramfs":
-                                       return DriveType.Ram;
-                               case "iso9660":
-                                       return DriveType.CDRom;
-                               case "ext2":
-                               case "ext3":
-                               case "sysv":
-                               case "reiserfs":
-                               case "ufs":
-                               case "vfat":
-                               case "udf":
-                               case "hfs":
-                               case "hpfs":
-                               case "qnx4":
-                                       return DriveType.Fixed;
-                               case "smbfs":
-                               case "fuse":
-                               case "nfs":
-                               case "nfs4":
-                               case "cifs":
-                               case "ncpfs":
-                               case "coda":
-                               case "afs":
-                                       return DriveType.Network;
-                               case "proc":
-                               case "sysfs":
-                               case "debugfs":
-                               case "devpts":
-                               case "securityfs":
-                                       return DriveType.Ram;
-                               default:
-                                       return DriveType.Unknown;
-                               }
-                       } else {
-                               return DriveType.Fixed;
-                       }
-               }
-               
                public DriveType DriveType {
                        get {
-                               return drive_type;
+                               return (DriveType) GetDriveTypeInternal (path);
                        }
                }
 
@@ -174,102 +143,41 @@ namespace System.IO {
                [MonoTODO("It always returns true")]
                public bool IsReady {
                        get {
-                               if (_drive_type != _DriveType.Windows)
-                                       return true;
-
-                               // Do something for Windows here.
                                return true;
                        }
                }
                
-               static StreamReader TryOpen (string name)
-               {
-                       if (File.Exists (name))
-                               return new StreamReader (name, Encoding.ASCII);
-                       return null;
-               }
-
-               static DriveInfo [] LinuxGetDrives ()
-               {
-                       using (StreamReader mounts = TryOpen ("/proc/mounts")){
-                               ArrayList drives = new ArrayList ();
-                               string line;
-                               
-                               while ((line = mounts.ReadLine ()) != null){
-                                       if (line.StartsWith ("rootfs"))
-                                               continue;
-                                       int p;
-
-                                       p = line.IndexOf (' ');
-                                       if (p == -1)
-                                               continue;
-                                       string rest = line.Substring (p+1);
-                                       p = rest.IndexOf (' ');
-                                       if (p == -1)
-                                               continue;
-                                       string path = rest.Substring (0, p);
-                                       rest = rest.Substring (p+1);
-                                       p = rest.IndexOf (' ');
-                                       if (p == -1)
-                                               continue;
-                                       string fstype = rest.Substring (0, p);
-                                       drives.Add (new DriveInfo (_DriveType.Linux, path, fstype));
-                               }
-
-                               return (DriveInfo []) drives.ToArray (typeof (DriveInfo));
-                       }
-               }
-               
-               static DriveInfo [] UnixGetDrives ()
+               [MonoTODO("In windows, alldrives are 'Fixed'")]
+               public static DriveInfo[] GetDrives ()
                {
-                       DriveInfo [] di = null;
-
-                       try {
-                               using (StreamReader linux_ostype = TryOpen ("/proc/sys/kernel/ostype")){
-                                       Console.WriteLine ("here {0}", linux_ostype);
-                                       if (linux_ostype != null){
-                                               string line = linux_ostype.ReadLine ();
-
-                                               Console.WriteLine ("L: {0}", line);
-                                               if (line == "Linux")
-                                                       di = LinuxGetDrives ();
-                                       }
-                               }
-                               
-                               if (di != null)
-                                       return di;
-                       } catch (Exception e) {
-                               Console.WriteLine ("Got {0}", e);
-                               // If anything happens.
-                       }
-                       
-                       DriveInfo [] unknown = new DriveInfo [1];
-                       unknown [0]= new DriveInfo (_DriveType.GenericUnix, "/", "unixfs");
+                       var drives = Environment.GetLogicalDrives ();
+                       DriveInfo [] infos = new DriveInfo [drives.Length];
+                       int i = 0;
+                       foreach (string s in drives)
+                               infos [i++] = new DriveInfo (s, GetDriveFormat (s));
 
-                       return unknown;
+                       return infos;
                }
 
-               static DriveInfo [] WindowsGetDrives ()
+               void ISerializable.GetObjectData (System.Runtime.Serialization.SerializationInfo info, System.Runtime.Serialization.StreamingContext context)
                {
                        throw new NotImplementedException ();
                }
-               
-               [MonoTODO("Currently only implemented on Mono/Linux")]
-               public static DriveInfo[] GetDrives ()
-               {
-                       int platform = (int) Environment.Platform;
-
-                       if (platform == 4 || platform == 128)
-                               return UnixGetDrives ();
-                       else
-                               return WindowsGetDrives ();
-               }
 
-               public void GetObjectData (System.Runtime.Serialization.SerializationInfo info, System.Runtime.Serialization.StreamingContext context)
+               public override string ToString ()
                {
-                       throw new NotImplementedException ();
+                       return(Name);
                }
+
+               [MethodImplAttribute (MethodImplOptions.InternalCall)]
+               extern static bool GetDiskFreeSpaceInternal (string pathName, out ulong freeBytesAvail,
+                                                            out ulong totalNumberOfBytes, out ulong totalNumberOfFreeBytes,
+                                                            out MonoIOError error);
+
+               [MethodImplAttribute (MethodImplOptions.InternalCall)]
+               extern static uint GetDriveTypeInternal (string rootPathName);
+
+               [MethodImplAttribute (MethodImplOptions.InternalCall)]
+               extern static string GetDriveFormat (string rootPathName);
        }
 }
-
-#endif