glib r7055 - trunk/gio



Author: hans
Date: Tue Jun 17 21:40:04 2008
New Revision: 7055
URL: http://svn.gnome.org/viewvc/glib?rev=7055&view=rev

Log:
2008-06-17  Hans Breuer  <hans breuer org>

        * gwin32mount.[ch] gwin32volumemonitor.[ch] : bits and pieces from 
        gtk-2-12 and gunix*.[hc] to make the file chooser show drive letter
	access again on win32, see bug #538127
        * giomodule.c : ensure GWin32VolumeMonitor is registered
        * glocaldireoctorymonitor.c : initial state on win32 is_mounted=TRUE
        * Makefile.am makefile.msc : updated


Added:
   trunk/gio/gwin32mount.c   (contents, props changed)
   trunk/gio/gwin32mount.h   (contents, props changed)
   trunk/gio/gwin32volumemonitor.c   (contents, props changed)
   trunk/gio/gwin32volumemonitor.h   (contents, props changed)
Modified:
   trunk/gio/ChangeLog
   trunk/gio/Makefile.am
   trunk/gio/giomodule.c
   trunk/gio/glocaldirectorymonitor.c
   trunk/gio/makefile.msc

Modified: trunk/gio/Makefile.am
==============================================================================
--- trunk/gio/Makefile.am	(original)
+++ trunk/gio/Makefile.am	Tue Jun 17 21:40:04 2008
@@ -148,6 +148,13 @@
 if OS_WIN32
 appinfo_sources += gwin32appinfo.c gwin32appinfo.h
 platform_libadd += -lshlwapi
+win32_sources = \
+	gwin32mount.c \
+	gwin32mount.h \
+	gwin32volumemonitor.c \
+	gwin32volumemonitor.h \
+	$(NULL)
+
 endif
 
 SUBDIRS += tests
@@ -210,6 +217,7 @@
 	gioaliasdef.c		\
 	$(appinfo_sources) 	\
 	$(unix_sources) 	\
+	$(win32_sources) 	\
 	$(local_sources) 	\
 	$(marshal_sources) 	\
 	$(NULL)

Modified: trunk/gio/giomodule.c
==============================================================================
--- trunk/gio/giomodule.c	(original)
+++ trunk/gio/giomodule.c	Tue Jun 17 21:40:04 2008
@@ -292,6 +292,7 @@
 extern GType _g_unix_volume_monitor_get_type (void);
 extern GType _g_local_vfs_get_type (void);
 
+extern GType _g_win32_volume_monitor_get_type (void);
 extern GType g_win32_directory_monitor_get_type (void);
 
 void
@@ -357,6 +358,7 @@
       _g_fen_file_monitor_get_type ();
 #endif
 #ifdef G_OS_WIN32
+      _g_win32_volume_monitor_get_type ();
       g_win32_directory_monitor_get_type ();
 #endif
 #ifdef G_OS_UNIX

Modified: trunk/gio/glocaldirectorymonitor.c
==============================================================================
--- trunk/gio/glocaldirectorymonitor.c	(original)
+++ trunk/gio/glocaldirectorymonitor.c	Tue Jun 17 21:40:04 2008
@@ -113,7 +113,8 @@
   if (!klass->mount_notify)
     {
 #ifdef G_OS_WIN32
-      g_warning ("G_OS_WIN32: no mount emulation");
+      /*claim everything was mounted */
+      local_monitor->was_mounted = TRUE;
 #else
       GUnixMountEntry *mount;
       
@@ -177,7 +178,8 @@
   /* Emulate unmount detection */
 #ifdef G_OS_WIN32
   mount = NULL;
-  g_warning ("G_OS_WIN32: no mount emulation");
+  /*claim everything was mounted */
+  is_mounted = TRUE;
 #else  
   mount = g_unix_mount_at (local_monitor->dirname, NULL);
   

Added: trunk/gio/gwin32mount.c
==============================================================================
--- (empty file)
+++ trunk/gio/gwin32mount.c	Tue Jun 17 21:40:04 2008
@@ -0,0 +1,410 @@
+/* GIO - GLib Input, Output and Streaming Library
+ * 
+ * Copyright (C) 2006-2007 Red Hat, Inc.
+ * Copyright (C) 2008 Hans Breuer
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General
+ * Public License along with this library; if not, write to the
+ * Free Software Foundation, Inc., 59 Temple Place, Suite 330,
+ * Boston, MA 02111-1307, USA.
+ *
+ * Author: Alexander Larsson <alexl redhat com>
+ *         David Zeuthen <davidz redhat com>
+ *         Hans Breuer <hans breuer org>
+ */
+
+#include <config.h>
+
+#include <string.h>
+#define WIN32_MEAN_AND_LEAN
+#include <windows.h>
+
+#include <glib.h>
+#include "gwin32volumemonitor.h"
+#include "gwin32mount.h"
+#include "gmountprivate.h"
+#include "gvolumemonitor.h"
+#include "gthemedicon.h"
+#include "gsimpleasyncresult.h"
+#include "glibintl.h"
+
+#include "gioalias.h"
+
+struct _GWin32Mount {
+  GObject parent;
+
+  GVolumeMonitor   *volume_monitor;
+
+  GWin32Volume      *volume; /* owned by volume monitor */
+  int   drive_type;
+
+  /* why does all this stuff need to be duplicated? It is in volume already! */
+  char *name;
+  GIcon *icon;
+  char *mount_path;
+
+  gboolean can_eject;
+};
+
+static void g_win32_mount_mount_iface_init (GMountIface *iface);
+
+#define g_win32_mount_get_type _g_win32_mount_get_type
+G_DEFINE_TYPE_WITH_CODE (GWin32Mount, g_win32_mount, G_TYPE_OBJECT,
+			 G_IMPLEMENT_INTERFACE (G_TYPE_MOUNT,
+						g_win32_mount_mount_iface_init))
+
+
+static void
+g_win32_mount_finalize (GObject *object)
+{
+  GWin32Mount *mount;
+  
+  mount = G_WIN32_MOUNT (object);
+
+  if (mount->volume_monitor != NULL)
+    g_object_unref (mount->volume_monitor);
+#if 0
+  if (mount->volume)
+    _g_win32_volume_unset_mount (mount->volume, mount);
+#endif
+  /* TODO: g_warn_if_fail (volume->volume == NULL); */
+  g_object_unref (mount->icon);
+  g_free (mount->name);
+  g_free (mount->mount_path);
+  
+  if (G_OBJECT_CLASS (g_win32_mount_parent_class)->finalize)
+    (*G_OBJECT_CLASS (g_win32_mount_parent_class)->finalize) (object);
+}
+
+static void
+g_win32_mount_class_init (GWin32MountClass *klass)
+{
+  GObjectClass *gobject_class = G_OBJECT_CLASS (klass);
+
+  gobject_class->finalize = g_win32_mount_finalize;
+}
+
+static void
+g_win32_mount_init (GWin32Mount *win32_mount)
+{
+}
+
+gchar *
+_win32_get_displayname (const char *drive)
+{
+  gunichar2 *wdrive = g_utf8_to_utf16 (drive, -1, NULL, NULL, NULL);
+  gchar *name = NULL;
+  SHFILEINFOW sfi;
+  if (SHGetFileInfoW(wdrive, 0, &sfi, sizeof(sfi), SHGFI_DISPLAYNAME))
+    name = g_utf16_to_utf8 (sfi.szDisplayName, -1, NULL, NULL, NULL);
+
+  g_free (wdrive);
+  return name ? name : g_strdup (drive);
+}
+
+/**
+ * _g_win32_mount_new:
+ * @volume_monitor: a #GVolumeMonitor.
+ * @path: a win32 path.
+ * @volume: ususally NULL
+ * 
+ * Returns: a #GWin32Mount for the given win32 path.
+ **/
+GWin32Mount *
+_g_win32_mount_new (GVolumeMonitor  *volume_monitor,
+                    const char       *path,
+                    GWin32Volume     *volume)
+{
+  GWin32Mount *mount;
+  const gchar *drive = path; //fixme
+
+#if 0  
+  /* No volume for mount: Ignore internal things */
+  if (volume == NULL && !g_win32_mount_guess_should_display (mount_entry))
+    return NULL;
+#endif
+
+  mount = g_object_new (G_TYPE_WIN32_MOUNT, NULL);
+  mount->volume_monitor = volume_monitor != NULL ? g_object_ref (volume_monitor) : NULL;
+  mount->mount_path = g_strdup (path);
+  mount->drive_type = GetDriveType (drive);
+  mount->can_eject = FALSE; /* TODO */
+  mount->name = _win32_get_displayname (drive);
+
+  /* need to do this last */
+  mount->volume = volume;
+#if 0
+  if (volume != NULL)
+    _g_win32_volume_set_mount (volume, mount);
+#endif
+  return mount;
+}
+
+void
+_g_win32_mount_unmounted (GWin32Mount *mount)
+{
+  if (mount->volume != NULL)
+    {
+#if 0
+      _g_win32_volume_unset_mount (mount->volume, mount);
+#endif
+      mount->volume = NULL;
+      g_signal_emit_by_name (mount, "changed");
+      /* there's really no need to emit mount_changed on the volume monitor 
+       * as we're going to be deleted.. */
+    }
+}
+
+void
+_g_win32_mount_unset_volume (GWin32Mount *mount,
+                            GWin32Volume  *volume)
+{
+  if (mount->volume == volume)
+    {
+      mount->volume = NULL;
+      /* TODO: Emit changed in idle to avoid locking issues */
+      g_signal_emit_by_name (mount, "changed");
+      if (mount->volume_monitor != NULL)
+        g_signal_emit_by_name (mount->volume_monitor, "mount_changed", mount);
+    }
+}
+
+static GFile *
+g_win32_mount_get_root (GMount *mount)
+{
+  GWin32Mount *win32_mount = G_WIN32_MOUNT (mount);
+
+  return g_file_new_for_path (win32_mount->mount_path);
+}
+
+const char *
+_win32_drive_type_to_icon (int type)
+{
+  switch (type)
+  {
+  case DRIVE_REMOVABLE : return "gtk-floppy";
+  case DRIVE_FIXED : return "gtk-harddisk";
+  case DRIVE_REMOTE : return "gtk-network"; 
+  case DRIVE_CDROM : return "gtk-cdrom";
+  default : return "gtk-directory";
+  }
+}
+
+static GIcon *
+g_win32_mount_get_icon (GMount *mount)
+{
+  GWin32Mount *win32_mount = G_WIN32_MOUNT (mount);
+
+  g_return_val_if_fail (win32_mount->mount_path != NULL, NULL);
+
+  /* lazy creation */
+  if (!win32_mount->icon)
+    {
+      SHFILEINFOW shfi;
+      wchar_t *wfn = g_utf8_to_utf16 (win32_mount->mount_path, -1, NULL, NULL, NULL);
+
+      if (SHGetFileInfoW (wfn, 0, &shfi, sizeof (shfi), SHGFI_ICONLOCATION))
+        {
+	  gchar *name = g_utf16_to_utf8 (shfi.szDisplayName, -1, NULL, NULL, NULL);
+	  gchar *id = g_strdup_printf ("%s,%i", name, shfi.iIcon);
+	  win32_mount->icon = g_themed_icon_new (id);
+	  g_free (name);
+	  g_free (id);
+	}
+      else
+        {
+          win32_mount->icon = g_themed_icon_new_with_default_fallbacks (
+	                        _win32_drive_type_to_icon (win32_mount->drive_type));
+	}
+    }
+
+  return g_object_ref (win32_mount->icon);
+}
+
+static char *
+g_win32_mount_get_uuid (GMount *mount)
+{
+  return NULL;
+}
+
+static char *
+g_win32_mount_get_name (GMount *mount)
+{
+  GWin32Mount *win32_mount = G_WIN32_MOUNT (mount);
+  
+  return g_strdup (win32_mount->name);
+}
+
+static GDrive *
+g_win32_mount_get_drive (GMount *mount)
+{
+  GWin32Mount *win32_mount = G_WIN32_MOUNT (mount);
+
+  if (win32_mount->volume != NULL)
+    return g_volume_get_drive (G_VOLUME (win32_mount->volume));
+
+  return NULL;
+}
+
+static GVolume *
+g_win32_mount_get_volume (GMount *mount)
+{
+  GWin32Mount *win32_mount = G_WIN32_MOUNT (mount);
+
+  if (win32_mount->volume)
+    return G_VOLUME (g_object_ref (win32_mount->volume));
+  
+  return NULL;
+}
+
+static gboolean
+g_win32_mount_can_unmount (GMount *mount)
+{
+  return FALSE;
+}
+
+static gboolean
+g_win32_mount_can_eject (GMount *mount)
+{
+  GWin32Mount *win32_mount = G_WIN32_MOUNT (mount);
+  return win32_mount->can_eject;
+}
+
+
+typedef struct {
+  GWin32Mount *win32_mount;
+  GAsyncReadyCallback callback;
+  gpointer user_data;
+  GCancellable *cancellable;
+  int error_fd;
+  GIOChannel *error_channel;
+  guint error_channel_source_id;
+  GString *error_string;
+} UnmountEjectOp;
+
+static void 
+eject_unmount_cb (GPid pid, gint status, gpointer user_data)
+{
+  UnmountEjectOp *data = user_data;
+  GSimpleAsyncResult *simple;
+
+#if 0  
+  if (WEXITSTATUS (status) != 0)
+    {
+      GError *error;
+      error = g_error_new_literal (G_IO_ERROR, 
+                                   G_IO_ERROR_FAILED,
+                                   data->error_string->str);
+      simple = g_simple_async_result_new_from_error (G_OBJECT (data->win32_mount),
+                                                     data->callback,
+                                                     data->user_data,
+                                                     error);
+      g_error_free (error);
+    }
+  else
+    {
+      simple = g_simple_async_result_new (G_OBJECT (data->win32_mount),
+                                          data->callback,
+                                          data->user_data,
+                                          NULL);
+    }
+
+  g_simple_async_result_complete (simple);
+  g_object_unref (simple);
+
+  g_source_remove (data->error_channel_source_id);
+  g_io_channel_unref (data->error_channel);
+  g_string_free (data->error_string, TRUE);
+  close (data->error_fd);
+  g_spawn_close_pid (pid);
+  g_free (data);
+#endif
+}
+
+static gboolean
+eject_unmount_read_error (GIOChannel *channel,
+                    GIOCondition condition,
+                    gpointer user_data)
+{
+  char *str;
+  gsize str_len;
+  UnmountEjectOp *data = user_data;
+
+  g_io_channel_read_to_end (channel, &str, &str_len, NULL);
+  g_string_append (data->error_string, str);
+  g_free (str);
+  return TRUE;
+}
+
+static void
+eject_unmount_do (GMount              *mount,
+                  GCancellable        *cancellable,
+                  GAsyncReadyCallback  callback,
+                  gpointer             user_data,
+                  char               **argv)
+{
+  GWin32Mount *win32_mount = G_WIN32_MOUNT (mount);
+}
+
+static void
+g_win32_mount_unmount (GMount             *mount,
+                      GMountUnmountFlags flags,
+                      GCancellable        *cancellable,
+                      GAsyncReadyCallback  callback,
+                      gpointer             user_data)
+{
+  GWin32Mount *win32_mount = G_WIN32_MOUNT (mount);
+}
+
+static gboolean
+g_win32_mount_unmount_finish (GMount       *mount,
+                             GAsyncResult  *result,
+                             GError       **error)
+{
+  return FALSE;
+}
+
+static void
+g_win32_mount_eject (GMount             *mount,
+                    GMountUnmountFlags flags,
+                    GCancellable        *cancellable,
+                    GAsyncReadyCallback  callback,
+                    gpointer             user_data)
+{
+  GWin32Mount *win32_mount = G_WIN32_MOUNT (mount);
+}
+
+static gboolean
+g_win32_mount_eject_finish (GMount       *mount,
+                           GAsyncResult  *result,
+                           GError       **error)
+{
+  return FALSE;
+}
+
+static void
+g_win32_mount_mount_iface_init (GMountIface *iface)
+{
+  iface->get_root = g_win32_mount_get_root;
+  iface->get_name = g_win32_mount_get_name;
+  iface->get_icon = g_win32_mount_get_icon;
+  iface->get_uuid = g_win32_mount_get_uuid;
+  iface->get_drive = g_win32_mount_get_drive;
+  iface->get_volume = g_win32_mount_get_volume;
+  iface->can_unmount = g_win32_mount_can_unmount;
+  iface->can_eject = g_win32_mount_can_eject;
+  iface->unmount = g_win32_mount_unmount;
+  iface->unmount_finish = g_win32_mount_unmount_finish;
+  iface->eject = g_win32_mount_eject;
+  iface->eject_finish = g_win32_mount_eject_finish;
+}

Added: trunk/gio/gwin32mount.h
==============================================================================
--- (empty file)
+++ trunk/gio/gwin32mount.h	Tue Jun 17 21:40:04 2008
@@ -0,0 +1,58 @@
+/* GIO - GLib Input, Output and Streaming Library
+ * 
+ * Copyright (C) 2006-2007 Red Hat, Inc.
+ * Copyright (C) 2008 Hans Breuer
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General
+ * Public License along with this library; if not, write to the
+ * Free Software Foundation, Inc., 59 Temple Place, Suite 330,
+ * Boston, MA 02111-1307, USA.
+ *
+ * Author: Alexander Larsson <alexl redhat com>
+ *         David Zeuthen <davidz redhat com>
+ *         Hans Breuer <hans breuer org>
+ */
+
+#ifndef __G_WIN32_MOUNT_H__
+#define __G_WIN32_MOUNT_H__
+
+#include <glib-object.h>
+#include <gio/gmount.h>
+#include <gio/gwin32volumemonitor.h>
+
+G_BEGIN_DECLS
+
+#define G_TYPE_WIN32_MOUNT        (_g_win32_mount_get_type ())
+#define G_WIN32_MOUNT(o)          (G_TYPE_CHECK_INSTANCE_CAST ((o), G_TYPE_WIN32_MOUNT, GWin32Mount))
+#define G_WIN32_MOUNT_CLASS(k)    (G_TYPE_CHECK_CLASS_CAST((k), G_TYPE_WIN32_MOUNT, GWin32MountClass))
+#define G_IS_WIN32_MOUNT(o)       (G_TYPE_CHECK_INSTANCE_TYPE ((o), G_TYPE_WIN32_MOUNT))
+#define G_IS_WIN32_MOUNT_CLASS(k) (G_TYPE_CHECK_CLASS_TYPE ((k), G_TYPE_WIN32_MOUNT))
+
+typedef struct _GWin32MountClass GWin32MountClass;
+
+struct _GWin32MountClass {
+   GObjectClass parent_class;
+};
+
+GType _g_win32_mount_get_type (void) G_GNUC_CONST;
+
+GWin32Mount *_g_win32_mount_new                    (GVolumeMonitor       *volume_monitor,
+                                                    const char           *path,
+                                                    GWin32Volume          *volume);
+void         _g_win32_mount_unset_volume          (GWin32Mount            *mount,
+                                                  GWin32Volume           *volume);
+void         _g_win32_mount_unmounted             (GWin32Mount           *mount);
+
+G_END_DECLS
+
+#endif /* __G_WIN32_MOUNT_H__ */

Added: trunk/gio/gwin32volumemonitor.c
==============================================================================
--- (empty file)
+++ trunk/gio/gwin32volumemonitor.c	Tue Jun 17 21:40:04 2008
@@ -0,0 +1,268 @@
+/* GIO - GLib Input, Output and Streaming Library
+ * 
+ * Copyright (C) 2006-2007 Red Hat, Inc.
+ * Copyright (C) 2008 Hans Breuer
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General
+ * Public License along with this library; if not, write to the
+ * Free Software Foundation, Inc., 59 Temple Place, Suite 330,
+ * Boston, MA 02111-1307, USA.
+ *
+ * Author: Alexander Larsson <alexl redhat com>
+ *         David Zeuthen <davidz redhat com>
+ *         Hans Breuer <hans breuer org>
+ */
+
+#include <config.h>
+
+#include <string.h>
+
+#include <glib.h>
+#include "glibintl.h"
+
+#include "gwin32volumemonitor.h"
+#include "gwin32mount.h"
+#include "giomodule.h"
+#include "gioalias.h"
+
+#define _WIN32_WINNT 0x0500
+#include <windows.h>
+
+struct _GWin32VolumeMonitor {
+  GNativeVolumeMonitor parent;
+
+  GList *volumes;
+  GList *mounts;
+};
+
+#define g_win32_volume_monitor_get_type _g_win32_volume_monitor_get_type
+G_DEFINE_TYPE_WITH_CODE (GWin32VolumeMonitor, g_win32_volume_monitor, G_TYPE_NATIVE_VOLUME_MONITOR,
+                         g_io_extension_point_implement (G_NATIVE_VOLUME_MONITOR_EXTENSION_POINT_NAME,
+							 g_define_type_id,
+							 "win32",
+							 0));
+							 
+static void
+g_win32_volume_monitor_finalize (GObject *object)
+{
+  GWin32VolumeMonitor *monitor;
+  
+  monitor = G_WIN32_VOLUME_MONITOR (object);
+
+  if (G_OBJECT_CLASS (g_win32_volume_monitor_parent_class)->finalize)
+    (*G_OBJECT_CLASS (g_win32_volume_monitor_parent_class)->finalize) (object);
+}
+
+/**
+ * get_viewable_logical_drives:
+ * 
+ * Returns the list of logical and viewable drives as defined by
+ * GetLogicalDrives() and the registry keys
+ * Software\Microsoft\Windows\CurrentVersion\Policies\Explorer under
+ * HKLM or HKCU. If neither key exists the result of
+ * GetLogicalDrives() is returned.
+ *
+ * Return value: bitmask with same meaning as returned by GetLogicalDrives()
+**/
+static guint32 
+get_viewable_logical_drives (void)
+{
+  guint viewable_drives = GetLogicalDrives ();
+  HKEY key;
+
+  DWORD var_type = REG_DWORD; //the value's a REG_DWORD type
+  DWORD no_drives_size = 4;
+  DWORD no_drives;
+  gboolean hklm_present = FALSE;
+
+  if (RegOpenKeyEx (HKEY_LOCAL_MACHINE,
+		    "Software\\Microsoft\\Windows\\"
+		    "CurrentVersion\\Policies\\Explorer",
+		    0, KEY_READ, &key) == ERROR_SUCCESS)
+    {
+      if (RegQueryValueEx (key, "NoDrives", NULL, &var_type,
+			   (LPBYTE) &no_drives, &no_drives_size) == ERROR_SUCCESS)
+	{
+	  /* We need the bits that are set in viewable_drives, and
+	   * unset in no_drives.
+	   */
+	  viewable_drives = viewable_drives & ~no_drives;
+	  hklm_present = TRUE;
+	}
+      RegCloseKey (key);
+    }
+
+  /* If the key is present in HKLM then the one in HKCU should be ignored */
+  if (!hklm_present)
+    {
+      if (RegOpenKeyEx (HKEY_CURRENT_USER,
+			"Software\\Microsoft\\Windows\\"
+			"CurrentVersion\\Policies\\Explorer",
+			0, KEY_READ, &key) == ERROR_SUCCESS)
+	{
+	  if (RegQueryValueEx (key, "NoDrives", NULL, &var_type,
+			       (LPBYTE) &no_drives, &no_drives_size) == ERROR_SUCCESS)
+	    {
+	      viewable_drives = viewable_drives & ~no_drives;
+	    }
+	  RegCloseKey (key);
+	}
+    }
+
+  return viewable_drives; 
+}
+
+/* deliver accesible (aka 'mounted') volumes */
+static GList *
+get_mounts (GVolumeMonitor *volume_monitor)
+{
+  GWin32VolumeMonitor *monitor;
+  DWORD   drives;
+  gchar   drive[4] = "A:\\";
+  GList *list = NULL;
+  
+  monitor = G_WIN32_VOLUME_MONITOR (volume_monitor);
+
+  drives = get_viewable_logical_drives ();
+
+  if (!drives)
+    g_warning ("get_viewable_logical_drives failed.");
+
+  while (drives && drive[0] <= 'Z')
+    {
+      if (drives & 1)
+      {
+	list = g_list_prepend (list, _g_win32_mount_new (volume_monitor, drive, NULL));
+      }
+      drives >>= 1;
+      drive[0]++;
+    }
+  return list;
+}
+
+/* actually 'mounting' volumes is out of GIOs business on win32, so no volumes are delivered either */
+static GList *
+get_volumes (GVolumeMonitor *volume_monitor)
+{
+  GWin32VolumeMonitor *monitor;
+  GList *l = NULL;
+  
+  monitor = G_WIN32_VOLUME_MONITOR (volume_monitor);
+
+  return l;
+}
+
+/* real hardware */
+static GList *
+get_connected_drives (GVolumeMonitor *volume_monitor)
+{
+  GWin32VolumeMonitor *monitor;
+  HANDLE  find_handle;
+  BOOL    found;
+  wchar_t wc_name[MAX_PATH+1];
+  GList *list = NULL;
+  
+  monitor = G_WIN32_VOLUME_MONITOR (volume_monitor);
+
+  find_handle = FindFirstVolumeW (wc_name, MAX_PATH);
+  found = (find_handle != INVALID_HANDLE_VALUE);
+  while (found)
+    {
+      wchar_t wc_dev_name[MAX_PATH+1];
+      guint trailing = wcslen(wc_name) - 1;
+
+      /* remove trailing backslash and leading \\?\\ */
+      wc_name[trailing] = L'\0';
+      if (QueryDosDeviceW(&wc_name[4], wc_dev_name, MAX_PATH))
+        {
+          gchar *name = g_utf16_to_utf8 (wc_dev_name, -1, NULL, NULL, NULL);
+          g_print ("%s\n", name);
+	  g_free (name);
+	}
+
+      found = FindNextVolumeW (find_handle, wc_name, MAX_PATH);
+    }
+  if (find_handle != INVALID_HANDLE_VALUE)
+    FindVolumeClose (find_handle);
+
+  return list;
+}
+
+static GVolume *
+get_volume_for_uuid (GVolumeMonitor *volume_monitor, const char *uuid)
+{
+  return NULL;
+}
+
+static GMount *
+get_mount_for_uuid (GVolumeMonitor *volume_monitor, const char *uuid)
+{
+  return NULL;
+}
+
+static gboolean
+is_supported (void)
+{
+  return TRUE;
+}
+
+static GMount *
+get_mount_for_mount_path (const char *mount_path,
+                          GCancellable *cancellable)
+{
+  GWin32Mount *mount;
+
+  /* TODO: Set mountable volume? */
+  mount = _g_win32_mount_new (NULL, mount_path, NULL);
+
+  return G_MOUNT (mount);
+}
+
+static void
+g_win32_volume_monitor_class_init (GWin32VolumeMonitorClass *klass)
+{
+  GObjectClass *gobject_class = G_OBJECT_CLASS (klass);
+  GVolumeMonitorClass *monitor_class = G_VOLUME_MONITOR_CLASS (klass);
+  GNativeVolumeMonitorClass *native_class = G_NATIVE_VOLUME_MONITOR_CLASS (klass);
+  
+  gobject_class->finalize = g_win32_volume_monitor_finalize;
+
+  monitor_class->get_mounts = get_mounts;
+  monitor_class->get_volumes = get_volumes;
+  monitor_class->get_connected_drives = get_connected_drives;
+  monitor_class->get_volume_for_uuid = get_volume_for_uuid;
+  monitor_class->get_mount_for_uuid = get_mount_for_uuid;
+  monitor_class->is_supported = is_supported;
+
+  native_class->get_mount_for_mount_path = get_mount_for_mount_path;
+}
+
+static void
+g_win32_volume_monitor_init (GWin32VolumeMonitor *win32_monitor)
+{
+  /* maybe we shoud setup a callback window to listern for WM_DEVICECHANGE ? */
+#if 0
+  unix_monitor->mount_monitor = g_win32_mount_monitor_new ();
+
+  g_signal_connect (win32_monitor->mount_monitor,
+		    "mounts_changed", G_CALLBACK (mounts_changed),
+		    win32_monitor);
+  
+  g_signal_connect (win32_monitor->mount_monitor,
+		    "mountpoints_changed", G_CALLBACK (mountpoints_changed),
+		    win32_monitor);
+		    
+  update_volumes (win32_monitor);
+  update_mounts (win32_monitor);
+#endif
+}

Added: trunk/gio/gwin32volumemonitor.h
==============================================================================
--- (empty file)
+++ trunk/gio/gwin32volumemonitor.h	Tue Jun 17 21:40:04 2008
@@ -0,0 +1,132 @@
+/* GIO - GLib Input, Output and Streaming Library
+ * 
+ * Copyright (C) 2006-2007 Red Hat, Inc.
+ * Copyright (C) 2008 Hans Breuer
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General
+ * Public License along with this library; if not, write to the
+ * Free Software Foundation, Inc., 59 Temple Place, Suite 330,
+ * Boston, MA 02111-1307, USA.
+ *
+ * Author: Alexander Larsson <alexl redhat com>
+ *         David Zeuthen <davidz redhat com>
+ *         Hans Breuer <hans breuer org>
+ */
+
+#ifndef __G_WIN32_VOLUME_MONITOR_H__
+#define __G_WIN32_VOLUME_MONITOR_H__
+
+#include <glib-object.h>
+#include <gio/gnativevolumemonitor.h>
+
+G_BEGIN_DECLS
+
+#define G_TYPE_WIN32_VOLUME_MONITOR        (_g_win32_volume_monitor_get_type ())
+#define G_WIN32_VOLUME_MONITOR(o)          (G_TYPE_CHECK_INSTANCE_CAST ((o), G_TYPE_WIN32_VOLUME_MONITOR, GWin32VolumeMonitor))
+#define G_WIN32_VOLUME_MONITOR_CLASS(k)    (G_TYPE_CHECK_CLASS_CAST((k), G_TYPE_WIN32_VOLUME_MONITOR, GWin32VolumeMonitorClass))
+#define G_IS_WIN32_VOLUME_MONITOR(o)       (G_TYPE_CHECK_INSTANCE_TYPE ((o), G_TYPE_WIN32_VOLUME_MONITOR))
+#define G_IS_WIN32_VOLUME_MONITOR_CLASS(k) (G_TYPE_CHECK_CLASS_TYPE ((k), G_TYPE_WIN32_VOLUME_MONITOR))
+
+typedef struct _GWin32VolumeMonitor GWin32VolumeMonitor;
+typedef struct _GWin32VolumeMonitorClass GWin32VolumeMonitorClass;
+
+/* Forward definitions */
+
+/**
+ * GWin32Mount:
+ *
+ * Implementation of the #GMount interface for Win32 systems.
+ */
+typedef struct _GWin32Mount GWin32Mount;
+typedef struct _GWin32Volume GWin32Volume;
+
+struct _GWin32VolumeMonitorClass {
+  GNativeVolumeMonitorClass parent_class;
+
+};
+
+GType _g_win32_volume_monitor_get_type (void) G_GNUC_CONST;
+
+GVolumeMonitor * _g_win32_volume_monitor_new                          (void);
+GWin32Volume *    _g_win32_volume_monitor_lookup_volume_for_mount_path (GWin32VolumeMonitor *monitor,
+                                                                      const char         *mount_path);
+
+G_END_DECLS
+
+#endif /* __G_WIN32_VOLUME_MONITOR_H__ */
+/* GIO - GLib Input, Output and Streaming Library
+ * 
+ * Copyright (C) 2006-2007 Red Hat, Inc.
+ * Copyright (C) 2008 Hans Breuer
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General
+ * Public License along with this library; if not, write to the
+ * Free Software Foundation, Inc., 59 Temple Place, Suite 330,
+ * Boston, MA 02111-1307, USA.
+ *
+ * Author: Alexander Larsson <alexl redhat com>
+ *         David Zeuthen <davidz redhat com>
+ *         Hans Breuer <hans breuer org>
+ */
+
+#ifndef __G_WIN32_VOLUME_MONITOR_H__
+#define __G_WIN32_VOLUME_MONITOR_H__
+
+#include <glib-object.h>
+#include <gio/gnativevolumemonitor.h>
+
+G_BEGIN_DECLS
+
+#define G_TYPE_WIN32_VOLUME_MONITOR        (_g_win32_volume_monitor_get_type ())
+#define G_WIN32_VOLUME_MONITOR(o)          (G_TYPE_CHECK_INSTANCE_CAST ((o), G_TYPE_WIN32_VOLUME_MONITOR, GWin32VolumeMonitor))
+#define G_WIN32_VOLUME_MONITOR_CLASS(k)    (G_TYPE_CHECK_CLASS_CAST((k), G_TYPE_WIN32_VOLUME_MONITOR, GWin32VolumeMonitorClass))
+#define G_IS_WIN32_VOLUME_MONITOR(o)       (G_TYPE_CHECK_INSTANCE_TYPE ((o), G_TYPE_WIN32_VOLUME_MONITOR))
+#define G_IS_WIN32_VOLUME_MONITOR_CLASS(k) (G_TYPE_CHECK_CLASS_TYPE ((k), G_TYPE_WIN32_VOLUME_MONITOR))
+
+typedef struct _GWin32VolumeMonitor GWin32VolumeMonitor;
+typedef struct _GWin32VolumeMonitorClass GWin32VolumeMonitorClass;
+
+/* Forward definitions */
+
+/**
+ * GWin32Mount:
+ *
+ * Implementation of the #GMount interface for Win32 systems.
+ */
+typedef struct _GWin32Mount GWin32Mount;
+typedef struct _GWin32Volume GWin32Volume;
+
+struct _GWin32VolumeMonitorClass {
+  GNativeVolumeMonitorClass parent_class;
+
+};
+
+GType _g_win32_volume_monitor_get_type (void) G_GNUC_CONST;
+
+GVolumeMonitor * _g_win32_volume_monitor_new                          (void);
+GWin32Volume *    _g_win32_volume_monitor_lookup_volume_for_mount_path (GWin32VolumeMonitor *monitor,
+                                                                      const char         *mount_path);
+
+G_END_DECLS
+
+#endif /* __G_WIN32_VOLUME_MONITOR_H__ */

Modified: trunk/gio/makefile.msc
==============================================================================
--- trunk/gio/makefile.msc	(original)
+++ trunk/gio/makefile.msc	Tue Jun 17 21:40:04 2008
@@ -130,7 +130,10 @@
 	gwin32appinfo.obj \
 	\
 	gio-marshal.obj \
-	gwin32directorymonitor.obj
+	gwin32directorymonitor.obj \
+	gwin32mount.obj \
+#	gwin32volume.obj \
+	gwin32volumemonitor.obj
 
 libgio_2_0_la_LIBADD = \
 	$(top_builddir)/glib/libglib-2.0.la \
@@ -258,7 +261,7 @@
 	$(CC) $(CFLAGS) -LD -Felibgio-$(PKG_VER).dll $(OBJECTS) \
 	..\glib\glib-2.0.lib ..\gobject\gobject-2.0.lib ..\gmodule\gmodule-2.0.lib \
 	$(INTL_LIBS) \
-	kernel32.lib user32.lib advapi32.lib shell32.lib wsock32.lib $(LDFLAGS) \
+	kernel32.lib user32.lib advapi32.lib shell32.lib wsock32.lib mpr.lib $(LDFLAGS) \
 	/implib:gio-2.0.lib /def:$(PACKAGE).def
 
 .c.obj :



[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]