#include <mono/metadata/marshal.h>
#include <mono/utils/strenc.h>
#include <utils/mono-io-portability.h>
+#include <mono/utils/w32handle.h>
#undef DEBUG
ves_icall_System_IO_MonoIO_CreateDirectory (MonoString *path, gint32 *error)
{
gboolean ret;
- MONO_PREPARE_BLOCKING;
+ MONO_ENTER_GC_SAFE;
*error=ERROR_SUCCESS;
*error=GetLastError ();
}
- MONO_FINISH_BLOCKING;
+ MONO_EXIT_GC_SAFE;
return(ret);
}
ves_icall_System_IO_MonoIO_RemoveDirectory (MonoString *path, gint32 *error)
{
gboolean ret;
- MONO_PREPARE_BLOCKING;
+ MONO_ENTER_GC_SAFE;
*error=ERROR_SUCCESS;
*error=GetLastError ();
}
- MONO_FINISH_BLOCKING;
+ MONO_EXIT_GC_SAFE;
return(ret);
}
ves_icall_System_IO_MonoIO_GetFileSystemEntries (MonoString *path,
MonoString *path_with_pattern,
gint attrs, gint mask,
- gint32 *error)
+ gint32 *ioerror)
{
+ MonoError error;
MonoDomain *domain = mono_domain_get ();
MonoArray *result;
int i;
GPtrArray *names;
- *error = ERROR_SUCCESS;
+ *ioerror = ERROR_SUCCESS;
- MONO_PREPARE_BLOCKING;
- names = get_filesystem_entries (mono_string_chars (path), mono_string_chars (path_with_pattern), attrs, mask, error);
- MONO_FINISH_BLOCKING;
+ MONO_ENTER_GC_SAFE;
+ names = get_filesystem_entries (mono_string_chars (path), mono_string_chars (path_with_pattern), attrs, mask, ioerror);
+ MONO_EXIT_GC_SAFE;
if (!names) {
// If there's no array and no error, then return an empty array.
- if (*error == ERROR_SUCCESS)
- return mono_array_new (domain, mono_defaults.string_class, 0);
+ if (*ioerror == ERROR_SUCCESS) {
+ MonoArray *arr = mono_array_new_checked (domain, mono_defaults.string_class, 0, &error);
+ mono_error_set_pending_exception (&error);
+ return arr;
+ }
return NULL;
}
- result = mono_array_new (domain, mono_defaults.string_class, names->len);
+ result = mono_array_new_checked (domain, mono_defaults.string_class, names->len, &error);
+ if (mono_error_set_pending_exception (&error))
+ goto leave;
for (i = 0; i < names->len; i++) {
mono_array_setref (result, i, mono_string_new (domain, (const char *)g_ptr_array_index (names, i)));
g_free (g_ptr_array_index (names, i));
}
+leave:
g_ptr_array_free (names, TRUE);
return result;
}
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);
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;
if (FindNextFile (find_handle, &data) == FALSE){
int e = GetLastError ();
if (e != ERROR_NO_MORE_FILES)
- *error = e;
+ *ioerror = e;
return NULL;
}
}
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;
}
gint32 *error)
{
gboolean ret;
- MONO_PREPARE_BLOCKING;
+ MONO_ENTER_GC_SAFE;
*error=ERROR_SUCCESS;
*error=GetLastError ();
}
- MONO_FINISH_BLOCKING;
+ MONO_EXIT_GC_SAFE;
return(ret);
}
gboolean ret;
gunichar2 *utf16_sourceFileName = NULL, *utf16_destinationFileName = NULL, *utf16_destinationBackupFileName = NULL;
guint32 replaceFlags = REPLACEFILE_WRITE_THROUGH;
- MONO_PREPARE_BLOCKING;
+ MONO_ENTER_GC_SAFE;
if (sourceFileName)
utf16_sourceFileName = mono_string_chars (sourceFileName);
if (ret == FALSE)
*error = GetLastError ();
- MONO_FINISH_BLOCKING;
+ MONO_EXIT_GC_SAFE;
return ret;
}
MonoBoolean overwrite, gint32 *error)
{
gboolean ret;
- MONO_PREPARE_BLOCKING;
+ MONO_ENTER_GC_SAFE;
*error=ERROR_SUCCESS;
*error=GetLastError ();
}
- MONO_FINISH_BLOCKING;
+ MONO_EXIT_GC_SAFE;
return(ret);
}
ves_icall_System_IO_MonoIO_DeleteFile (MonoString *path, gint32 *error)
{
gboolean ret;
- MONO_PREPARE_BLOCKING;
+ MONO_ENTER_GC_SAFE;
*error=ERROR_SUCCESS;
*error=GetLastError ();
}
- MONO_FINISH_BLOCKING;
+ MONO_EXIT_GC_SAFE;
return(ret);
}
ves_icall_System_IO_MonoIO_GetFileAttributes (MonoString *path, gint32 *error)
{
gint32 ret;
- MONO_PREPARE_BLOCKING;
+ MONO_ENTER_GC_SAFE;
*error=ERROR_SUCCESS;
*error=GetLastError ();
}
- MONO_FINISH_BLOCKING;
+ MONO_EXIT_GC_SAFE;
return(ret);
}
gint32 *error)
{
gboolean ret;
- MONO_PREPARE_BLOCKING;
+ MONO_ENTER_GC_SAFE;
*error=ERROR_SUCCESS;
*error=GetLastError ();
}
- MONO_FINISH_BLOCKING;
+ MONO_EXIT_GC_SAFE;
return(ret);
}
ves_icall_System_IO_MonoIO_GetFileType (HANDLE handle, gint32 *error)
{
gboolean ret;
- MONO_PREPARE_BLOCKING;
+ MONO_ENTER_GC_SAFE;
*error=ERROR_SUCCESS;
*error=GetLastError ();
}
- MONO_FINISH_BLOCKING;
+ MONO_EXIT_GC_SAFE;
return(ret);
}
{
gboolean result;
WIN32_FILE_ATTRIBUTE_DATA data;
- MONO_PREPARE_BLOCKING;
+ MONO_ENTER_GC_SAFE;
*error=ERROR_SUCCESS;
memset (stat, 0, sizeof (MonoIOStat));
}
- MONO_FINISH_BLOCKING;
+ MONO_EXIT_GC_SAFE;
return result;
}
HANDLE ret;
int attributes, attrs;
gunichar2 *chars;
- MONO_PREPARE_BLOCKING;
+ MONO_ENTER_GC_SAFE;
chars = mono_string_chars (filename);
*error=ERROR_SUCCESS;
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
*error=GetLastError ();
}
- MONO_FINISH_BLOCKING;
+ MONO_EXIT_GC_SAFE;
return(ret);
}
ves_icall_System_IO_MonoIO_Close (HANDLE handle, gint32 *error)
{
gboolean ret;
- MONO_PREPARE_BLOCKING;
+ MONO_ENTER_GC_SAFE;
*error=ERROR_SUCCESS;
*error=GetLastError ();
}
- MONO_FINISH_BLOCKING;
+ MONO_EXIT_GC_SAFE;
return(ret);
}
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 ();
}
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 ();
gint32 *error)
{
gint32 offset_hi;
- MONO_PREPARE_BLOCKING;
+ MONO_ENTER_GC_SAFE;
*error=ERROR_SUCCESS;
*error=GetLastError ();
}
- MONO_FINISH_BLOCKING;
+ MONO_EXIT_GC_SAFE;
return offset | ((gint64)offset_hi << 32);
}
ves_icall_System_IO_MonoIO_Flush (HANDLE handle, gint32 *error)
{
gboolean ret;
- MONO_PREPARE_BLOCKING;
+ MONO_ENTER_GC_SAFE;
*error=ERROR_SUCCESS;
*error=GetLastError ();
}
- MONO_FINISH_BLOCKING;
+ MONO_EXIT_GC_SAFE;
return(ret);
}
{
gint64 length;
guint32 length_hi;
- MONO_PREPARE_BLOCKING;
+ MONO_ENTER_GC_SAFE;
*error=ERROR_SUCCESS;
*error=GetLastError ();
}
- MONO_FINISH_BLOCKING;
+ MONO_EXIT_GC_SAFE;
return length | ((gint64)length_hi << 32);
}
const FILETIME *creation_filetime;
const FILETIME *last_access_filetime;
const FILETIME *last_write_filetime;
- MONO_PREPARE_BLOCKING;
+ MONO_ENTER_GC_SAFE;
*error=ERROR_SUCCESS;
*error=GetLastError ();
}
- MONO_FINISH_BLOCKING;
+ MONO_EXIT_GC_SAFE;
return(ret);
}
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 ();
/* 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 ();
MonoArray *
ves_icall_System_IO_MonoIO_get_InvalidPathChars ()
{
+ MonoError error;
MonoArray *chars;
MonoDomain *domain;
int i, n;
domain = mono_domain_get ();
n = sizeof (invalid_path_chars) / sizeof (gunichar2);
- chars = mono_array_new (domain, mono_defaults.char_class, n);
+ chars = mono_array_new_checked (domain, mono_defaults.char_class, n, &error);
+ if (mono_error_set_pending_exception (&error))
+ return NULL;
for (i = 0; i < n; ++ i)
mono_array_set (chars, gunichar2, i, invalid_path_chars [i]);
gint64 length, gint32 *error)
{
gboolean ret;
- MONO_PREPARE_BLOCKING;
+ MONO_ENTER_GC_SAFE;
*error=ERROR_SUCCESS;
*error = GetLastError ();
}
- MONO_FINISH_BLOCKING;
+ MONO_EXIT_GC_SAFE;
}
void ves_icall_System_IO_MonoIO_Unlock (HANDLE handle, gint64 position,
gint64 length, gint32 *error)
{
gboolean ret;
- MONO_PREPARE_BLOCKING;
+ MONO_ENTER_GC_SAFE;
*error=ERROR_SUCCESS;
*error = GetLastError ();
}
- MONO_FINISH_BLOCKING;
+ MONO_EXIT_GC_SAFE;
}
//Support for io-layer free mmap'd files.
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
g_free (path);
- MONO_FINISH_BLOCKING;
+ MONO_EXIT_GC_SAFE;
return res;
}
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;
#endif
-void _wapi_handle_dump (void);
+void mono_w32handle_dump (void);
void ves_icall_System_IO_MonoIO_DumpHandles (void)
{
#ifndef HOST_WIN32
- _wapi_handle_dump ();
+ mono_w32handle_dump ();
#endif
}