Merge pull request #3936 from kumpera/monoclass_reorg2
[mono.git] / mono / metadata / file-io.c
index c10b1fee8d934b8249c8ca70b32497e0c5a174dc..0b001db668921cde759f8d3dbc434bc30aedf43f 100644 (file)
 #include <mono/metadata/object.h>
 #include <mono/io-layer/io-layer.h>
 #include <mono/metadata/file-io.h>
+#include <mono/metadata/file-io-internals.h>
 #include <mono/metadata/exception.h>
 #include <mono/metadata/appdomain.h>
 #include <mono/metadata/marshal.h>
 #include <mono/utils/strenc.h>
 #include <utils/mono-io-portability.h>
+#include <mono/metadata/w32handle.h>
 
 #undef DEBUG
 
@@ -270,7 +272,7 @@ MonoBoolean
 ves_icall_System_IO_MonoIO_CreateDirectory (MonoString *path, gint32 *error)
 {
        gboolean ret;
-       MONO_PREPARE_BLOCKING;
+       MONO_ENTER_GC_SAFE;
        
        *error=ERROR_SUCCESS;
        
@@ -279,7 +281,7 @@ ves_icall_System_IO_MonoIO_CreateDirectory (MonoString *path, gint32 *error)
                *error=GetLastError ();
        }
 
-       MONO_FINISH_BLOCKING;
+       MONO_EXIT_GC_SAFE;
        return(ret);
 }
 
@@ -287,7 +289,7 @@ MonoBoolean
 ves_icall_System_IO_MonoIO_RemoveDirectory (MonoString *path, gint32 *error)
 {
        gboolean ret;
-       MONO_PREPARE_BLOCKING;
+       MONO_ENTER_GC_SAFE;
        
        *error=ERROR_SUCCESS;
        
@@ -296,7 +298,7 @@ ves_icall_System_IO_MonoIO_RemoveDirectory (MonoString *path, gint32 *error)
                *error=GetLastError ();
        }
 
-       MONO_FINISH_BLOCKING;
+       MONO_EXIT_GC_SAFE;
        return(ret);
 }
 
@@ -404,9 +406,9 @@ ves_icall_System_IO_MonoIO_GetFileSystemEntries (MonoString *path,
        
        *ioerror = ERROR_SUCCESS;
 
-       MONO_PREPARE_BLOCKING;
+       MONO_ENTER_GC_SAFE;
        names = get_filesystem_entries (mono_string_chars (path), mono_string_chars (path_with_pattern), attrs, mask, ioerror);
-       MONO_FINISH_BLOCKING;
+       MONO_EXIT_GC_SAFE;
 
        if (!names) {
                // If there's no array and no error, then return an empty array.
@@ -461,15 +463,16 @@ incremental_find_check_match (IncrementalFind *handle, WIN32_FIND_DATA *data, Mo
 MonoString *
 ves_icall_System_IO_MonoIO_FindFirst (MonoString *path,
                                      MonoString *path_with_pattern,
-                                     gint32 *result_attr, gint32 *error,
+                                     gint32 *result_attr, gint32 *ioerror,
                                      gpointer *handle)
 {
+       MonoError error;
        WIN32_FIND_DATA data;
        HANDLE find_handle;
        IncrementalFind *ifh;
        MonoString *result;
        
-       *error = ERROR_SUCCESS;
+       *ioerror = ERROR_SUCCESS;
        
        find_handle = FindFirstFile (mono_string_chars (path_with_pattern), &data);
        
@@ -480,13 +483,20 @@ ves_icall_System_IO_MonoIO_FindFirst (MonoString *path,
                if (find_error == ERROR_FILE_NOT_FOUND) 
                        return NULL;
                
-               *error = find_error;
+               *ioerror = find_error;
                return NULL;
        }
 
        ifh = g_new (IncrementalFind, 1);
        ifh->find_handle = find_handle;
-       ifh->utf8_path = mono_string_to_utf8 (path);
+       ifh->utf8_path = mono_string_to_utf8_checked (path, &error);
+       if (mono_error_set_pending_exception (&error)) {
+               MONO_ENTER_GC_SAFE;
+               FindClose (find_handle);
+               MONO_EXIT_GC_SAFE;
+               g_free (ifh);
+               return NULL;
+       }
        ifh->domain = mono_domain_get ();
        *handle = ifh;
 
@@ -494,7 +504,7 @@ ves_icall_System_IO_MonoIO_FindFirst (MonoString *path,
                if (FindNextFile (find_handle, &data) == FALSE){
                        int e = GetLastError ();
                        if (e != ERROR_NO_MORE_FILES)
-                               *error = e;
+                               *ioerror = e;
                        return NULL;
                }
        }
@@ -531,14 +541,14 @@ ves_icall_System_IO_MonoIO_FindClose (gpointer handle)
        IncrementalFind *ifh = (IncrementalFind *)handle;
        gint32 error;
 
-       MONO_PREPARE_BLOCKING;
+       MONO_ENTER_GC_SAFE;
        if (FindClose (ifh->find_handle) == FALSE){
                error = GetLastError ();
        } else
                error = ERROR_SUCCESS;
        g_free (ifh->utf8_path);
        g_free (ifh);
-       MONO_FINISH_BLOCKING;
+       MONO_EXIT_GC_SAFE;
 
        return error;
 }
@@ -597,33 +607,55 @@ ves_icall_System_IO_MonoIO_SetCurrentDirectory (MonoString *path,
        return(ret);
 }
 
+#if G_HAVE_API_SUPPORT(HAVE_CLASSIC_WINAPI_SUPPORT)
+gboolean
+mono_file_io_move_file (gunichar2 *path, gunichar2 *dest, gint32 *error)
+{
+       gboolean result = FALSE;
+       MONO_ENTER_GC_SAFE;
+
+       result = MoveFile (path, dest);
+       if (result == FALSE) {
+               *error=GetLastError ();
+       }
+
+       MONO_EXIT_GC_SAFE;
+       return result;
+}
+#endif /* HAVE_CLASSIC_WINAPI_SUPPORT */
+
 MonoBoolean
-ves_icall_System_IO_MonoIO_MoveFile (MonoString *path, MonoString *dest,
-                                    gint32 *error)
+ves_icall_System_IO_MonoIO_MoveFile (MonoString *path, MonoString *dest, gint32 *error)
 {
-       gboolean ret;
-       MONO_PREPARE_BLOCKING;
-       
        *error=ERROR_SUCCESS;
+       return mono_file_io_move_file (mono_string_chars (path), mono_string_chars (dest), error);
+}
 
-       ret=MoveFile (mono_string_chars (path), mono_string_chars (dest));
-       if(ret==FALSE) {
+#if G_HAVE_API_SUPPORT(HAVE_CLASSIC_WINAPI_SUPPORT)
+gboolean
+mono_file_io_replace_file (gunichar2 *destinationFileName, gunichar2 *sourceFileName,
+                          gunichar2 *destinationBackupFileName, guint32 flags, gint32 *error)
+{
+       gboolean result = FALSE;
+       MONO_ENTER_GC_SAFE;
+
+       result = ReplaceFile (destinationFileName, sourceFileName, destinationBackupFileName, flags, NULL, NULL);
+       if (result == FALSE) {
                *error=GetLastError ();
        }
 
-       MONO_FINISH_BLOCKING;
-       return(ret);
+       MONO_EXIT_GC_SAFE;
+       return result;
 }
+#endif /* HAVE_CLASSIC_WINAPI_SUPPORT */
 
 MonoBoolean
 ves_icall_System_IO_MonoIO_ReplaceFile (MonoString *sourceFileName, MonoString *destinationFileName,
                                        MonoString *destinationBackupFileName, MonoBoolean ignoreMetadataErrors,
                                        gint32 *error)
 {
-       gboolean ret;
        gunichar2 *utf16_sourceFileName = NULL, *utf16_destinationFileName = NULL, *utf16_destinationBackupFileName = NULL;
        guint32 replaceFlags = REPLACEFILE_WRITE_THROUGH;
-       MONO_PREPARE_BLOCKING;
 
        if (sourceFileName)
                utf16_sourceFileName = mono_string_chars (sourceFileName);
@@ -637,38 +669,40 @@ ves_icall_System_IO_MonoIO_ReplaceFile (MonoString *sourceFileName, MonoString *
                replaceFlags |= REPLACEFILE_IGNORE_MERGE_ERRORS;
 
        /* FIXME: source and destination file names must not be NULL, but apparently they might be! */
-       ret = ReplaceFile (utf16_destinationFileName, utf16_sourceFileName, utf16_destinationBackupFileName,
-                        replaceFlags, NULL, NULL);
-       if (ret == FALSE)
-               *error = GetLastError ();
+       return mono_file_io_replace_file (utf16_destinationFileName, utf16_sourceFileName,
+                                         utf16_destinationBackupFileName, replaceFlags, error);
+}
+
+#if G_HAVE_API_SUPPORT(HAVE_CLASSIC_WINAPI_SUPPORT)
+gboolean
+mono_file_io_copy_file (gunichar2 *path, gunichar2 *dest, gboolean overwrite, gint32 *error)
+{
+       gboolean result = FALSE;
+       MONO_ENTER_GC_SAFE;
+
+       result = CopyFile (path, dest, !overwrite);
+       if (result == FALSE) {
+               *error=GetLastError ();
+       }
 
-       MONO_FINISH_BLOCKING;
-       return ret;
+       MONO_EXIT_GC_SAFE;
+       return result;
 }
+#endif /* HAVE_CLASSIC_WINAPI_SUPPORT */
 
 MonoBoolean
 ves_icall_System_IO_MonoIO_CopyFile (MonoString *path, MonoString *dest,
                                     MonoBoolean overwrite, gint32 *error)
 {
-       gboolean ret;
-       MONO_PREPARE_BLOCKING;
-       
        *error=ERROR_SUCCESS;
-       
-       ret=CopyFile (mono_string_chars (path), mono_string_chars (dest), !overwrite);
-       if(ret==FALSE) {
-               *error=GetLastError ();
-       }
-       
-       MONO_FINISH_BLOCKING;
-       return(ret);
+       return mono_file_io_copy_file (mono_string_chars (path), mono_string_chars (dest), overwrite, error);
 }
 
 MonoBoolean
 ves_icall_System_IO_MonoIO_DeleteFile (MonoString *path, gint32 *error)
 {
        gboolean ret;
-       MONO_PREPARE_BLOCKING;
+       MONO_ENTER_GC_SAFE;
        
        *error=ERROR_SUCCESS;
        
@@ -677,7 +711,7 @@ ves_icall_System_IO_MonoIO_DeleteFile (MonoString *path, gint32 *error)
                *error=GetLastError ();
        }
        
-       MONO_FINISH_BLOCKING;
+       MONO_EXIT_GC_SAFE;
        return(ret);
 }
 
@@ -685,7 +719,7 @@ gint32
 ves_icall_System_IO_MonoIO_GetFileAttributes (MonoString *path, gint32 *error)
 {
        gint32 ret;
-       MONO_PREPARE_BLOCKING;
+       MONO_ENTER_GC_SAFE;
 
        *error=ERROR_SUCCESS;
        
@@ -702,7 +736,7 @@ ves_icall_System_IO_MonoIO_GetFileAttributes (MonoString *path, gint32 *error)
                *error=GetLastError ();
        }
        
-       MONO_FINISH_BLOCKING;
+       MONO_EXIT_GC_SAFE;
        return(ret);
 }
 
@@ -711,7 +745,7 @@ ves_icall_System_IO_MonoIO_SetFileAttributes (MonoString *path, gint32 attrs,
                                              gint32 *error)
 {
        gboolean ret;
-       MONO_PREPARE_BLOCKING;
+       MONO_ENTER_GC_SAFE;
        
        *error=ERROR_SUCCESS;
        
@@ -721,7 +755,7 @@ ves_icall_System_IO_MonoIO_SetFileAttributes (MonoString *path, gint32 attrs,
                *error=GetLastError ();
        }
 
-       MONO_FINISH_BLOCKING;
+       MONO_EXIT_GC_SAFE;
        return(ret);
 }
 
@@ -729,7 +763,7 @@ gint32
 ves_icall_System_IO_MonoIO_GetFileType (HANDLE handle, gint32 *error)
 {
        gboolean ret;
-       MONO_PREPARE_BLOCKING;
+       MONO_ENTER_GC_SAFE;
 
        *error=ERROR_SUCCESS;
        
@@ -741,7 +775,7 @@ ves_icall_System_IO_MonoIO_GetFileType (HANDLE handle, gint32 *error)
                *error=GetLastError ();
        }
        
-       MONO_FINISH_BLOCKING;
+       MONO_EXIT_GC_SAFE;
        return(ret);
 }
 
@@ -751,7 +785,7 @@ ves_icall_System_IO_MonoIO_GetFileStat (MonoString *path, MonoIOStat *stat,
 {
        gboolean result;
        WIN32_FILE_ATTRIBUTE_DATA data;
-       MONO_PREPARE_BLOCKING;
+       MONO_ENTER_GC_SAFE;
 
        *error=ERROR_SUCCESS;
        
@@ -764,7 +798,7 @@ ves_icall_System_IO_MonoIO_GetFileStat (MonoString *path, MonoIOStat *stat,
                memset (stat, 0, sizeof (MonoIOStat));
        }
 
-       MONO_FINISH_BLOCKING;
+       MONO_EXIT_GC_SAFE;
        return result;
 }
 
@@ -776,7 +810,7 @@ ves_icall_System_IO_MonoIO_Open (MonoString *filename, gint32 mode,
        HANDLE ret;
        int attributes, attrs;
        gunichar2 *chars;
-       MONO_PREPARE_BLOCKING;
+       MONO_ENTER_GC_SAFE;
 
        chars = mono_string_chars (filename);   
        *error=ERROR_SUCCESS;
@@ -796,10 +830,6 @@ ves_icall_System_IO_MonoIO_Open (MonoString *filename, gint32 mode,
                if (options & FileOptions_Temporary)
                        attributes |= FILE_ATTRIBUTE_TEMPORARY;
                
-               /* Not sure if we should set FILE_FLAG_OVERLAPPED, how does this mix with the "Async" bool here? */
-               if (options & FileOptions_Asynchronous)
-                       attributes |= FILE_FLAG_OVERLAPPED;
-               
                if (options & FileOptions_WriteThrough)
                        attributes |= FILE_FLAG_WRITE_THROUGH;
        } else
@@ -821,7 +851,7 @@ ves_icall_System_IO_MonoIO_Open (MonoString *filename, gint32 mode,
                *error=GetLastError ();
        } 
        
-       MONO_FINISH_BLOCKING;
+       MONO_EXIT_GC_SAFE;
        return(ret);
 }
 
@@ -829,7 +859,7 @@ MonoBoolean
 ves_icall_System_IO_MonoIO_Close (HANDLE handle, gint32 *error)
 {
        gboolean ret;
-       MONO_PREPARE_BLOCKING;
+       MONO_ENTER_GC_SAFE;
 
        *error=ERROR_SUCCESS;
        
@@ -838,7 +868,7 @@ ves_icall_System_IO_MonoIO_Close (HANDLE handle, gint32 *error)
                *error=GetLastError ();
        }
        
-       MONO_FINISH_BLOCKING;
+       MONO_EXIT_GC_SAFE;
        return(ret);
 }
 
@@ -862,9 +892,9 @@ ves_icall_System_IO_MonoIO_Read (HANDLE handle, MonoArray *dest,
 
        buffer = mono_array_addr (dest, guchar, dest_offset);
 
-       MONO_PREPARE_BLOCKING;
+       MONO_ENTER_GC_SAFE;
        result = ReadFile (handle, buffer, count, &n, NULL);
-       MONO_FINISH_BLOCKING;
+       MONO_EXIT_GC_SAFE;
 
        if (!result) {
                *error=GetLastError ();
@@ -893,9 +923,9 @@ ves_icall_System_IO_MonoIO_Write (HANDLE handle, MonoArray *src,
        }
        
        buffer = mono_array_addr (src, guchar, src_offset);
-       MONO_PREPARE_BLOCKING;
+       MONO_ENTER_GC_SAFE;
        result = WriteFile (handle, buffer, count, &n, NULL);
-       MONO_FINISH_BLOCKING;
+       MONO_EXIT_GC_SAFE;
 
        if (!result) {
                *error=GetLastError ();
@@ -910,7 +940,7 @@ ves_icall_System_IO_MonoIO_Seek (HANDLE handle, gint64 offset, gint32 origin,
                                 gint32 *error)
 {
        gint32 offset_hi;
-       MONO_PREPARE_BLOCKING;
+       MONO_ENTER_GC_SAFE;
 
        *error=ERROR_SUCCESS;
        
@@ -922,7 +952,7 @@ ves_icall_System_IO_MonoIO_Seek (HANDLE handle, gint64 offset, gint32 origin,
                *error=GetLastError ();
        }
 
-       MONO_FINISH_BLOCKING;
+       MONO_EXIT_GC_SAFE;
        return offset | ((gint64)offset_hi << 32);
 }
 
@@ -930,7 +960,7 @@ MonoBoolean
 ves_icall_System_IO_MonoIO_Flush (HANDLE handle, gint32 *error)
 {
        gboolean ret;
-       MONO_PREPARE_BLOCKING;
+       MONO_ENTER_GC_SAFE;
 
        *error=ERROR_SUCCESS;
        
@@ -939,27 +969,35 @@ ves_icall_System_IO_MonoIO_Flush (HANDLE handle, gint32 *error)
                *error=GetLastError ();
        }
        
-       MONO_FINISH_BLOCKING;
+       MONO_EXIT_GC_SAFE;
        return(ret);
 }
 
-gint64 
-ves_icall_System_IO_MonoIO_GetLength (HANDLE handle, gint32 *error)
+#if G_HAVE_API_SUPPORT(HAVE_CLASSIC_WINAPI_SUPPORT)
+gint64
+mono_file_io_get_file_size (HANDLE handle, gint32 *error)
 {
        gint64 length;
        guint32 length_hi;
-       MONO_PREPARE_BLOCKING;
 
-       *error=ERROR_SUCCESS;
-       
+       MONO_ENTER_GC_SAFE;
+
        length = GetFileSize (handle, &length_hi);
        if(length==INVALID_FILE_SIZE) {
                *error=GetLastError ();
        }
-       
-       MONO_FINISH_BLOCKING;
+
+       MONO_EXIT_GC_SAFE;
        return length | ((gint64)length_hi << 32);
 }
+#endif /* G_HAVE_API_SUPPORT(HAVE_CLASSIC_WINAPI_SUPPORT) */
+
+gint64
+ves_icall_System_IO_MonoIO_GetLength (HANDLE handle, gint32 *error)
+{
+       *error=ERROR_SUCCESS;
+       return mono_file_io_get_file_size (handle, error);
+}
 
 /* FIXME make gc suspendable */
 MonoBoolean
@@ -1019,7 +1057,7 @@ ves_icall_System_IO_MonoIO_SetFileTime (HANDLE handle, gint64 creation_time,
        const FILETIME *creation_filetime;
        const FILETIME *last_access_filetime;
        const FILETIME *last_write_filetime;
-       MONO_PREPARE_BLOCKING;
+       MONO_ENTER_GC_SAFE;
 
        *error=ERROR_SUCCESS;
        
@@ -1043,26 +1081,50 @@ ves_icall_System_IO_MonoIO_SetFileTime (HANDLE handle, gint64 creation_time,
                *error=GetLastError ();
        }
 
-       MONO_FINISH_BLOCKING;
+       MONO_EXIT_GC_SAFE;
        return(ret);
 }
 
+#if G_HAVE_API_SUPPORT(HAVE_CLASSIC_WINAPI_SUPPORT)
+HANDLE
+mono_file_io_get_console_output (void)
+{
+       return GetStdHandle (STD_OUTPUT_HANDLE);
+}
+#endif /* G_HAVE_API_SUPPORT(HAVE_CLASSIC_WINAPI_SUPPORT) */
+
 HANDLE 
 ves_icall_System_IO_MonoIO_get_ConsoleOutput ()
 {
-       return GetStdHandle (STD_OUTPUT_HANDLE);
+       return mono_file_io_get_console_output ();
+}
+
+#if G_HAVE_API_SUPPORT(HAVE_CLASSIC_WINAPI_SUPPORT)
+HANDLE
+mono_file_io_get_console_input (void)
+{
+       return GetStdHandle (STD_INPUT_HANDLE);
 }
+#endif /* G_HAVE_API_SUPPORT(HAVE_CLASSIC_WINAPI_SUPPORT) */
 
 HANDLE 
 ves_icall_System_IO_MonoIO_get_ConsoleInput ()
 {
-       return GetStdHandle (STD_INPUT_HANDLE);
+       return mono_file_io_get_console_input ();
 }
 
+#if G_HAVE_API_SUPPORT(HAVE_CLASSIC_WINAPI_SUPPORT)
+HANDLE
+mono_file_io_get_console_error (void)
+{
+       return GetStdHandle (STD_ERROR_HANDLE);
+}
+#endif /* G_HAVE_API_SUPPORT(HAVE_CLASSIC_WINAPI_SUPPORT) */
+
 HANDLE 
 ves_icall_System_IO_MonoIO_get_ConsoleError ()
 {
-       return GetStdHandle (STD_ERROR_HANDLE);
+       return mono_file_io_get_console_error ();
 }
 
 MonoBoolean
@@ -1075,9 +1137,9 @@ ves_icall_System_IO_MonoIO_CreatePipe (HANDLE *read_handle, HANDLE *write_handle
        attr.bInheritHandle=TRUE;
        attr.lpSecurityDescriptor=NULL;
 
-       MONO_PREPARE_BLOCKING;
+       MONO_ENTER_GC_SAFE;
        ret=CreatePipe (read_handle, write_handle, &attr, 0);
-       MONO_FINISH_BLOCKING;
+       MONO_EXIT_GC_SAFE;
 
        if(ret==FALSE) {
                *error = GetLastError ();
@@ -1095,9 +1157,9 @@ ves_icall_System_IO_MonoIO_DuplicateHandle (HANDLE source_process_handle, HANDLE
        /* This is only used on Windows */
        gboolean ret;
        
-       MONO_PREPARE_BLOCKING;
+       MONO_ENTER_GC_SAFE;
        ret=DuplicateHandle (source_process_handle, source_handle, target_process_handle, target_handle, access, inherit, options);
-       MONO_FINISH_BLOCKING;
+       MONO_EXIT_GC_SAFE;
 
        if(ret==FALSE) {
                *error = GetLastError ();
@@ -1108,48 +1170,34 @@ ves_icall_System_IO_MonoIO_DuplicateHandle (HANDLE source_process_handle, HANDLE
        return(TRUE);
 }
 
+#ifndef HOST_WIN32
 gunichar2 
 ves_icall_System_IO_MonoIO_get_VolumeSeparatorChar ()
 {
-#if defined (TARGET_WIN32)
-       return (gunichar2) ':'; /* colon */
-#else
        return (gunichar2) '/'; /* forward slash */
-#endif
 }
 
 gunichar2 
 ves_icall_System_IO_MonoIO_get_DirectorySeparatorChar ()
 {
-#if defined (TARGET_WIN32)
-       return (gunichar2) '\\';        /* backslash */
-#else
        return (gunichar2) '/'; /* forward slash */
-#endif
 }
 
 gunichar2 
 ves_icall_System_IO_MonoIO_get_AltDirectorySeparatorChar ()
 {
-#if defined (TARGET_WIN32)
-       return (gunichar2) '/'; /* forward slash */
-#else
        if (IS_PORTABILITY_SET)
                return (gunichar2) '\\';        /* backslash */
        else
                return (gunichar2) '/'; /* forward slash */
-#endif
 }
 
 gunichar2 
 ves_icall_System_IO_MonoIO_get_PathSeparator ()
 {
-#if defined (TARGET_WIN32)
-       return (gunichar2) ';'; /* semicolon */
-#else
        return (gunichar2) ':'; /* colon */
-#endif
 }
+#endif /* !HOST_WIN32 */
 
 static const gunichar2
 invalid_path_chars [] = {
@@ -1192,38 +1240,56 @@ ves_icall_System_IO_MonoIO_get_InvalidPathChars ()
        return chars;
 }
 
+#if G_HAVE_API_SUPPORT(HAVE_CLASSIC_WINAPI_SUPPORT)
+gboolean
+mono_file_io_lock_file (HANDLE handle, gint64 position, gint64 length, gint32 *error)
+{
+       gboolean result = FALSE;
+       MONO_ENTER_GC_SAFE;
+
+       result = LockFile (handle, position & 0xFFFFFFFF, position >> 32,
+                          length & 0xFFFFFFFF, length >> 32);
+
+       if (result == FALSE) {
+               *error = GetLastError ();
+       }
+
+       MONO_EXIT_GC_SAFE;
+       return result;
+}
+#endif /* G_HAVE_API_SUPPORT(HAVE_CLASSIC_WINAPI_SUPPORT) */
+
 void ves_icall_System_IO_MonoIO_Lock (HANDLE handle, gint64 position,
                                      gint64 length, gint32 *error)
 {
-       gboolean ret;
-       MONO_PREPARE_BLOCKING;
-       
        *error=ERROR_SUCCESS;
+       mono_file_io_lock_file (handle, position, length, error);
+}
+
+#if G_HAVE_API_SUPPORT(HAVE_CLASSIC_WINAPI_SUPPORT)
+gboolean
+mono_file_io_unlock_file (HANDLE handle, gint64 position, gint64 length, gint32 *error)
+{
+       gboolean result = FALSE;
+       MONO_ENTER_GC_SAFE;
        
-       ret=LockFile (handle, position & 0xFFFFFFFF, position >> 32,
-                     length & 0xFFFFFFFF, length >> 32);
-       if (ret == FALSE) {
+       result = UnlockFile (handle, position & 0xFFFFFFFF, position >> 32,
+                            length & 0xFFFFFFFF, length >> 32);
+
+       if (result == FALSE) {
                *error = GetLastError ();
        }
 
-       MONO_FINISH_BLOCKING;
+       MONO_EXIT_GC_SAFE;
+       return result;
 }
+#endif /* G_HAVE_API_SUPPORT(HAVE_CLASSIC_WINAPI_SUPPORT) */
 
 void ves_icall_System_IO_MonoIO_Unlock (HANDLE handle, gint64 position,
                                        gint64 length, gint32 *error)
 {
-       gboolean ret;
-       MONO_PREPARE_BLOCKING;
-       
        *error=ERROR_SUCCESS;
-       
-       ret=UnlockFile (handle, position & 0xFFFFFFFF, position >> 32,
-                       length & 0xFFFFFFFF, length >> 32);
-       if (ret == FALSE) {
-               *error = GetLastError ();
-       }
-
-       MONO_FINISH_BLOCKING;
+       mono_file_io_unlock_file (handle, position, length, error);
 }
 
 //Support for io-layer free mmap'd files.
@@ -1233,11 +1299,13 @@ void ves_icall_System_IO_MonoIO_Unlock (HANDLE handle, gint64 position,
 gint64
 mono_filesize_from_path (MonoString *string)
 {
+       MonoError error;
        struct stat buf;
        gint64 res;
-       char *path = mono_string_to_utf8 (string);
+       char *path = mono_string_to_utf8_checked (string, &error);
+       mono_error_raise_exception (&error); /* OK to throw, external only without a good alternative */
 
-       MONO_PREPARE_BLOCKING;
+       MONO_ENTER_GC_SAFE;
        if (stat (path, &buf) == -1)
                res = -1;
        else
@@ -1245,7 +1313,7 @@ mono_filesize_from_path (MonoString *string)
 
        g_free (path);
 
-       MONO_FINISH_BLOCKING;
+       MONO_EXIT_GC_SAFE;
        return res;
 }
 
@@ -1255,9 +1323,9 @@ mono_filesize_from_fd (int fd)
        struct stat buf;
        int res;
 
-       MONO_PREPARE_BLOCKING;
+       MONO_ENTER_GC_SAFE;
        res = fstat (fd, &buf);
-       MONO_FINISH_BLOCKING;
+       MONO_EXIT_GC_SAFE;
        
        if (res == -1)
                return (gint64)-1;
@@ -1267,11 +1335,12 @@ mono_filesize_from_fd (int fd)
 
 #endif
 
-void _wapi_handle_dump (void);
+#ifndef HOST_WIN32
+void mono_w32handle_dump (void);
 
 void ves_icall_System_IO_MonoIO_DumpHandles (void)
 {
-#ifndef HOST_WIN32
-       _wapi_handle_dump ();
-#endif
+
+       mono_w32handle_dump ();
 }
+#endif /* !HOST_WIN32 */