X-Git-Url: http://wien.tomnetworks.com/gitweb/?a=blobdiff_plain;f=mono%2Fmetadata%2Fprocess.c;h=1d08c7f481397d5a4175c83f1e4826f0cdc9bbdb;hb=ba6dad488203bdacecee7f23ef35f576ad94f04d;hp=6aa9e66d9f557d8a51392cdb573794d843a18efd;hpb=93703b4ef8bdcf1d6cf336e14f534454221730c5;p=mono.git diff --git a/mono/metadata/process.c b/mono/metadata/process.c index 6aa9e66d9f5..1d08c7f4813 100644 --- a/mono/metadata/process.c +++ b/mono/metadata/process.c @@ -98,15 +98,32 @@ static guint32 unicode_bytes (const gunichar2 *str) } while(1); } +static gunichar2* +unicode_get (const gunichar2 *str) +{ + gunichar2 *swapped; + int i, len; + + len = unicode_bytes (str); + swapped = g_malloc0 (len); + i = 0; + while (str [i]) { + swapped [i] = GUINT16_FROM_LE (str [i]); + i ++; + } + + return swapped; +} + /* - * compare a null-terminated utf16 string and a normal string. + * compare a little-endian null-terminated utf16 string and a normal string. * Can be used only for ascii or latin1 chars. */ static gboolean unicode_string_equals (const gunichar2 *str1, const gchar *str2) { while (*str1 && *str2) { - if (*str1 != *str2) + if (GUINT16_TO_LE (*str1) != *str2) return FALSE; ++str1; ++str2; @@ -126,6 +143,7 @@ static void process_set_field_object (MonoObject *obj, const gchar *fieldname, field=mono_class_get_field_from_name (mono_object_class (obj), fieldname); + /* FIXME: moving GC */ *(MonoObject **)(((char *)obj) + field->offset)=data; } @@ -144,6 +162,7 @@ static void process_set_field_string (MonoObject *obj, const gchar *fieldname, field=mono_class_get_field_from_name (mono_object_class (obj), fieldname); + /* FIXME: moving GC */ *(MonoString **)(((char *)obj) + field->offset)=string; } @@ -163,6 +182,7 @@ static void process_set_field_string_utf8 (MonoObject *obj, field=mono_class_get_field_from_name (mono_object_class (obj), fieldname); + /* FIXME: moving GC */ *(MonoString **)(((char *)obj) + field->offset)=string; } @@ -209,13 +229,13 @@ typedef struct { static gpointer process_get_versioninfo_block (gpointer data, version_data *block) { - block->data_len=*((guint16 *)data); + block->data_len=GUINT16_TO_LE (*((guint16 *)data)); data = (char *)data + sizeof(guint16); - block->value_len=*((guint16 *)data); + block->value_len=GUINT16_TO_LE (*((guint16 *)data)); data = (char *)data + sizeof(guint16); /* No idea what the type is supposed to indicate */ - block->type=*((guint16 *)data); + block->type=GUINT16_TO_LE (*((guint16 *)data)); data = (char *)data + sizeof(guint16); block->key=((gunichar2 *)data); @@ -285,7 +305,7 @@ static gpointer process_read_string_block (MonoObject *filever, } string_len=string_len+block.data_len; - value=(gunichar2 *)data_ptr; + value=unicode_get ((gunichar2 *)data_ptr); /* Skip over the value */ data_ptr=((gunichar2 *)data_ptr)+block.value_len; @@ -320,6 +340,7 @@ static gpointer process_read_string_block (MonoObject *filever, */ } } + g_free (value); } return(data_ptr); @@ -335,6 +356,7 @@ static gpointer process_read_stringtable_block (MonoObject *filever, guint16 data_len) { version_data block; + gunichar2 *value; gchar *language; guint16 string_len=36; /* length of the StringFileInfo block */ @@ -362,7 +384,8 @@ static gpointer process_read_stringtable_block (MonoObject *filever, } string_len=string_len+block.data_len; - language = g_utf16_to_utf8 (block.key, unicode_bytes (block.key), NULL, NULL, NULL); + value = unicode_get (block.key); + language = g_utf16_to_utf8 (value, unicode_bytes (block.key), NULL, NULL, NULL); g_strdown (language); /* Kludge: treat en_US as neutral too */ @@ -385,7 +408,8 @@ static gpointer process_read_stringtable_block (MonoObject *filever, FALSE); } g_free (language); - + g_free (value); + if(data_ptr==NULL) { /* Child block hit padding */ #ifdef DEBUG @@ -458,6 +482,7 @@ static void process_get_fileversion (MonoObject *filever, MonoImage *image) data=mono_image_rva_map (image, version_info->rde_data_offset); + g_free (version_info); if(data==NULL) { return; } @@ -588,6 +613,7 @@ static void process_add_module (GPtrArray *modules, MonoAssembly *ass) process_set_field_string_utf8 (item, "modulename", modulename); g_free (modulename); + /* FIXME: moving GC */ g_ptr_array_add (modules, item); } @@ -774,19 +800,19 @@ MonoBoolean ves_icall_System_Diagnostics_Process_CreateProcess_internal (MonoPro gunichar2 *shell_path = NULL; gchar *env_vars = NULL; gboolean free_shell_path = TRUE; -#ifdef PLATFORM_WIN32 - gchar *newcmd, *tmp; -#endif gchar *spath = NULL; MonoString *cmd = proc_start_info->arguments; + guint32 creation_flags, logon_flags; - MONO_ARCH_SAVE_REGS; - startinfo.cb=sizeof(STARTUPINFO); startinfo.dwFlags=STARTF_USESTDHANDLES; startinfo.hStdInput=stdin_handle; startinfo.hStdOutput=stdout_handle; startinfo.hStdError=stderr_handle; + + creation_flags = CREATE_UNICODE_ENVIRONMENT; + if (proc_start_info->create_no_window) + creation_flags |= CREATE_NO_WINDOW; shell_path = mono_string_chars (proc_start_info->filename); complete_path (shell_path, &spath); @@ -799,11 +825,17 @@ MonoBoolean ves_icall_System_Diagnostics_Process_CreateProcess_internal (MonoPro * This hack is needed to deal with paths containing spaces */ shell_path = NULL; free_shell_path = FALSE; - tmp = mono_string_to_utf8 (cmd); - newcmd = g_strdup_printf ("%s %s", spath, tmp); - cmd = mono_string_new_wrapper (newcmd); - g_free (newcmd); - g_free (tmp); + if (cmd) { + gchar *newcmd, *tmp; + tmp = mono_string_to_utf8 (cmd); + newcmd = g_strdup_printf ("%s %s", spath, tmp); + cmd = mono_string_new_wrapper (newcmd); + g_free (tmp); + g_free (newcmd); + } + else { + cmd = mono_string_new_wrapper (spath); + } #else shell_path = g_utf8_to_utf16 (spath, -1, NULL, NULL, NULL); #endif @@ -858,8 +890,13 @@ MonoBoolean ves_icall_System_Diagnostics_Process_CreateProcess_internal (MonoPro } else { dir=mono_string_chars (proc_start_info->working_directory); } - - ret=CreateProcess (shell_path, mono_string_chars (cmd), NULL, NULL, TRUE, CREATE_UNICODE_ENVIRONMENT, env_vars, dir, &startinfo, &procinfo); + + if (process_info->username) { + logon_flags = process_info->load_user_profile ? LOGON_WITH_PROFILE : 0; + ret=CreateProcessWithLogonW (mono_string_chars (process_info->username), process_info->domain ? mono_string_chars (process_info->domain) : NULL, process_info->password, logon_flags, shell_path, cmd? mono_string_chars (cmd): NULL, creation_flags, env_vars, dir, &startinfo, &procinfo); + } else { + ret=CreateProcess (shell_path, cmd? mono_string_chars (cmd): NULL, NULL, NULL, TRUE, creation_flags, env_vars, dir, &startinfo, &procinfo); + } g_free (env_vars); if (free_shell_path) @@ -869,7 +906,7 @@ MonoBoolean ves_icall_System_Diagnostics_Process_CreateProcess_internal (MonoPro process_info->process_handle=procinfo.hProcess; /*process_info->thread_handle=procinfo.hThread;*/ process_info->thread_handle=NULL; - if (procinfo.hThread != NULL) + if (procinfo.hThread != NULL && procinfo.hThread != INVALID_HANDLE_VALUE) CloseHandle(procinfo.hThread); process_info->pid=procinfo.dwProcessId; process_info->tid=procinfo.dwThreadId; @@ -1059,3 +1096,34 @@ ves_icall_System_Diagnostics_Process_Kill_internal (HANDLE process, gint32 sig) return TerminateProcess (process, -sig); } +gint64 +ves_icall_System_Diagnostics_Process_Times (HANDLE process, gint32 type) +{ + FILETIME create_time, exit_time, kernel_time, user_time; + + if (GetProcessTimes (process, &create_time, &exit_time, &kernel_time, &user_time)) { + if (type == 0) + return *(gint64*)&user_time; + else if (type == 1) + return *(gint64*)&kernel_time; + /* system + user time: FILETIME can be (memory) cast to a 64 bit int */ + return *(gint64*)&kernel_time + *(gint64*)&user_time; + } + return 0; +} + +gint32 +ves_icall_System_Diagnostics_Process_GetPriorityClass (HANDLE process, gint32 *error) +{ + gint32 ret = GetPriorityClass (process); + *error = ret == 0 ? GetLastError () : 0; + return ret; +} + +MonoBoolean +ves_icall_System_Diagnostics_Process_SetPriorityClass (HANDLE process, gint32 priority_class, gint32 *error) +{ + gboolean ret = SetPriorityClass (process, priority_class); + *error = ret == 0 ? GetLastError () : 0; + return ret; +}