提交 155ca60a 编写于 作者: J Jonathan Chambers

Implement path remapping support (case 992909)

This was previously stubbed out when rebasing
onto mono master branch.
上级 5d92128b
......@@ -1360,8 +1360,9 @@ do_mono_image_open (const char *fname, MonoImageOpenStatus *status,
MonoCLIImageInfo *iinfo;
MonoImage *image;
MonoFileMap *filed;
gboolean remapped = mono_unity_file_remap_path(&fname);
const char *fname_remap;
if (fname_remap = mono_unity_remap_path (fname))
fname = fname_remap;
if ((filed = mono_file_map_open (fname)) == NULL){
if (IS_PORTABILITY_SET) {
......@@ -1375,8 +1376,7 @@ do_mono_image_open (const char *fname, MonoImageOpenStatus *status,
if (filed == NULL) {
if (status)
*status = MONO_IMAGE_ERROR_ERRNO;
if (remapped)
g_free((void*)fname);
g_free((void*)fname_remap);
return NULL;
}
}
......@@ -1396,8 +1396,7 @@ do_mono_image_open (const char *fname, MonoImageOpenStatus *status,
g_free (image);
if (status)
*status = MONO_IMAGE_IMAGE_INVALID;
if (remapped)
g_free((void*)fname);
g_free((void*)fname_remap);
return NULL;
}
iinfo = g_new0 (MonoCLIImageInfo, 1);
......@@ -1411,8 +1410,7 @@ do_mono_image_open (const char *fname, MonoImageOpenStatus *status,
image->core_clr_platform_code = mono_security_core_clr_determine_platform_image (image);
mono_file_map_close (filed);
if (remapped)
g_free((void*)fname);
g_free((void*)fname_remap);
return do_mono_image_load (image, status, care_about_cli, care_about_pecoff);
}
......
......@@ -1115,26 +1115,26 @@ static MonoDl*
cached_module_load (const char *name, int flags, char **err)
{
MonoDl *res;
const char *name_remap;
if (err)
*err = NULL;
gboolean remapped = mono_unity_file_remap_path(&name);
if (name_remap = mono_unity_remap_path (name))
name = name_remap;
global_loader_data_lock ();
if (!global_module_map)
global_module_map = g_hash_table_new (g_str_hash, g_str_equal);
res = (MonoDl *)g_hash_table_lookup (global_module_map, name);
if (res) {
global_loader_data_unlock ();
if (remapped)
g_free((void*)name);
g_free((void*)name_remap);
return res;
}
res = mono_dl_open (name, flags, err);
if (res)
g_hash_table_insert (global_module_map, g_strdup (name), res);
global_loader_data_unlock ();
if (remapped)
g_free((void*)name);
g_free((void*)name_remap);
return res;
}
......
......@@ -1197,6 +1197,12 @@ size_t RemapPathFunction (const char* path, char* buffer, size_t buffer_len)
*/
static RemapPathFunction g_RemapPathFunc = NULL;
void
mono_unity_register_path_remapper (RemapPathFunction func)
{
g_RemapPathFunc = func;
}
/* calls remapper function if registered; allocates memory if remapping is available */
static inline size_t
call_remapper(const char* path, char** buf)
......@@ -1204,7 +1210,7 @@ call_remapper(const char* path, char** buf)
size_t len;
if (!g_RemapPathFunc)
return FALSE;
return 0;
*buf = NULL;
len = g_RemapPathFunc(path, *buf, 0);
......@@ -1218,80 +1224,67 @@ call_remapper(const char* path, char** buf)
return len;
}
/* updates 'path' if remapping is available; returns TRUE if updated (path must be free()'d) */
gboolean
mono_unity_file_remap_path(const char** path)
MonoBoolean
ves_icall_System_IO_MonoIO_RemapPath (MonoString *path, MonoString **new_path)
{
size_t len;
char * buf;
MonoError error;
const gunichar2* path_remapped;
len = call_remapper(*path, &buf);
if (len == 0)
if (!g_RemapPathFunc)
return 0;
path_remapped = mono_unity_remap_path_utf16 (mono_string_chars (path));
if (!path_remapped)
return FALSE;
*path = buf;
mono_gc_wbarrier_generic_store (new_path, (MonoObject*)mono_string_from_utf16_checked (path_remapped, &error));
g_free (path_remapped);
mono_error_set_pending_exception (&error);
return TRUE;
}
const char*
mono_unity_remap_path (const char* path)
{
const char* path_remap = NULL;
call_remapper (path, &path_remap);
return path_remap;
}
/* sets 'new_path', and returns TRUE, if remapping is available */
static gboolean
remap_path (MonoString *path, MonoString** new_path)
const gunichar2*
mono_unity_remap_path_utf16 (const gunichar2* path)
{
MonoError error;
MonoString * str;
const gunichar2* path_remap = NULL;
char * utf8_path;
char * buf;
char * path_end;
size_t len;
*new_path = NULL;
if (!g_RemapPathFunc)
return FALSE;
return path_remap;
utf8_path = mono_string_to_utf8_ignore(path);
len = call_remapper(utf8_path, &buf);
utf8_path = g_utf16_to_utf8 (path, -1, NULL, NULL, NULL);
len = call_remapper (utf8_path, &buf);
if (len == 0)
{
g_free(utf8_path);
return FALSE;
g_free (utf8_path);
return path_remap;
}
path_end = memchr(buf, '\0', len);
len = path_end ? (size_t) (path_end - buf) : len;
str = mono_string_new_len_checked (mono_domain_get (), buf, (guint)len, &error);
path_end = memchr (buf, '\0', len);
len = path_end ? (size_t)(path_end - buf) : len;
g_free(utf8_path);
g_free (buf);
path_remap = g_utf8_to_utf16 (buf, len, NULL, NULL, NULL);
mono_gc_wbarrier_generic_store(new_path, (MonoObject*)str);
mono_error_set_pending_exception (&error);
return *new_path ? TRUE : FALSE;
}
/* returns remapped path, if remapping is available. otherwise returns original path */
const gunichar2 *
mono_unity_get_remapped_path (const gunichar2 *path)
{
// JON TODO:
return path;
//MonoString * new_path;
//return remap_path(path, &new_path) ? new_path : path;
}
MonoBoolean
ves_icall_System_IO_MonoIO_RemapPath (MonoString *path, MonoString **new_path)
{
return remap_path(path, new_path);
}
g_free (utf8_path);
g_free (buf);
void
mono_unity_register_path_remapper(RemapPathFunction func)
{
g_RemapPathFunc = func;
return path_remap;
}
MonoMethod*
......
......@@ -172,12 +172,15 @@ MONO_API MonoClass* mono_custom_attrs_get_attrs (MonoCustomAttrInfo *ainfo, gpoi
typedef size_t (*RemapPathFunction)(const char* path, char* buffer, size_t buffer_len);
MONO_API void mono_unity_register_path_remapper (RemapPathFunction func);
gboolean
mono_unity_file_remap_path(const char** path);
const char*
mono_unity_remap_path (const char* path);
const gunichar2*
mono_unity_remap_path_utf16 (const gunichar2* path);
MonoBoolean
ves_icall_System_IO_MonoIO_RemapPath (MonoString *path, MonoString **new_path);
const gunichar2 *
mono_unity_get_remapped_path (const gunichar2 *path);
MonoMethod*
mono_method_get_method_definition(MonoMethod *method);
......
......@@ -191,8 +191,11 @@ MonoBoolean
ves_icall_System_IO_MonoIO_CreateDirectory (const gunichar2 *path, gint32 *error)
{
gboolean ret;
path = mono_unity_get_remapped_path(path);
const gunichar2 *path_remapped;
if (path_remapped = mono_unity_remap_path_utf16 (path))
path = path_remapped;
*error=ERROR_SUCCESS;
ret=mono_w32file_create_directory (path);
......@@ -200,6 +203,8 @@ ves_icall_System_IO_MonoIO_CreateDirectory (const gunichar2 *path, gint32 *error
*error=mono_w32error_get_last ();
}
g_free (path_remapped);
return(ret);
}
......@@ -207,7 +212,10 @@ MonoBoolean
ves_icall_System_IO_MonoIO_RemoveDirectory (const gunichar2 *path, gint32 *error)
{
gboolean ret;
path = mono_unity_get_remapped_path(path);
const gunichar2 *path_remapped;
if (path_remapped = mono_unity_remap_path_utf16 (path))
path = path_remapped;
*error=ERROR_SUCCESS;
......@@ -216,6 +224,8 @@ ves_icall_System_IO_MonoIO_RemoveDirectory (const gunichar2 *path, gint32 *error
*error=mono_w32error_get_last ();
}
g_free (path_remapped);
return(ret);
}
......@@ -224,7 +234,10 @@ ves_icall_System_IO_MonoIO_FindFirstFile (const gunichar2 *path_with_pattern, Mo
{
HANDLE hnd;
WIN32_FIND_DATA data;
path_with_pattern = mono_unity_get_remapped_path(path_with_pattern);
const gunichar2 *path_with_pattern_remapped;
if (path_with_pattern_remapped = mono_unity_remap_path_utf16 (path_with_pattern))
path_with_pattern = path_with_pattern_remapped;
hnd = mono_w32file_find_first (path_with_pattern, &data);
......@@ -232,6 +245,7 @@ ves_icall_System_IO_MonoIO_FindFirstFile (const gunichar2 *path_with_pattern, Mo
MONO_HANDLE_ASSIGN (file_name, NULL_HANDLE_STRING);
*file_attr = 0;
*ioerror = mono_w32error_get_last ();
g_free (path_with_pattern_remapped);
return hnd;
}
......@@ -243,6 +257,7 @@ ves_icall_System_IO_MonoIO_FindFirstFile (const gunichar2 *path_with_pattern, Mo
*file_attr = data.dwFileAttributes;
*ioerror = ERROR_SUCCESS;
g_free (path_with_pattern_remapped);
return hnd;
}
......@@ -319,7 +334,10 @@ ves_icall_System_IO_MonoIO_SetCurrentDirectory (const gunichar2 *path,
gint32 *error)
{
gboolean ret;
path = mono_unity_get_remapped_path(path);
const gunichar2 *path_remapped;
if (path_remapped = mono_unity_remap_path_utf16 (path))
path = path_remapped;
*error=ERROR_SUCCESS;
......@@ -327,21 +345,31 @@ ves_icall_System_IO_MonoIO_SetCurrentDirectory (const gunichar2 *path,
if(ret==FALSE) {
*error=mono_w32error_get_last ();
}
g_free (path_remapped);
return(ret);
}
MonoBoolean
ves_icall_System_IO_MonoIO_MoveFile (const gunichar2 *path, const gunichar2 *dest, gint32 *error)
{
// TODO_UNITY
gboolean ret;
path = mono_unity_get_remapped_path(path);
dest = mono_unity_get_remapped_path(dest);
const gunichar2 *path_remapped;
const gunichar2 *dest_remapped;
if (path_remapped = mono_unity_remap_path_utf16 (path))
path = path_remapped;
if (dest_remapped = mono_unity_remap_path_utf16 (dest))
dest = dest_remapped;
*error=ERROR_SUCCESS;
return mono_w32file_move (path, dest, error);
ret = mono_w32file_move (path, dest, error);
g_free (path_remapped);
g_free (dest_remapped);
return ret;
}
MonoBoolean
......@@ -349,35 +377,63 @@ ves_icall_System_IO_MonoIO_ReplaceFile (const gunichar2 *source_file_name, const
const gunichar2 *destination_backup_file_name, MonoBoolean ignore_metadata_errors,
gint32 *error)
{
gboolean ret;
guint32 replace_flags = REPLACEFILE_WRITE_THROUGH;
source_file_name = mono_unity_get_remapped_path(source_file_name);
destination_file_name = mono_unity_get_remapped_path(destination_file_name);
destination_backup_file_name = mono_unity_get_remapped_path(destination_backup_file_name);
const gunichar2 *source_file_name_remapped;
const gunichar2 *destination_file_name_remapped;
const gunichar2 *destination_backup_file_name_remapped;
if (source_file_name_remapped = mono_unity_remap_path_utf16 (source_file_name))
source_file_name = source_file_name_remapped;
if (destination_file_name_remapped = mono_unity_remap_path_utf16 (destination_file_name))
destination_file_name = destination_file_name_remapped;
if (destination_backup_file_name_remapped = mono_unity_remap_path_utf16 (destination_backup_file_name))
destination_backup_file_name = destination_backup_file_name_remapped;
*error = ERROR_SUCCESS;
if (ignore_metadata_errors)
replace_flags |= REPLACEFILE_IGNORE_MERGE_ERRORS;
/* FIXME: source and destination file names must not be NULL, but apparently they might be! */
return mono_w32file_replace (destination_file_name, source_file_name,
ret = mono_w32file_replace (destination_file_name, source_file_name,
destination_backup_file_name, replace_flags, error);
g_free (source_file_name_remapped);
g_free (destination_file_name_remapped);
g_free (destination_backup_file_name_remapped);
return ret;
}
MonoBoolean
ves_icall_System_IO_MonoIO_CopyFile (const gunichar2 *path, const gunichar2 *dest,
MonoBoolean overwrite, gint32 *error)
{
path = mono_unity_get_remapped_path(path);
dest = mono_unity_get_remapped_path(dest);
gboolean ret;
const gunichar2 *path_remapped;
const gunichar2 *dest_remapped;
if (path_remapped = mono_unity_remap_path_utf16 (path))
path = path_remapped;
if (dest_remapped = mono_unity_remap_path_utf16 (dest))
dest = dest_remapped;
*error=ERROR_SUCCESS;
return mono_w32file_copy (path, dest, overwrite, error);
ret = mono_w32file_copy (path, dest, overwrite, error);
g_free (path_remapped);
g_free (dest_remapped);
return ret;
}
MonoBoolean
ves_icall_System_IO_MonoIO_DeleteFile (const gunichar2 *path, gint32 *error)
{
gboolean ret;
path = mono_unity_get_remapped_path(path);
const gunichar2 *path_remapped;
if (path_remapped = mono_unity_remap_path_utf16 (path))
path = path_remapped;
*error=ERROR_SUCCESS;
......@@ -385,6 +441,8 @@ ves_icall_System_IO_MonoIO_DeleteFile (const gunichar2 *path, gint32 *error)
if(ret==FALSE) {
*error=mono_w32error_get_last ();
}
g_free (path_remapped);
return(ret);
}
......@@ -393,7 +451,11 @@ gint32
ves_icall_System_IO_MonoIO_GetFileAttributes (const gunichar2 *path, gint32 *error)
{
gint32 ret;
path = mono_unity_get_remapped_path(path);
const gunichar2 *path_remapped;
if (path_remapped = mono_unity_remap_path_utf16 (path))
path = path_remapped;
*error=ERROR_SUCCESS;
ret = mono_w32file_get_attributes (path);
......@@ -408,6 +470,9 @@ ves_icall_System_IO_MonoIO_GetFileAttributes (const gunichar2 *path, gint32 *err
/* if(ret==INVALID_FILE_ATTRIBUTES) { */
*error=mono_w32error_get_last ();
}
g_free (path_remapped);
return(ret);
}
......@@ -448,7 +513,10 @@ MonoBoolean
ves_icall_System_IO_MonoIO_GetFileStat (const gunichar2 *path, MonoIOStat *stat, gint32 *error)
{
gboolean result;
path = mono_unity_get_remapped_path(path);
const gunichar2 *path_remapped;
if (path_remapped = mono_unity_remap_path_utf16 (path))
path = path_remapped;
*error=ERROR_SUCCESS;
......@@ -459,6 +527,8 @@ ves_icall_System_IO_MonoIO_GetFileStat (const gunichar2 *path, MonoIOStat *stat,
memset (stat, 0, sizeof (MonoIOStat));
}
g_free (path_remapped);
return result;
}
......@@ -469,7 +539,10 @@ ves_icall_System_IO_MonoIO_Open (const gunichar2 *filename, gint32 mode,
{
HANDLE ret;
int attributes, attrs;
filename = mono_unity_get_remapped_path(filename);
const gunichar2 *filename_remapped;
if (filename_remapped = mono_unity_remap_path_utf16 (filename))
filename = filename_remapped;
*error=ERROR_SUCCESS;
......@@ -505,8 +578,10 @@ ves_icall_System_IO_MonoIO_Open (const gunichar2 *filename, gint32 mode,
ret=mono_w32file_create (filename, convert_access ((MonoFileAccess)access_mode), convert_share ((MonoFileShare)share), convert_mode ((MonoFileMode)mode), attributes);
if(ret==INVALID_HANDLE_VALUE) {
*error=mono_w32error_get_last ();
}
}
g_free (filename_remapped);
return(ret);
}
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册