#include <glib.h>
#include "mono/utils/mono-compiler.h"
+// FIXME: In order to share function declarations at least, this
+// file should be merged with its non-uwp counterpart, and fine-grained #if used there.
+
#if G_HAVE_API_SUPPORT(HAVE_UWP_WINAPI_SUPPORT)
+
#include <windows.h>
#include <mono/metadata/object-internals.h>
#include "mono/metadata/w32process.h"
#include "mono/metadata/w32process-win32-internals.h"
#include "icall-decl.h"
-gboolean
-mono_process_win_enum_processes (DWORD *pids, DWORD count, DWORD *needed)
+MonoArrayHandle
+ves_icall_System_Diagnostics_Process_GetProcesses_internal (MonoError *error)
{
g_unsupported_api ("EnumProcesses");
- *needed = 0;
SetLastError (ERROR_NOT_SUPPORTED);
-
- return FALSE;
+ mono_error_set_not_supported (error, "This system does not support EnumProcesses");
+ return NULL_HANDLE_ARRAY;
}
HANDLE
-ves_icall_System_Diagnostics_Process_GetProcess_internal (guint32 pid)
+ves_icall_System_Diagnostics_Process_GetProcess_internal (guint32 pid, MonoError *error)
{
- ERROR_DECL (error);
-
g_unsupported_api ("OpenProcess");
-
mono_error_set_not_supported (error, G_UNSUPPORTED_API, "OpenProcess");
- mono_error_set_pending_exception (error);
-
SetLastError (ERROR_NOT_SUPPORTED);
-
return NULL;
}
void
-mono_w32process_get_fileversion (MonoObject *filever, gunichar2 *filename, MonoError *error)
+ves_icall_System_Diagnostics_FileVersionInfo_GetVersionInfo_internal (MonoObjectHandle this_obj,
+ const gunichar2 *filename, int filename_length, MonoError *error)
{
g_unsupported_api ("GetFileVersionInfoSize, GetFileVersionInfo, VerQueryValue, VerLanguageName");
-
- error_init (error);
mono_error_set_not_supported (error, G_UNSUPPORTED_API, "GetFileVersionInfoSize, GetFileVersionInfo, VerQueryValue, VerLanguageName");
-
SetLastError (ERROR_NOT_SUPPORTED);
}
-MonoObject*
-process_add_module (HANDLE process, HMODULE mod, gunichar2 *filename, gunichar2 *modulename, MonoClass *proc_class, MonoError *error)
+MonoArrayHandle
+ves_icall_System_Diagnostics_Process_GetModules_internal (MonoObjectHandle this_obj, HANDLE process, MonoError *error)
{
- g_unsupported_api ("GetModuleInformation");
-
- error_init (error);
- mono_error_set_not_supported (error, G_UNSUPPORTED_API, "GetModuleInformation");
-
+ g_unsupported_api ("EnumProcessModules");
+ mono_error_set_not_supported (error, G_UNSUPPORTED_API, "EnumProcessModules");
SetLastError (ERROR_NOT_SUPPORTED);
-
- return NULL;
-}
-
-MonoArray *
-ves_icall_System_Diagnostics_Process_GetModules_internal (MonoObject *this_obj, HANDLE process)
-{
- ERROR_DECL (error);
-
- g_unsupported_api ("EnumProcessModules, GetModuleBaseName, GetModuleFileNameEx");
-
- mono_error_set_not_supported (error, G_UNSUPPORTED_API, "EnumProcessModules, GetModuleBaseName, GetModuleFileNameEx");
- mono_error_set_pending_exception (error);
-
- SetLastError (ERROR_NOT_SUPPORTED);
-
- return NULL;
+ return NULL_HANDLE_ARRAY;
}
MonoBoolean
-ves_icall_System_Diagnostics_Process_ShellExecuteEx_internal (MonoW32ProcessStartInfo *proc_start_info, MonoW32ProcessInfo *process_info)
+ves_icall_System_Diagnostics_Process_ShellExecuteEx_internal (MonoW32ProcessStartInfoHandle proc_start_info, MonoW32ProcessInfo *process_info, MonoError *error)
{
- ERROR_DECL (error);
-
g_unsupported_api ("ShellExecuteEx");
-
mono_error_set_not_supported (error, G_UNSUPPORTED_API, "ShellExecuteEx");
- mono_error_set_pending_exception (error);
-
process_info->pid = (guint32)(-ERROR_NOT_SUPPORTED);
SetLastError (ERROR_NOT_SUPPORTED);
-
return FALSE;
}
-MonoString *
-ves_icall_System_Diagnostics_Process_ProcessName_internal (HANDLE process)
+// This is the only function in this file that does anything.
+// Note that process is ignored and it just operates on the current process.
+MonoStringHandle
+ves_icall_System_Diagnostics_Process_ProcessName_internal (HANDLE process, MonoError *error)
{
- ERROR_DECL (error);
- MonoString *string;
- gunichar2 name[MAX_PATH];
- guint32 len;
-
- len = GetModuleFileName (NULL, name, G_N_ELEMENTS (name));
+ gunichar2 name [MAX_PATH]; // FIXME MAX_PATH
+ const guint32 len = GetModuleFileNameW (NULL, name, G_N_ELEMENTS (name));
if (len == 0)
- return NULL;
-
- string = mono_string_new_utf16_checked (mono_domain_get (), name, len, error);
- if (!mono_error_ok (error))
- mono_error_set_pending_exception (error);
-
- return string;
-}
-
-void
-mono_process_init_startup_info (HANDLE stdin_handle, HANDLE stdout_handle, HANDLE stderr_handle, STARTUPINFO *startinfo)
-{
- startinfo->cb = sizeof(STARTUPINFO);
- startinfo->dwFlags = 0;
- startinfo->hStdInput = INVALID_HANDLE_VALUE;
- startinfo->hStdOutput = INVALID_HANDLE_VALUE;
- startinfo->hStdError = INVALID_HANDLE_VALUE;
- return;
+ return NULL_HANDLE_STRING;
+ return mono_string_new_utf16_handle (mono_domain_get (), name, len, error);
}
-gboolean
-mono_process_create_process (MonoW32ProcessInfo *mono_process_info, MonoString *cmd, guint32 creation_flags,
- gunichar2 *env_vars, gunichar2 *dir, STARTUPINFO *start_info, PROCESS_INFORMATION *process_info)
+MonoBoolean
+ves_icall_System_Diagnostics_Process_CreateProcess_internal (MonoW32ProcessStartInfoHandle proc_start_info,
+ HANDLE stdin_handle, HANDLE stdout_handle, HANDLE stderr_handle, MonoW32ProcessInfo *process_info, MonoError *error)
{
- ERROR_DECL (error);
- gchar *api_name = "";
-
- if (mono_process_info->username) {
- api_name = "CreateProcessWithLogonW";
- } else {
- api_name = "CreateProcess";
- }
+ // FIXME CreateProcess is supported for UWP. Use finer grained #if.
- memset (&process_info, 0, sizeof (PROCESS_INFORMATION));
+ const char *api_name = mono_process_info->username ? "CreateProcessWithLogonW" : "CreateProcess";
+ memset (process_info, 0, sizeof (*process_info));
g_unsupported_api (api_name);
-
mono_error_set_not_supported (error, G_UNSUPPORTED_API, api_name);
- mono_error_set_pending_exception (error);
-
SetLastError (ERROR_NOT_SUPPORTED);
-
return FALSE;
}
MonoBoolean
-mono_icall_get_process_working_set_size (gpointer handle, gsize *min, gsize *max)
+ves_icall_Microsoft_Win32_NativeMethods_GetProcessWorkingSetSize (gpointer handle, gsize *min, gsize *max, MonoError *error)
{
- ERROR_DECL (error);
-
g_unsupported_api ("GetProcessWorkingSetSize");
-
mono_error_set_not_supported(error, G_UNSUPPORTED_API, "GetProcessWorkingSetSize");
- mono_error_set_pending_exception (error);
-
SetLastError (ERROR_NOT_SUPPORTED);
-
return FALSE;
}
MonoBoolean
-mono_icall_set_process_working_set_size (gpointer handle, gsize min, gsize max)
+ves_icall_Microsoft_Win32_NativeMethods_SetProcessWorkingSetSize (gpointer handle, gsize min, gsize max, MonoError *error)
{
- ERROR_DECL (error);
-
g_unsupported_api ("SetProcessWorkingSetSize");
-
mono_error_set_not_supported (error, G_UNSUPPORTED_API, "SetProcessWorkingSetSize");
- mono_error_set_pending_exception (error);
-
SetLastError (ERROR_NOT_SUPPORTED);
-
return FALSE;
}
gint32
-mono_icall_get_priority_class (gpointer handle)
+ves_icall_Microsoft_Win32_NativeMethods_GetPriorityClass (gpointer handle, MonoError *error)
{
- ERROR_DECL (error);
+ // FIXME GetPriorityClass is supported for UWP. Use finer grained #if.
g_unsupported_api ("GetPriorityClass");
-
mono_error_set_not_supported (error, G_UNSUPPORTED_API, "GetPriorityClass");
- mono_error_set_pending_exception (error);
-
SetLastError (ERROR_NOT_SUPPORTED);
-
return FALSE;
}
MonoBoolean
-mono_icall_set_priority_class (gpointer handle, gint32 priorityClass)
+ves_icall_Microsoft_Win32_NativeMethods_SetPriorityClass (gpointer handle, gint32 priorityClass, MonoError *error)
{
- ERROR_DECL (error);
+ // FIXME SetPriorityClass is supported for UWP. Use finer grained #if.
g_unsupported_api ("SetPriorityClass");
-
mono_error_set_not_supported(error, G_UNSUPPORTED_API, "SetPriorityClass");
- mono_error_set_pending_exception (error);
-
SetLastError (ERROR_NOT_SUPPORTED);
-
return FALSE;
}
#include "w32process.h"
#include "w32process-internals.h"
-#include "w32process-win32-internals.h"
#include "w32file.h"
#include "object.h"
#include "object-internals.h"
static guint32
mono_w32process_module_get_name (gpointer process, gpointer module, gunichar2 *basename, guint32 size)
{
- return GetModuleBaseName (process, (HMODULE)module, basename, size);
+ return GetModuleBaseNameW (process, (HMODULE)module, basename, size);
}
static guint32
mono_w32process_module_get_filename (gpointer process, gpointer module, gunichar2 *basename, guint32 size)
{
- return GetModuleFileNameEx (process, (HMODULE)module, basename, size);
+ return GetModuleFileNameExW (process, (HMODULE)module, basename, size);
}
static gboolean
mono_w32process_get_fileversion_info (const gunichar2 *filename, gpointer *data)
{
DWORD handle;
- gsize datasize;
g_assert (data);
*data = NULL;
- datasize = GetFileVersionInfoSize (filename, &handle);
+ DWORD datasize = GetFileVersionInfoSizeW (filename, &handle);
if (datasize <= 0)
return FALSE;
*data = g_malloc0 (datasize);
- if (!GetFileVersionInfo (filename, handle, datasize, *data)) {
+ if (!GetFileVersionInfoW (filename, handle, datasize, *data)) {
g_free (*data);
return FALSE;
}
static gboolean
mono_w32process_ver_query_value (gconstpointer datablock, const gunichar2 *subblock, gpointer *buffer, guint32 *len)
{
- return VerQueryValue (datablock, subblock, buffer, len);
+ return VerQueryValueW (datablock, subblock, buffer, len);
}
static guint32
mono_w32process_ver_language_name (guint32 lang, gunichar2 *lang_out, guint32 lang_len)
{
- return VerLanguageName (lang, lang_out, lang_len);
+ return VerLanguageNameW (lang, lang_out, lang_len);
}
#endif /* G_HAVE_API_SUPPORT(HAVE_CLASSIC_WINAPI_SUPPORT) && defined(HOST_WIN32) */
system_image, "System.Diagnostics", "ProcessModule");
}
-static guint32
-unicode_chars (const gunichar2 *str)
+static void
+process_set_field_ref (MonoObjectHandle obj, const char *fieldname, MonoObjectHandle data)
{
- guint32 len;
- for (len = 0; str [len] != '\0'; ++len) {}
- return len;
+ // FIXME Cache offsets. Per-class.
+ MonoClass *klass = mono_handle_class (obj);
+ g_assert (klass);
+
+ MonoClassField *field = mono_class_get_field_from_name_full (klass, fieldname, NULL);
+ g_assert (field);
+
+ MONO_HANDLE_SET_FIELD_REF (obj, field, data);
}
static void
-process_set_field_object (MonoObject *obj, const gchar *fieldname, MonoObject *data)
+process_set_field_object (MonoObjectHandle obj, const char *fieldname, MonoObjectHandle data)
{
- MonoClass *klass;
- MonoClassField *field;
-
LOGDEBUG (g_message ("%s: Setting field %s to object at %p", __func__, fieldname, data));
- klass = mono_object_class (obj);
- g_assert (klass);
-
- field = mono_class_get_field_from_name_full (klass, fieldname, NULL);
- g_assert (field);
-
- mono_gc_wbarrier_generic_store_internal (((char *)obj) + field->offset, data);
+ process_set_field_ref (obj, fieldname, data);
}
static void
-process_set_field_string (MonoObject *obj, const gchar *fieldname, const gunichar2 *val, guint32 len, MonoError *error)
+process_set_field_string (MonoObjectHandle obj, const char *fieldname, MonoStringHandle string)
{
- MonoDomain *domain;
- MonoClass *klass;
- MonoClassField *field;
- MonoString *string;
+ process_set_field_ref (obj, fieldname, MONO_HANDLE_CAST (MonoObject, string));
+}
- error_init (error);
+static void
+process_set_field_utf16 (MonoObjectHandle obj, MonoStringHandle str, const char *fieldname, const gunichar2 *val, guint32 len, MonoError *error)
+{
+ HANDLE_FUNCTION_ENTER ();
LOGDEBUG (g_message ("%s: Setting field %s to [%s]", __func__, fieldname, g_utf16_to_utf8 (val, len, NULL, NULL, NULL)));
- domain = mono_object_domain (obj);
+ MonoDomain *domain = MONO_HANDLE_DOMAIN (obj);
g_assert (domain);
- klass = mono_object_class (obj);
- g_assert (klass);
-
- field = mono_class_get_field_from_name_full (klass, fieldname, NULL);
- g_assert (field);
+ MONO_HANDLE_ASSIGN (str, mono_string_new_utf16_handle (domain, val, len, error));
+ goto_if_nok (error, exit);
+ process_set_field_string (obj, fieldname, str);
- string = mono_string_new_utf16_checked (domain, val, len, error);
- return_if_nok (error);
-
- mono_gc_wbarrier_generic_store_internal (((char *)obj) + field->offset, (MonoObject*)string);
+exit:
+ HANDLE_FUNCTION_RETURN ();
}
static void
-process_set_field_string_char (MonoObject *obj, const gchar *fieldname, const gchar *val, MonoError *error)
+process_set_field_utf8 (MonoObjectHandle obj, MonoStringHandle str, const char *fieldname, const char *val, MonoError *error)
{
- MonoDomain *domain;
- MonoClass *klass;
- MonoClassField *field;
- MonoString *string;
+ HANDLE_FUNCTION_ENTER ();
- error_init (error);
LOGDEBUG (g_message ("%s: Setting field %s to [%s]", __func__, fieldname, val));
- domain = mono_object_domain (obj);
+ MonoDomain *domain = MONO_HANDLE_DOMAIN (obj);
g_assert (domain);
- klass = mono_object_class (obj);
- g_assert (klass);
+ MONO_HANDLE_ASSIGN (str, mono_string_new_utf8_len (domain, val, strlen (val), error));
+ goto_if_nok (error, exit);
- field = mono_class_get_field_from_name_full (klass, fieldname, NULL);
- g_assert (field);
+ process_set_field_string (obj, fieldname, str);
- string = mono_string_new_checked (domain, val, error);
- return_if_nok (error);
-
- mono_gc_wbarrier_generic_store_internal (((char *)obj) + field->offset, (MonoObject*)string);
+exit:
+ HANDLE_FUNCTION_RETURN ();
}
-static void
-process_set_field_int (MonoObject *obj, const gchar *fieldname, guint32 val)
+static MonoClassField*
+process_resolve_field (MonoObjectHandle obj, const char *fieldname)
{
- MonoClass *klass;
- MonoClassField *field;
-
- LOGDEBUG (g_message ("%s: Setting field %s to %d", __func__,fieldname, val));
-
- klass = mono_object_class (obj);
+ // FIXME Cache offsets. Per-class.
+ MonoClass *klass = mono_handle_class (obj);
g_assert (klass);
- field = mono_class_get_field_from_name_full (klass, fieldname, NULL);
+ MonoClassField *field = mono_class_get_field_from_name_full (klass, fieldname, NULL);
g_assert (field);
- *(guint32 *)(((char *)obj) + field->offset)=val;
+ return field;
}
static void
-process_set_field_intptr (MonoObject *obj, const gchar *fieldname, gpointer val)
+process_set_field_int (MonoObjectHandle obj, const char *fieldname, guint32 val)
{
- MonoClass *klass;
- MonoClassField *field;
-
- LOGDEBUG (g_message ("%s: Setting field %s to %p", __func__, fieldname, val));
+ LOGDEBUG (g_message ("%s: Setting field %s to %d", __func__, fieldname, val));
- klass = mono_object_class (obj);
- g_assert (klass);
-
- field = mono_class_get_field_from_name_full (klass, fieldname, NULL);
- g_assert (field);
-
- *(gpointer *)(((char *)obj) + field->offset) = val;
+ MONO_HANDLE_SET_FIELD_VAL (obj, guint32, process_resolve_field (obj, fieldname), val);
}
static void
-process_set_field_bool (MonoObject *obj, const gchar *fieldname, gboolean val)
+process_set_field_intptr (MonoObjectHandle obj, const char *fieldname, gpointer val)
{
- MonoClass *klass;
- MonoClassField *field;
-
- LOGDEBUG (g_message ("%s: Setting field %s to %s", __func__, fieldname, val ? "TRUE":"FALSE"));
+ LOGDEBUG (g_message ("%s: Setting field %s to %p", __func__, fieldname, val));
- klass = mono_object_class (obj);
- g_assert (klass);
+ MONO_HANDLE_SET_FIELD_VAL (obj, gpointer, process_resolve_field (obj, fieldname), val);
+}
- field = mono_class_get_field_from_name_full (klass, fieldname, NULL);
- g_assert (field);
+static void
+process_set_field_bool (MonoObjectHandle obj, const char *fieldname, guint8 val)
+{
+ LOGDEBUG (g_message ("%s: Setting field %s to %s", __func__, fieldname, val ? "TRUE" : "FALSE"));
- *(guint8 *)(((char *)obj) + field->offset) = val;
+ MONO_HANDLE_SET_FIELD_VAL (obj, guint8, process_resolve_field (obj, fieldname), val);
}
#if G_HAVE_API_SUPPORT(HAVE_CLASSIC_WINAPI_SUPPORT)
#define SFI_PRODUCTNAME "\\StringFileInfo\\%02X%02X%02X%02X\\ProductName"
#define SFI_PRODUCTVERSION "\\StringFileInfo\\%02X%02X%02X%02X\\ProductVersion"
#define SFI_SPECIALBUILD "\\StringFileInfo\\%02X%02X%02X%02X\\SpecialBuild"
-#define EMPTY_STRING (gunichar2*)"\000\000"
+static const gunichar2 mono_empty_string [ ] = { 0 };
+#define EMPTY_STRING mono_empty_string
typedef struct {
const char *name;
const char *id;
} StringTableEntry;
-static StringTableEntry stringtable_entries [] = {
+static const StringTableEntry stringtable_entries [] = {
{ "comments", SFI_COMMENTS },
{ "companyname", SFI_COMPANYNAME },
{ "filedescription", SFI_FILEDESCRIPTION },
};
static void
-process_module_string_read (MonoObject *filever, gpointer data, const gchar *fieldname,
+process_module_string_read (MonoObjectHandle filever, MonoStringHandle str, gpointer data, const char *fieldname,
guchar lang_hi, guchar lang_lo, const gchar *key, MonoError *error)
{
- gchar *lang_key_utf8;
- gunichar2 *lang_key, *buffer;
+ char *lang_key_utf8 = NULL;
+ gunichar2 *lang_key = NULL;
+ const gunichar2 *buffer;
UINT chars;
- error_init (error);
-
lang_key_utf8 = g_strdup_printf (key, lang_lo, lang_hi, 0x04, 0xb0);
+ if (!lang_key_utf8)
+ goto exit;
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 (!lang_key)
+ goto exit;
if (mono_w32process_ver_query_value (data, lang_key, (gpointer *)&buffer, &chars) && chars > 0) {
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, error);
+ chars -= 1;
} else {
- process_set_field_string (filever, fieldname, EMPTY_STRING, 0, error);
+ buffer = EMPTY_STRING;
+ chars = 0;
}
-
+ process_set_field_utf16 (filever, str, fieldname, buffer, chars, error);
+exit:
g_free (lang_key);
g_free (lang_key_utf8);
}
static void
-process_module_stringtable (MonoObject *filever, gpointer data, guchar lang_hi, guchar lang_lo, MonoError *error)
+process_module_stringtable (MonoObjectHandle filever, MonoStringHandle str, gpointer data, guchar lang_hi, guchar lang_lo, MonoError *error)
{
- for (int i = 0; i < G_N_ELEMENTS (stringtable_entries); ++i) {
- process_module_string_read (filever, data, stringtable_entries [i].name,
+ for (int i = 0; is_ok (error) && i < G_N_ELEMENTS (stringtable_entries); ++i) {
+ process_module_string_read (filever, str, data, stringtable_entries [i].name,
lang_hi, lang_lo, stringtable_entries [i].id, error);
- return_if_nok (error);
}
}
static void
-mono_w32process_get_fileversion (MonoObject *filever, gunichar2 *filename, MonoError *error)
+mono_w32process_get_fileversion (MonoObjectHandle filever, MonoStringHandle str, const gunichar2 *filename, MonoError *error)
{
VS_FIXEDFILEINFO *ffi;
- gpointer data;
+ gpointer data = NULL;
guchar *trans_data;
- gunichar2 *query;
+ gunichar2 *query = NULL;
UINT ffi_size, trans_size;
- gunichar2 lang_buf[128];
+ gunichar2 lang_buf [128];
guint32 lang, lang_count;
- error_init (error);
-
if (!mono_w32process_get_fileversion_info (filename, &data))
- return;
+ goto cleanup;
query = g_utf8_to_utf16 ("\\", -1, NULL, NULL, NULL);
- if (query == NULL) {
- g_free (data);
- return;
- }
+ if (query == NULL)
+ goto cleanup;
if (mono_w32process_ver_query_value (data, query, (gpointer *)&ffi, &ffi_size)) {
#define LOWORD(i32) ((guint16)((i32) & 0xFFFF))
g_free (query);
query = g_utf8_to_utf16 ("\\VarFileInfo\\Translation", -1, NULL, NULL, NULL);
- if (query == NULL) {
- g_free (data);
- return;
- }
+ if (query == NULL)
+ goto cleanup;
if (mono_w32process_ver_query_value (data, query, (gpointer *)&trans_data, &trans_size)) {
/* use the first language ID we see */
/* Only give the lower 16 bits to mono_w32process_ver_language_name, as Windows gets confused otherwise */
lang_count = mono_w32process_ver_language_name (lang & 0xFFFF, lang_buf, 128);
if (lang_count) {
- process_set_field_string (filever, "language", lang_buf, lang_count, error);
- if (!is_ok (error))
- goto cleanup;
+ process_set_field_utf16 (filever, str, "language", lang_buf, lang_count, error);
+ goto_if_nok (error, cleanup);
}
- process_module_stringtable (filever, data, trans_data[0], trans_data[1], error);
- if (!is_ok (error))
- goto cleanup;
+ process_module_stringtable (filever, str, data, trans_data [0], trans_data [1], error);
+ goto_if_nok (error, cleanup);
}
} else {
int i;
for (i = 0; i < G_N_ELEMENTS (stringtable_entries); ++i) {
/* No strings, so set every field to the empty string */
- process_set_field_string (filever, stringtable_entries [i].name, EMPTY_STRING, 0, error);
- if (!is_ok (error))
- goto cleanup;
+ process_set_field_utf16 (filever, str, stringtable_entries [i].name, EMPTY_STRING, 0, error);
+ goto_if_nok (error, cleanup);
}
/* And language seems to be set to en_US according to bug 374600 */
lang_count = mono_w32process_ver_language_name (0x0409, lang_buf, 128);
if (lang_count) {
- process_set_field_string (filever, "language", lang_buf, lang_count, error);
- if (!is_ok (error))
- goto cleanup;
+ process_set_field_utf16 (filever, str, "language", lang_buf, lang_count, error);
+ goto_if_nok (error, cleanup);
}
}
g_free (data);
}
-#endif /* #if G_HAVE_API_SUPPORT(HAVE_CLASSIC_WINAPI_SUPPORT) */
+#endif // G_HAVE_API_SUPPORT(HAVE_CLASSIC_WINAPI_SUPPORT)
void
-ves_icall_System_Diagnostics_FileVersionInfo_GetVersionInfo_internal (MonoObject *this_obj, MonoString *filename)
+ves_icall_System_Diagnostics_FileVersionInfo_GetVersionInfo_internal (MonoObjectHandle this_obj,
+ const gunichar2 *filename, int filename_length, MonoError *error)
{
- ERROR_DECL (error);
+ MonoStringHandle str = MONO_HANDLE_CAST (MonoString, mono_new_null ());
- stash_system_image (m_class_get_image (mono_object_class (this_obj)));
+ stash_system_image (m_class_get_image (mono_handle_class (this_obj)));
- mono_w32process_get_fileversion (this_obj, mono_string_chars_internal (filename), error);
- if (!mono_error_ok (error)) {
- mono_error_set_pending_exception (error);
- return;
- }
+ mono_w32process_get_fileversion (this_obj, str, filename, error);
+ return_if_nok (error);
- process_set_field_string (this_obj, "filename", mono_string_chars_internal (filename), mono_string_length_internal (filename), error);
- if (!mono_error_ok (error)) {
- mono_error_set_pending_exception (error);
- }
+ process_set_field_utf16 (this_obj, str, "filename", filename, filename_length, error);
}
#if G_HAVE_API_SUPPORT(HAVE_CLASSIC_WINAPI_SUPPORT)
* 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 = (MonoAssembly *)tmp->data;
if (m_image_is_fileio_used (ass->image))
continue;
g_ptr_array_add (assemblies, ass);
}
+
mono_domain_assemblies_unlock (domain);
return assemblies;
}
-static MonoObject*
-process_add_module (HANDLE process, HMODULE mod, gunichar2 *filename, gunichar2 *modulename, MonoClass *proc_class, MonoError *error)
+static void
+process_add_module (MonoObjectHandle item, MonoObjectHandle filever, MonoStringHandle str,
+ HANDLE process, HMODULE mod, const gunichar2 *filename, const gunichar2 *modulename,
+ MonoClass *proc_class, MonoError *error)
{
- MonoObject *item, *filever;
- MonoDomain *domain = mono_domain_get ();
+ HANDLE_FUNCTION_ENTER ();
+
MODULEINFO modinfo;
- BOOL ok;
- error_init (error);
+ MonoDomain *domain = mono_domain_get ();
+ g_assert (domain);
/* Build a System.Diagnostics.ProcessModule with the data. */
- item = mono_object_new_checked (domain, proc_class, error);
- return_val_if_nok (error, NULL);
+ MONO_HANDLE_ASSIGN (item, mono_object_new_handle (domain, proc_class, error));
+ goto_if_nok (error, exit);
- filever = mono_object_new_checked (domain, get_file_version_info_class (), error);
- return_val_if_nok (error, NULL);
+ MONO_HANDLE_ASSIGN (filever, mono_object_new_handle (domain, get_file_version_info_class (), error));
+ goto_if_nok (error, exit);
- mono_w32process_get_fileversion (filever, filename, error);
- return_val_if_nok (error, NULL);
+ mono_w32process_get_fileversion (filever, str, filename, error);
+ goto_if_nok (error, exit);
- process_set_field_string (filever, "filename", filename, unicode_chars (filename), error);
- return_val_if_nok (error, NULL);
+ process_set_field_utf16 (filever, str, "filename", filename, g_utf16_len (filename), error);
+ goto_if_nok (error, exit);
- ok = mono_w32process_module_get_information (process, mod, &modinfo, sizeof(MODULEINFO));
- if (ok) {
+ if (mono_w32process_module_get_information (process, mod, &modinfo, sizeof (MODULEINFO))) {
process_set_field_intptr (item, "baseaddr", modinfo.lpBaseOfDll);
process_set_field_intptr (item, "entryaddr", modinfo.EntryPoint);
process_set_field_int (item, "memory_size", modinfo.SizeOfImage);
}
- process_set_field_string (item, "filename", filename, unicode_chars (filename), error);
- return_val_if_nok (error, NULL);
+ process_set_field_utf16 (item, str, "filename", filename, g_utf16_len (filename), error);
+ goto_if_nok (error, exit);
- process_set_field_string (item, "modulename", modulename, unicode_chars (modulename), error);
- return_val_if_nok (error, NULL);
+ process_set_field_utf16 (item, str, "modulename", modulename, g_utf16_len (modulename), error);
+ goto_if_nok (error, exit);
process_set_field_object (item, "version_info", filever);
- return item;
+exit:
+ HANDLE_FUNCTION_RETURN ();
}
static void
-process_get_assembly_fileversion (MonoObject *filever, MonoAssembly *assembly)
+process_get_assembly_fileversion (MonoObjectHandle 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*
-process_get_module (MonoAssembly *assembly, MonoClass *proc_class, MonoError *error)
+static void
+process_get_module (MonoObjectHandle item, MonoObjectHandle filever,
+ MonoStringHandle str, MonoAssembly *assembly, MonoClass *proc_class, MonoError *error)
{
- MonoObject *item, *filever;
- MonoDomain *domain;
- char *filename = NULL;
- const gchar *modulename;
-
- error_init (error);
-
- domain = mono_domain_get ();
+ HANDLE_FUNCTION_ENTER ();
- modulename = assembly->aname.name;
+ MonoDomain *domain = mono_domain_get ();
+ const char *modulename = assembly->aname.name;
+ char *filename = g_strdup_printf ("[In Memory] %s", modulename);
/* Build a System.Diagnostics.ProcessModule with the data. */
- item = mono_object_new_checked (domain, proc_class, error);
- goto_if_nok (error, return_null);
-
- filever = mono_object_new_checked (domain, get_file_version_info_class (), error);
- goto_if_nok (error, return_null);
+ MONO_HANDLE_ASSIGN (item, mono_object_new_handle (domain, proc_class, error));
+ goto_if_nok (error, exit);
- filename = g_strdup_printf ("[In Memory] %s", modulename);
+ MONO_HANDLE_ASSIGN (filever, mono_object_new_handle (domain, get_file_version_info_class (), error));
+ goto_if_nok (error, exit);
process_get_assembly_fileversion (filever, assembly);
- process_set_field_string_char (filever, "filename", filename, error);
- goto_if_nok (error, return_null);
+ process_set_field_utf8 (filever, str, "filename", filename, error);
+ goto_if_nok (error, exit);
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, error);
- goto_if_nok (error, return_null);
- process_set_field_string_char (item, "modulename", modulename, error);
- goto_if_nok (error, return_null);
-
- goto exit;
-return_null:
- item = NULL;
+ process_set_field_utf8 (item, str, "filename", filename, error);
+ goto_if_nok (error, exit);
+ process_set_field_utf8 (item, str, "modulename", modulename, error);
exit:
g_free (filename);
- return item;
+
+ HANDLE_FUNCTION_RETURN ();
}
/* Returns an array of System.Diagnostics.ProcessModule */
-MonoArray *
-ves_icall_System_Diagnostics_Process_GetModules_internal (MonoObject *this_obj, HANDLE process)
-{
- ERROR_DECL (error);
- MonoArray *temp_arr = NULL;
- MonoArray *arr;
- HMODULE mods[1024];
- gunichar2 filename[MAX_PATH];
- gunichar2 modname[MAX_PATH];
- DWORD needed;
- guint32 count = 0, module_count = 0, assembly_count = 0;
- guint32 i, num_added = 0;
+MonoArrayHandle
+ves_icall_System_Diagnostics_Process_GetModules_internal (MonoObjectHandle this_obj, HANDLE process, MonoError *error)
+{
+ MonoArrayHandle temp_arr = NULL_HANDLE_ARRAY;
+ MonoArrayHandle arr = NULL_HANDLE_ARRAY;
+ HMODULE mods [1024];
+ gunichar2 filename [MAX_PATH]; // FIXME (MAX_PATH)
+ gunichar2 modname [MAX_PATH]; // FIXME (MAX_PATH)
+ DWORD needed = 0;
+ guint32 count = 0;
+ guint32 module_count = 0;
+ guint32 assembly_count = 0;
+ guint32 i = 0;
+ guint32 num_added = 0;
GPtrArray *assemblies = NULL;
- stash_system_image (m_class_get_image (mono_object_class (this_obj)));
+ // Coop handles are created here, once, in order to cut down on
+ // handle creation and ease use of loops that would
+ // otherwise create handles.
+ MonoObjectHandle module = mono_new_null ();
+ MonoObjectHandle filever = mono_new_null ();
+ MonoStringHandle str = MONO_HANDLE_CAST (MonoString, mono_new_null ());
+
+ stash_system_image (m_class_get_image (mono_handle_class (this_obj)));
if (mono_w32process_get_pid (process) == mono_process_current_pid ()) {
assemblies = get_domain_assemblies (mono_domain_get ());
assembly_count = assemblies->len;
}
- if (mono_w32process_try_get_modules (process, mods, sizeof(mods), &needed))
- module_count += needed / sizeof(HMODULE);
+ if (mono_w32process_try_get_modules (process, mods, sizeof (mods), &needed))
+ module_count += needed / sizeof (HMODULE);
count = module_count + assembly_count;
- temp_arr = mono_array_new_checked (mono_domain_get (), get_process_module_class (), count, error);
- if (mono_error_set_pending_exception (error))
- return NULL;
+ temp_arr = mono_array_new_handle (mono_domain_get (), get_process_module_class (), count, error);
+ return_val_if_nok (error, NULL_HANDLE_ARRAY);
for (i = 0; i < module_count; i++) {
- if (mono_w32process_module_get_name (process, mods[i], modname, MAX_PATH)
- && mono_w32process_module_get_filename (process, mods[i], filename, MAX_PATH))
+ if (mono_w32process_module_get_name (process, mods [i], modname, MAX_PATH)
+ && mono_w32process_module_get_filename (process, mods [i], filename, MAX_PATH))
{
- MonoObject *module = process_add_module (process, mods[i], filename, modname, get_process_module_class (), error);
- if (!mono_error_ok (error)) {
- mono_error_set_pending_exception (error);
- return NULL;
- }
- mono_array_setref_internal (temp_arr, num_added++, module);
+ process_add_module (module, filever, str, process, mods [i], filename, modname, get_process_module_class (), error);
+ return_val_if_nok (error, NULL_HANDLE_ARRAY);
+ MONO_HANDLE_ARRAY_SETREF (temp_arr, num_added++, module);
}
}
if (assemblies) {
for (i = 0; i < assembly_count; i++) {
MonoAssembly *ass = (MonoAssembly *)g_ptr_array_index (assemblies, i);
- MonoObject *module = process_get_module (ass, get_process_module_class (), error);
- if (!mono_error_ok (error)) {
- mono_error_set_pending_exception (error);
- return NULL;
- }
- mono_array_setref_internal (temp_arr, num_added++, module);
+ process_get_module (module, filever, str, ass, get_process_module_class (), error);
+ return_val_if_nok (error, NULL_HANDLE_ARRAY);
+ MONO_HANDLE_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_checked (mono_domain_get (), get_process_module_class (), num_added, error);
- if (mono_error_set_pending_exception (error))
- return NULL;
+ if (count == num_added)
+ return temp_arr;
- for (i = 0; i < num_added; i++)
- mono_array_setref_internal (arr, i, mono_array_get_internal (temp_arr, MonoObject*, i));
+ /* shorter version of the array */
+ arr = mono_array_new_handle (mono_domain_get (), get_process_module_class (), num_added, error);
+ return_val_if_nok (error, NULL_HANDLE_ARRAY);
+
+ for (i = 0; i < num_added; i++) {
+ MONO_HANDLE_ARRAY_GETREF (module, temp_arr, i);
+ MONO_HANDLE_ARRAY_SETREF (arr, i, module);
}
return arr;
}
-#endif /* G_HAVE_API_SUPPORT(HAVE_CLASSIC_WINAPI_SUPPORT) */
-
-#if G_HAVE_API_SUPPORT(HAVE_CLASSIC_WINAPI_SUPPORT)
-
-MonoString *
-ves_icall_System_Diagnostics_Process_ProcessName_internal (HANDLE process)
+MonoStringHandle
+ves_icall_System_Diagnostics_Process_ProcessName_internal (HANDLE process, MonoError *error)
{
- ERROR_DECL (error);
- MonoString *string;
- gunichar2 name[MAX_PATH];
- guint32 len;
- gboolean ok;
- HMODULE mod;
- DWORD needed;
-
- ok = mono_w32process_try_get_modules (process, &mod, sizeof(mod), &needed);
- if (!ok)
- return NULL;
+ gunichar2 name [MAX_PATH]; // FIXME (MAX_PATH)
+ HMODULE mod = 0;
+ DWORD needed = 0;
- len = mono_w32process_module_get_name (process, mod, name, MAX_PATH);
- if (len == 0)
- return NULL;
+ if (!mono_w32process_try_get_modules (process, &mod, sizeof (mod), &needed))
+ return NULL_HANDLE_STRING;
- string = mono_string_new_utf16_checked (mono_domain_get (), name, len, error);
- if (!mono_error_ok (error))
- mono_error_set_pending_exception (error);
+ const guint32 len = mono_w32process_module_get_name (process, mod, name, MAX_PATH);
- return string;
+ return len ? mono_string_new_utf16_handle (mono_domain_get (), name, len, error) : NULL_HANDLE_STRING;
}
-#endif /* G_HAVE_API_SUPPORT(HAVE_CLASSIC_WINAPI_SUPPORT) */
+#endif // G_HAVE_API_SUPPORT(HAVE_CLASSIC_WINAPI_SUPPORT) && defined(HOST_WIN32)
+// This is the only part of this file common to classic and UWP.
gint64
-ves_icall_System_Diagnostics_Process_GetProcessData (int pid, gint32 data_type, gint32 *error)
+ves_icall_System_Diagnostics_Process_GetProcessData (int pid, gint32 data_type, MonoProcessError *error)
{
- MonoProcessError perror;
- guint64 res;
-
- res = mono_process_get_data_with_error (GINT_TO_POINTER (pid), (MonoProcessData)data_type, &perror);
- if (error)
- *error = perror;
- return res;
+ g_static_assert (sizeof (MonoProcessError) == sizeof (gint32));
+ g_assert (error);
+ *error = MONO_PROCESS_ERROR_NONE;
+ return mono_process_get_data_with_error (GINT_TO_POINTER (pid), (MonoProcessData)data_type, error);
}
+#if G_HAVE_API_SUPPORT(HAVE_CLASSIC_WINAPI_SUPPORT)
+
static void
mono_pin_string (MonoStringHandle in_coophandle, MonoStringHandle *out_coophandle, gunichar2 **chars, gsize *length, gchandle_t *gchandle)
{
mono_unpin_array ((gchandle_t*)&coop->gchandle, sizeof (coop->gchandle) / sizeof (gchandle_t));
memset (coop, 0, sizeof (*coop));
}
+
+#endif // G_HAVE_API_SUPPORT(HAVE_CLASSIC_WINAPI_SUPPORT)