X-Git-Url: http://wien.tomnetworks.com/gitweb/?a=blobdiff_plain;f=mono%2Fmetadata%2Fprocess.c;h=74c238232ccec76b3e80182c78552b15adedb70a;hb=0717f141b92db56481cc09af70c026d7ffad8921;hp=25c4ebd72fa63906434af59983f2e640b5f13db2;hpb=f2ab023d8d9b656b27c5d51afd7f4e7e2b4b112c;p=mono.git diff --git a/mono/metadata/process.c b/mono/metadata/process.c index 25c4ebd72fa..74c238232cc 100644 --- a/mono/metadata/process.c +++ b/mono/metadata/process.c @@ -4,8 +4,8 @@ * Author: * Dick Porter (dick@ximian.com) * - * (C) 2002 Ximian, Inc. - * Copyright (c) 2002-2006 Novell, Inc. + * Copyright 2002 Ximian, Inc. + * Copyright 2002-2006 Novell, Inc. */ #include @@ -13,7 +13,7 @@ #include #include -#include +#include #include #include #include @@ -21,11 +21,14 @@ #include #include #include +#include #include /* FIXME: fix this code to not depend so much on the inetrnals */ #include -#undef DEBUG +#define LOGDEBUG(...) +/* define LOGDEBUG(...) g_message(__VA_ARGS__) */ + HANDLE ves_icall_System_Diagnostics_Process_GetProcess_internal (guint32 pid) { @@ -59,8 +62,7 @@ void ves_icall_System_Diagnostics_Process_Process_free_internal (MonoObject *thi MONO_ARCH_SAVE_REGS; #ifdef THREAD_DEBUG - g_message (G_GNUC_PRETTY_FUNCTION ": Closing process %p, handle %p", - this, process); + g_message ("%s: Closing process %p, handle %p", __func__, this, process); #endif CloseHandle (process); @@ -90,15 +92,11 @@ static void process_set_field_object (MonoObject *obj, const gchar *fieldname, { MonoClassField *field; -#ifdef DEBUG - g_message (G_GNUC_PRETTY_FUNCTION ": Setting field %s to object at %p", - fieldname, data); -#endif + LOGDEBUG (g_message ("%s: Setting field %s to object at %p", __func__, fieldname, data)); field=mono_class_get_field_from_name (mono_object_class (obj), fieldname); - /* FIXME: moving GC */ - *(MonoObject **)(((char *)obj) + field->offset)=data; + mono_gc_wbarrier_generic_store (((char *)obj) + field->offset, data); } static void process_set_field_string (MonoObject *obj, const gchar *fieldname, @@ -107,17 +105,13 @@ static void process_set_field_string (MonoObject *obj, const gchar *fieldname, MonoClassField *field; MonoString *string; -#ifdef DEBUG - g_message (G_GNUC_PRETTY_FUNCTION ": Setting field %s to [%s]", - fieldname, g_utf16_to_utf8 (val, len, NULL, NULL, NULL)); -#endif + LOGDEBUG (g_message ("%s: Setting field %s to [%s]", __func__, fieldname, g_utf16_to_utf8 (val, len, NULL, NULL, NULL))); string=mono_string_new_utf16 (mono_object_domain (obj), val, len); field=mono_class_get_field_from_name (mono_object_class (obj), fieldname); - /* FIXME: moving GC */ - *(MonoString **)(((char *)obj) + field->offset)=string; + mono_gc_wbarrier_generic_store (((char *)obj) + field->offset, (MonoObject*)string); } static void process_set_field_int (MonoObject *obj, const gchar *fieldname, @@ -125,10 +119,7 @@ static void process_set_field_int (MonoObject *obj, const gchar *fieldname, { MonoClassField *field; -#ifdef DEBUG - g_message (G_GNUC_PRETTY_FUNCTION ": Setting field %s to %d", - fieldname, val); -#endif + LOGDEBUG (g_message ("%s: Setting field %s to %d", __func__,fieldname, val)); field=mono_class_get_field_from_name (mono_object_class (obj), fieldname); @@ -140,9 +131,7 @@ static void process_set_field_intptr (MonoObject *obj, const gchar *fieldname, { MonoClassField *field; -#ifdef DEBUG - g_message ("%s: Setting field %s to %p", __func__, fieldname, val); -#endif + LOGDEBUG (g_message ("%s: Setting field %s to %p", __func__, fieldname, val)); field=mono_class_get_field_from_name (mono_object_class (obj), fieldname); @@ -154,10 +143,7 @@ static void process_set_field_bool (MonoObject *obj, const gchar *fieldname, { MonoClassField *field; -#ifdef DEBUG - g_message (G_GNUC_PRETTY_FUNCTION ": Setting field %s to %s", - fieldname, val?"TRUE":"FALSE"); -#endif + LOGDEBUG (g_message ("%s: Setting field %s to %s", __func__, fieldname, val?"TRUE":"FALSE")); field=mono_class_get_field_from_name (mono_object_class (obj), fieldname); @@ -189,17 +175,12 @@ static void process_module_string_read (MonoObject *filever, gpointer data, lang_key_utf8 = g_strdup_printf (key, lang_lo, lang_hi, 0x04, 0xb0); -#ifdef DEBUG - g_message ("%s: asking for [%s]", __func__, lang_key_utf8); -#endif + LOGDEBUG (g_message ("%s: asking for [%s]", __func__, lang_key_utf8)); lang_key = g_utf8_to_utf16 (lang_key_utf8, -1, NULL, NULL, NULL); if (VerQueryValue (data, lang_key, (gpointer *)&buffer, &chars) && chars > 0) { -#ifdef DEBUG - g_message ("%s: found %d chars of [%s]", __func__, chars, - g_utf16_to_utf8 (buffer, chars, NULL, NULL, NULL)); -#endif + LOGDEBUG (g_message ("%s: found %d chars of [%s]", __func__, chars, g_utf16_to_utf8 (buffer, chars, NULL, NULL, NULL))); /* chars includes trailing null */ process_set_field_string (filever, fieldname, buffer, chars - 1); } else { @@ -266,9 +247,7 @@ static void process_get_fileversion (MonoObject *filever, gunichar2 *filename) if (VerQueryValue (data, query, (gpointer *)&ffi, &ffi_size)) { -#ifdef DEBUG - g_message (G_GNUC_PRETTY_FUNCTION ": recording assembly: FileName [%s] FileVersionInfo [%d.%d.%d.%d]", g_utf16_to_utf8 (filename, -1, NULL, NULL, NULL), HIWORD (ffi->dwFileVersionMS), LOWORD (ffi->dwFileVersionMS), HIWORD (ffi->dwFileVersionLS), LOWORD (ffi->dwFileVersionLS)); -#endif + LOGDEBUG (g_message ("%s: recording assembly: FileName [%s] FileVersionInfo [%d.%d.%d.%d]", __func__, g_utf16_to_utf8 (filename, -1, NULL, NULL, NULL), HIWORD (ffi->dwFileVersionMS), LOWORD (ffi->dwFileVersionMS), HIWORD (ffi->dwFileVersionLS), LOWORD (ffi->dwFileVersionLS))); process_set_field_int (filever, "filemajorpart", HIWORD (ffi->dwFileVersionMS)); process_set_field_int (filever, "fileminorpart", LOWORD (ffi->dwFileVersionMS)); @@ -300,9 +279,7 @@ static void process_get_fileversion (MonoObject *filever, gunichar2 *filename) /* use the first language ID we see */ if (trans_size >= 4) { -#ifdef DEBUG - g_message("%s: %s has 0x%0x 0x%0x 0x%0x 0x%0x", __func__, g_utf16_to_utf8 (filename, -1, NULL, NULL, NULL), trans_data[0], trans_data[1], trans_data[2], trans_data[3]); -#endif + LOGDEBUG (g_message("%s: %s has 0x%0x 0x%0x 0x%0x 0x%0x", __func__, g_utf16_to_utf8 (filename, -1, NULL, NULL, NULL), trans_data[0], trans_data[1], trans_data[2], trans_data[3])); lang = (trans_data[0]) | (trans_data[1] << 8) | (trans_data[2] << 16) | @@ -374,8 +351,7 @@ static void process_get_fileversion (MonoObject *filever, gunichar2 *filename) } } -static void process_add_module (GPtrArray *modules, HANDLE process, HMODULE mod, - gunichar2 *filename, gunichar2 *modulename) +static MonoObject* process_add_module (HANDLE process, HMODULE mod, gunichar2 *filename, gunichar2 *modulename) { MonoClass *proc_class, *filever_class; MonoObject *item, *filever; @@ -414,50 +390,47 @@ static void process_add_module (GPtrArray *modules, HANDLE process, HMODULE mod, unicode_chars (modulename)); process_set_field_object (item, "version_info", filever); - /* FIXME: moving GC */ - g_ptr_array_add (modules, item); + return item; } /* Returns an array of System.Diagnostics.ProcessModule */ MonoArray *ves_icall_System_Diagnostics_Process_GetModules_internal (MonoObject *this, HANDLE process) { - GPtrArray *modules_list=g_ptr_array_new (); + MonoArray *temp_arr = NULL; MonoArray *arr; HMODULE mods[1024]; gunichar2 filename[MAX_PATH]; gunichar2 modname[MAX_PATH]; DWORD needed; - guint32 count; - guint32 i; - - MONO_ARCH_SAVE_REGS; + guint32 count = 0; + guint32 i, num_added = 0; STASH_SYS_ASS (this); if (EnumProcessModules (process, mods, sizeof(mods), &needed)) { count = needed / sizeof(HMODULE); + temp_arr = mono_array_new (mono_domain_get (), mono_get_object_class (), count); for (i = 0; i < count; i++) { - if (GetModuleBaseName (process, mods[i], modname, - MAX_PATH) && - GetModuleFileNameEx (process, mods[i], filename, - MAX_PATH)) { - process_add_module (modules_list, process, - mods[i], filename, modname); + if (GetModuleBaseName (process, mods[i], modname, MAX_PATH) && + GetModuleFileNameEx (process, mods[i], filename, MAX_PATH)) { + MonoObject *module = process_add_module (process, mods[i], + filename, modname); + mono_array_setref (temp_arr, num_added++, module); } } } - /* Build a MonoArray out of modules_list */ - arr=mono_array_new (mono_domain_get (), mono_get_object_class (), - modules_list->len); - - for(i=0; ilen; i++) { - mono_array_setref (arr, i, g_ptr_array_index (modules_list, i)); + if (count == num_added) { + arr = temp_arr; + } else { + /* shorter version of the array */ + arr = mono_array_new (mono_domain_get (), mono_get_object_class (), num_added); + + for (i = 0; i < num_added; i++) + mono_array_setref (arr, i, mono_array_get (temp_arr, MonoObject*, i)); } - - g_ptr_array_free (modules_list, TRUE); - - return(arr); + + return arr; } void ves_icall_System_Diagnostics_FileVersionInfo_GetVersionInfo_internal (MonoObject *this, MonoString *filename) @@ -477,7 +450,7 @@ static gchar * quote_path (const gchar *path) { gchar *res = g_shell_quote (path); -#ifdef PLATFORM_WIN32 +#ifdef TARGET_WIN32 { gchar *q = res; while (*q) { @@ -494,38 +467,52 @@ quote_path (const gchar *path) static gboolean complete_path (const gunichar2 *appname, gchar **completed) { - gchar *utf8app; + gchar *utf8app, *utf8appmemory; gchar *found; - utf8app = g_utf16_to_utf8 (appname, -1, NULL, NULL, NULL); + utf8appmemory = utf8app = g_utf16_to_utf8 (appname, -1, NULL, NULL, NULL); +#ifdef TARGET_WIN32 // Should this happen on all platforms? + { + // remove the quotes around utf8app. + size_t len; + len = strlen (utf8app); + if (len) { + if (utf8app[len-1] == '\"') + utf8app[len-1] = '\0'; + if (utf8app[0] == '\"') + utf8app++; + } + } +#endif + if (g_path_is_absolute (utf8app)) { *completed = quote_path (utf8app); - g_free (utf8app); + g_free (utf8appmemory); return TRUE; } if (g_file_test (utf8app, G_FILE_TEST_IS_EXECUTABLE) && !g_file_test (utf8app, G_FILE_TEST_IS_DIR)) { *completed = quote_path (utf8app); - g_free (utf8app); + g_free (utf8appmemory); return TRUE; } found = g_find_program_in_path (utf8app); if (found == NULL) { *completed = NULL; - g_free (utf8app); + g_free (utf8appmemory); return FALSE; } *completed = quote_path (found); g_free (found); - g_free (utf8app); + g_free (utf8appmemory); return TRUE; } #ifndef HAVE_GETPROCESSID /* Run-time GetProcessId detection for Windows */ -#ifdef PLATFORM_WIN32 +#ifdef TARGET_WIN32 #define HAVE_GETPROCESSID typedef DWORD (WINAPI *GETPROCESSID_PROC) (HANDLE); @@ -590,7 +577,7 @@ static DWORD WINAPI GetProcessId_detect (HANDLE process) GetProcessId = &GetProcessId_stub; return GetProcessId (process); } -#endif /* PLATFORM_WIN32 */ +#endif /* HOST_WIN32 */ #endif /* !HAVE_GETPROCESSID */ MonoBoolean ves_icall_System_Diagnostics_Process_ShellExecuteEx_internal (MonoProcessStartInfo *proc_start_info, MonoProcInfo *process_info) @@ -600,8 +587,8 @@ MonoBoolean ves_icall_System_Diagnostics_Process_ShellExecuteEx_internal (MonoPr shellex.cbSize = sizeof(SHELLEXECUTEINFO); shellex.fMask = SEE_MASK_FLAG_DDEWAIT | SEE_MASK_NOCLOSEPROCESS | SEE_MASK_UNICODE; - shellex.nShow = SW_SHOWNORMAL; - + shellex.nShow = proc_start_info->window_style; + shellex.nShow = (shellex.nShow == 0) ? 1 : (shellex.nShow == 1 ? 0 : shellex.nShow); if (proc_start_info->filename != NULL) { @@ -637,7 +624,7 @@ MonoBoolean ves_icall_System_Diagnostics_Process_ShellExecuteEx_internal (MonoPr /* It appears that there's no way to get the pid from a * process handle before windows xp. Really. */ -#ifdef HAVE_GETPROCESSID +#if defined(HAVE_GETPROCESSID) && !defined(MONO_CROSS_COMPILE) process_info->pid = GetProcessId (shellex.hProcess); #else process_info->pid = 0; @@ -677,7 +664,7 @@ MonoBoolean ves_icall_System_Diagnostics_Process_CreateProcess_internal (MonoPro process_info->pid = -ERROR_FILE_NOT_FOUND; return FALSE; } -#ifdef PLATFORM_WIN32 +#ifdef TARGET_WIN32 /* Seems like our CreateProcess does not work as the windows one. * This hack is needed to deal with paths containing spaces */ shell_path = NULL; @@ -793,6 +780,22 @@ MonoBoolean ves_icall_System_Diagnostics_Process_WaitForExit_internal (MonoObjec } } +MonoBoolean ves_icall_System_Diagnostics_Process_WaitForInputIdle_internal (MonoObject *this, HANDLE process, gint32 ms) +{ + guint32 ret; + + MONO_ARCH_SAVE_REGS; + + if(ms<0) { + /* Wait forever */ + ret=WaitForInputIdle (process, INFINITE); + } else { + ret=WaitForInputIdle (process, ms); + } + + return (ret) ? FALSE : TRUE; +} + gint64 ves_icall_System_Diagnostics_Process_ExitTime_internal (HANDLE process) { gboolean ret; @@ -841,9 +844,7 @@ gint32 ves_icall_System_Diagnostics_Process_ExitCode_internal (HANDLE process) GetExitCodeProcess (process, &code); -#ifdef DEBUG - g_message (G_GNUC_PRETTY_FUNCTION ": process exit code is %d", code); -#endif + LOGDEBUG (g_message ("%s: process exit code is %d", __func__, code)); return(code); } @@ -869,10 +870,7 @@ MonoString *ves_icall_System_Diagnostics_Process_ProcessName_internal (HANDLE pr return(NULL); } -#ifdef DEBUG - g_message (G_GNUC_PRETTY_FUNCTION ": process name is [%s]", - g_utf16_to_utf8 (name, -1, NULL, NULL, NULL)); -#endif + LOGDEBUG (g_message ("%s: process name is [%s]", __func__, g_utf16_to_utf8 (name, -1, NULL, NULL, NULL))); string=mono_string_new_utf16 (mono_domain_get (), name, len); @@ -985,3 +983,41 @@ ves_icall_System_Diagnostics_Process_SetPriorityClass (HANDLE process, gint32 pr *error = ret == 0 ? GetLastError () : 0; return ret; } + +HANDLE +ves_icall_System_Diagnostics_Process_ProcessHandle_duplicate (HANDLE process) +{ + HANDLE ret; + + MONO_ARCH_SAVE_REGS; + + LOGDEBUG (g_message ("%s: Duplicating process handle %p", __func__, process)); + + DuplicateHandle (GetCurrentProcess (), process, GetCurrentProcess (), + &ret, THREAD_ALL_ACCESS, TRUE, 0); + + return ret; +} + +void +ves_icall_System_Diagnostics_Process_ProcessHandle_close (HANDLE process) +{ + MONO_ARCH_SAVE_REGS; + + LOGDEBUG (g_message ("%s: Closing process handle %p", __func__, process)); + + CloseHandle (process); +} + +gint64 +ves_icall_System_Diagnostics_Process_GetProcessData (int pid, gint32 data_type, gint32 *error) +{ + MonoProcessError perror; + guint64 res; + + res = mono_process_get_data_with_error (GINT_TO_POINTER (pid), data_type, &perror); + if (error) + *error = perror; + return res; +} +