credits
[mono.git] / mcs / class / corlib / System.IO / MonoIO.cs
1 //
2 // System.IO.MonoIO.cs: static interface to native filesystem.
3 //
4 // Author:
5 //   Dan Lewis (dihlewis@yahoo.co.uk)
6 //   Dick Porter (dick@ximian.com)
7 //
8 // (C) 2002
9 //
10
11 //
12 // Copyright (C) 2004 Novell, Inc (http://www.novell.com)
13 //
14 // Permission is hereby granted, free of charge, to any person obtaining
15 // a copy of this software and associated documentation files (the
16 // "Software"), to deal in the Software without restriction, including
17 // without limitation the rights to use, copy, modify, merge, publish,
18 // distribute, sublicense, and/or sell copies of the Software, and to
19 // permit persons to whom the Software is furnished to do so, subject to
20 // the following conditions:
21 // 
22 // The above copyright notice and this permission notice shall be
23 // included in all copies or substantial portions of the Software.
24 // 
25 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
26 // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
27 // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
28 // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
29 // LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
30 // OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
31 // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
32 //
33
34 using System;
35 using System.Runtime.CompilerServices;
36 using System.Runtime.InteropServices;
37 using System.Threading;
38
39 namespace System.IO
40 {
41         unsafe internal sealed class MonoIO {
42                 public static readonly FileAttributes
43                         InvalidFileAttributes = (FileAttributes)(-1);
44
45                 public static readonly IntPtr
46                         InvalidHandle = (IntPtr)(-1L);
47
48                 public static readonly bool SupportsAsync = GetSupportsAsync ();
49
50                 // error methods
51
52                 public static Exception GetException (MonoIOError error)
53                 {
54                         return GetException (String.Empty, error);
55                 }
56
57                 public static Exception GetException (string path,
58                                                       MonoIOError error)
59                 {
60                         string message;
61
62                         switch (error) {
63                         // FIXME: add more exception mappings here
64                         case MonoIOError.ERROR_FILE_NOT_FOUND:
65                                 message = String.Format ("Could not find file \"{0}\"", path);
66                                 return new FileNotFoundException (message,
67                                                                   path);
68
69                         case MonoIOError.ERROR_PATH_NOT_FOUND:
70                                 message = String.Format ("Could not find a part of the path \"{0}\"", path);
71                                 return new DirectoryNotFoundException (message);
72
73                         case MonoIOError.ERROR_ACCESS_DENIED:
74                                 message = String.Format ("Access to the path \"{0}\" is denied.", path);
75                                 return new UnauthorizedAccessException (message);
76
77                         case MonoIOError.ERROR_FILE_EXISTS:
78                                 message = String.Format ("Could not create file \"{0}\". File already exists.", path);
79                                 return new IOException (message);
80
81                         case MonoIOError.ERROR_FILENAME_EXCED_RANGE:
82                                 message = String.Format ("Path is too long. Path: {0}", path); 
83                                 return new PathTooLongException (message);
84
85                         case MonoIOError.ERROR_INVALID_PARAMETER:
86                                 message = String.Format ("Invalid parameter");
87                                 return new IOException (message);
88
89                         case MonoIOError.ERROR_SHARING_VIOLATION:
90                                 message = String.Format ("Sharing violation on path {0}", path);
91                                 return new IOException (message);
92                                 
93                         default:
94                                 message = String.Format ("Win32 IO returned {0}. Path: {1}", error, path);
95                                 return new IOException (message);
96                         }
97                 }
98
99                 // directory methods
100
101                 [MethodImplAttribute (MethodImplOptions.InternalCall)]
102                 public extern static bool CreateDirectory (string path, out MonoIOError error);
103
104                 [MethodImplAttribute (MethodImplOptions.InternalCall)]
105                 public extern static bool RemoveDirectory (string path, out MonoIOError error);
106
107                 [MethodImplAttribute (MethodImplOptions.InternalCall)]
108                 public extern static IntPtr FindFirstFile (string path, out MonoIOStat stat, out MonoIOError error);
109
110                 [MethodImplAttribute (MethodImplOptions.InternalCall)]
111                 public extern static bool FindNextFile (IntPtr find, out MonoIOStat stat, out MonoIOError error);
112
113                 [MethodImplAttribute (MethodImplOptions.InternalCall)]
114                 public extern static bool FindClose (IntPtr find,
115                                                      out MonoIOError error);
116
117                 [MethodImplAttribute (MethodImplOptions.InternalCall)]
118                 public extern static string GetCurrentDirectory (out MonoIOError error);
119
120                 [MethodImplAttribute (MethodImplOptions.InternalCall)]
121                 public extern static bool SetCurrentDirectory (string path, out MonoIOError error);
122
123                 // file methods
124
125                 [MethodImplAttribute (MethodImplOptions.InternalCall)]
126                 public extern static bool MoveFile (string path, string dest,
127                                                     out MonoIOError error);
128
129                 [MethodImplAttribute (MethodImplOptions.InternalCall)]
130                 public extern static bool CopyFile (string path, string dest,
131                                                     bool overwrite,
132                                                     out MonoIOError error);
133
134                 [MethodImplAttribute (MethodImplOptions.InternalCall)]
135                 public extern static bool DeleteFile (string path,
136                                                       out MonoIOError error);
137
138                 [MethodImplAttribute (MethodImplOptions.InternalCall)]
139                 public extern static FileAttributes GetFileAttributes (string path, out MonoIOError error);
140
141                 [MethodImplAttribute (MethodImplOptions.InternalCall)]
142                 public extern static bool SetFileAttributes (string path, FileAttributes attrs, out MonoIOError error);
143
144                 [MethodImplAttribute (MethodImplOptions.InternalCall)]
145                 public extern static MonoFileType GetFileType (IntPtr handle, out MonoIOError error);
146
147                 // aio_* methods
148                 [MethodImplAttribute (MethodImplOptions.InternalCall)]
149                 extern static bool GetSupportsAsync ();
150
151                 public static bool Exists (string path, out MonoIOError error)
152                 {
153                         FileAttributes attrs = GetFileAttributes (path,
154                                                                   out error);
155                         if (attrs == InvalidFileAttributes)
156                                 return false;
157
158                         return true;
159                 }
160
161                 public static bool ExistsFile (string path,
162                                                out MonoIOError error)
163                 {
164                         FileAttributes attrs = GetFileAttributes (path,
165                                                                   out error);
166                         if (attrs == InvalidFileAttributes)
167                                 return false;
168
169                         if ((attrs & FileAttributes.Directory) != 0)
170                                 return false;
171
172                         return true;
173                 }
174
175                 public static bool ExistsDirectory (string path,
176                                                     out MonoIOError error)
177                 {
178                         FileAttributes attrs = GetFileAttributes (path,
179                                                                   out error);
180                                                                   
181                         // Actually, we are looking for a directory, not a file
182                         if (error == MonoIOError.ERROR_FILE_NOT_FOUND)
183                                 error = MonoIOError.ERROR_PATH_NOT_FOUND;
184                                 
185                         if (attrs == InvalidFileAttributes)
186                                 return false;
187
188                         if ((attrs & FileAttributes.Directory) == 0)
189                                 return false;
190
191                         return true;
192                 }
193
194                 [MethodImplAttribute (MethodImplOptions.InternalCall)]
195                 public extern static bool GetFileStat (string path,
196                                                        out MonoIOStat stat,
197                                                        out MonoIOError error);
198
199                 // handle methods
200
201                 [MethodImplAttribute (MethodImplOptions.InternalCall)]
202                 public extern static IntPtr Open (string filename,
203                                                   FileMode mode,
204                                                   FileAccess access,
205                                                   FileShare share,
206                                                   bool async,
207                                                   out MonoIOError error);
208                 
209                 [MethodImplAttribute (MethodImplOptions.InternalCall)]
210                 public extern static bool Close (IntPtr handle,
211                                                  out MonoIOError error);
212                 
213                 [MethodImplAttribute (MethodImplOptions.InternalCall)]
214                 public extern static int Read (IntPtr handle, byte [] dest,
215                                                int dest_offset, int count,
216                                                out MonoIOError error);
217                 
218                 [MethodImplAttribute (MethodImplOptions.InternalCall)]
219                 public extern static int Write (IntPtr handle, [In] byte [] src,
220                                                 int src_offset, int count,
221                                                 out MonoIOError error);
222                 
223                 [MethodImplAttribute (MethodImplOptions.InternalCall)]
224                 public extern static long Seek (IntPtr handle, long offset,
225                                                 SeekOrigin origin,
226                                                 out MonoIOError error);
227                 
228                 [MethodImplAttribute (MethodImplOptions.InternalCall)]
229                 public extern static bool Flush (IntPtr handle,
230                                                  out MonoIOError error);
231
232                 [MethodImplAttribute (MethodImplOptions.InternalCall)]
233                 public extern static long GetLength (IntPtr handle,
234                                                      out MonoIOError error);
235
236                 [MethodImplAttribute (MethodImplOptions.InternalCall)]
237                 public extern static bool SetLength (IntPtr handle,
238                                                      long length,
239                                                      out MonoIOError error);
240
241                 [MethodImplAttribute (MethodImplOptions.InternalCall)]
242                 public extern static bool SetFileTime (IntPtr handle,
243                                                        long creation_time,
244                                                        long last_access_time,
245                                                        long last_write_time,
246                                                        out MonoIOError error);
247
248                 public static bool SetFileTime (string path,
249                                                 long creation_time,
250                                                 long last_access_time,
251                                                 long last_write_time,
252                                                 out MonoIOError error)
253                 {
254                         return SetFileTime (path,
255                                 0,
256                                 creation_time,
257                                 last_access_time,
258                                 last_write_time,
259                                 DateTime.MinValue,
260                                 out error);
261                 }
262
263                 public static bool SetCreationTime (string path,
264                                                 DateTime dateTime,
265                                                 out MonoIOError error)
266                 {
267                         return SetFileTime (path, 1, -1, -1, -1, dateTime, out error);
268                 }
269
270                 public static bool SetLastAccessTime (string path,
271                                                 DateTime dateTime,
272                                                 out MonoIOError error)
273                 {
274                         return SetFileTime (path, 2, -1, -1, -1, dateTime, out error);
275                 }
276
277                 public static bool SetLastWriteTime (string path,
278                                                 DateTime dateTime,
279                                                 out MonoIOError error)
280                 {
281                         return SetFileTime (path, 3, -1, -1, -1, dateTime, out error);
282                 }
283
284                 public static bool SetFileTime (string path,
285                                                 int type,
286                                                 long creation_time,
287                                                 long last_access_time,
288                                                 long last_write_time,
289                                                 DateTime dateTime,
290                                                 out MonoIOError error)
291                 {
292                         IntPtr handle;
293                         bool result;
294
295                         handle = Open (path, FileMode.Open,
296                                        FileAccess.ReadWrite,
297                                        FileShare.ReadWrite, false, out error);
298                         if (handle == MonoIO.InvalidHandle)
299                                 return false;
300
301                         switch (type) {
302                         case 1:
303                                 creation_time = dateTime.ToFileTime ();
304                                 break;
305                         case 2:
306                                 last_access_time = dateTime.ToFileTime ();
307                                 break;
308                         case 3:
309                                 last_write_time = dateTime.ToFileTime ();
310                                 break;
311                         }
312
313                         result = SetFileTime (handle, creation_time,
314                                               last_access_time,
315                                               last_write_time, out error);
316
317                         MonoIOError ignore_error;
318                         Close (handle, out ignore_error);
319                         
320                         return result;
321                 }
322
323                 [MethodImplAttribute (MethodImplOptions.InternalCall)]
324                 public extern static void Lock (IntPtr handle,
325                                                 long position, long length,
326                                                 out MonoIOError error);
327
328                 [MethodImplAttribute (MethodImplOptions.InternalCall)]
329                 public extern static void Unlock (IntPtr handle,
330                                                   long position, long length,
331                                                   out MonoIOError error);
332
333                 // console handles
334
335                 public extern static IntPtr ConsoleOutput {
336                         [MethodImplAttribute (MethodImplOptions.InternalCall)]
337                         get;
338                 }
339
340                 public extern static IntPtr ConsoleInput {
341                         [MethodImplAttribute (MethodImplOptions.InternalCall)]
342                         get;
343                 }
344
345                 public extern static IntPtr ConsoleError {
346                         [MethodImplAttribute (MethodImplOptions.InternalCall)]
347                         get;
348                 }
349
350                 // pipe handles
351
352                 [MethodImplAttribute (MethodImplOptions.InternalCall)]
353                 public extern static bool CreatePipe (out IntPtr read_handle, out IntPtr write_handle);
354
355                 // path characters
356
357                 public extern static char VolumeSeparatorChar {
358                         [MethodImplAttribute (MethodImplOptions.InternalCall)]
359                         get;
360                 }
361
362                 public extern static char DirectorySeparatorChar {
363                         [MethodImplAttribute (MethodImplOptions.InternalCall)]
364                         get;
365                 }
366
367                 public extern static char AltDirectorySeparatorChar {
368                         [MethodImplAttribute (MethodImplOptions.InternalCall)]
369                         get;
370                 }
371
372                 public extern static char PathSeparator {
373                         [MethodImplAttribute (MethodImplOptions.InternalCall)]
374                         get;
375                 }
376
377                 public extern static char [] InvalidPathChars {
378                         [MethodImplAttribute (MethodImplOptions.InternalCall)]
379                         get;
380                 }
381
382                 [MethodImplAttribute (MethodImplOptions.InternalCall)]
383                 public extern static int GetTempPath(out string path);
384
385                 [MethodImplAttribute (MethodImplOptions.InternalCall)]
386                 public extern static void BeginWrite (IntPtr handle,FileStreamAsyncResult ares);
387
388                 [MethodImplAttribute (MethodImplOptions.InternalCall)]
389                 public extern static void BeginRead (IntPtr handle, FileStreamAsyncResult ares);
390
391         }
392 }
393