#include #include #include "Directory-c-api.h" #include "File-c-api.h" #include "w32error.h" #include "w32file.h" #include "utils/strenc.h" #include #ifdef HOST_WIN32 gunichar2 ves_icall_System_IO_MonoIO_get_VolumeSeparatorChar () { return (gunichar2) ':'; /* colon */ } gunichar2 ves_icall_System_IO_MonoIO_get_DirectorySeparatorChar () { return (gunichar2) '\\'; /* backslash */ } gunichar2 ves_icall_System_IO_MonoIO_get_AltDirectorySeparatorChar () { return (gunichar2) '/'; /* forward slash */ } gunichar2 ves_icall_System_IO_MonoIO_get_PathSeparator () { return (gunichar2) ';'; /* semicolon */ } void ves_icall_System_IO_MonoIO_DumpHandles (void) { return; } #endif /* HOST_WIN32 */ gpointer mono_w32file_create(const gunichar2 *name, guint32 fileaccess, guint32 sharemode, guint32 createmode, guint32 attrs) { int error = 0; gpointer handle; gchar* palPath = mono_unicode_to_external(name); handle = UnityPalOpen(palPath, (int) createmode, (int) fileaccess, (int) sharemode, attrs, &error); mono_w32error_set_last(error); g_free(palPath); if (handle == NULL) return INVALID_HANDLE_VALUE; return handle; } gboolean mono_w32file_close (gpointer handle) { if (handle == NULL) return FALSE; int error = 0; gboolean result = UnityPalClose(handle, &error); mono_w32error_set_last(error); return result; } gboolean mono_w32file_read(gpointer handle, gpointer buffer, guint32 numbytes, guint32 *bytesread) { int error = 0; *bytesread = UnityPalRead(handle, buffer, numbytes, &error); mono_w32error_set_last(error); return TRUE; } gboolean mono_w32file_write (gpointer handle, gconstpointer buffer, guint32 numbytes, guint32 *byteswritten) { int error = 0; *byteswritten = UnityPalWrite(handle, buffer, numbytes, &error); mono_w32error_set_last(error); return (*byteswritten > 0); } gboolean mono_w32file_flush (gpointer handle) { int error = 0; gboolean result = UnityPalFlush(handle, &error); mono_w32error_set_last(error); return result; } gboolean mono_w32file_truncate (gpointer handle) { int error = 0; gboolean result = UnityPalTruncate(handle, &error); mono_w32error_set_last(error); return result; } guint32 mono_w32file_seek (gpointer handle, gint32 movedistance, gint32 *highmovedistance, guint32 method) { int error = 0; int32_t result = UnityPalSeek(handle, movedistance, 0, &error); mono_w32error_set_last(error); return result; } gint mono_w32file_get_type (gpointer handle) { if (handle == NULL) return 0; return UnityPalGetFileType(handle); } gboolean mono_w32file_get_times (gpointer handle, FILETIME *create_time, FILETIME *access_time, FILETIME *write_time) { /* Not Supported in UnityPAL */ g_assert_not_reached(); } gboolean mono_w32file_set_times (gpointer handle, const FILETIME *create_time, const FILETIME *access_time, const FILETIME *write_time) { int error = 0; gboolean result = UnityPalSetFileTime(handle, create_time, access_time, write_time, &error); mono_w32error_set_last(error); return result; } gpointer mono_w32file_find_first (const gunichar2 *pattern, WIN32_FIND_DATA *find_data) { gchar* palPath = mono_unicode_to_external(pattern); UnityPalFindHandle* findHandle = UnityPalDirectoryFindHandleNew(palPath); int32_t resultAttributes = 0; int32_t result = 0; const char* filename; result = UnityPalDirectoryFindFirstFile(findHandle, palPath, &filename, &resultAttributes); if (result != 0) { mono_w32error_set_last(result); return INVALID_HANDLE_VALUE; } find_data->dwFileAttributes = resultAttributes; gunichar2 *utf16_basename; glong bytes; utf16_basename = g_utf8_to_utf16 (filename, -1, NULL, &bytes, NULL); /* this next section of memset and memcpy is code from mono, the cFileName field is gunichar2 cFileName [MAX_PATH]. Notes from mono: Truncating a utf16 string like this might leave the last gchar incomplete utf16 is 2 * utf8 */ bytes *= 2; memset (find_data->cFileName, '\0', (MAX_PATH * 2)); memcpy (find_data->cFileName, utf16_basename, bytes < (MAX_PATH * 2) - 2 ? bytes : (MAX_PATH * 2) - 2); g_free(filename); g_free(palPath); g_free(utf16_basename); find_data->dwReserved0 = 0; find_data->dwReserved1 = 0; find_data->cAlternateFileName [0] = 0; return findHandle; } gboolean mono_w32file_find_next (gpointer handle, WIN32_FIND_DATA *find_data) { int32_t resultAttributes = 0; int32_t result; const char* filename; result = UnityPalDirectoryFindNextFile(handle, &filename, &resultAttributes); find_data->dwFileAttributes = resultAttributes; gunichar2 *utf16_basename; glong bytes; utf16_basename = g_utf8_to_utf16 (filename, -1, NULL, &bytes, NULL); bytes *= 2; memset (find_data->cFileName, '\0', (MAX_PATH * 2)); memcpy (find_data->cFileName, utf16_basename, bytes < (MAX_PATH * 2) - 2 ? bytes : (MAX_PATH * 2) - 2); g_free(filename); g_free(utf16_basename); find_data->dwReserved0 = 0; find_data->dwReserved1 = 0; find_data->cAlternateFileName [0] = 0; return (result == 0); } gboolean mono_w32file_find_close (gpointer handle) { gboolean result = UnityPalDirectoryCloseOSHandle(handle); UnityPalDirectoryFindHandleDelete(handle); return result; } gboolean mono_w32file_create_directory (const gunichar2 *name) { int error = 0; gchar* palPath = mono_unicode_to_external(name); gboolean result = UnityPalDirectoryCreate(palPath, &error); mono_w32error_set_last(error); g_free(palPath); return result; } guint32 mono_w32file_get_attributes (const gunichar2 *name) { int error = 0; gchar* palPath = mono_unicode_to_external(name); guint32 result = UnityPalGetFileAttributes(palPath, &error); mono_w32error_set_last(error); g_free(palPath); return result; } gboolean mono_w32file_get_attributes_ex (const gunichar2 *name, MonoIOStat *stat) { gboolean result; UnityPalFileStat palStat; int error = 0; gchar* palPath = mono_unicode_to_external(name); result = UnityPalGetFileStat(palPath, &palStat, &error); mono_w32error_set_last(error); if (result) { stat->attributes = palStat.attributes; stat->creation_time = palStat.creation_time; stat->last_access_time = palStat.last_access_time; stat->last_write_time = palStat.last_write_time; stat->length = palStat.length; } g_free(palPath); return result; } gboolean mono_w32file_set_attributes (const gunichar2 *name, guint32 attrs) { int error = 0; gchar* palPath = mono_unicode_to_external(name); gboolean result = UnityPalSetFileAttributes(palPath, attrs, &error); mono_w32error_set_last(error); g_free(palPath); return result; } gboolean mono_w32file_create_pipe (gpointer *readpipe, gpointer *writepipe, guint32 size) { return UnityPalCreatePipe(*readpipe, *writepipe); } gboolean mono_w32file_get_disk_free_space (const gunichar2 *path_name, guint64 *free_bytes_avail, guint64 *total_number_of_bytes, guint64 *total_number_of_free_bytes) { g_assert_not_reached(); return FALSE; } gboolean mono_w32file_get_volume_information (const gunichar2 *path, gunichar2 *volumename, gint volumesize, gint *outserial, gint *maxcomp, gint *fsflags, gunichar2 *fsbuffer, gint fsbuffersize) { g_assert_not_reached(); return FALSE; } gboolean mono_w32file_move (const gunichar2 *path, const gunichar2 *dest, gint32 *error) { gboolean result; *error = 0; MONO_ENTER_GC_SAFE; gchar* palPath = mono_unicode_to_external(path); gchar* palDest = mono_unicode_to_external(dest); result = UnityPalMoveFile(palPath, palDest, error); mono_w32error_set_last(*error); g_free(palPath); g_free(palDest); MONO_EXIT_GC_SAFE; return result; } gboolean mono_w32file_replace (const gunichar2 *destination_file_name, const gunichar2 *source_file_name, const gunichar2 *destination_backup_file_name, guint32 flags, gint32 *error) { gboolean result; gchar* destPath = NULL; gchar* sourcePath = NULL; gchar* destBackupPath = NULL; if (destination_file_name != NULL) { destPath = mono_unicode_to_external(destination_file_name); } if (source_file_name != NULL) { sourcePath = mono_unicode_to_external(source_file_name); } if (destination_backup_file_name != NULL) { destBackupPath = mono_unicode_to_external(destination_backup_file_name); } MONO_ENTER_GC_SAFE; result = UnityPalReplaceFile(sourcePath, destPath, destBackupPath, 0, error); mono_w32error_set_last(*error); MONO_EXIT_GC_SAFE; g_free(destPath); g_free(sourcePath); g_free(destBackupPath); return result; } gboolean mono_w32file_copy (const gunichar2 *path, const gunichar2 *dest, gboolean overwrite, gint32 *error) { gboolean result; *error = 0; MONO_ENTER_GC_SAFE; gchar* palPath = mono_unicode_to_external(path); gchar* palDest = mono_unicode_to_external(dest); result = UnityPalCopyFile(palPath, palDest, overwrite, error); mono_w32error_set_last(*error); g_free(palPath); g_free(palDest); MONO_EXIT_GC_SAFE; return result; } gboolean mono_w32file_lock (gpointer handle, gint64 position, gint64 length, gint32 *error) { MONO_ENTER_GC_SAFE; UnityPalLock(handle, position, length, error); mono_w32error_set_last(*error); MONO_EXIT_GC_SAFE; return (*error == 0); } gboolean mono_w32file_unlock (gpointer handle, gint64 position, gint64 length, gint32 *error) { MONO_ENTER_GC_SAFE; UnityPalUnlock(handle, position, length, error); mono_w32error_set_last(*error); MONO_EXIT_GC_SAFE; return (*error == 0); } gpointer mono_w32file_get_console_input (void) { return UnityPalGetStdInput(); } gpointer mono_w32file_get_console_output (void) { return UnityPalGetStdOutput(); } gpointer mono_w32file_get_console_error (void) { return UnityPalGetStdError(); } gint64 mono_w32file_get_file_size (gpointer handle, gint32 *error) { gint64 length; MONO_ENTER_GC_SAFE; length = UnityPalGetLength(handle, error); mono_w32error_set_last(*error); MONO_EXIT_GC_SAFE; return length; } guint32 mono_w32file_get_drive_type (const gunichar2 *root_path_name) { return 0; } gint32 mono_w32file_get_logical_drive (guint32 len, gunichar2 *buf) { return -1; } gboolean mono_w32file_remove_directory (const gunichar2 *name) { int error = 0; gchar* palPath = mono_unicode_to_external (name); gboolean result = UnityPalDirectoryRemove(palPath, &error); mono_w32error_set_last(error); g_free(palPath); return result; } gboolean mono_w32file_delete(const gunichar2 *name) { int error = 0; gchar* palPath = mono_unicode_to_external (name); gboolean result = UnityPalDeleteFile(palPath, &error); mono_w32error_set_last (error); g_free(palPath); return result; } guint32 mono_w32file_get_cwd (guint32 length, gunichar2 *buffer) { /* length is the number of characters in buffer, including the null terminator */ /* count is the number of characters in the current directory, including the null terminator */ gunichar2 *utf16_path; glong count; uintptr_t bytes; int error = 0; const char* palPath = UnityPalDirectoryGetCurrent(&error); mono_w32error_set_last (error); utf16_path = mono_unicode_from_external(palPath, &bytes); count = (bytes / 2) + 1; if (count <= length) { /* Add the terminator */ memset (buffer, '\0', bytes+2); memcpy (buffer, utf16_path, bytes); } g_free(utf16_path); g_free(palPath); return count; } gboolean mono_w32file_set_cwd (const gunichar2 *path) { int error = 0; gchar* palPath = mono_unicode_to_external(path); gboolean result = UnityPalDirectorySetCurrent(palPath, &error); mono_w32error_set_last (error); g_free(palPath); return result; } gboolean mono_w32file_set_length (gpointer handle, gint64 length, gint32 *error) { gboolean result = UnityPalSetLength(handle, length, error); mono_w32error_set_last(*error); return result; } void mono_w32file_cleanup (void) { } void mono_w32file_init (void) { }