* 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 <config.h>
#include <mono/metadata/cil-coff.h>
#include <mono/metadata/exception.h>
#include <mono/utils/strenc.h>
+#include <mono/utils/mono-proclib.h>
#include <mono/io-layer/io-layer.h>
/* FIXME: fix this code to not depend so much on the inetrnals */
#include <mono/metadata/class-internals.h>
#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 void process_module_string_read (MonoObject *filever, gpointer data,
const gchar *fieldname,
lang_key = g_utf8_to_utf16 (lang_key_utf8, -1, NULL, NULL, NULL);
- if (VerQueryValue (data, lang_key, (gpointer *)&buffer, &chars)) {
+ 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
/* chars includes trailing null */
process_set_field_string (filever, fieldname, buffer, chars - 1);
+ } else {
+ process_set_field_string (filever, fieldname, EMPTY_STRING, 0);
}
g_free (lang_key);
gunichar2 *query;
UINT ffi_size, trans_size;
BOOL ok;
- int i;
+ gunichar2 lang_buf[128];
+ guint32 lang, lang_count;
datalen = GetFileVersionInfoSize (filename, &verinfohandle);
if (datalen) {
if (VerQueryValue (data, query,
(gpointer *)&trans_data,
&trans_size)) {
- /* Look for neutral or en_US language data
- * (or should we use the first language ID we
- * see?)
+ /* use the first language ID we see
*/
- for (i = 0; i < trans_size; i += 4) {
+ 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[i], trans_data[i+1], trans_data[i+2], trans_data[i+3]);
+ 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
-
- if ((trans_data[i] == 0x09 &&
- trans_data[i+1] == 0x04 &&
- trans_data[i+2] == 0xb0 &&
- trans_data[i+3] == 0x04) ||
- (trans_data[i] == 0x00 &&
- trans_data[i+1] == 0x00 &&
- trans_data[i+2] == 0xb0 &&
- trans_data[i+3] == 0x04) ||
- (trans_data[i] == 0x7f &&
- trans_data[i+1] == 0x00 &&
- trans_data[i+2] == 0xb0 &&
- trans_data[i+3] == 0x04)) {
- gunichar2 lang_buf[128];
- guint32 lang, lang_count;
-
- lang = (trans_data[i]) |
- (trans_data[i+1] << 8) |
- (trans_data[i+2] << 16) |
- (trans_data[i+3] << 24);
- lang_count = VerLanguageName (lang, lang_buf, 128);
- if (lang_count) {
- process_set_field_string (filever, "language", lang_buf, lang_count);
- }
- process_module_stringtable (filever, data, trans_data[i], trans_data[i+1]);
+ lang = (trans_data[0]) |
+ (trans_data[1] << 8) |
+ (trans_data[2] << 16) |
+ (trans_data[3] << 24);
+ /* Only give the lower 16 bits
+ * to VerLanguageName, as
+ * Windows gets confused
+ * otherwise
+ */
+ lang_count = VerLanguageName (lang & 0xFFFF, lang_buf, 128);
+ if (lang_count) {
+ process_set_field_string (filever, "language", lang_buf, lang_count);
}
+ process_module_stringtable (filever, data, trans_data[0], trans_data[1]);
+ }
+ } else {
+ /* No strings, so set every field to
+ * the empty string
+ */
+ process_set_field_string (filever,
+ "comments",
+ EMPTY_STRING, 0);
+ process_set_field_string (filever,
+ "companyname",
+ EMPTY_STRING, 0);
+ process_set_field_string (filever,
+ "filedescription",
+ EMPTY_STRING, 0);
+ process_set_field_string (filever,
+ "fileversion",
+ EMPTY_STRING, 0);
+ process_set_field_string (filever,
+ "internalname",
+ EMPTY_STRING, 0);
+ process_set_field_string (filever,
+ "legalcopyright",
+ EMPTY_STRING, 0);
+ process_set_field_string (filever,
+ "legaltrademarks",
+ EMPTY_STRING, 0);
+ process_set_field_string (filever,
+ "originalfilename",
+ EMPTY_STRING, 0);
+ process_set_field_string (filever,
+ "privatebuild",
+ EMPTY_STRING, 0);
+ process_set_field_string (filever,
+ "productname",
+ EMPTY_STRING, 0);
+ process_set_field_string (filever,
+ "productversion",
+ EMPTY_STRING, 0);
+ process_set_field_string (filever,
+ "specialbuild",
+ EMPTY_STRING, 0);
+
+ /* And language seems to be set to
+ * en_US according to bug 374600
+ */
+ lang_count = VerLanguageName (0x0409, lang_buf, 128);
+ if (lang_count) {
+ process_set_field_string (filever, "language", lang_buf, lang_count);
}
}
+
g_free (query);
}
g_free (data);
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 PLATFORM_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;
}
}
}
+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;
*error = ret == 0 ? GetLastError () : 0;
return ret;
}
+
+HANDLE
+ves_icall_System_Diagnostics_Process_ProcessHandle_duplicate (HANDLE process)
+{
+ HANDLE ret;
+
+ MONO_ARCH_SAVE_REGS;
+
+#ifdef DEBUG
+ g_message ("%s: Duplicating process handle %p", __func__, process);
+#endif
+
+ 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;
+
+#ifdef DEBUG
+ g_message ("%s: Closing process handle %p", __func__, process);
+#endif
+
+ 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;
+}
+