diff -urpN original/gnome-volume-manager-2.17.0/src/autorun_inf_parser.c modified/gnome-volume-manager-2.17.0/src/autorun_inf_parser.c
--- original/gnome-volume-manager-2.17.0/src/autorun_inf_parser.c	1970-01-01 01:00:00.000000000 +0100
+++ modified/gnome-volume-manager-2.17.0/src/autorun_inf_parser.c	2007-07-03 00:31:30.000000000 +0200
@@ -0,0 +1,983 @@
+/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
+/*
+ * src/autorun_inf_parser.c - Autorun.inf Parser
+ *
+ * Written by Hanusz Leszek <leszek.hanusz@gmail.com>
+ *
+ * Autorun.inf Parser is a parser for the autorun.inf format.
+ *
+ * Currently, it only supports fetching the open key in the autorun group
+ *
+ * Most of the code come from the glib file: gkeyfile.c
+ * It has been modified to allow case insensitive searches.
+ *
+ * Licensed under the GNU GPL v2.  See COPYING.
+ */
+
+
+#include "autorun_inf_parser.h"
+
+#include <errno.h>
+#include <fcntl.h>
+#include <string.h>
+
+#include <glib/gstdio.h>
+#include <glib.h>
+
+typedef struct _AutorunInfGroup AutorunInfGroup;
+
+struct _AutorunInf
+{
+	GList *groups;
+
+	AutorunInfGroup *start_group;
+	AutorunInfGroup *current_group;
+
+	GString *parse_buffer; /* Holds up to one line of not-yet-parsed data */
+};
+
+typedef struct _AutorunInfKeyValuePair AutorunInfKeyValuePair;
+
+struct _AutorunInfGroup
+{
+	const gchar *name;
+	GHashTable *lookup_map;
+};
+
+struct _AutorunInfKeyValuePair
+{
+	gchar *key;
+	gchar *value;
+};
+
+#define warn(fmt,arg...) g_warning("%s/%d: " fmt,__FILE__,__LINE__,##arg)
+
+static gboolean			autorun_inf_load_from_fd	(AutorunInf               *key_file,
+								gint                    fd,
+								GError                **error);
+
+static GList			*autorun_inf_lookup_group_node	(AutorunInf               *key_file,
+								const gchar            *group_name);
+
+static AutorunInfGroup		*autorun_inf_lookup_group	(AutorunInf               *key_file,
+								const gchar            *group_name);
+
+static AutorunInfKeyValuePair 	*autorun_inf_lookup_key_value_pair	(AutorunInf       *key_file,
+									AutorunInfGroup  *group,
+									const gchar    *key);
+
+static void			autorun_inf_remove_group_node	(AutorunInf      *key_file,
+								GList         *group_node);
+
+static void 			autorun_inf_add_key		(AutorunInf               *key_file,
+								AutorunInfGroup          *group,
+								const gchar            *key,
+								const gchar            *value);
+
+static void			autorun_inf_add_group		(AutorunInf               *key_file,
+								const gchar            *group_name);
+
+static gboolean			autorun_inf_is_group_name	(const gchar *name);
+static gboolean			autorun_inf_is_key_name		(const gchar *name);
+static gboolean			autorun_inf_line_is_comment	(const gchar            *line);
+static gboolean			autorun_inf_line_is_group	(const gchar            *line);
+static gboolean			autorun_inf_line_is_key_value_pair (const gchar            *line);
+
+static void			autorun_inf_parse_key_value_pair	(AutorunInf               *key_file,
+									const gchar            *line,
+									gsize                   length,
+									GError                **error);
+
+static void			autorun_inf_parse_group		(AutorunInf               *key_file,
+								const gchar            *line,
+								gsize                   length,
+								GError                **error);
+
+static void			autorun_inf_parse_data		(AutorunInf               *key_file,
+								const gchar            *data,
+								gsize                   length,
+								GError                **error);
+
+static void			autorun_inf_flush_parse_buffer	(AutorunInf               *key_file,
+								GError                **error);
+
+GQuark
+autorun_inf_error_quark (void)
+{
+	return g_quark_from_static_string ("g-autorun-inf-error-quark");
+}
+
+static void
+autorun_inf_init (AutorunInf *key_file)
+{  
+	key_file->current_group = g_new0 (AutorunInfGroup, 1);
+	key_file->groups = g_list_prepend (NULL, key_file->current_group);
+	key_file->start_group = NULL;
+	key_file->parse_buffer = g_string_sized_new (128);
+}
+
+static void
+autorun_inf_clear (AutorunInf *key_file)
+{
+	GList *tmp, *group_node;
+
+	if (key_file->parse_buffer)
+		g_string_free (key_file->parse_buffer, TRUE);
+
+	tmp = key_file->groups;
+	while (tmp != NULL)
+	{
+		group_node = tmp;
+		tmp = tmp->next;
+		autorun_inf_remove_group_node (key_file, group_node);
+	}
+
+	g_assert (key_file->groups == NULL);
+}
+
+
+/**
+ * autorun_inf_new:
+ *
+ * Creates a new empty #AutorunInf object.
+ *
+ * Return value: an empty #AutorunInf.
+ **/
+AutorunInf *
+autorun_inf_new (void)
+{
+	AutorunInf *key_file;
+
+	key_file = g_new0 (AutorunInf, 1);
+	autorun_inf_init (key_file);
+
+	return key_file;
+}
+
+static gboolean
+autorun_inf_load_from_fd (AutorunInf       *key_file,
+				gint            fd,
+				GError        **error)
+{
+	GError *key_file_error = NULL;
+	gssize bytes_read;
+	struct stat stat_buf;
+	gchar read_buf[4096];
+  
+	if (fstat (fd, &stat_buf) < 0)
+	{
+		g_set_error (error, G_FILE_ERROR,
+				g_file_error_from_errno (errno),
+                   		"%s", g_strerror (errno));
+      		return FALSE;
+	}
+
+	if (!S_ISREG (stat_buf.st_mode))
+	{
+		g_set_error (error, AUTORUN_INF_ERROR,
+				AUTORUN_INF_ERROR_PARSE,
+				"Not a regular file");
+		return FALSE;
+	}
+
+	if (stat_buf.st_size == 0)
+	{
+		g_set_error (error, AUTORUN_INF_ERROR,
+				AUTORUN_INF_ERROR_PARSE,
+				"File is empty");
+		return FALSE;
+	}
+
+	bytes_read = 0;
+	do
+	{
+		bytes_read = read (fd, read_buf, 4096);
+
+		if (bytes_read == 0)  // End of File 
+			break;
+
+		if (bytes_read < 0)
+		{
+			if (errno == EINTR || errno == EAGAIN)
+				continue;
+
+			g_set_error (error, G_FILE_ERROR,
+						g_file_error_from_errno (errno),
+						"%s", g_strerror (errno));
+			return FALSE;
+		}
+
+		autorun_inf_parse_data (key_file, 
+					read_buf, bytes_read,
+					&key_file_error);
+	}
+  	while (!key_file_error);
+
+	if (key_file_error)
+	{
+		g_propagate_error (error, key_file_error);
+		return FALSE;
+	}
+
+	autorun_inf_flush_parse_buffer (key_file, &key_file_error);
+
+	if (key_file_error)
+	{
+		g_propagate_error (error, key_file_error);
+		return FALSE;
+	}
+
+	return TRUE;
+}
+
+/**
+ * autorun_inf_load_from_file:
+ * @key_file: an empty #AutorunInf struct
+ * @file: the path of a filename to load
+ * @error: return location for a #GError, or %NULL
+ *
+ * Loads a key file into an empty #AutorunInf structure.
+ * If the file could not be loaded then %error is set to 
+ * either a #GFileError or #AutorunInfError.
+ *
+ * the keys and groups ard converted to lowercase
+ * to implement case insensitive searches.
+ *
+ * Return value: %TRUE if a key file could be loaded, %FALSE othewise
+ **/
+gboolean
+autorun_inf_load_from_file (AutorunInf       *key_file,
+			   const gchar    *file,
+			   GError        **error)
+{
+	GError *key_file_error = NULL;
+	gint fd;
+
+	g_return_val_if_fail (key_file != NULL, FALSE);
+	g_return_val_if_fail (file != NULL, FALSE);
+
+	fd = g_open (file, O_RDONLY, 0);
+
+	if (fd < 0)
+	{
+		g_set_error (error, G_FILE_ERROR,
+				g_file_error_from_errno (errno),
+				"%s", g_strerror (errno));
+		return FALSE;
+	}
+
+	autorun_inf_load_from_fd (key_file, fd, &key_file_error);
+	close (fd);
+
+	if (key_file_error)
+	{
+		g_propagate_error (error, key_file_error);
+		return FALSE;
+    	}
+
+	return TRUE;
+}
+
+/**
+ * autorun_inf_free:
+ * @key_file: a #AutorunInf
+ *
+ * Frees a #AutorunInf.
+ **/
+void
+autorun_inf_free (AutorunInf *key_file)
+{
+	g_return_if_fail (key_file != NULL);
+
+	autorun_inf_clear (key_file);
+	g_free (key_file);
+}
+
+static void
+autorun_inf_parse_line (AutorunInf     *key_file,
+			const gchar  *line,
+			gsize         length,
+			GError      **error)
+{
+	GError *parse_error = NULL;
+	gchar *line_start;
+
+	g_return_if_fail (key_file != NULL);
+	g_return_if_fail (line != NULL);
+
+	line_start = (gchar *) line;
+	while (g_ascii_isspace (*line_start))
+    		line_start++;
+
+	if (!autorun_inf_line_is_comment (line_start))
+	{
+		if (autorun_inf_line_is_group (line_start))
+			autorun_inf_parse_group (key_file, line_start,
+						length - (line_start - line),
+						&parse_error);
+  		else if (autorun_inf_line_is_key_value_pair (line_start))
+    			autorun_inf_parse_key_value_pair (key_file, line_start,
+						length - (line_start - line),
+						&parse_error);
+		else
+		{
+			/*g_set_error (error, AUTORUN_INF_ERROR,
+					AUTORUN_INF_ERROR_PARSE,
+					"autorun.inf file contains line '%s' which is not "
+					"a key-value pair, group, or comment", 
+		   			line);*/
+			warn("autorun.inf file contains line '%s' which is not "
+				"a key-value pair, group, or comment", line); 
+      			return;
+		}
+	}
+
+	if (parse_error)
+		g_propagate_error (error, parse_error);
+}
+
+static void
+autorun_inf_parse_group (AutorunInf     *key_file,
+			const gchar  *line,
+			gsize         length,
+			GError      **error)
+{
+	gchar *group_name, *group_name_lowercase;
+	const gchar *group_name_start, *group_name_end;
+
+	// advance past opening '['
+	group_name_start = line + 1;
+	group_name_end = line + length - 1;
+
+	while (*group_name_end != ']')
+		group_name_end--;
+
+	group_name = g_strndup (group_name_start, 
+				group_name_end - group_name_start);
+
+	group_name_lowercase = g_ascii_strdown(group_name,-1);
+	g_free (group_name);
+
+	if (autorun_inf_is_group_name (group_name_lowercase))
+	{
+		autorun_inf_add_group (key_file, group_name_lowercase);
+	}
+	else
+	{
+		g_set_error (error, AUTORUN_INF_ERROR,
+				AUTORUN_INF_ERROR_PARSE,
+				"Invalid group name: %s", group_name_lowercase);
+	}
+
+	g_free (group_name_lowercase);
+}
+
+static void
+autorun_inf_parse_key_value_pair (AutorunInf     *key_file,
+				 const gchar  *line,
+				 gsize         length,
+				 GError      **error)
+{
+	gchar *key, *key_lowercase, *value, *key_end, *value_start, *locale;
+	gsize key_len, value_len;
+	unsigned int i;
+
+	if (key_file->current_group == NULL || key_file->current_group->name == NULL)
+	{
+		g_set_error (error, AUTORUN_INF_ERROR,
+					AUTORUN_INF_ERROR_GROUP_NOT_FOUND,
+					"Key file does not start with a group");
+		return;
+	}
+
+	key_end = value_start = strchr (line, '=');
+
+	g_assert (key_end != NULL);
+
+	key_end--;
+	value_start++;
+
+	// Pull the key name from the line (chomping trailing whitespace)
+	while (g_ascii_isspace (*key_end))
+		key_end--;
+
+	key_len = key_end - line + 2;
+
+	g_assert (key_len <= length);
+
+	key = g_strndup (line, key_len - 1);
+
+	key_lowercase = g_ascii_strdown(key,-1);
+
+	g_free (key);
+
+	if (!autorun_inf_is_key_name (key_lowercase))
+	{
+		g_set_error (error, AUTORUN_INF_ERROR,
+					AUTORUN_INF_ERROR_PARSE,
+					"Invalid key name: %s", key_lowercase);
+		g_free (key_lowercase);
+		return;
+	}
+
+	// Pull the value from the line (chugging leading whitespace)
+	while (g_ascii_isspace (*value_start))
+		value_start++;
+
+	value_len = line + length - value_start + 1;
+
+	value = g_strndup (value_start, value_len);
+
+	//convert to windows path to unix path
+	for(i=0;i < strlen(value);i++) 
+	{
+		if(value[i]=='\\')
+			value[i]='/';
+  	}
+
+  	g_assert (key_file->start_group != NULL);
+
+  	autorun_inf_add_key (key_file, key_file->current_group, key_lowercase, value);
+
+  	g_free (key_lowercase);
+	g_free (value);
+}
+
+static void
+autorun_inf_parse_data (AutorunInf     *key_file,
+		       const gchar  *data,
+		       gsize         length,
+		       GError      **error)
+{
+	GError *parse_error;
+	gsize i;
+
+	g_return_if_fail (key_file != NULL);
+	g_return_if_fail (data != NULL);
+
+	parse_error = NULL;
+
+	for (i = 0; i < length; i++)
+	{
+		if (data[i] == '\n')
+		{
+			if (i > 0 && data[i - 1] == '\r')
+				g_string_erase (key_file->parse_buffer,
+						key_file->parse_buffer->len - 1,
+						1); 
+	    
+			/* When a newline is encountered flush the parse buffer so that the
+			* line can be parsed. 
+			*/
+			if (key_file->parse_buffer->len > 0)
+				autorun_inf_flush_parse_buffer (key_file, &parse_error);
+
+			if (parse_error)
+			{
+				g_propagate_error (error, parse_error);
+				return;
+			}
+		}
+		else
+			g_string_append_c (key_file->parse_buffer, data[i]);
+	}
+}
+
+static void
+autorun_inf_flush_parse_buffer (AutorunInf  *key_file,
+			       GError   **error)
+{
+	GError *file_error = NULL;
+
+	g_return_if_fail (key_file != NULL);
+
+	file_error = NULL;
+
+	if (key_file->parse_buffer->len > 0)
+	{
+		autorun_inf_parse_line (key_file, key_file->parse_buffer->str,
+					key_file->parse_buffer->len,
+					&file_error);
+		g_string_erase (key_file->parse_buffer, 0, -1);
+
+		if (file_error)
+		{
+			g_propagate_error (error, file_error);
+			return;
+		}
+	}
+}
+
+/**
+ * autorun_inf_get_value:
+ * @key_file: a #AutorunInf
+ * @group_name: a group name
+ * @key: a key
+ * @error: return location for a #GError, or %NULL
+ *
+ * Returns the value associated with @key under @group_name.
+ * 
+ * key has to be lowercase !
+ *
+ * In the event the key cannot be found, %NULL is returned and 
+ * @error is set to #AUTORUN_INF_ERROR_KEY_NOT_FOUND.  In the 
+ * event that the @group_name cannot be found, %NULL is returned 
+ * and @error is set to #AUTORUN_INF_ERROR_GROUP_NOT_FOUND.
+ *
+ * Return value: a newly allocated string or %NULL if the specified 
+ *  key cannot be found.
+ **/
+gchar *
+autorun_inf_get_value (AutorunInf     *key_file,
+			const gchar  *group_name,
+			const gchar  *key,
+			GError      **error)
+{
+	AutorunInfGroup *group;
+	AutorunInfKeyValuePair *pair;
+	gchar *value = NULL;
+
+	g_return_val_if_fail (key_file != NULL, NULL);
+	g_return_val_if_fail (group_name != NULL, NULL);
+	g_return_val_if_fail (key != NULL, NULL);
+
+	group = autorun_inf_lookup_group (key_file, group_name);
+
+	if (!group)
+	{
+		g_set_error (error, AUTORUN_INF_ERROR,
+				AUTORUN_INF_ERROR_GROUP_NOT_FOUND,
+				"Key file does not have group '%s'",
+				group_name ? group_name : "(null)");
+		return NULL;
+	}
+
+	pair = autorun_inf_lookup_key_value_pair (key_file, group, key);
+
+	if (pair)
+		value = g_strdup (pair->value);
+	else
+		g_set_error (error, AUTORUN_INF_ERROR,
+				AUTORUN_INF_ERROR_KEY_NOT_FOUND,
+				"Key file does not have key '%s'", key);
+
+	return value;
+}
+
+static void
+autorun_inf_add_group (AutorunInf    *key_file,
+			const gchar *group_name)
+{
+	AutorunInfGroup *group;
+
+	g_return_if_fail (key_file != NULL);
+	g_return_if_fail (autorun_inf_is_group_name (group_name));
+
+	group = autorun_inf_lookup_group (key_file, group_name);
+	if (group != NULL)
+	{
+		key_file->current_group = group;
+		return;
+	}
+
+	group = g_new0 (AutorunInfGroup, 1);
+	group->name = g_strdup (group_name);
+	group->lookup_map = g_hash_table_new (g_str_hash, g_str_equal);
+	key_file->groups = g_list_prepend (key_file->groups, group);
+	key_file->current_group = group;
+
+	if (key_file->start_group == NULL)
+		key_file->start_group = group;
+}
+
+static void
+autorun_inf_remove_group_node (AutorunInf *key_file,
+				GList    *group_node)
+{
+	AutorunInfGroup *group;
+	GList *tmp;
+
+	group = (AutorunInfGroup *) group_node->data;
+
+	/* If the current group gets deleted make the current group the last
+	* added group.
+	*/
+	
+	if (key_file->current_group == group)
+	{
+		/* groups should always contain at least the top comment group,
+		* unless autorun_inf_clear has been called
+		*/
+		if (key_file->groups)
+			key_file->current_group = (AutorunInfGroup *) key_file->groups->data;
+		else
+			key_file->current_group = NULL;
+	}
+
+	/* If the start group gets deleted make the start group the first
+	* added group.
+	*/
+	if (key_file->start_group == group)
+	{
+		tmp = g_list_last (key_file->groups);
+		while (tmp != NULL)
+		{
+			if (tmp != group_node && ((AutorunInfGroup *) tmp->data)->name != NULL)
+				break;
+
+			tmp = tmp->prev;
+		}
+
+		if (tmp)
+			key_file->start_group = (AutorunInfGroup *) tmp->data;
+		else
+			key_file->start_group = NULL;
+	}
+
+	key_file->groups = g_list_remove_link (key_file->groups, group_node);
+
+	if (group->lookup_map)
+	{
+		g_hash_table_destroy (group->lookup_map);
+		group->lookup_map = NULL;
+	}
+
+	g_free ((gchar *) group->name);
+	g_free (group);
+	g_list_free_1 (group_node);
+}
+
+static void
+autorun_inf_add_key (AutorunInf      *key_file,
+			AutorunInfGroup *group,
+			const gchar   *key,
+			const gchar   *value)
+{
+	AutorunInfKeyValuePair *pair;
+
+	pair = g_new0 (AutorunInfKeyValuePair, 1);
+
+	pair->key = g_strdup (key);
+	pair->value = g_strdup (value);
+
+	g_hash_table_replace (group->lookup_map, pair->key, pair);
+}
+
+static GList *
+autorun_inf_lookup_group_node (AutorunInf    *key_file,
+				const gchar *group_name)
+{
+	AutorunInfGroup *group;
+	GList *tmp;
+
+	for (tmp = key_file->groups; tmp != NULL; tmp = tmp->next)
+	{
+		group = (AutorunInfGroup *) tmp->data;
+
+		if (group && group->name && strcmp (group->name, group_name) == 0)
+			break;
+	}
+
+	return tmp;
+}
+
+static AutorunInfGroup *
+autorun_inf_lookup_group (AutorunInf    *key_file,
+			 const gchar *group_name)
+{
+	GList *group_node;
+
+	group_node = autorun_inf_lookup_group_node (key_file, group_name);
+
+	if (group_node != NULL)
+		return (AutorunInfGroup *) group_node->data; 
+
+	return NULL;
+}
+
+static AutorunInfKeyValuePair *
+autorun_inf_lookup_key_value_pair (AutorunInf      *key_file,
+					AutorunInfGroup *group,
+					const gchar   *key)
+{
+	return (AutorunInfKeyValuePair *) g_hash_table_lookup (group->lookup_map, key);
+}
+
+/* Lines starting with # or ; or consisting entirely of whitespace are
+ * not parsed. This function assumes all leading whitespace
+ * has been stripped.
+ */
+static gboolean
+autorun_inf_line_is_comment (const gchar *line)
+{
+	return (*line == '#' || *line == ';' || *line == '\0' || *line == '\n');
+}
+
+static gboolean 
+autorun_inf_is_group_name (const gchar *name)
+{
+	gchar *p, *q;
+
+	if (name == NULL)
+		return FALSE;
+
+	p = q = (gchar *) name;
+	while (*q && *q != ']' && *q != '[' && !g_ascii_iscntrl (*q))
+		q = g_utf8_next_char (q);
+  
+	if (*q != '\0' || q == p)
+		return FALSE;
+
+	return TRUE;
+}
+
+static gboolean
+autorun_inf_is_key_name (const gchar *name)
+{
+	gchar *p, *q;
+
+	if (name == NULL)
+		return FALSE;
+
+	p = q = (gchar *) name;
+
+	while (*q && *q != '=')
+		q = g_utf8_next_char (q);
+  
+	// No empty keys, please
+	if (q == p)
+		return FALSE;
+
+	if (*p == ' ' || q[-1] == ' ')
+		return FALSE;
+
+	if (*q != '\0')
+		return FALSE;
+
+	return TRUE;
+}
+
+/* A group in a key file is made up of a starting '[' followed by one
+ * or more letters making up the group name followed by ']'.
+ */
+static gboolean
+autorun_inf_line_is_group (const gchar *line)
+{
+	gchar *p;
+
+	p = (gchar *) line;
+	if (*p != '[')
+		return FALSE;
+
+	p++;
+
+	while (*p && *p != ']')
+		p = g_utf8_next_char (p);
+
+	if (*p != ']')
+		return FALSE;
+
+	// silently accept whitespace after the ] 
+  	p = g_utf8_next_char (p);
+	while (*p == ' ' || *p == '\t')
+		p = g_utf8_next_char (p);
+     
+	if (*p)
+		return FALSE;
+
+	return TRUE;
+}
+
+static gboolean
+autorun_inf_line_is_key_value_pair (const gchar *line)
+{
+	gchar *p;
+
+	p = (gchar *) g_utf8_strchr (line, -1, '=');
+
+	if (!p)
+		return FALSE;
+
+	// Key must be non-empty
+	if (*p == line[0])
+		return FALSE;
+
+	return TRUE;
+}
+
+gchar *
+autorun_inf_get_autorun_value (AutorunInf    *key_file,
+				GError              **error)
+{
+	GError *key_file_error;
+	gchar *autorun_value;
+
+	key_file_error = NULL;
+
+	autorun_value = autorun_inf_get_value(key_file, "autorun", "open", &key_file_error);
+
+	if (key_file_error)
+	{
+		g_propagate_error (error, key_file_error);
+	return NULL;
+	}
+
+	return autorun_value;
+}
+
+static gchar *
+autorun_inf_find_file	(const gchar* directory, const gchar* filename, GError **error)
+{
+	GDir*       dir;
+	GError *dir_error;
+	gchar *file, *file_lwr, *filename_lwr;
+
+	dir_error=NULL;
+
+	dir = g_dir_open (directory,0,&dir_error);
+
+	if(dir_error != NULL)
+	{
+		g_propagate_error (error, dir_error);
+		return NULL;
+	}
+
+	filename_lwr = g_ascii_strdown(filename,-1);
+	
+	while (file = (gchar *)g_dir_read_name (dir))
+	{
+		file_lwr = g_ascii_strdown(file,-1);
+		if(strcmp(file_lwr,filename_lwr) == 0 )
+		{
+			g_free(file_lwr);
+			g_dir_close(dir);
+			
+			return g_strdup(file);
+		}
+		g_free(file_lwr);
+	}
+
+	
+	g_set_error (error, AUTORUN_INF_ERROR,
+                   	AUTORUN_INF_ERROR_NOT_FOUND,
+                   	"%s file could not be found in %s\n", 
+			filename,
+			directory);
+
+	g_free(filename_lwr);
+	g_dir_close(dir);
+	return NULL;
+}
+
+/**
+ * autorun_inf_find_autorun_file:
+ * @directory: a nul-terminated string.
+ *
+ * Find the case-preserved autorun.inf in the directory
+ *
+ * Return value: a nul-terminated string (gchar*) if file found, NULL otherwise.
+
+ **/
+gchar *
+autorun_inf_find_autorun_file	(const gchar* directory)
+{
+	return autorun_inf_find_file (directory, "autorun.inf", NULL);
+}
+
+/**
+ * autorun_inf_has_suffix:
+ * @str: a nul-terminated string.
+ * @suffix: the nul-terminated suffix to look for.
+ *
+ * Looks whether the string @str ends with @suffix.
+ * 
+ * CASE INSENSITIVE
+ *
+ * Return value: %TRUE if @str end with @suffix, %FALSE otherwise.
+
+ **/
+static gboolean
+autorun_inf_has_suffix (const gchar  *str,
+                  const gchar  *suffix)
+{
+	int str_len;
+	int suffix_len;
+	char *suffix_insens, *str_insens;
+	gboolean has_suffix;
+
+	g_return_val_if_fail (str != NULL, FALSE);
+	g_return_val_if_fail (suffix != NULL, FALSE);
+
+	str_len = strlen (str);
+	suffix_len = strlen (suffix);
+
+	if (str_len < suffix_len)
+		return FALSE;
+
+	suffix_insens = g_ascii_strdown(suffix,-1);
+	str_insens = g_ascii_strdown(str + str_len - suffix_len,-1);
+
+	has_suffix = strcmp (str_insens, suffix_insens) == 0;
+
+	g_free(suffix_insens);
+	g_free(str_insens);
+
+	return has_suffix;
+}
+
+/**
+ * autorun_inf_is_exe:
+ * @mount_point: a nul-terminated string.
+ * @str: nul-terminated string.
+ *
+ * determine if str ends with .exe (case insensitive)
+ * 
+ * In case str doesn't end with .exe, and there is no "." in the string
+ * (except at the first place)
+ * trying to find a file in the mount_point by adding .exe
+ *
+ * Return value: %TRUE if @str is a exe file, %FALSE otherwise.
+
+ **/
+gboolean
+autorun_inf_is_exe (const gchar  *str)
+{
+	gboolean is_exe;
+	gchar **str_split;
+	gchar *str_with_exe, *str_with_exe_dir, *str_with_exe_filename;
+	char *p, *g;
+	str_split = g_strsplit (str," ",-1);
+	is_exe = autorun_inf_has_suffix (str_split[0],".exe");
+	if (!is_exe && strchr(str_split[0]+1,'.')==NULL)
+	{
+		// when there is no "." in the command, try to add a .exe and find this file.
+		str_with_exe = g_strdup_printf("%s.exe", str_split[0]);
+		//warn ("No '.' found in command, try to find this file: %s \n", str_with_exe);
+
+		for (g=p=str_with_exe;*p!='\0';p++)
+		{
+			if (*p == '/' || *p == '\\')
+				g=p;
+		}
+
+		str_with_exe_dir = g_strndup(str_with_exe, g - str_with_exe);
+		g++;
+		str_with_exe_filename = g_strndup(g, p-g);
+
+		//warn ("Looking for %s file in %s directory \n ",str_with_exe_filename, str_with_exe_dir);
+		
+		if(autorun_inf_find_file(str_with_exe_dir, str_with_exe_filename, NULL) != NULL)
+			is_exe = TRUE;
+
+		g_free(str_with_exe_dir);
+		g_free(str_with_exe_filename);
+			
+		g_free(str_with_exe);
+	}
+	g_strfreev(str_split);
+	return is_exe;
+}
+
+
+
+#define __AUTORUN_INF_C__
diff -urpN original/gnome-volume-manager-2.17.0/src/autorun_inf_parser.h modified/gnome-volume-manager-2.17.0/src/autorun_inf_parser.h
--- original/gnome-volume-manager-2.17.0/src/autorun_inf_parser.h	1970-01-01 01:00:00.000000000 +0100
+++ modified/gnome-volume-manager-2.17.0/src/autorun_inf_parser.h	2007-07-03 00:20:32.000000000 +0200
@@ -0,0 +1,60 @@
+/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
+/*
+ * src/autorun_inf_parser.h - Autorun.inf Parser
+ *
+ * Written by Hanusz Leszek <leszek.hanusz@gmail.com>
+ *
+ * Autorun.inf Parser is a parser for the autorun.inf format.
+ *
+ * Currently, it only supports fetching the open key in the autorun group
+ *
+ * Most of the code come from the glib file: gkeyfile.h
+ * It has been modified to allow case insensitive searches.
+ *
+ * Licensed under the GNU GPL v2.  See COPYING.
+ */
+
+
+#ifndef __AUTORUN_INF_PARSER_H__
+#define __AUTORUN_INF_PARSER_H__
+
+#include <glib/gerror.h>
+
+G_BEGIN_DECLS
+
+typedef enum
+{
+  AUTORUN_INF_ERROR_PARSE,
+  AUTORUN_INF_ERROR_NOT_FOUND,
+  AUTORUN_INF_ERROR_KEY_NOT_FOUND,
+  AUTORUN_INF_ERROR_GROUP_NOT_FOUND
+} AutorunInfError;
+
+#define AUTORUN_INF_ERROR autorun_inf_error_quark()
+
+GQuark autorun_inf_error_quark (void);
+
+typedef struct _AutorunInf AutorunInf;
+
+AutorunInf*	autorun_inf_new				(void);
+void		autorun_inf_free			(AutorunInf *key_file);
+
+gboolean	autorun_inf_load_from_file		(AutorunInf *key_file,
+							const gchar *file,
+							GError **error);
+
+gchar*		autorun_inf_get_value			(AutorunInf *key_file,
+							const gchar *group_name,
+							const gchar *key,
+							GError **error) G_GNUC_MALLOC;
+
+gchar*		autorun_inf_get_autorun_value		(AutorunInf *key_file,
+							GError **error) G_GNUC_MALLOC;
+
+gboolean	autorun_inf_is_exe			(const gchar  *str);
+
+gchar*		autorun_inf_find_autorun_file		(const gchar* directory);
+
+G_END_DECLS
+
+#endif /* __AUTORUN_INF_PARSER_H__ */
diff -urpN original/gnome-volume-manager-2.17.0/src/Makefile.am modified/gnome-volume-manager-2.17.0/src/Makefile.am
--- original/gnome-volume-manager-2.17.0/src/Makefile.am	2006-11-07 19:01:17.000000000 +0100
+++ modified/gnome-volume-manager-2.17.0/src/Makefile.am	2007-07-01 22:26:01.000000000 +0200
@@ -14,7 +14,7 @@ INCLUDES = 					   \
 
 bin_PROGRAMS = gnome-volume-manager gnome-volume-properties
 
-gnome_volume_manager_SOURCES = manager.c clipboard.c gvm.h
+gnome_volume_manager_SOURCES = manager.c clipboard.c gvm.h autorun_inf_parser.c
 gnome_volume_manager_LDADD = $(GVM_LIBS) $(NOTIFY_LIBS)
 
 gnome_volume_properties_SOURCES = properties.c gvm.h
diff -urpN original/gnome-volume-manager-2.17.0/src/manager.c modified/gnome-volume-manager-2.17.0/src/manager.c
--- original/gnome-volume-manager-2.17.0/src/manager.c	2006-11-07 19:01:17.000000000 +0100
+++ modified/gnome-volume-manager-2.17.0/src/manager.c	2007-07-03 17:20:50.000000000 +0200
@@ -46,6 +46,7 @@
 #include <dbus/dbus-glib.h>
 #include <dbus/dbus-glib-lowlevel.h>
 #include <libhal.h>
+#include <autorun_inf_parser.h>
 
 #include "gvm.h"
 
@@ -1196,6 +1197,60 @@ autorun_cb (GvmPromptCtx *ctx, int actio
 }
 
 static void
+autorun_inf_cb (GvmPromptCtx *ctx, int action)
+{
+	gboolean autobrowse = TRUE;
+	GError *error = NULL;
+	
+	if (action == GVM_RESPONSE_RUN) {
+		if (autorun_inf_is_exe(ctx->path)) {
+			if (g_file_test ("/usr/bin/wine", G_FILE_TEST_EXISTS)) {
+				gchar** argv;
+				gchar* path;
+
+				path = g_strdup_printf ("%s %s", "/usr/bin/wine", ctx->path);
+				argv = g_strsplit (path," ",-1);
+				
+				dbg ("Running command: %s\n", path);
+
+				g_spawn_async (ctx->mount_point, argv, NULL,
+					       0, NULL, NULL, NULL, &error);
+
+				g_free(path);
+				g_strfreev (argv);
+
+				if (error)
+					warn ("failed to exec %s: %s", ctx->path, error->message);
+				else
+					autobrowse = FALSE;			
+			} else {
+				// TODO : insert here code to propose the installation of wine
+				// Should connect to another package because the same thing should happen when
+				// double-clicking a .exe file
+				warn ("/usr/bin/wine is not found. You need to install the wine package.");
+			}
+		} else {
+			char *argv[2];
+			argv[0] = ctx->path;
+			argv[1] = NULL;
+			
+			dbg ("Autorun command is not a .exe file\nRunning command: %s \n", argv[0]);
+
+			g_spawn_async (ctx->mount_point, argv, NULL,
+				       0, NULL, NULL, NULL, &error);
+			if (error) {
+				warn ("failed to exec %s: %s", ctx->path, error->message);
+				g_error_free (error);
+			} else
+				autobrowse = FALSE;
+		}
+	}
+	
+	if (config.autobrowse && autobrowse)
+		gvm_run_command (NAUTILUS_COMMAND, ctx->udi, ctx->device, ctx->mount_point);
+}
+
+static void
 autoopen_cb (GvmPromptCtx *ctx, int action)
 {
 	gboolean autobrowse = TRUE;
@@ -1264,6 +1319,94 @@ canon_path (char *path)
 }
 
 /*
+ * gvm_autoexecute - automatically execute programs
+ * coming from either autorun.inf
+ * or config.autorun_path
+ *
+ * @return 	TRUE if handled
+ * 		FALSE if not handled
+ */
+static gboolean 
+gvm_autoexecute (const char *udi, const char *device, const char *mount_point)
+{
+	char **autopath, *argv[1], *path, *autorun_inf_path, *autorun_command, *autorun_inf_file;
+	gboolean handled = FALSE;
+	GvmPromptCtx *ctx;
+	AutorunInf *autorun_inf;
+	GError *error = NULL;
+	unsigned int i;
+
+	if (config.autorun) {
+		// Checking autorun.inf
+
+		autorun_inf_file = (char*) autorun_inf_find_autorun_file((const gchar *)mount_point);
+		if (autorun_inf_file==NULL) {
+			dbg("No autorun.inf file found\n");
+		} else {
+			dbg ("autorun.inf file found :  %s \n", autorun_inf_file);
+			autorun_inf=autorun_inf_new ();
+			autorun_inf_path = g_strdup_printf ("%s/%s", mount_point, autorun_inf_file);
+			if (autorun_inf_load_from_file (autorun_inf,autorun_inf_path,&error)) {
+				dbg ("autorun.inf file loaded \n");
+				autorun_command = autorun_inf_get_autorun_value (autorun_inf,&error);
+				if (error!=NULL) {
+					warn("The autorun.inf file doesn't contain a the 'open' key in the 'autorun' group : %s\n", error->message);
+					g_error_free (error);
+				} else {
+					dbg ("autorun command found: %s \n", autorun_command);
+					argv[0]=autorun_command;
+					path = g_strdup_printf ("%s/%s", mount_point, autorun_command);
+					ctx = gvm_prompt_ctx_new (GVM_PROMPT_AUTORUN, autorun_inf_cb, udi, device, mount_point, path);
+					gvm_prompt (ctx, 1, argv);
+					handled = TRUE;
+
+					g_free(path);
+					g_free(autorun_command);
+				}
+			} else {
+				warn("Impossible to load the autorun.inf file : %s\n", error->message);
+				g_error_free (error);
+			}
+			
+			autorun_inf_free(autorun_inf);
+			g_free (autorun_inf_path);
+			g_free (autorun_inf_file);
+		}
+
+		if (handled)
+			return TRUE;
+
+		if (config.autorun_path) {
+			// Checking for files in autorun path (gconf)
+
+			autopath = g_strsplit (config.autorun_path, ":", -1);
+		
+			for (i = 0; autopath[i]; i++) {
+				path = g_strdup_printf ("%s/%s", mount_point, autopath[i]);
+				if (access (path, F_OK | R_OK | X_OK) != 0 ) {
+					g_free (path);
+					continue;
+				}
+			
+				argv[0] = autopath[i];
+				ctx = gvm_prompt_ctx_new (GVM_PROMPT_AUTORUN, autorun_cb, udi, device, mount_point, path);
+				gvm_prompt (ctx, 1, argv);
+				handled = TRUE;
+				g_free (path);
+				break;
+			}
+
+			g_strfreev (autopath);
+
+			if (handled)
+				return TRUE;
+		}
+	}
+	return FALSE;
+}
+
+
+/*
  * gvm_autorun - automatically execute stuff
  *
  * we currently autorun: autorun files, video DVD's, and digital photos
@@ -1274,44 +1417,23 @@ gvm_autorun (const char *udi, const char
 	char **autopath, *argv[1], *path;
 	gboolean handled = FALSE;
 	GvmPromptCtx *ctx;
-	int i;
-	
+	unsigned int i;
+
 	if (gvm_check_dvd (udi, device, mount_point))
 		return;
 	
 	if (gvm_check_vcd (udi, device, mount_point))
 		return;
-	
+
+	if (gvm_autoexecute (udi, device, mount_point))
+		return;
+
 	if (config.autophoto && gvm_check_photos (udi, device, mount_point)) {
 		ctx = gvm_prompt_ctx_new (GVM_PROMPT_IMPORT_PHOTOS, import_photos_cb, udi, device, mount_point, NULL);
 		gvm_prompt (ctx, 0, NULL);
 		return;
 	}
 	
-	if (config.autorun && config.autorun_path) {
-		autopath = g_strsplit (config.autorun_path, ":", -1);
-		
-		for (i = 0; autopath[i]; i++) {
-			path = g_strdup_printf ("%s/%s", mount_point, autopath[i]);
-			if (access (path, F_OK | R_OK | X_OK) != 0) {
-				g_free (path);
-				continue;
-			}
-			
-			argv[0] = autopath[i];
-			ctx = gvm_prompt_ctx_new (GVM_PROMPT_AUTORUN, autorun_cb, udi, device, mount_point, path);
-			gvm_prompt (ctx, 1, argv);
-			handled = TRUE;
-			g_free (path);
-			break;
-		}
-		
-		g_strfreev (autopath);
-		
-		if (handled)
-			return;
-	}
-	
 	if (config.autoopen && config.autoopen_path) {
 		autopath = g_strsplit (config.autoopen_path, ":", -1);
 		
@@ -1772,7 +1894,7 @@ gvm_mount_options (GPtrArray *options, g
 /*
  * gvm_device_mount - mount the given device.
  *
- * @return TRUE iff the mount was succesful
+ * @return TRUE if the mount was succesful
  */
 static gboolean
 gvm_device_mount (const char *udi, gboolean interactive)
