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.1 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, see <http://www.gnu.org/licenses/>.
19 * Author: Alexander Larsson <alexl@redhat.com>
20 * David Zeuthen <davidz@redhat.com>
21 * Hans Breuer <hans@breuer.org>
27 #define WIN32_MEAN_AND_LEAN
31 #include "gwin32volumemonitor.h"
32 #include "gwin32mount.h"
35 #include "gmountprivate.h"
36 #include "gvolumemonitor.h"
37 #include "gthemedicon.h"
44 GVolumeMonitor
*volume_monitor
;
46 GWin32Volume
*volume
; /* owned by volume monitor */
49 /* why does all this stuff need to be duplicated? It is in volume already! */
58 static void g_win32_mount_mount_iface_init (GMountIface
*iface
);
60 #define g_win32_mount_get_type _g_win32_mount_get_type
61 G_DEFINE_TYPE_WITH_CODE (GWin32Mount
, g_win32_mount
, G_TYPE_OBJECT
,
62 G_IMPLEMENT_INTERFACE (G_TYPE_MOUNT
,
63 g_win32_mount_mount_iface_init
))
67 g_win32_mount_finalize (GObject
*object
)
71 mount
= G_WIN32_MOUNT (object
);
73 if (mount
->volume_monitor
!= NULL
)
74 g_object_unref (mount
->volume_monitor
);
77 _g_win32_volume_unset_mount (mount
->volume
, mount
);
79 /* TODO: g_warn_if_fail (volume->volume == NULL); */
81 if (mount
->icon
!= NULL
)
82 g_object_unref (mount
->icon
);
83 if (mount
->symbolic_icon
!= NULL
)
84 g_object_unref (mount
->symbolic_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
, gboolean use_symbolic
)
199 case DRIVE_REMOVABLE
: return use_symbolic
? "drive-removable-media-symbolic" : "drive-removable-media";
200 case DRIVE_FIXED
: return use_symbolic
? "drive-harddisk-symbolic" : "drive-harddisk";
201 case DRIVE_REMOTE
: return use_symbolic
? "folder-remote-symbolic" : "folder-remote";
202 case DRIVE_CDROM
: return use_symbolic
? "drive-optical-symbolic" : "drive-optical";
203 default : return use_symbolic
? "folder-symbolic" : "folder";
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 (_win32_drive_type_to_icon (win32_mount
->drive_type
, FALSE
));
234 return g_object_ref (win32_mount
->icon
);
238 g_win32_mount_get_symbolic_icon (GMount
*mount
)
240 GWin32Mount
*win32_mount
= G_WIN32_MOUNT (mount
);
242 g_return_val_if_fail (win32_mount
->mount_path
!= NULL
, NULL
);
245 if (!win32_mount
->symbolic_icon
)
247 win32_mount
->symbolic_icon
= g_themed_icon_new_with_default_fallbacks (_win32_drive_type_to_icon (win32_mount
->drive_type
, TRUE
));
250 return g_object_ref (win32_mount
->symbolic_icon
);
254 g_win32_mount_get_uuid (GMount
*mount
)
260 g_win32_mount_get_name (GMount
*mount
)
262 GWin32Mount
*win32_mount
= G_WIN32_MOUNT (mount
);
264 return g_strdup (win32_mount
->name
);
268 g_win32_mount_get_drive (GMount
*mount
)
270 GWin32Mount
*win32_mount
= G_WIN32_MOUNT (mount
);
272 if (win32_mount
->volume
!= NULL
)
273 return g_volume_get_drive (G_VOLUME (win32_mount
->volume
));
279 g_win32_mount_get_volume (GMount
*mount
)
281 GWin32Mount
*win32_mount
= G_WIN32_MOUNT (mount
);
283 if (win32_mount
->volume
)
284 return G_VOLUME (g_object_ref (win32_mount
->volume
));
290 g_win32_mount_can_unmount (GMount
*mount
)
296 g_win32_mount_can_eject (GMount
*mount
)
298 GWin32Mount
*win32_mount
= G_WIN32_MOUNT (mount
);
299 return win32_mount
->can_eject
;
304 GWin32Mount
*win32_mount
;
305 GAsyncReadyCallback callback
;
307 GCancellable
*cancellable
;
309 GIOChannel
*error_channel
;
310 guint error_channel_source_id
;
311 GString
*error_string
;
315 g_win32_mount_unmount (GMount
*mount
,
316 GMountUnmountFlags flags
,
317 GCancellable
*cancellable
,
318 GAsyncReadyCallback callback
,
324 g_win32_mount_unmount_finish (GMount
*mount
,
325 GAsyncResult
*result
,
332 g_win32_mount_eject (GMount
*mount
,
333 GMountUnmountFlags flags
,
334 GCancellable
*cancellable
,
335 GAsyncReadyCallback callback
,
341 g_win32_mount_eject_finish (GMount
*mount
,
342 GAsyncResult
*result
,
349 g_win32_mount_mount_iface_init (GMountIface
*iface
)
351 iface
->get_root
= g_win32_mount_get_root
;
352 iface
->get_name
= g_win32_mount_get_name
;
353 iface
->get_icon
= g_win32_mount_get_icon
;
354 iface
->get_symbolic_icon
= g_win32_mount_get_symbolic_icon
;
355 iface
->get_uuid
= g_win32_mount_get_uuid
;
356 iface
->get_drive
= g_win32_mount_get_drive
;
357 iface
->get_volume
= g_win32_mount_get_volume
;
358 iface
->can_unmount
= g_win32_mount_can_unmount
;
359 iface
->can_eject
= g_win32_mount_can_eject
;
360 iface
->unmount
= g_win32_mount_unmount
;
361 iface
->unmount_finish
= g_win32_mount_unmount_finish
;
362 iface
->eject
= g_win32_mount_eject
;
363 iface
->eject_finish
= g_win32_mount_eject_finish
;