Merge pull request #2003 from esdrubal/seq_test_fix2
[mono.git] / mcs / class / corlib / System.IO / MonoIO.cs
index 84a78c5a73832b095643f901d5939ea13ecba1fb..9d816f40a5952a5e7edcb570a187b34eec2d5427 100644 (file)
@@ -5,6 +5,7 @@
 //   Dick Porter (dick@ximian.com)
 //
 // (C) 2002
+// Copyright 2011 Xamarin Inc (http://www.xamarin.com).
 //
 
 //
@@ -34,14 +35,17 @@ using System;
 using System.Runtime.CompilerServices;
 using System.Runtime.InteropServices;
 using System.Threading;
+using Microsoft.Win32.SafeHandles;
 #if NET_2_1
 using System.IO.IsolatedStorage;
 #endif
 
 namespace System.IO
 {
-       unsafe internal sealed class MonoIO {
-               public static readonly FileAttributes
+       unsafe static class MonoIO {
+               public const int FileAlreadyExistsHResult = unchecked ((int) 0x80070000) | (int)MonoIOError.ERROR_FILE_EXISTS;
+
+               public const FileAttributes
                        InvalidFileAttributes = (FileAttributes)(-1);
 
                public static readonly IntPtr
@@ -61,7 +65,7 @@ namespace System.IO
                                return new UnauthorizedAccessException ("Access to the path is denied.");
                        case MonoIOError.ERROR_FILE_EXISTS:
                                string message = "Cannot create a file that already exist.";
-                               return new IOException (message, unchecked ((int) 0x80070000) | (int) error);
+                               return new IOException (message, FileAlreadyExistsHResult);
                        default:
                                /* Add more mappings here if other
                                 * errors trigger the named but empty
@@ -82,22 +86,14 @@ namespace System.IO
                        // FIXME: add more exception mappings here
                        case MonoIOError.ERROR_FILE_NOT_FOUND:
                                message = String.Format ("Could not find file \"{0}\"", path);
-#if NET_2_1
-                               return new IsolatedStorageException (message);
-#else
                                return new FileNotFoundException (message, path);
-#endif
 
                        case MonoIOError.ERROR_TOO_MANY_OPEN_FILES:
                                return new IOException ("Too many open files", unchecked((int)0x80070000) | (int)error);
                                
                        case MonoIOError.ERROR_PATH_NOT_FOUND:
                                message = String.Format ("Could not find a part of the path \"{0}\"", path);
-#if NET_2_1
-                               return new IsolatedStorageException (message);
-#else
                                return new DirectoryNotFoundException (message);
-#endif
 
                        case MonoIOError.ERROR_ACCESS_DENIED:
                                message = String.Format ("Access to the path \"{0}\" is denied.", path);
@@ -108,7 +104,7 @@ namespace System.IO
                                return new IOException (message, unchecked((int)0x80070000) | (int)error);
                        case MonoIOError.ERROR_INVALID_DRIVE:
                                message = String.Format ("Could not find the drive  '{0}'. The drive might not be ready or might not be mapped.", path);
-#if NET_2_0
+#if !NET_2_1
                                return new DriveNotFoundException (message);
 #else
                                return new IOException (message, unchecked((int)0x80070000) | (int)error);
@@ -208,8 +204,32 @@ namespace System.IO
                public extern static bool SetFileAttributes (string path, FileAttributes attrs, out MonoIOError error);
 
                [MethodImplAttribute (MethodImplOptions.InternalCall)]
-               public extern static MonoFileType GetFileType (IntPtr handle, out MonoIOError error);
+               private extern static MonoFileType GetFileType (IntPtr handle, out MonoIOError error);
+
+               public static MonoFileType GetFileType (SafeHandle safeHandle, out MonoIOError error)
+               {
+                       bool release = false;
+                       try {
+                               safeHandle.DangerousAddRef (ref release);
+                               return GetFileType (safeHandle.DangerousGetHandle (), out error);
+                       } finally {
+                               if (release)
+                                       safeHandle.DangerousRelease ();
+                       }
+               }
 
+               //
+               // Find file methods
+               //
+               [MethodImplAttribute (MethodImplOptions.InternalCall)]
+               public extern static string FindFirst (string path, string pattern, out FileAttributes result_attr, out MonoIOError error, out IntPtr handle);
+               
+               [MethodImplAttribute (MethodImplOptions.InternalCall)]
+               public extern static string FindNext (IntPtr handle, out FileAttributes result_attr, out MonoIOError error);
+               
+               [MethodImplAttribute (MethodImplOptions.InternalCall)]
+               public extern static int FindClose (IntPtr handle);
+               
                public static bool Exists (string path, out MonoIOError error)
                {
                        FileAttributes attrs = GetFileAttributes (path,
@@ -281,46 +301,144 @@ namespace System.IO
                                                  FileShare share,
                                                  FileOptions options,
                                                  out MonoIOError error);
-               
+
                [MethodImplAttribute (MethodImplOptions.InternalCall)]
                public extern static bool Close (IntPtr handle,
                                                 out MonoIOError error);
                
                [MethodImplAttribute (MethodImplOptions.InternalCall)]
-               public extern static int Read (IntPtr handle, byte [] dest,
+               private extern static int Read (IntPtr handle, byte [] dest,
                                               int dest_offset, int count,
                                               out MonoIOError error);
+
+               public static int Read (SafeHandle safeHandle, byte [] dest,
+                                              int dest_offset, int count,
+                                              out MonoIOError error)
+               {
+                       bool release = false;
+                       try {
+                               safeHandle.DangerousAddRef (ref release);
+                               return Read (safeHandle.DangerousGetHandle (), dest, dest_offset, count, out error);
+                       } finally {
+                               if (release)
+                                       safeHandle.DangerousRelease ();
+                       }
+               }
                
                [MethodImplAttribute (MethodImplOptions.InternalCall)]
-               public extern static int Write (IntPtr handle, [In] byte [] src,
+               private extern static int Write (IntPtr handle, [In] byte [] src,
                                                int src_offset, int count,
                                                out MonoIOError error);
+
+               public static int Write (SafeHandle safeHandle, byte [] src,
+                                               int src_offset, int count,
+                                               out MonoIOError error)
+               {
+                       bool release = false;
+                       try {
+                               safeHandle.DangerousAddRef (ref release);
+                               return Write (safeHandle.DangerousGetHandle (), src, src_offset, count, out error);
+                       } finally {
+                               if (release)
+                                       safeHandle.DangerousRelease ();
+                       }
+               }
                
                [MethodImplAttribute (MethodImplOptions.InternalCall)]
-               public extern static long Seek (IntPtr handle, long offset,
+               private extern static long Seek (IntPtr handle, long offset,
                                                SeekOrigin origin,
                                                out MonoIOError error);
+
+               public static long Seek (SafeHandle safeHandle, long offset,
+                                               SeekOrigin origin,
+                                               out MonoIOError error)
+               {
+                       bool release = false;
+                       try {
+                               safeHandle.DangerousAddRef (ref release);
+                               return Seek (safeHandle.DangerousGetHandle (), offset, origin, out error);
+                       } finally {
+                               if (release)
+                                       safeHandle.DangerousRelease ();
+                       }
+               }
                
                [MethodImplAttribute (MethodImplOptions.InternalCall)]
-               public extern static bool Flush (IntPtr handle,
+               private extern static bool Flush (IntPtr handle,
                                                 out MonoIOError error);
 
+               public static bool Flush (SafeHandle safeHandle,
+                                                out MonoIOError error)
+               {
+                       bool release = false;
+                       try {
+                               safeHandle.DangerousAddRef (ref release);
+                               return Flush (safeHandle.DangerousGetHandle (), out error);
+                       } finally {
+                               if (release)
+                                       safeHandle.DangerousRelease ();
+                       }
+               }
+
                [MethodImplAttribute (MethodImplOptions.InternalCall)]
-               public extern static long GetLength (IntPtr handle,
+               private extern static long GetLength (IntPtr handle,
                                                     out MonoIOError error);
 
+               public static long GetLength (SafeHandle safeHandle,
+                                                    out MonoIOError error)
+               {
+                       bool release = false;
+                       try {
+                               safeHandle.DangerousAddRef (ref release);
+                               return GetLength (safeHandle.DangerousGetHandle (), out error);
+                       } finally {
+                               if (release)
+                                       safeHandle.DangerousRelease ();
+                       }
+               }
+
                [MethodImplAttribute (MethodImplOptions.InternalCall)]
-               public extern static bool SetLength (IntPtr handle,
+               private extern static bool SetLength (IntPtr handle,
                                                     long length,
                                                     out MonoIOError error);
 
+               public static bool SetLength (SafeHandle safeHandle,
+                                                    long length,
+                                                    out MonoIOError error)
+               {
+                       bool release = false;
+                       try {
+                               safeHandle.DangerousAddRef (ref release);
+                               return SetLength (safeHandle.DangerousGetHandle (), length, out error);
+                       } finally {
+                               if (release)
+                                       safeHandle.DangerousRelease ();
+                       }
+               }
+
                [MethodImplAttribute (MethodImplOptions.InternalCall)]
-               public extern static bool SetFileTime (IntPtr handle,
+               private extern static bool SetFileTime (IntPtr handle,
                                                       long creation_time,
                                                       long last_access_time,
                                                       long last_write_time,
                                                       out MonoIOError error);
 
+               public static bool SetFileTime (SafeHandle safeHandle,
+                                                      long creation_time,
+                                                      long last_access_time,
+                                                      long last_write_time,
+                                                      out MonoIOError error)
+               {
+                       bool release = false;
+                       try {
+                               safeHandle.DangerousAddRef (ref release);
+                               return SetFileTime (safeHandle.DangerousGetHandle (), creation_time, last_access_time, last_write_time, out error);
+                       } finally {
+                               if (release)
+                                       safeHandle.DangerousRelease ();
+                       }
+               }
+
                public static bool SetFileTime (string path,
                                                long creation_time,
                                                long last_access_time,
@@ -386,7 +504,7 @@ namespace System.IO
                                break;
                        }
 
-                       result = SetFileTime (handle, creation_time,
+                       result = SetFileTime (new SafeFileHandle(handle, false), creation_time,
                                              last_access_time,
                                              last_write_time, out error);
 
@@ -397,15 +515,43 @@ namespace System.IO
                }
 
                [MethodImplAttribute (MethodImplOptions.InternalCall)]
-               public extern static void Lock (IntPtr handle,
+               private extern static void Lock (IntPtr handle,
                                                long position, long length,
                                                out MonoIOError error);
 
+               public static void Lock (SafeHandle safeHandle,
+                                               long position, long length,
+                                               out MonoIOError error)
+               {
+                       bool release = false;
+                       try {
+                               safeHandle.DangerousAddRef (ref release);
+                               Lock (safeHandle.DangerousGetHandle (), position, length, out error);
+                       } finally {
+                               if (release)
+                                       safeHandle.DangerousRelease ();
+                       }
+               }
+
                [MethodImplAttribute (MethodImplOptions.InternalCall)]
-               public extern static void Unlock (IntPtr handle,
+               private extern static void Unlock (IntPtr handle,
                                                  long position, long length,
                                                  out MonoIOError error);
 
+               public static void Unlock (SafeHandle safeHandle,
+                                                 long position, long length,
+                                                 out MonoIOError error)
+               {
+                       bool release = false;
+                       try {
+                               safeHandle.DangerousAddRef (ref release);
+                               Unlock (safeHandle.DangerousGetHandle (), position, length, out error);
+                       } finally {
+                               if (release)
+                                       safeHandle.DangerousRelease ();
+                       }
+               }
+
                // console handles
 
                public extern static IntPtr ConsoleOutput {
@@ -453,9 +599,6 @@ namespace System.IO
                        [MethodImplAttribute (MethodImplOptions.InternalCall)]
                        get;
                }
-
-               [MethodImplAttribute (MethodImplOptions.InternalCall)]
-               public extern static int GetTempPath(out string path);
        }
 }