X-Git-Url: http://wien.tomnetworks.com/gitweb/?a=blobdiff_plain;f=mono%2Fmetadata%2Fprocess.c;h=fd039db49f7843fb8366b67b17689fed1db5c73a;hb=c8229679ca4da20e484349fd02d3e8382c71d282;hp=f6b47165d0cafbb11f1e759b0182fa0c9c3d974c;hpb=e3d2fbc79e29343b0267ad91f58f59f349215b7c;p=mono.git diff --git a/mono/metadata/process.c b/mono/metadata/process.c index f6b47165d0c..fd039db49f7 100644 --- a/mono/metadata/process.c +++ b/mono/metadata/process.c @@ -5,6 +5,7 @@ * Dick Porter (dick@ximian.com) * * (C) 2002 Ximian, Inc. + * Copyright (c) 2002-2006 Novell, Inc. */ #include @@ -97,7 +98,40 @@ static guint32 unicode_bytes (const gunichar2 *str) } while(1); } -static void process_set_field_object (MonoObject *obj, const guchar *fieldname, +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 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 (GUINT16_TO_LE (*str1) != *str2) + return FALSE; + ++str1; + ++str2; + } + return *str1 == *str2; +} + +static void process_set_field_object (MonoObject *obj, const gchar *fieldname, MonoObject *data) { MonoClassField *field; @@ -109,10 +143,11 @@ static void process_set_field_object (MonoObject *obj, const guchar *fieldname, field=mono_class_get_field_from_name (mono_object_class (obj), fieldname); + /* FIXME: moving GC */ *(MonoObject **)(((char *)obj) + field->offset)=data; } -static void process_set_field_string (MonoObject *obj, const guchar *fieldname, +static void process_set_field_string (MonoObject *obj, const gchar *fieldname, const gunichar2 *val, guint32 len) { MonoClassField *field; @@ -127,12 +162,13 @@ static void process_set_field_string (MonoObject *obj, const guchar *fieldname, field=mono_class_get_field_from_name (mono_object_class (obj), fieldname); + /* FIXME: moving GC */ *(MonoString **)(((char *)obj) + field->offset)=string; } static void process_set_field_string_utf8 (MonoObject *obj, - const guchar *fieldname, - const guchar *val) + const gchar *fieldname, + const gchar *val) { MonoClassField *field; MonoString *string; @@ -146,10 +182,11 @@ 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; } -static void process_set_field_int (MonoObject *obj, const guchar *fieldname, +static void process_set_field_int (MonoObject *obj, const gchar *fieldname, guint32 val) { MonoClassField *field; @@ -164,7 +201,7 @@ static void process_set_field_int (MonoObject *obj, const guchar *fieldname, *(guint32 *)(((char *)obj) + field->offset)=val; } -static void process_set_field_bool (MonoObject *obj, const guchar *fieldname, +static void process_set_field_bool (MonoObject *obj, const gchar *fieldname, gboolean val) { MonoClassField *field; @@ -192,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); @@ -241,66 +278,8 @@ static gpointer process_read_string_block (MonoObject *filever, gboolean store) { version_data block; - guint16 string_len=0; - guchar comments_key[]= {'C', '\0', 'o', '\0', 'm', '\0', - 'm', '\0', 'e', '\0', 'n', '\0', - 't', '\0', 's', '\0', '\0', '\0'}; - guchar compname_key[]= {'C', '\0', 'o', '\0', 'm', '\0', - 'p', '\0', 'a', '\0', 'n', '\0', - 'y', '\0', 'N', '\0', 'a', '\0', - 'm', '\0', 'e', '\0', '\0', '\0'}; - guchar filedesc_key[]= {'F', '\0', 'i', '\0', 'l', '\0', - 'e', '\0', 'D', '\0', 'e', '\0', - 's', '\0', 'c', '\0', 'r', '\0', - 'i', '\0', 'p', '\0', 't', '\0', - 'i', '\0', 'o', '\0', 'n', '\0', - '\0', '\0'}; - guchar filever_key[]= {'F', '\0', 'i', '\0', 'l', '\0', - 'e', '\0', 'V', '\0', 'e', '\0', - 'r', '\0', 's', '\0', 'i', '\0', - 'o', '\0', 'n', '\0', '\0', '\0'}; - guchar internal_key[]= {'I', '\0', 'n', '\0', 't', '\0', - 'e', '\0', 'r', '\0', 'n', '\0', - 'a', '\0', 'l', '\0', 'N', '\0', - 'a', '\0', 'm', '\0', 'e', '\0', - '\0', '\0'}; - guchar legalcpy_key[]= {'L', '\0', 'e', '\0', 'g', '\0', - 'a', '\0', 'l', '\0', 'C', '\0', - 'o', '\0', 'p', '\0', 'y', '\0', - 'r', '\0', 'i', '\0', 'g', '\0', - 'h', '\0', 't', '\0', '\0', '\0'}; - guchar legaltrade_key[]= {'L', '\0', 'e', '\0', 'g', '\0', - 'a', '\0', 'l', '\0', 'T', '\0', - 'r', '\0', 'a', '\0', 'd', '\0', - 'e', '\0', 'm', '\0', 'a', '\0', - 'r', '\0', 'k', '\0', 's', '\0', - '\0', '\0'}; - guchar origfile_key[]= {'O', '\0', 'r', '\0', 'i', '\0', - 'g', '\0', 'i', '\0', 'n', '\0', - 'a', '\0', 'l', '\0', 'F', '\0', - 'i', '\0', 'l', '\0', 'e', '\0', - 'n', '\0', 'a', '\0', 'm', '\0', - 'e', '\0', '\0', '\0'}; - guchar privbuild_key[]= {'P', '\0', 'r', '\0', 'i', '\0', - 'v', '\0', 'a', '\0', 't', '\0', - 'e', '\0', 'B', '\0', 'u', '\0', - 'i', '\0', 'l', '\0', 'd', '\0', - '\0', '\0'}; - guchar prodname_key[]= {'P', '\0', 'r', '\0', 'o', '\0', - 'd', '\0', 'u', '\0', 'c', '\0', - 't', '\0', 'N', '\0', 'a', '\0', - 'm', '\0', 'e', '\0', '\0', '\0'}; - guchar prodver_key[]= {'P', '\0', 'r', '\0', 'o', '\0', - 'd', '\0', 'u', '\0', 'c', '\0', - 't', '\0', 'V', '\0', 'e', '\0', - 'r', '\0', 's', '\0', 'i', '\0', - 'o', '\0', 'n', '\0', '\0', '\0'}; - guchar specbuild_key[]= {'S', '\0', 'p', '\0', 'e', '\0', - 'c', '\0', 'i', '\0', 'a', '\0', - 'l', '\0', 'B', '\0', 'u', '\0', - 'i', '\0', 'l', '\0', 'd', '\0', - '\0', '\0'}; - + guint16 string_len=28; /* Length of the StringTable block */ + /* data_ptr is pointing at an array of one or more String * blocks with total length (not including alignment padding) * of data_len. @@ -326,47 +305,34 @@ 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; if(store==TRUE) { - if(!memcmp (block.key, &comments_key, - unicode_bytes (block.key))) { - + if (unicode_string_equals (block.key, "Comments")) { process_set_field_string (filever, "comments", value, unicode_chars (value)); - } else if (!memcmp (block.key, &compname_key, - unicode_bytes (block.key))) { + } else if (unicode_string_equals (block.key, "CompanyName")) { process_set_field_string (filever, "companyname", value, unicode_chars (value)); - } else if (!memcmp (block.key, &filedesc_key, - unicode_bytes (block.key))) { + } else if (unicode_string_equals (block.key, "FileDescription")) { process_set_field_string (filever, "filedescription", value, unicode_chars (value)); - } else if (!memcmp (block.key, &filever_key, - unicode_bytes (block.key))) { + } else if (unicode_string_equals (block.key, "FileVersion")) { process_set_field_string (filever, "fileversion", value, unicode_chars (value)); - } else if (!memcmp (block.key, &internal_key, - unicode_bytes (block.key))) { + } else if (unicode_string_equals (block.key, "InternalName")) { process_set_field_string (filever, "internalname", value, unicode_chars (value)); - } else if (!memcmp (block.key, &legalcpy_key, - unicode_bytes (block.key))) { + } else if (unicode_string_equals (block.key, "LegalCopyright")) { process_set_field_string (filever, "legalcopyright", value, unicode_chars (value)); - } else if (!memcmp (block.key, &legaltrade_key, - unicode_bytes (block.key))) { + } else if (unicode_string_equals (block.key, "LegalTrademarks")) { process_set_field_string (filever, "legaltrademarks", value, unicode_chars (value)); - } else if (!memcmp (block.key, &origfile_key, - unicode_bytes (block.key))) { + } else if (unicode_string_equals (block.key, "OriginalFilename")) { process_set_field_string (filever, "originalfilename", value, unicode_chars (value)); - } else if (!memcmp (block.key, &privbuild_key, - unicode_bytes (block.key))) { + } else if (unicode_string_equals (block.key, "PrivateBuild")) { process_set_field_string (filever, "privatebuild", value, unicode_chars (value)); - } else if (!memcmp (block.key, &prodname_key, - unicode_bytes (block.key))) { + } else if (unicode_string_equals (block.key, "ProductName")) { process_set_field_string (filever, "productname", value, unicode_chars (value)); - } else if (!memcmp (block.key, &prodver_key, - unicode_bytes (block.key))) { + } else if (unicode_string_equals (block.key, "ProductVersion")) { process_set_field_string (filever, "productversion", value, unicode_chars (value)); - } else if (!memcmp (block.key, &specbuild_key, - unicode_bytes (block.key))) { + } else if (unicode_string_equals (block.key, "SpecialBuild")) { process_set_field_string (filever, "specialbuild", value, unicode_chars (value)); } else { /* Not an error, just not interesting @@ -374,6 +340,7 @@ static gpointer process_read_string_block (MonoObject *filever, */ } } + g_free (value); } return(data_ptr); @@ -389,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 */ @@ -416,9 +384,14 @@ 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); - if (!strcmp (language, "007f04b0") || !strcmp (language, "000004b0")) { + + /* Kludge: treat en_US as neutral too */ + if (!strcmp (language, "007f04b0") || + !strcmp (language, "000004b0") || + !strcmp (language, "040904b0")) { /* Got the one we're interested in */ process_set_field_string_utf8 (filever, "language", "Language Neutral"); @@ -435,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 @@ -493,21 +467,7 @@ static void process_get_fileversion (MonoObject *filever, MonoImage *image) gpointer data_ptr; version_data block; gint32 data_len; /* signed to guard against underflow */ - guchar vs_key[]= {'V', '\0', 'S', '\0', '_', '\0', 'V', '\0', - 'E', '\0', 'R', '\0', 'S', '\0', 'I', '\0', - 'O', '\0', 'N', '\0', '_', '\0', 'I', '\0', - 'N', '\0', 'F', '\0', 'O', '\0', '\0', '\0' - }; - guchar var_key[]= {'V', '\0', 'a', '\0', 'r', '\0', 'F', '\0', - 'i', '\0', 'l', '\0', 'e', '\0', 'I', '\0', - 'n', '\0', 'f', '\0', 'o', '\0', '\0', '\0', - }; - guchar str_key[]= {'S', '\0', 't', '\0', 'r', '\0', 'i', '\0', - 'n', '\0', 'g', '\0', 'F', '\0', 'i', '\0', - 'l', '\0', 'e', '\0', 'I', '\0', 'n', '\0', - 'f', '\0', 'o', '\0', '\0', '\0', - }; - + version_info=mono_image_lookup_resource (image, MONO_PE_RESOURCE_ID_VERSION, 0, NULL); @@ -522,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; } @@ -543,7 +504,7 @@ static void process_get_fileversion (MonoObject *filever, MonoImage *image) return; } - if(memcmp (block.key, &vs_key, unicode_bytes (block.key))) { + if (!unicode_string_equals (block.key, "VS_VERSION_INFO")) { #ifdef DEBUG g_message (G_GNUC_PRETTY_FUNCTION ": VS_VERSION_INFO mismatch"); @@ -589,11 +550,10 @@ static void process_get_fileversion (MonoObject *filever, MonoImage *image) data_len=data_len-block.data_len; - if(!memcmp (block.key, &var_key, unicode_bytes (block.key))) { + if (unicode_string_equals (block.key, "VarFileInfo")) { data_ptr=process_read_var_block (filever, data_ptr, block.data_len); - } else if (!memcmp (block.key, &str_key, - unicode_bytes (block.key))) { + } else if (unicode_string_equals (block.key, "StringFileInfo")) { data_ptr=process_read_stringtable_block (filever, data_ptr, block.data_len); } else { /* Bogus data */ @@ -653,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); } @@ -696,11 +657,10 @@ MonoArray *ves_icall_System_Diagnostics_Process_GetModules_internal (MonoObject modules_list->len); for(i=0; ilen; i++) { - mono_array_set (arr, MonoObject *, i, - g_ptr_array_index (modules_list, i)); + mono_array_setref (arr, i, g_ptr_array_index (modules_list, i)); } - g_ptr_array_free (modules_list, FALSE); + g_ptr_array_free (modules_list, TRUE); return(arr); } @@ -708,14 +668,14 @@ MonoArray *ves_icall_System_Diagnostics_Process_GetModules_internal (MonoObject void ves_icall_System_Diagnostics_FileVersionInfo_GetVersionInfo_internal (MonoObject *this, MonoString *filename) { MonoImage *image; - guchar *filename_utf8; + gchar *filename_utf8; MONO_ARCH_SAVE_REGS; STASH_SYS_ASS (this); - filename_utf8=mono_string_to_utf8 (filename); - image=mono_image_open (filename_utf8, NULL); + filename_utf8 = mono_string_to_utf8 (filename); + image = mono_pe_file_open (filename_utf8, NULL); g_free (filename_utf8); if(image==NULL) { @@ -733,6 +693,7 @@ void ves_icall_System_Diagnostics_FileVersionInfo_GetVersionInfo_internal (MonoO mono_image_close (image); } +/* Only used when UseShellExecute is false */ static gchar * quote_path (const gchar *path) { @@ -750,26 +711,22 @@ quote_path (const gchar *path) return res; } +/* Only used when UseShellExecute is false */ static gboolean -complete_path (const gunichar2 *appname, gunichar2 **completed) +complete_path (const gunichar2 *appname, gchar **completed) { gchar *utf8app; gchar *found; - gchar *quoted8; utf8app = g_utf16_to_utf8 (appname, -1, NULL, NULL, NULL); if (g_path_is_absolute (utf8app)) { - quoted8 = quote_path (utf8app); - *completed = g_utf8_to_utf16 (quoted8, -1, NULL, NULL, NULL); - g_free (quoted8); + *completed = quote_path (utf8app); g_free (utf8app); return TRUE; } if (g_file_test (utf8app, G_FILE_TEST_IS_EXECUTABLE) && !g_file_test (utf8app, G_FILE_TEST_IS_DIR)) { - quoted8 = quote_path (utf8app); - *completed = g_utf8_to_utf16 (quoted8, -1, NULL, NULL, NULL); - g_free (quoted8); + *completed = quote_path (utf8app); g_free (utf8app); return TRUE; } @@ -781,15 +738,60 @@ complete_path (const gunichar2 *appname, gunichar2 **completed) return FALSE; } - quoted8 = quote_path (found); - *completed = g_utf8_to_utf16 (quoted8, -1, NULL, NULL, NULL); - g_free (quoted8); + *completed = quote_path (found); g_free (found); g_free (utf8app); return TRUE; } -MonoBoolean ves_icall_System_Diagnostics_Process_Start_internal (MonoString *appname, MonoString *cmd, MonoString *dirname, HANDLE stdin_handle, HANDLE stdout_handle, HANDLE stderr_handle, MonoProcInfo *process_info) +MonoBoolean ves_icall_System_Diagnostics_Process_ShellExecuteEx_internal (MonoProcessStartInfo *proc_start_info, MonoProcInfo *process_info) +{ + SHELLEXECUTEINFO shellex = {0}; + gboolean ret; + + shellex.cbSize = sizeof(SHELLEXECUTEINFO); + shellex.fMask = SEE_MASK_FLAG_DDEWAIT | SEE_MASK_NOCLOSEPROCESS | SEE_MASK_UNICODE; + shellex.nShow = SW_SHOWNORMAL; + + if (proc_start_info->filename != NULL) { + shellex.lpFile = mono_string_chars (proc_start_info->filename); + } + + if (proc_start_info->arguments != NULL) { + shellex.lpParameters = mono_string_chars (proc_start_info->arguments); + } + + if (proc_start_info->verb != NULL && + mono_string_length (proc_start_info->verb) != 0) { + shellex.lpVerb = mono_string_chars (proc_start_info->verb); + } + + if (proc_start_info->working_directory != NULL && + mono_string_length (proc_start_info->working_directory) != 0) { + shellex.lpDirectory = mono_string_chars (proc_start_info->working_directory); + } + + ret = ShellExecuteEx (&shellex); + if (ret == FALSE) { + process_info->pid = -GetLastError (); + } 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. + */ +#ifdef HAVE_GETPROCESSID + process_info->pid = GetProcessId (shellex.hProcess); +#else + process_info->pid = 0; +#endif + process_info->tid = 0; + } + + return (ret); +} + +MonoBoolean ves_icall_System_Diagnostics_Process_CreateProcess_internal (MonoProcessStartInfo *proc_start_info, HANDLE stdin_handle, HANDLE stdout_handle, HANDLE stderr_handle, MonoProcInfo *process_info) { gboolean ret; gunichar2 *dir; @@ -798,57 +800,46 @@ MonoBoolean ves_icall_System_Diagnostics_Process_Start_internal (MonoString *app gunichar2 *shell_path = NULL; gchar *env_vars = NULL; gboolean free_shell_path = TRUE; + gchar *spath = NULL; + MonoString *cmd = proc_start_info->arguments; + guint32 creation_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; - if (process_info->use_shell) { - const gchar *spath; - const gchar *shell_args; + shell_path = mono_string_chars (proc_start_info->filename); + complete_path (shell_path, &spath); + if (spath == NULL) { + process_info->pid = -ERROR_FILE_NOT_FOUND; + return FALSE; + } #ifdef PLATFORM_WIN32 - spath = g_getenv ("COMSPEC"); - shell_args = "/c %s"; + /* Seems like our CreateProcess does not work as the windows one. + * This hack is needed to deal with paths containing spaces */ + shell_path = NULL; + free_shell_path = FALSE; + 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 - spath = g_getenv ("SHELL"); - shell_args = "-c %s"; -#endif - if (spath != NULL) { - gint dummy; - gchar *newcmd, *tmp; - gchar *quoted; - - shell_path = mono_unicode_from_external (spath, &dummy); - tmp = mono_string_to_utf8 (cmd); - quoted = g_shell_quote (tmp); -#ifdef PLATFORM_WIN32 - { - gchar *q = quoted; - while (*q) { - if (*q == '\'') - *q = '\"'; - q++; - } - } + shell_path = g_utf8_to_utf16 (spath, -1, NULL, NULL, NULL); #endif - newcmd = g_strdup_printf (shell_args, quoted); - g_free (quoted); - g_free (tmp); - cmd = mono_string_new (mono_domain_get (), newcmd); - g_free (newcmd); - } - } else { - shell_path = mono_string_chars (appname); - free_shell_path = complete_path (shell_path, &shell_path); - if (shell_path == NULL) { - process_info->pid = -ERROR_FILE_NOT_FOUND; - return FALSE; - } - } + g_free (spath); if (process_info->env_keys != NULL) { gint i, len; @@ -894,13 +885,13 @@ MonoBoolean ves_icall_System_Diagnostics_Process_Start_internal (MonoString *app /* The default dir name is "". Turn that into NULL to mean * "current directory" */ - if(mono_string_length (dirname)==0) { + if(mono_string_length (proc_start_info->working_directory)==0) { dir=NULL; } else { - dir=mono_string_chars (dirname); + 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); + + 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) @@ -910,7 +901,8 @@ MonoBoolean ves_icall_System_Diagnostics_Process_Start_internal (MonoString *app process_info->process_handle=procinfo.hProcess; /*process_info->thread_handle=procinfo.hThread;*/ process_info->thread_handle=NULL; - CloseHandle(procinfo.hThread); + if (procinfo.hThread != NULL && procinfo.hThread != INVALID_HANDLE_VALUE) + CloseHandle(procinfo.hThread); process_info->pid=procinfo.dwProcessId; process_info->tid=procinfo.dwThreadId; } else { @@ -1010,7 +1002,7 @@ MonoString *ves_icall_System_Diagnostics_Process_ProcessName_internal (HANDLE pr return(NULL); } - len=GetModuleBaseName (process, mod, name, sizeof(name)); + len=GetModuleBaseName (process, mod, name, MAX_PATH); if(len==0) { return(NULL); } @@ -1099,3 +1091,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; +}