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! */
61 static void g_win32_mount_mount_iface_init (GMountIface
*iface
);
63 #define g_win32_mount_get_type _g_win32_mount_get_type
64 G_DEFINE_TYPE_WITH_CODE (GWin32Mount
, g_win32_mount
, G_TYPE_OBJECT
,
65 G_IMPLEMENT_INTERFACE (G_TYPE_MOUNT
,
66 g_win32_mount_mount_iface_init
))
70 g_win32_mount_finalize (GObject
*object
)
74 mount
= G_WIN32_MOUNT (object
);
76 if (mount
->volume_monitor
!= NULL
)
77 g_object_unref (mount
->volume_monitor
);
80 _g_win32_volume_unset_mount (mount
->volume
, mount
);
82 /* TODO: g_warn_if_fail (volume->volume == NULL); */
84 if (mount
->icon
!= NULL
)
85 g_object_unref (mount
->icon
);
86 if (mount
->symbolic_icon
!= NULL
)
87 g_object_unref (mount
->symbolic_icon
);
90 g_free (mount
->mount_path
);
92 if (G_OBJECT_CLASS (g_win32_mount_parent_class
)->finalize
)
93 (*G_OBJECT_CLASS (g_win32_mount_parent_class
)->finalize
) (object
);
97 g_win32_mount_class_init (GWin32MountClass
*klass
)
99 GObjectClass
*gobject_class
= G_OBJECT_CLASS (klass
);
101 gobject_class
->finalize
= g_win32_mount_finalize
;
105 g_win32_mount_init (GWin32Mount
*win32_mount
)
110 _win32_get_displayname (const char *drive
)
112 gunichar2
*wdrive
= g_utf8_to_utf16 (drive
, -1, NULL
, NULL
, NULL
);
115 if (SHGetFileInfoW(wdrive
, 0, &sfi
, sizeof(sfi
), SHGFI_DISPLAYNAME
))
116 name
= g_utf16_to_utf8 (sfi
.szDisplayName
, -1, NULL
, NULL
, NULL
);
119 return name
? name
: g_strdup (drive
);
123 * _g_win32_mount_new:
124 * @volume_monitor: a #GVolumeMonitor.
125 * @path: a win32 path.
126 * @volume: usually NULL
128 * Returns: a #GWin32Mount for the given win32 path.
131 _g_win32_mount_new (GVolumeMonitor
*volume_monitor
,
133 GWin32Volume
*volume
)
136 const gchar
*drive
= path
; //fixme
139 /* No volume for mount: Ignore internal things */
140 if (volume
== NULL
&& !g_win32_mount_guess_should_display (mount_entry
))
144 mount
= g_object_new (G_TYPE_WIN32_MOUNT
, NULL
);
145 mount
->volume_monitor
= volume_monitor
!= NULL
? g_object_ref (volume_monitor
) : NULL
;
146 mount
->mount_path
= g_strdup (path
);
147 mount
->drive_type
= GetDriveType (drive
);
148 mount
->can_eject
= FALSE
; /* TODO */
149 mount
->name
= _win32_get_displayname (drive
);
151 /* need to do this last */
152 mount
->volume
= volume
;
155 _g_win32_volume_set_mount (volume
, mount
);
161 _g_win32_mount_unmounted (GWin32Mount
*mount
)
163 if (mount
->volume
!= NULL
)
166 _g_win32_volume_unset_mount (mount
->volume
, mount
);
168 mount
->volume
= NULL
;
169 g_signal_emit_by_name (mount
, "changed");
170 /* there's really no need to emit mount_changed on the volume monitor
171 * as we're going to be deleted.. */
176 _g_win32_mount_unset_volume (GWin32Mount
*mount
,
177 GWin32Volume
*volume
)
179 if (mount
->volume
== volume
)
181 mount
->volume
= NULL
;
182 /* TODO: Emit changed in idle to avoid locking issues */
183 g_signal_emit_by_name (mount
, "changed");
184 if (mount
->volume_monitor
!= NULL
)
185 g_signal_emit_by_name (mount
->volume_monitor
, "mount-changed", mount
);
190 g_win32_mount_get_root (GMount
*mount
)
192 GWin32Mount
*win32_mount
= G_WIN32_MOUNT (mount
);
194 return g_file_new_for_path (win32_mount
->mount_path
);
198 _win32_drive_type_to_icon (int type
, gboolean use_symbolic
)
202 case DRIVE_REMOVABLE
: return use_symbolic
? "drive-removable-media-symbolic" : "drive-removable-media";
203 case DRIVE_FIXED
: return use_symbolic
? "drive-harddisk-symbolic" : "drive-harddisk";
204 case DRIVE_REMOTE
: return use_symbolic
? "folder-remote-symbolic" : "folder-remote";
205 case DRIVE_CDROM
: return use_symbolic
? "drive-optical-symbolic" : "drive-optical";
206 default : return use_symbolic
? "folder-symbolic" : "folder";
211 g_win32_mount_get_icon (GMount
*mount
)
213 GWin32Mount
*win32_mount
= G_WIN32_MOUNT (mount
);
215 g_return_val_if_fail (win32_mount
->mount_path
!= NULL
, NULL
);
218 if (!win32_mount
->icon
)
221 wchar_t *wfn
= g_utf8_to_utf16 (win32_mount
->mount_path
, -1, NULL
, NULL
, NULL
);
223 if (SHGetFileInfoW (wfn
, 0, &shfi
, sizeof (shfi
), SHGFI_ICONLOCATION
))
225 gchar
*name
= g_utf16_to_utf8 (shfi
.szDisplayName
, -1, NULL
, NULL
, NULL
);
226 gchar
*id
= g_strdup_printf ("%s,%i", name
, shfi
.iIcon
);
227 win32_mount
->icon
= g_themed_icon_new (id
);
233 win32_mount
->icon
= g_themed_icon_new_with_default_fallbacks (_win32_drive_type_to_icon (win32_mount
->drive_type
, FALSE
));
237 return g_object_ref (win32_mount
->icon
);
241 g_win32_mount_get_symbolic_icon (GMount
*mount
)
243 GWin32Mount
*win32_mount
= G_WIN32_MOUNT (mount
);
245 g_return_val_if_fail (win32_mount
->mount_path
!= NULL
, NULL
);
248 if (!win32_mount
->symbolic_icon
)
250 win32_mount
->symbolic_icon
= g_themed_icon_new_with_default_fallbacks (_win32_drive_type_to_icon (win32_mount
->drive_type
, TRUE
));
253 return g_object_ref (win32_mount
->symbolic_icon
);
257 g_win32_mount_get_uuid (GMount
*mount
)
263 g_win32_mount_get_name (GMount
*mount
)
265 GWin32Mount
*win32_mount
= G_WIN32_MOUNT (mount
);
267 return g_strdup (win32_mount
->name
);
271 g_win32_mount_get_drive (GMount
*mount
)
273 GWin32Mount
*win32_mount
= G_WIN32_MOUNT (mount
);
275 if (win32_mount
->volume
!= NULL
)
276 return g_volume_get_drive (G_VOLUME (win32_mount
->volume
));
282 g_win32_mount_get_volume (GMount
*mount
)
284 GWin32Mount
*win32_mount
= G_WIN32_MOUNT (mount
);
286 if (win32_mount
->volume
)
287 return G_VOLUME (g_object_ref (win32_mount
->volume
));
293 g_win32_mount_can_unmount (GMount
*mount
)
299 g_win32_mount_can_eject (GMount
*mount
)
301 GWin32Mount
*win32_mount
= G_WIN32_MOUNT (mount
);
302 return win32_mount
->can_eject
;
307 GWin32Mount
*win32_mount
;
308 GAsyncReadyCallback callback
;
310 GCancellable
*cancellable
;
312 GIOChannel
*error_channel
;
313 guint error_channel_source_id
;
314 GString
*error_string
;
318 g_win32_mount_unmount (GMount
*mount
,
319 GMountUnmountFlags flags
,
320 GCancellable
*cancellable
,
321 GAsyncReadyCallback callback
,
327 g_win32_mount_unmount_finish (GMount
*mount
,
328 GAsyncResult
*result
,
335 g_win32_mount_eject (GMount
*mount
,
336 GMountUnmountFlags flags
,
337 GCancellable
*cancellable
,
338 GAsyncReadyCallback callback
,
344 g_win32_mount_eject_finish (GMount
*mount
,
345 GAsyncResult
*result
,
352 g_win32_mount_mount_iface_init (GMountIface
*iface
)
354 iface
->get_root
= g_win32_mount_get_root
;
355 iface
->get_name
= g_win32_mount_get_name
;
356 iface
->get_icon
= g_win32_mount_get_icon
;
357 iface
->get_symbolic_icon
= g_win32_mount_get_symbolic_icon
;
358 iface
->get_uuid
= g_win32_mount_get_uuid
;
359 iface
->get_drive
= g_win32_mount_get_drive
;
360 iface
->get_volume
= g_win32_mount_get_volume
;
361 iface
->can_unmount
= g_win32_mount_can_unmount
;
362 iface
->can_eject
= g_win32_mount_can_eject
;
363 iface
->unmount
= g_win32_mount_unmount
;
364 iface
->unmount_finish
= g_win32_mount_unmount_finish
;
365 iface
->eject
= g_win32_mount_eject
;
366 iface
->eject_finish
= g_win32_mount_eject_finish
;