X-Git-Url: http://wien.tomnetworks.com/gitweb/?a=blobdiff_plain;f=mono%2Fmetadata%2Fprocess.c;h=02b36b631c612ab69e00fc7ab69a382fe6d5d468;hb=d37df4b0c64f75e7de39a13ec614c7c2719a0491;hp=d7cc110aec6bbca2ac91b363582f40410cf1fba0;hpb=92d86659ca5a71b91c631cb69fb5c6ceccd68c7c;p=mono.git diff --git a/mono/metadata/process.c b/mono/metadata/process.c index d7cc110aec6..02b36b631c6 100644 --- a/mono/metadata/process.c +++ b/mono/metadata/process.c @@ -20,6 +20,7 @@ #include #include #include +#include #include #include #include @@ -34,8 +35,6 @@ HANDLE ves_icall_System_Diagnostics_Process_GetProcess_internal (guint32 pid) { HANDLE handle; - MONO_ARCH_SAVE_REGS; - /* GetCurrentProcess returns a pseudo-handle, so use * OpenProcess instead */ @@ -52,18 +51,14 @@ HANDLE ves_icall_System_Diagnostics_Process_GetProcess_internal (guint32 pid) guint32 ves_icall_System_Diagnostics_Process_GetPid_internal (void) { - MONO_ARCH_SAVE_REGS; - return mono_process_current_pid (); } -void ves_icall_System_Diagnostics_Process_Process_free_internal (MonoObject *this, +void ves_icall_System_Diagnostics_Process_Process_free_internal (MonoObject *this_obj, HANDLE process) { - MONO_ARCH_SAVE_REGS; - #ifdef THREAD_DEBUG - g_message ("%s: Closing process %p, handle %p", __func__, this, process); + g_message ("%s: Closing process %p, handle %p", __func__, this_obj, process); #endif #if defined(TARGET_WIN32) || defined(HOST_WIN32) @@ -73,9 +68,9 @@ void ves_icall_System_Diagnostics_Process_Process_free_internal (MonoObject *thi #endif } -#define STASH_SYS_ASS(this) \ +#define STASH_SYS_ASS(this_obj) \ if(system_assembly == NULL) { \ - system_assembly=this->vtable->klass->image; \ + system_assembly=this_obj->vtable->klass->image; \ } static MonoImage *system_assembly=NULL; @@ -119,6 +114,20 @@ static void process_set_field_string (MonoObject *obj, const gchar *fieldname, mono_gc_wbarrier_generic_store (((char *)obj) + field->offset, (MonoObject*)string); } +static void process_set_field_string_char (MonoObject *obj, const gchar *fieldname, + const gchar *val) +{ + MonoClassField *field; + MonoString *string; + + LOGDEBUG (g_message ("%s: Setting field %s to [%s]", __func__, fieldname, val)); + + string=mono_string_new (mono_object_domain (obj), val); + + field=mono_class_get_field_from_name (mono_object_class (obj), fieldname); + mono_gc_wbarrier_generic_store (((char *)obj) + field->offset, (MonoObject*)string); +} + static void process_set_field_int (MonoObject *obj, const gchar *fieldname, guint32 val) { @@ -264,11 +273,11 @@ static void process_get_fileversion (MonoObject *filever, gunichar2 *filename) process_set_field_int (filever, "productbuildpart", HIWORD (ffi->dwProductVersionLS)); process_set_field_int (filever, "productprivatepart", LOWORD (ffi->dwProductVersionLS)); - process_set_field_bool (filever, "isdebug", (ffi->dwFileFlags & ffi->dwFileFlagsMask) & VS_FF_DEBUG); - process_set_field_bool (filever, "isprerelease", (ffi->dwFileFlags & ffi->dwFileFlagsMask) & VS_FF_PRERELEASE); - process_set_field_bool (filever, "ispatched", (ffi->dwFileFlags & ffi->dwFileFlagsMask) & VS_FF_PATCHED); - process_set_field_bool (filever, "isprivatebuild", (ffi->dwFileFlags & ffi->dwFileFlagsMask) & VS_FF_PRIVATEBUILD); - process_set_field_bool (filever, "isspecialbuild", (ffi->dwFileFlags & ffi->dwFileFlagsMask) & VS_FF_SPECIALBUILD); + process_set_field_bool (filever, "isdebug", ((ffi->dwFileFlags & ffi->dwFileFlagsMask) & VS_FF_DEBUG) != 0); + process_set_field_bool (filever, "isprerelease", ((ffi->dwFileFlags & ffi->dwFileFlagsMask) & VS_FF_PRERELEASE) != 0); + process_set_field_bool (filever, "ispatched", ((ffi->dwFileFlags & ffi->dwFileFlagsMask) & VS_FF_PATCHED) != 0); + process_set_field_bool (filever, "isprivatebuild", ((ffi->dwFileFlags & ffi->dwFileFlagsMask) & VS_FF_PRIVATEBUILD) != 0); + process_set_field_bool (filever, "isspecialbuild", ((ffi->dwFileFlags & ffi->dwFileFlagsMask) & VS_FF_SPECIALBUILD) != 0); } g_free (query); @@ -356,9 +365,49 @@ static void process_get_fileversion (MonoObject *filever, gunichar2 *filename) } } -static MonoObject* process_add_module (HANDLE process, HMODULE mod, gunichar2 *filename, gunichar2 *modulename) +static void process_get_assembly_fileversion (MonoObject *filever, MonoAssembly *assembly) +{ + process_set_field_int (filever, "filemajorpart", assembly->aname.major); + process_set_field_int (filever, "fileminorpart", assembly->aname.minor); + process_set_field_int (filever, "filebuildpart", assembly->aname.build); +} + +static MonoObject* get_process_module (MonoAssembly *assembly, MonoClass *proc_class) +{ + static MonoClass *filever_class = NULL; + MonoObject *item, *filever; + MonoDomain *domain = mono_domain_get (); + char filename [80] = "[In Memory] "; + const char *modulename = assembly->aname.name; + + strncat (filename, modulename, 80); + + /* Build a System.Diagnostics.ProcessModule with the data. + */ + item = mono_object_new (domain, proc_class); + + if (!filever_class) + filever_class = mono_class_from_name (system_assembly, + "System.Diagnostics", + "FileVersionInfo"); + + filever = mono_object_new (domain, filever_class); + + process_get_assembly_fileversion (filever, assembly); + process_set_field_string_char (filever, "filename", filename); + process_set_field_object (item, "version_info", filever); + + process_set_field_intptr (item, "baseaddr", assembly->image->raw_data); + process_set_field_int (item, "memory_size", assembly->image->raw_data_len); + process_set_field_string_char (item, "filename", filename); + process_set_field_string_char (item, "modulename", modulename); + + return item; +} + +static MonoObject* process_add_module (HANDLE process, HMODULE mod, gunichar2 *filename, gunichar2 *modulename, MonoClass *proc_class) { - MonoClass *proc_class, *filever_class; + static MonoClass *filever_class = NULL; MonoObject *item, *filever; MonoDomain *domain=mono_domain_get (); MODULEINFO modinfo; @@ -366,13 +415,13 @@ static MonoObject* process_add_module (HANDLE process, HMODULE mod, gunichar2 *f /* Build a System.Diagnostics.ProcessModule with the data. */ - proc_class=mono_class_from_name (system_assembly, "System.Diagnostics", - "ProcessModule"); item=mono_object_new (domain, proc_class); - filever_class=mono_class_from_name (system_assembly, + if (!filever_class) + filever_class=mono_class_from_name (system_assembly, "System.Diagnostics", "FileVersionInfo"); + filever=mono_object_new (domain, filever_class); process_get_fileversion (filever, filename); @@ -398,8 +447,30 @@ static MonoObject* process_add_module (HANDLE process, HMODULE mod, gunichar2 *f return item; } +static GPtrArray* get_domain_assemblies (MonoDomain *domain) +{ + GSList *tmp; + GPtrArray *assemblies; + + /* + * Make a copy of the list of assemblies because we can't hold the assemblies + * lock while creating objects etc. + */ + assemblies = g_ptr_array_new (); + mono_domain_assemblies_lock (domain); + for (tmp = domain->domain_assemblies; tmp; tmp = tmp->next) { + MonoAssembly *ass = tmp->data; + if (ass->image->fileio_used) + continue; + g_ptr_array_add (assemblies, ass); + } + mono_domain_assemblies_unlock (domain); + + return assemblies; +} + /* Returns an array of System.Diagnostics.ProcessModule */ -MonoArray *ves_icall_System_Diagnostics_Process_GetModules_internal (MonoObject *this, HANDLE process) +MonoArray *ves_icall_System_Diagnostics_Process_GetModules_internal (MonoObject *this_obj, HANDLE process) { MonoArray *temp_arr = NULL; MonoArray *arr; @@ -407,29 +478,67 @@ MonoArray *ves_icall_System_Diagnostics_Process_GetModules_internal (MonoObject gunichar2 filename[MAX_PATH]; gunichar2 modname[MAX_PATH]; DWORD needed; - guint32 count = 0; + guint32 count = 0, module_count = 0, assembly_count = 0; guint32 i, num_added = 0; + static MonoClass *proc_class = NULL; + GPtrArray *assemblies = NULL; + static HANDLE current_process = 0; + + if (current_process == 0) { + int pid = mono_process_current_pid (); + current_process = ves_icall_System_Diagnostics_Process_GetProcess_internal (pid); + } - STASH_SYS_ASS (this); + STASH_SYS_ASS (this_obj); + + if (process == current_process) { + assemblies = get_domain_assemblies (mono_domain_get ()); + assembly_count = assemblies->len; + } 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)) { - MonoObject *module = process_add_module (process, mods[i], - filename, modname); - mono_array_setref (temp_arr, num_added++, module); - } + module_count += needed / sizeof(HMODULE); + } + + count = module_count + assembly_count; + if (!proc_class) + proc_class = mono_class_from_name (system_assembly, "System.Diagnostics", "ProcessModule"); + + temp_arr = mono_array_new (mono_domain_get (), proc_class, count); + + for (i = 0; i < module_count; i++) { + 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, proc_class); + mono_array_setref (temp_arr, num_added++, module); + } + } + + if (assemblies) { + for (i = 0; i < assembly_count; i++) { + MonoAssembly *ass = g_ptr_array_index (assemblies, i); + MonoObject *module = get_process_module (ass, proc_class); + mono_array_setref (temp_arr, num_added++, module); } + g_ptr_array_free (assemblies, TRUE); + } + + if (count == num_added) { + arr = temp_arr; + } else { + /* shorter version of the array */ + arr = mono_array_new (mono_domain_get (), proc_class, num_added); + + for (i = 0; i < num_added; i++) + mono_array_setref (arr, i, mono_array_get (temp_arr, MonoObject*, 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); + arr = mono_array_new (mono_domain_get (), proc_class, num_added); for (i = 0; i < num_added; i++) mono_array_setref (arr, i, mono_array_get (temp_arr, MonoObject*, i)); @@ -438,14 +547,12 @@ MonoArray *ves_icall_System_Diagnostics_Process_GetModules_internal (MonoObject return arr; } -void ves_icall_System_Diagnostics_FileVersionInfo_GetVersionInfo_internal (MonoObject *this, MonoString *filename) +void ves_icall_System_Diagnostics_FileVersionInfo_GetVersionInfo_internal (MonoObject *this_obj, MonoString *filename) { - MONO_ARCH_SAVE_REGS; - - STASH_SYS_ASS (this); + STASH_SYS_ASS (this_obj); - process_get_fileversion (this, mono_string_chars (filename)); - process_set_field_string (this, "filename", + process_get_fileversion (this_obj, mono_string_chars (filename)); + process_set_field_string (this_obj, "filename", mono_string_chars (filename), mono_string_length (filename)); } @@ -556,10 +663,7 @@ MonoBoolean ves_icall_System_Diagnostics_Process_ShellExecuteEx_internal (MonoPr } else { process_info->process_handle = shellex.hProcess; process_info->thread_handle = NULL; - /* It appears that there's no way to get the pid from a - * process handle before windows xp. Really. - */ -#if defined(HAVE_GETPROCESSID) && !defined(MONO_CROSS_COMPILE) +#if !defined(MONO_CROSS_COMPILE) process_info->pid = GetProcessId (shellex.hProcess); #else process_info->pid = 0; @@ -696,18 +800,19 @@ MonoBoolean ves_icall_System_Diagnostics_Process_CreateProcess_internal (MonoPro return(ret); } -MonoBoolean ves_icall_System_Diagnostics_Process_WaitForExit_internal (MonoObject *this, HANDLE process, gint32 ms) +MonoBoolean ves_icall_System_Diagnostics_Process_WaitForExit_internal (MonoObject *this_obj, HANDLE process, gint32 ms) { guint32 ret; - MONO_ARCH_SAVE_REGS; - + MONO_PREPARE_BLOCKING if(ms<0) { /* Wait forever */ ret=WaitForSingleObjectEx (process, INFINITE, TRUE); } else { ret=WaitForSingleObjectEx (process, ms, TRUE); } + MONO_FINISH_BLOCKING + if(ret==WAIT_OBJECT_0) { return(TRUE); } else { @@ -715,12 +820,10 @@ MonoBoolean ves_icall_System_Diagnostics_Process_WaitForExit_internal (MonoObjec } } -MonoBoolean ves_icall_System_Diagnostics_Process_WaitForInputIdle_internal (MonoObject *this, HANDLE process, gint32 ms) +MonoBoolean ves_icall_System_Diagnostics_Process_WaitForInputIdle_internal (MonoObject *this_obj, HANDLE process, gint32 ms) { guint32 ret; - MONO_ARCH_SAVE_REGS; - if(ms<0) { /* Wait forever */ ret=WaitForInputIdle (process, INFINITE); @@ -742,8 +845,6 @@ gint64 ves_icall_System_Diagnostics_Process_ExitTime_internal (HANDLE process) gboolean ret; FILETIME create_time, exit_time, kernel_time, user_time; - MONO_ARCH_SAVE_REGS; - ret = GetProcessTimes (process, &create_time, &exit_time, &kernel_time, &user_time); if (ret) @@ -757,8 +858,6 @@ gint64 ves_icall_System_Diagnostics_Process_StartTime_internal (HANDLE process) gboolean ret; FILETIME create_time, exit_time, kernel_time, user_time; - MONO_ARCH_SAVE_REGS; - ret = GetProcessTimes (process, &create_time, &exit_time, &kernel_time, &user_time); if (ret) @@ -771,8 +870,6 @@ gint32 ves_icall_System_Diagnostics_Process_ExitCode_internal (HANDLE process) { DWORD code; - MONO_ARCH_SAVE_REGS; - GetExitCodeProcess (process, &code); LOGDEBUG (g_message ("%s: process exit code is %d", __func__, code)); @@ -789,8 +886,6 @@ MonoString *ves_icall_System_Diagnostics_Process_ProcessName_internal (HANDLE pr DWORD needed; guint32 len; - MONO_ARCH_SAVE_REGS; - ok=EnumProcessModules (process, &mod, sizeof(mod), &needed); if(ok==FALSE) { return(NULL); @@ -809,21 +904,22 @@ MonoString *ves_icall_System_Diagnostics_Process_ProcessName_internal (HANDLE pr } /* Returns an array of pids */ -MonoArray *ves_icall_System_Diagnostics_Process_GetProcesses_internal (void) +MonoArray * +ves_icall_System_Diagnostics_Process_GetProcesses_internal (void) { #if !defined(HOST_WIN32) MonoArray *procs; gpointer *pidarray; int i, count; - MONO_ARCH_SAVE_REGS; - pidarray = mono_process_list (&count); - if (!pidarray) - mono_raise_exception (mono_get_exception_not_supported ("This system does not support EnumProcesses")); + if (!pidarray) { + mono_set_pending_exception (mono_get_exception_not_supported ("This system does not support EnumProcesses")); + return NULL; + } procs = mono_array_new (mono_domain_get (), mono_get_int32_class (), count); if (sizeof (guint32) == sizeof (gpointer)) { - memcpy (mono_array_addr (procs, guint32, 0), pidarray, count); + memcpy (mono_array_addr (procs, guint32, 0), pidarray, count * sizeof (gint32)); } else { for (i = 0; i < count; ++i) *(mono_array_addr (procs, guint32, i)) = GPOINTER_TO_UINT (pidarray [i]); @@ -848,8 +944,8 @@ MonoArray *ves_icall_System_Diagnostics_Process_GetProcesses_internal (void) g_free (pids); pids = NULL; exc = mono_get_exception_not_supported ("This system does not support EnumProcesses"); - mono_raise_exception (exc); - g_assert_not_reached (); + mono_set_pending_exception (exc); + return NULL; } if (needed < (count * sizeof (guint32))) break; @@ -873,8 +969,6 @@ MonoBoolean ves_icall_System_Diagnostics_Process_GetWorkingSet_internal (HANDLE gboolean ret; SIZE_T ws_min, ws_max; - MONO_ARCH_SAVE_REGS; - ret=GetProcessWorkingSetSize (process, &ws_min, &ws_max); *min=(guint32)ws_min; *max=(guint32)ws_max; @@ -888,8 +982,6 @@ MonoBoolean ves_icall_System_Diagnostics_Process_SetWorkingSet_internal (HANDLE SIZE_T ws_min; SIZE_T ws_max; - MONO_ARCH_SAVE_REGS; - ret=GetProcessWorkingSetSize (process, &ws_min, &ws_max); if(ret==FALSE) { return(FALSE); @@ -909,8 +1001,6 @@ MonoBoolean ves_icall_System_Diagnostics_Process_SetWorkingSet_internal (HANDLE MonoBoolean ves_icall_System_Diagnostics_Process_Kill_internal (HANDLE process, gint32 sig) { - MONO_ARCH_SAVE_REGS; - /* sig == 1 -> Kill, sig == 2 -> CloseMainWindow */ return TerminateProcess (process, -sig); @@ -956,8 +1046,6 @@ 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 (), @@ -969,8 +1057,6 @@ ves_icall_System_Diagnostics_Process_ProcessHandle_duplicate (HANDLE process) 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); @@ -988,3 +1074,9 @@ ves_icall_System_Diagnostics_Process_GetProcessData (int pid, gint32 data_type, return res; } +void +ves_icall_System_Diagnostics_Process_ProcessAsyncReader_RemoveFromIOThreadPool (HANDLE handle) +{ + mono_threadpool_ms_io_remove_socket (GPOINTER_TO_INT (handle)); +} +