Normalize line endings.
[mono.git] / mcs / class / corlib / System.IO / DriveInfo.cs
1 //
2 // Copyright (C) 2006 Novell, Inc (http://www.novell.com)
3 //
4 // Permission is hereby granted, free of charge, to any person obtaining
5 // a copy of this software and associated documentation files (the
6 // "Software"), to deal in the Software without restriction, including
7 // without limitation the rights to use, copy, modify, merge, publish,
8 // distribute, sublicense, and/or sell copies of the Software, and to
9 // permit persons to whom the Software is furnished to do so, subject to
10 // the following conditions:
11 // 
12 // The above copyright notice and this permission notice shall be
13 // included in all copies or substantial portions of the Software.
14 // 
15 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
16 // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
17 // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
18 // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
19 // LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
20 // OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
21 // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
22 //
23
24 using System;
25 using System.Collections;
26 using System.Text;
27 using System.Runtime.Serialization;
28 using System.Runtime.CompilerServices;
29 using System.Runtime.InteropServices;
30
31 namespace System.IO {
32         [SerializableAttribute] 
33         [ComVisibleAttribute(true)] 
34         public sealed class DriveInfo : ISerializable {
35                 _DriveType _drive_type;
36                 string drive_format;
37                 string path;
38
39                 DriveInfo (_DriveType _drive_type, string path, string fstype)
40                 {
41                         this._drive_type = _drive_type;
42                         this.drive_format = fstype;
43                         this.path = path;
44                 }
45
46                 public DriveInfo (string driveName)
47                 {
48                         DriveInfo [] drives = GetDrives ();
49
50                         foreach (DriveInfo d in drives){
51                                 if (d.path == driveName){
52                                         this.path = d.path;
53                                         this.drive_format = d.drive_format;
54                                         this.path = d.path;
55                                         return;
56                                 }
57                         }
58                         throw new ArgumentException ("The drive name does not exist", "driveName");
59                 }
60                 
61                 enum _DriveType {
62                         GenericUnix,
63                         Linux,
64                         Windows,
65                 }
66
67                 static void GetDiskFreeSpace (string path, out ulong availableFreeSpace, out ulong totalSize, out ulong totalFreeSpace)
68                 {
69                         MonoIOError error;
70                         if (!GetDiskFreeSpaceInternal (path, out availableFreeSpace, out totalSize, out totalFreeSpace, out error))
71                                 throw MonoIO.GetException (path, error);
72                 }
73
74                 public long AvailableFreeSpace {
75                         get {
76                                 ulong availableFreeSpace;
77                                 ulong totalSize;
78                                 ulong totalFreeSpace;
79
80                                 GetDiskFreeSpace (path, out availableFreeSpace, out totalSize, out totalFreeSpace);
81                                 return availableFreeSpace > long.MaxValue ?  long.MaxValue : (long) availableFreeSpace;
82                         }
83                 }
84
85                 public long TotalFreeSpace {
86                         get {
87                                 ulong availableFreeSpace;
88                                 ulong totalSize;
89                                 ulong totalFreeSpace;
90
91                                 GetDiskFreeSpace (path, out availableFreeSpace, out totalSize, out totalFreeSpace);
92                                 return totalFreeSpace > long.MaxValue ?  long.MaxValue : (long) totalFreeSpace;
93                         }
94                 }
95
96                 public long TotalSize {
97                         get {
98                                 ulong availableFreeSpace;
99                                 ulong totalSize;
100                                 ulong totalFreeSpace;
101
102                                 GetDiskFreeSpace (path, out availableFreeSpace, out totalSize, out totalFreeSpace);
103                                 return totalSize > long.MaxValue ?  long.MaxValue : (long) totalSize;
104                         }
105                 }
106
107                 [MonoTODO ("Currently get only works on Mono/Unix; set not implemented")]
108                 public string VolumeLabel {
109                         get {
110                                 if (_drive_type != _DriveType.Windows)
111                                         return path;
112                                 else
113                                         return path;
114                         }
115                         set {
116                                 throw new NotImplementedException ();
117                         }
118                 }
119                 
120                 public string DriveFormat {
121                         get {
122                                 return drive_format;
123                         }
124                 }
125
126                 public DriveType DriveType {
127                         get {
128                                 return (DriveType) GetDriveTypeInternal (path);
129                         }
130                 }
131
132                 public string Name {
133                         get {
134                                 return path;
135                         }
136                 }
137
138                 public DirectoryInfo RootDirectory {
139                         get {
140                                 return new DirectoryInfo (path);
141                         }
142                 }
143
144                 [MonoTODO("It always returns true")]
145                 public bool IsReady {
146                         get {
147                                 if (_drive_type != _DriveType.Windows)
148                                         return true;
149
150                                 // Do something for Windows here.
151                                 return true;
152                         }
153                 }
154                 
155                 static StreamReader TryOpen (string name)
156                 {
157                         if (File.Exists (name))
158                                 return new StreamReader (name, Encoding.ASCII);
159                         return null;
160                 }
161
162                 static DriveInfo [] LinuxGetDrives ()
163                 {
164                         using (StreamReader mounts = TryOpen ("/proc/mounts")){
165                                 ArrayList drives = new ArrayList ();
166                                 string line;
167                                 
168                                 while ((line = mounts.ReadLine ()) != null){
169                                         if (line.StartsWith ("rootfs"))
170                                                 continue;
171                                         int p;
172
173                                         p = line.IndexOf (' ');
174                                         if (p == -1)
175                                                 continue;
176                                         string rest = line.Substring (p+1);
177                                         p = rest.IndexOf (' ');
178                                         if (p == -1)
179                                                 continue;
180                                         string path = rest.Substring (0, p);
181                                         rest = rest.Substring (p+1);
182                                         p = rest.IndexOf (' ');
183                                         if (p == -1)
184                                                 continue;
185                                         string fstype = rest.Substring (0, p);
186                                         drives.Add (new DriveInfo (_DriveType.Linux, path, fstype));
187                                 }
188
189                                 return (DriveInfo []) drives.ToArray (typeof (DriveInfo));
190                         }
191                 }
192                 
193                 static DriveInfo [] UnixGetDrives ()
194                 {
195                         DriveInfo [] di = null;
196
197                         try {
198                                 using (StreamReader linux_ostype = TryOpen ("/proc/sys/kernel/ostype")){
199                                         if (linux_ostype != null){
200                                                 string line = linux_ostype.ReadLine ();
201                                                 if (line == "Linux")
202                                                         di = LinuxGetDrives ();
203                                         }
204                                 }
205                                 
206                                 if (di != null)
207                                         return di;
208                         } catch (Exception) {
209                                 // If anything happens.
210                         }
211                         
212                         DriveInfo [] unknown = new DriveInfo [1];
213                         unknown [0]= new DriveInfo (_DriveType.GenericUnix, "/", "unixfs");
214
215                         return unknown;
216                 }
217
218                 static DriveInfo [] WindowsGetDrives ()
219                 {
220                         throw new NotImplementedException ();
221                 }
222                 
223                 [MonoTODO("Currently only implemented on Mono/Linux")]
224                 public static DriveInfo[] GetDrives ()
225                 {
226                         if (Environment.IsUnix)
227                                 return UnixGetDrives ();
228                         else
229                                 return WindowsGetDrives ();
230                 }
231
232                 void ISerializable.GetObjectData (System.Runtime.Serialization.SerializationInfo info, System.Runtime.Serialization.StreamingContext context)
233                 {
234                         throw new NotImplementedException ();
235                 }
236
237                 public override string ToString ()
238                 {
239                         return(Name);
240                 }
241
242                 [MethodImplAttribute (MethodImplOptions.InternalCall)]
243                 extern static bool GetDiskFreeSpaceInternal (string pathName, out ulong freeBytesAvail,
244                                                              out ulong totalNumberOfBytes, out ulong totalNumberOfFreeBytes,
245                                                              out MonoIOError error);
246
247                 [MethodImplAttribute (MethodImplOptions.InternalCall)]
248                 extern static uint GetDriveTypeInternal (string rootPathName);
249         }
250 }