Merge pull request #309 from i59/patch-1
[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.Generic;
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                 string drive_format;
36                 string path;
37
38                 DriveInfo (string path, string fstype)
39                 {
40                         this.drive_format = fstype;
41                         this.path = path;
42                 }
43
44                 public DriveInfo (string driveName)
45                 {
46                         if (!Environment.IsUnix) {
47                                 if (driveName == null || driveName.Length == 0)
48                                         throw new ArgumentException ("The drive name is null or empty", "driveName");
49
50                                 if (driveName.Length >= 2 && driveName [1] != ':')
51                                         throw new ArgumentException ("Invalid drive name", "driveName");
52
53                                 // Convert the path to a standard format so we can find it later.
54                                 driveName = String.Concat (Char.ToUpper (driveName [0]).ToString (), ":\\");
55                         }
56
57                         DriveInfo [] drives = GetDrives ();
58                         foreach (DriveInfo d in drives){
59                                 if (d.path == driveName){
60                                         this.path = d.path;
61                                         this.drive_format = d.drive_format;
62                                         this.path = d.path;
63                                         return;
64                                 }
65                         }
66                         throw new ArgumentException ("The drive name does not exist", "driveName");
67                 }
68                 
69                 static void GetDiskFreeSpace (string path, out ulong availableFreeSpace, out ulong totalSize, out ulong totalFreeSpace)
70                 {
71                         MonoIOError error;
72                         if (!GetDiskFreeSpaceInternal (path, out availableFreeSpace, out totalSize, out totalFreeSpace, out error))
73                                 throw MonoIO.GetException (path, error);
74                 }
75
76                 public long AvailableFreeSpace {
77                         get {
78                                 ulong availableFreeSpace;
79                                 ulong totalSize;
80                                 ulong totalFreeSpace;
81
82                                 GetDiskFreeSpace (path, out availableFreeSpace, out totalSize, out totalFreeSpace);
83                                 return availableFreeSpace > long.MaxValue ?  long.MaxValue : (long) availableFreeSpace;
84                         }
85                 }
86
87                 public long TotalFreeSpace {
88                         get {
89                                 ulong availableFreeSpace;
90                                 ulong totalSize;
91                                 ulong totalFreeSpace;
92
93                                 GetDiskFreeSpace (path, out availableFreeSpace, out totalSize, out totalFreeSpace);
94                                 return totalFreeSpace > long.MaxValue ?  long.MaxValue : (long) totalFreeSpace;
95                         }
96                 }
97
98                 public long TotalSize {
99                         get {
100                                 ulong availableFreeSpace;
101                                 ulong totalSize;
102                                 ulong totalFreeSpace;
103
104                                 GetDiskFreeSpace (path, out availableFreeSpace, out totalSize, out totalFreeSpace);
105                                 return totalSize > long.MaxValue ?  long.MaxValue : (long) totalSize;
106                         }
107                 }
108
109                 [MonoTODO ("Currently get only works on Mono/Unix; set not implemented")]
110                 public string VolumeLabel {
111                         get {
112                                 return path;
113                         }
114                         set {
115                                 throw new NotImplementedException ();
116                         }
117                 }
118                 
119                 public string DriveFormat {
120                         get {
121                                 return drive_format;
122                         }
123                 }
124
125                 public DriveType DriveType {
126                         get {
127                                 return (DriveType) GetDriveTypeInternal (path);
128                         }
129                 }
130
131                 public string Name {
132                         get {
133                                 return path;
134                         }
135                 }
136
137                 public DirectoryInfo RootDirectory {
138                         get {
139                                 return new DirectoryInfo (path);
140                         }
141                 }
142
143                 [MonoTODO("It always returns true")]
144                 public bool IsReady {
145                         get {
146                                 return true;
147                         }
148                 }
149                 
150                 [MonoTODO("In windows, alldrives are 'Fixed'")]
151                 public static DriveInfo[] GetDrives ()
152                 {
153                         var drives = Environment.GetLogicalDrives ();
154                         DriveInfo [] infos = new DriveInfo [drives.Length];
155                         int i = 0;
156                         foreach (string s in drives)
157                                 infos [i++] = new DriveInfo (s, GetDriveFormat (s));
158
159                         return infos;
160                 }
161
162                 void ISerializable.GetObjectData (System.Runtime.Serialization.SerializationInfo info, System.Runtime.Serialization.StreamingContext context)
163                 {
164                         throw new NotImplementedException ();
165                 }
166
167                 public override string ToString ()
168                 {
169                         return(Name);
170                 }
171
172                 [MethodImplAttribute (MethodImplOptions.InternalCall)]
173                 extern static bool GetDiskFreeSpaceInternal (string pathName, out ulong freeBytesAvail,
174                                                              out ulong totalNumberOfBytes, out ulong totalNumberOfFreeBytes,
175                                                              out MonoIOError error);
176
177                 [MethodImplAttribute (MethodImplOptions.InternalCall)]
178                 extern static uint GetDriveTypeInternal (string rootPathName);
179
180                 [MethodImplAttribute (MethodImplOptions.InternalCall)]
181                 extern static string GetDriveFormat (string rootPathName);
182         }
183 }