} while(1);
}
+/*
+ * compare a 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 guchar *str2)
+{
+ while (*str1 && *str2) {
+ if (*str1 != *str2)
+ return FALSE;
+ ++str1;
+ ++str2;
+ }
+ return *str1 == *str2;
+}
+
static void process_set_field_object (MonoObject *obj, const guchar *fieldname,
MonoObject *data)
{
data=((gunichar2 *)data)+(unicode_chars (block->key)+1);
/* align on a 32-bit boundary */
- data=(gpointer)(((unsigned)data+3) & (~3));
+ data=(gpointer)((char *)data + 3);
+ data=(gpointer)((char *)data - (GPOINTER_TO_INT(data) & 3));
return(data);
}
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.
gunichar2 *value;
/* align on a 32-bit boundary */
- data_ptr=(gpointer)(((unsigned)data_ptr+3) & (~3));
+ data_ptr=(gpointer)((char *)data_ptr + 3);
+ data_ptr=(gpointer)((char *)data_ptr -
+ (GPOINTER_TO_INT(data_ptr) & 3));
data_ptr=process_get_versioninfo_block (data_ptr, &block);
if(block.data_len==0) {
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
while(string_len<data_len) {
/* align on a 32-bit boundary */
- data_ptr=(gpointer)(((unsigned)data_ptr+3) & (~3));
+ data_ptr=(gpointer)((char *)data_ptr + 3);
+ data_ptr=(gpointer)((char *)data_ptr -
+ (GPOINTER_TO_INT(data_ptr) & 3));
data_ptr=process_get_versioninfo_block (data_ptr, &block);
if(block.data_len==0) {
language = g_utf16_to_utf8 (block.key, 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");
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);
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");
*/
while(data_len > 0) {
/* align on a 32-bit boundary */
- data_ptr=(gpointer)(((unsigned)data_ptr+3) & (~3));
+ data_ptr=(gpointer)((char *)data_ptr + 3);
+ data_ptr=(gpointer)((char *)data_ptr -
+ (GPOINTER_TO_INT(data_ptr) & 3));
data_ptr=process_get_versioninfo_block (data_ptr, &block);
if(block.data_len==0) {
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 */
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) {
mono_image_close (image);
}
+/* Only used when UseShellExecute is false */
+static gchar *
+quote_path (const gchar *path)
+{
+ gchar *res = g_shell_quote (path);
+#ifdef PLATFORM_WIN32
+ {
+ gchar *q = res;
+ while (*q) {
+ if (*q == '\'')
+ *q = '\"';
+ q++;
+ }
+ }
+#endif
+ 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;
utf8app = g_utf16_to_utf8 (appname, -1, NULL, NULL, NULL);
if (g_path_is_absolute (utf8app)) {
+ *completed = quote_path (utf8app);
g_free (utf8app);
- return FALSE;
+ 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);
- return FALSE;
+ return TRUE;
}
found = g_find_program_in_path (utf8app);
return FALSE;
}
- *completed = g_utf8_to_utf16 (found, -1, NULL, NULL, NULL);
+ *completed = quote_path (found);
g_free (found);
g_free (utf8app);
return TRUE;
gunichar2 *shell_path = NULL;
gchar *env_vars = NULL;
gboolean free_shell_path = TRUE;
+ gchar *newcmd, *tmp;
MONO_ARCH_SAVE_REGS;
shell_args = "-c %s";
#endif
if (spath != NULL) {
- gint dummy;
- gchar *newcmd, *tmp;
+ gsize dummy;
gchar *quoted;
shell_path = mono_unicode_from_external (spath, &dummy);
g_free (newcmd);
}
} else {
+ gchar *spath = NULL;
shell_path = mono_string_chars (appname);
- free_shell_path = complete_path (shell_path, &shell_path);
- if (shell_path == NULL) {
+ complete_path (shell_path, &spath);
+ if (spath == NULL) {
process_info->pid = -ERROR_FILE_NOT_FOUND;
return FALSE;
}
+#ifdef PLATFORM_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;
+ free_shell_path = FALSE;
+ tmp = mono_string_to_utf8 (cmd);
+ newcmd = g_strdup_printf ("%s %s", spath, tmp);
+ cmd = mono_string_new_wrapper (newcmd);
+ g_free (newcmd);
+ g_free (tmp);
+#else
+ shell_path = g_utf8_to_utf16 (spath, -1, NULL, NULL, NULL);
+#endif
+ g_free (spath);
}
if (process_info->env_keys != NULL) {
if(ret) {
process_info->process_handle=procinfo.hProcess;
- process_info->thread_handle=procinfo.hThread;
+ /*process_info->thread_handle=procinfo.hThread;*/
+ process_info->thread_handle=NULL;
+ if (procinfo.hThread != NULL)
+ CloseHandle(procinfo.hThread);
process_info->pid=procinfo.dwProcessId;
process_info->tid=procinfo.dwThreadId;
} else {
return(NULL);
}
- len=GetModuleBaseName (process, mod, name, sizeof(name));
+ len=GetModuleBaseName (process, mod, name, MAX_PATH);
if(len==0) {
return(NULL);
}