1 /* GIO - GLib Input, Output and Streaming Library
3 * Copyright (C) 2006-2007 Red Hat, Inc.
4 * Copyright (C) 2008 Hans Breuer
6 * This library is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU Lesser General Public
8 * License as published by the Free Software Foundation; either
9 * version 2 of the License, or (at your option) any later version.
11 * This library is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * Lesser General Public License for more details.
16 * You should have received a copy of the GNU Lesser General
17 * Public License along with this library; if not, write to the
18 * Free Software Foundation, Inc., 59 Temple Place, Suite 330,
19 * Boston, MA 02111-1307, USA.
21 * Author: Alexander Larsson <alexl@redhat.com>
22 * David Zeuthen <davidz@redhat.com>
23 * Hans Breuer <hans@breuer.org>
29 #define WIN32_MEAN_AND_LEAN
33 #include "gwin32volumemonitor.h"
34 #include "gwin32mount.h"
37 #include "gmountprivate.h"
38 #include "gvolumemonitor.h"
39 #include "gthemedicon.h"
40 #include "gsimpleasyncresult.h"
47 GVolumeMonitor
*volume_monitor
;
49 GWin32Volume
*volume
; /* owned by volume monitor */
52 /* why does all this stuff need to be duplicated? It is in volume already! */
60 static void g_win32_mount_mount_iface_init (GMountIface
*iface
);
62 #define g_win32_mount_get_type _g_win32_mount_get_type
63 G_DEFINE_TYPE_WITH_CODE (GWin32Mount
, g_win32_mount
, G_TYPE_OBJECT
,
64 G_IMPLEMENT_INTERFACE (G_TYPE_MOUNT
,
65 g_win32_mount_mount_iface_init
))
69 g_win32_mount_finalize (GObject
*object
)
73 mount
= G_WIN32_MOUNT (object
);
75 if (mount
->volume_monitor
!= NULL
)
76 g_object_unref (mount
->volume_monitor
);
79 _g_win32_volume_unset_mount (mount
->volume
, mount
);
81 /* TODO: g_warn_if_fail (volume->volume == NULL); */
83 if (mount
->icon
!= NULL
)
84 g_object_unref (mount
->icon
);
87 g_free (mount
->mount_path
);
89 if (G_OBJECT_CLASS (g_win32_mount_parent_class
)->finalize
)
90 (*G_OBJECT_CLASS (g_win32_mount_parent_class
)->finalize
) (object
);
94 g_win32_mount_class_init (GWin32MountClass
*klass
)
96 GObjectClass
*gobject_class
= G_OBJECT_CLASS (klass
);
98 gobject_class
->finalize
= g_win32_mount_finalize
;
102 g_win32_mount_init (GWin32Mount
*win32_mount
)
107 _win32_get_displayname (const char *drive
)
109 gunichar2
*wdrive
= g_utf8_to_utf16 (drive
, -1, NULL
, NULL
, NULL
);
112 if (SHGetFileInfoW(wdrive
, 0, &sfi
, sizeof(sfi
), SHGFI_DISPLAYNAME
))
113 name
= g_utf16_to_utf8 (sfi
.szDisplayName
, -1, NULL
, NULL
, NULL
);
116 return name
? name
: g_strdup (drive
);
120 * _g_win32_mount_new:
121 * @volume_monitor: a #GVolumeMonitor.
122 * @path: a win32 path.
123 * @volume: usually NULL
125 * Returns: a #GWin32Mount for the given win32 path.
128 _g_win32_mount_new (GVolumeMonitor
*volume_monitor
,
130 GWin32Volume
*volume
)
133 const gchar
*drive
= path
; //fixme
136 /* No volume for mount: Ignore internal things */
137 if (volume
== NULL
&& !g_win32_mount_guess_should_display (mount_entry
))
141 mount
= g_object_new (G_TYPE_WIN32_MOUNT
, NULL
);
142 mount
->volume_monitor
= volume_monitor
!= NULL
? g_object_ref (volume_monitor
) : NULL
;
143 mount
->mount_path
= g_strdup (path
);
144 mount
->drive_type
= GetDriveType (drive
);
145 mount
->can_eject
= FALSE
; /* TODO */
146 mount
->name
= _win32_get_displayname (drive
);
148 /* need to do this last */
149 mount
->volume
= volume
;
152 _g_win32_volume_set_mount (volume
, mount
);
158 _g_win32_mount_unmounted (GWin32Mount
*mount
)
160 if (mount
->volume
!= NULL
)
163 _g_win32_volume_unset_mount (mount
->volume
, mount
);
165 mount
->volume
= NULL
;
166 g_signal_emit_by_name (mount
, "changed");
167 /* there's really no need to emit mount_changed on the volume monitor
168 * as we're going to be deleted.. */
173 _g_win32_mount_unset_volume (GWin32Mount
*mount
,
174 GWin32Volume
*volume
)
176 if (mount
->volume
== volume
)
178 mount
->volume
= NULL
;
179 /* TODO: Emit changed in idle to avoid locking issues */
180 g_signal_emit_by_name (mount
, "changed");
181 if (mount
->volume_monitor
!= NULL
)
182 g_signal_emit_by_name (mount
->volume_monitor
, "mount-changed", mount
);
187 g_win32_mount_get_root (GMount
*mount
)
189 GWin32Mount
*win32_mount
= G_WIN32_MOUNT (mount
);
191 return g_file_new_for_path (win32_mount
->mount_path
);
195 _win32_drive_type_to_icon (int type
)
199 case DRIVE_REMOVABLE
: return "gtk-floppy";
200 case DRIVE_FIXED
: return "gtk-harddisk";
201 case DRIVE_REMOTE
: return "gtk-network";
202 case DRIVE_CDROM
: return "gtk-cdrom";
203 default : return "gtk-directory";
208 g_win32_mount_get_icon (GMount
*mount
)
210 GWin32Mount
*win32_mount
= G_WIN32_MOUNT (mount
);
212 g_return_val_if_fail (win32_mount
->mount_path
!= NULL
, NULL
);
215 if (!win32_mount
->icon
)
218 wchar_t *wfn
= g_utf8_to_utf16 (win32_mount
->mount_path
, -1, NULL
, NULL
, NULL
);
220 if (SHGetFileInfoW (wfn
, 0, &shfi
, sizeof (shfi
), SHGFI_ICONLOCATION
))
222 gchar
*name
= g_utf16_to_utf8 (shfi
.szDisplayName
, -1, NULL
, NULL
, NULL
);
223 gchar
*id
= g_strdup_printf ("%s,%i", name
, shfi
.iIcon
);
224 win32_mount
->icon
= g_themed_icon_new (id
);
230 win32_mount
->icon
= g_themed_icon_new_with_default_fallbacks (
231 _win32_drive_type_to_icon (win32_mount
->drive_type
));
235 return g_object_ref (win32_mount
->icon
);
239 g_win32_mount_get_uuid (GMount
*mount
)
245 g_win32_mount_get_name (GMount
*mount
)
247 GWin32Mount
*win32_mount
= G_WIN32_MOUNT (mount
);
249 return g_strdup (win32_mount
->name
);
253 g_win32_mount_get_drive (GMount
*mount
)
255 GWin32Mount
*win32_mount
= G_WIN32_MOUNT (mount
);
257 if (win32_mount
->volume
!= NULL
)
258 return g_volume_get_drive (G_VOLUME (win32_mount
->volume
));
264 g_win32_mount_get_volume (GMount
*mount
)
266 GWin32Mount
*win32_mount
= G_WIN32_MOUNT (mount
);
268 if (win32_mount
->volume
)
269 return G_VOLUME (g_object_ref (win32_mount
->volume
));
275 g_win32_mount_can_unmount (GMount
*mount
)
281 g_win32_mount_can_eject (GMount
*mount
)
283 GWin32Mount
*win32_mount
= G_WIN32_MOUNT (mount
);
284 return win32_mount
->can_eject
;
289 GWin32Mount
*win32_mount
;
290 GAsyncReadyCallback callback
;
292 GCancellable
*cancellable
;
294 GIOChannel
*error_channel
;
295 guint error_channel_source_id
;
296 GString
*error_string
;
300 g_win32_mount_unmount (GMount
*mount
,
301 GMountUnmountFlags flags
,
302 GCancellable
*cancellable
,
303 GAsyncReadyCallback callback
,
309 g_win32_mount_unmount_finish (GMount
*mount
,
310 GAsyncResult
*result
,
317 g_win32_mount_eject (GMount
*mount
,
318 GMountUnmountFlags flags
,
319 GCancellable
*cancellable
,
320 GAsyncReadyCallback callback
,
326 g_win32_mount_eject_finish (GMount
*mount
,
327 GAsyncResult
*result
,
334 g_win32_mount_mount_iface_init (GMountIface
*iface
)
336 iface
->get_root
= g_win32_mount_get_root
;
337 iface
->get_name
= g_win32_mount_get_name
;
338 iface
->get_icon
= g_win32_mount_get_icon
;
339 iface
->get_uuid
= g_win32_mount_get_uuid
;
340 iface
->get_drive
= g_win32_mount_get_drive
;
341 iface
->get_volume
= g_win32_mount_get_volume
;
342 iface
->can_unmount
= g_win32_mount_can_unmount
;
343 iface
->can_eject
= g_win32_mount_can_eject
;
344 iface
->unmount
= g_win32_mount_unmount
;
345 iface
->unmount_finish
= g_win32_mount_unmount_finish
;
346 iface
->eject
= g_win32_mount_eject
;
347 iface
->eject_finish
= g_win32_mount_eject_finish
;