1 // g-udisks-device.c
2 //
3 // Copyright 2010 Hong Jen Yee (PCMan) <pcman.tw@gmail.com>
4 //
5 // This program is free software; you can redistribute it and/or modify
6 // it under the terms of the GNU General Public License as published by
7 // the Free Software Foundation; either version 2 of the License, or
8 // (at your option) any later version.
9 //
10 // This program is distributed in the hope that it will be useful,
11 // but WITHOUT ANY WARRANTY; without even the implied warranty of
12 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 // GNU General Public License for more details.
14 //
15 // You should have received a copy of the GNU General Public License
16 // along with this program; if not, write to the Free Software
17 // Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
18 // MA 02110-1301, USA.
19
20 #ifdef HAVE_CONFIG_H
21 #include <config.h>
22 #endif
23
24 #include "g-udisks-device.h"
25 #include "dbus-utils.h"
26 #include "udisks-device.h"
27 #include <string.h>
28 #include <glib/gi18n-lib.h>
29
30 /* This array is taken from gnome-disk-utility: gdu-volume.c
31 * Copyright (C) 2007 David Zeuthen, licensed under GNU LGPL
32 */
33 static const struct
34 {
35 const char *disc_type;
36 const char *icon_name;
37 const char *ui_name;
38 const char *ui_name_blank;
39 } disc_data[] = {
40 /* Translator: The word "blank" is used as an adjective, e.g. we are decsribing discs that are already blank */
41 {"optical_cd", "media-optical-cd-rom", N_("CD-ROM Disc"), N_("Blank CD-ROM Disc")},
42 {"optical_cd_r", "media-optical-cd-r", N_("CD-R Disc"), N_("Blank CD-R Disc")},
43 {"optical_cd_rw", "media-optical-cd-rw", N_("CD-RW Disc"), N_("Blank CD-RW Disc")},
44 {"optical_dvd", "media-optical-dvd-rom", N_("DVD-ROM Disc"), N_("Blank DVD-ROM Disc")},
45 {"optical_dvd_r", "media-optical-dvd-r", N_("DVD-ROM Disc"), N_("Blank DVD-ROM Disc")},
46 {"optical_dvd_rw", "media-optical-dvd-rw", N_("DVD-RW Disc"), N_("Blank DVD-RW Disc")},
47 {"optical_dvd_ram", "media-optical-dvd-ram", N_("DVD-RAM Disc"), N_("Blank DVD-RAM Disc")},
48 {"optical_dvd_plus_r", "media-optical-dvd-r-plus", N_("DVD+R Disc"), N_("Blank DVD+R Disc")},
49 {"optical_dvd_plus_rw", "media-optical-dvd-rw-plus", N_("DVD+RW Disc"), N_("Blank DVD+RW Disc")},
50 {"optical_dvd_plus_r_dl", "media-optical-dvd-dl-r-plus", N_("DVD+R DL Disc"), N_("Blank DVD+R DL Disc")},
51 {"optical_dvd_plus_rw_dl", "media-optical-dvd-dl-r-plus", N_("DVD+RW DL Disc"), N_("Blank DVD+RW DL Disc")},
52 {"optical_bd", "media-optical-bd-rom", N_("Blu-Ray Disc"), N_("Blank Blu-Ray Disc")},
53 {"optical_bd_r", "media-optical-bd-r", N_("Blu-Ray R Disc"), N_("Blank Blu-Ray R Disc")},
54 {"optical_bd_re", "media-optical-bd-re", N_("Blu-Ray RW Disc"), N_("Blank Blu-Ray RW Disc")},
55 {"optical_hddvd", "media-optical-hddvd-rom", N_("HD DVD Disc"), N_("Blank HD DVD Disc")},
56 {"optical_hddvd_r", "media-optical-hddvd-r", N_("HD DVD-R Disc"), N_("Blank HD DVD-R Disc")},
57 {"optical_hddvd_rw", "media-optical-hddvd-rw", N_("HD DVD-RW Disc"), N_("Blank HD DVD-RW Disc")},
58 {"optical_mo", "media-optical-mo", N_("MO Disc"), N_("Blank MO Disc")},
59 {"optical_mrw", "media-optical-mrw", N_("MRW Disc"), N_("Blank MRW Disc")},
60 {"optical_mrw_w", "media-optical-mrw-w", N_("MRW/W Disc"), N_("Blank MRW/W Disc")},
61 {NULL, NULL, NULL, NULL}
62 };
63
64 static void g_udisks_device_finalize (GObject *object);
65
G_DEFINE_TYPE(GUDisksDevice,g_udisks_device,G_TYPE_OBJECT)66 G_DEFINE_TYPE(GUDisksDevice, g_udisks_device, G_TYPE_OBJECT)
67
68
69 static void g_udisks_device_class_init(GUDisksDeviceClass *klass)
70 {
71 GObjectClass *g_object_class;
72
73 g_object_class = G_OBJECT_CLASS(klass);
74 g_object_class->finalize = g_udisks_device_finalize;
75 }
76
clear_props(GUDisksDevice * dev)77 static void clear_props(GUDisksDevice* dev)
78 {
79 g_free(dev->dev_file);
80 g_free(dev->dev_file_presentation);
81 g_free(dev->name);
82 g_free(dev->icon_name);
83 g_free(dev->usage);
84 g_free(dev->type);
85 g_free(dev->uuid);
86 g_free(dev->label);
87 g_free(dev->vender);
88 g_free(dev->model);
89 g_free(dev->conn_iface);
90 g_free(dev->media);
91 g_free(dev->partition_slave);
92
93 g_strfreev(dev->mount_paths);
94 }
95
set_props(GUDisksDevice * dev,GHashTable * props)96 static void set_props(GUDisksDevice* dev, GHashTable* props)
97 {
98 dev->dev_file = dbus_prop_dup_str(props, "DeviceFile");
99 dev->dev_file_presentation = dbus_prop_dup_str(props, "DeviceFilePresentation");
100 dev->is_sys_internal = dbus_prop_bool(props, "DeviceIsSystemInternal");
101 dev->is_removable = dbus_prop_bool(props, "DeviceIsRemovable");
102 dev->is_read_only = dbus_prop_bool(props, "DeviceIsReadOnly");
103 dev->is_drive = dbus_prop_bool(props, "DeviceIsDrive");
104 dev->is_optic_disc = dbus_prop_bool(props, "DeviceIsOpticalDisc");
105 dev->is_mounted = dbus_prop_bool(props, "DeviceIsMounted");
106 dev->is_media_available = dbus_prop_bool(props, "DeviceIsMediaAvailable");
107 dev->is_media_change_notification_polling = dbus_prop_bool(props, "DeviceIsMediaChangeDetectionPolling");
108 dev->is_luks = dbus_prop_bool(props, "DeviceIsLuks");
109 dev->is_luks_clear_text = dbus_prop_bool(props, "DeviceIsLuksCleartext");
110 dev->is_linux_md_component = dbus_prop_bool(props, "DeviceIsLinuxMdComponent");
111 dev->is_linux_md = dbus_prop_bool(props, "DeviceIsLinuxMd");
112 dev->is_linux_lvm2lv = dbus_prop_bool(props, "DeviceIsLinuxLvm2LV");
113 dev->is_linux_lvm2pv = dbus_prop_bool(props, "DeviceIsLinuxLvm2PV");
114 dev->is_linux_dmmp_component = dbus_prop_bool(props, "DeviceIsLinuxDmmpComponent");
115 dev->is_linux_dmmp = dbus_prop_bool(props, "DeviceIsLinuxDmmp");
116
117 dev->is_ejectable = dbus_prop_bool(props, "DriveIsMediaEjectable");
118 dev->is_disc_blank = dbus_prop_bool(props, "OpticalDiscIsBlank");
119
120 dev->is_hidden = dbus_prop_bool(props, "DevicePresentationHide");
121 dev->auto_mount = !dbus_prop_bool(props, "DevicePresentationNopolicy");
122
123 dev->mounted_by_uid = dbus_prop_uint(props, "DeviceMountedByUid");
124 dev->mount_paths = dbus_prop_dup_strv(props, "DeviceMountPaths");
125
126 dev->dev_size = dbus_prop_uint64(props, "DeviceSize");
127 dev->partition_size = dbus_prop_uint64(props, "PartitionSize");
128
129 dev->luks_unlocked_by_uid = dbus_prop_uint(props, "LuksCleartextUnlockedByUid");
130 dev->num_audio_tracks = dbus_prop_uint(props, "OpticalDiscNumAudioTracks");
131
132 dev->name = dbus_prop_dup_str(props, "DevicePresentationName");
133 dev->icon_name = dbus_prop_dup_str(props, "DevicePresentationIconName");
134
135 dev->usage = dbus_prop_dup_str(props, "IdUsage");
136 dev->type = dbus_prop_dup_str(props, "IdType");
137 dev->uuid = dbus_prop_dup_str(props, "IdUuid");
138 dev->label = dbus_prop_dup_str(props, "IdLabel");
139 dev->vender = dbus_prop_dup_str(props, "DriveVendor");
140 dev->model = dbus_prop_dup_str(props, "DriveModel");
141 dev->conn_iface = dbus_prop_dup_str(props, "DriveConnectionInterface");
142 dev->media = dbus_prop_dup_str(props, "DriveMedia");
143
144 dev->partition_slave = dbus_prop_dup_obj_path(props, "PartitionSlave");
145
146 /* how to support LUKS? */
147 /*
148 'LuksHolder' read 'o'
149 'LuksCleartextSlave' read 'o'
150 */
151
152 }
153
g_udisks_device_finalize(GObject * object)154 static void g_udisks_device_finalize(GObject *object)
155 {
156 GUDisksDevice *self;
157
158 g_return_if_fail(object != NULL);
159 g_return_if_fail(G_IS_UDISKS_DEVICE(object));
160
161 self = G_UDISKS_DEVICE(object);
162
163 g_free(self->obj_path);
164 clear_props(self);
165
166 G_OBJECT_CLASS(g_udisks_device_parent_class)->finalize(object);
167 }
168
169
g_udisks_device_init(GUDisksDevice * self)170 static void g_udisks_device_init(GUDisksDevice *self)
171 {
172 }
173
174
g_udisks_device_new(const char * obj_path,GHashTable * props)175 GUDisksDevice *g_udisks_device_new(const char* obj_path, GHashTable* props)
176 {
177 GUDisksDevice* dev = (GUDisksDevice*)g_object_new(G_TYPE_UDISKS_DEVICE, NULL);
178 dev->obj_path = g_strdup(obj_path);
179 set_props(dev, props);
180 return dev;
181 }
182
g_udisks_device_update(GUDisksDevice * dev,GHashTable * props)183 void g_udisks_device_update(GUDisksDevice* dev, GHashTable* props)
184 {
185 clear_props(dev);
186 set_props(dev, props);
187 }
188
g_udisks_device_get_proxy(GUDisksDevice * dev,DBusGConnection * con)189 DBusGProxy* g_udisks_device_get_proxy(GUDisksDevice* dev, DBusGConnection* con)
190 {
191 DBusGProxy* proxy = dbus_g_proxy_new_for_name(con,
192 "org.freedesktop.UDisks",
193 dev->obj_path,
194 "org.freedesktop.UDisks.Device");
195 return proxy;
196 }
197
g_udisks_device_get_icon_name(GUDisksDevice * dev)198 const char* g_udisks_device_get_icon_name(GUDisksDevice* dev)
199 {
200 const char* icon_name = NULL;
201 if(dev->icon_name && *dev->icon_name)
202 icon_name = dev->icon_name;
203 else if(dev->media && *dev->media) /* by media type */
204 {
205 if(dev->is_optic_disc)
206 {
207 if(dev->num_audio_tracks > 0)
208 icon_name = "media-optical-audio";
209 else
210 {
211 guint i;
212 icon_name = "media-optical";
213 for( i = 0; i < G_N_ELEMENTS(disc_data); ++i)
214 {
215 if(strcmp(dev->media, disc_data[i].disc_type) == 0)
216 {
217 if(dev->is_disc_blank)
218 icon_name = disc_data[i].icon_name;
219 break;
220 }
221 }
222 }
223 }
224 else
225 {
226 if(strcmp (dev->media, "flash_cf") == 0)
227 icon_name = "media-flash-cf";
228 else if(strcmp (dev->media, "flash_ms") == 0)
229 icon_name = "media-flash-ms";
230 else if(strcmp (dev->media, "flash_sm") == 0)
231 icon_name = "media-flash-sm";
232 else if(strcmp (dev->media, "flash_sd") == 0)
233 icon_name = "media-flash-sd";
234 else if(strcmp (dev->media, "flash_sdhc") == 0)
235 icon_name = "media-flash-sd";
236 else if(strcmp (dev->media, "flash_mmc") == 0)
237 icon_name = "media-flash-sd";
238 else if(strcmp (dev->media, "floppy") == 0)
239 icon_name = "media-floppy";
240 else if(strcmp (dev->media, "floppy_zip") == 0)
241 icon_name = "media-floppy-zip";
242 else if(strcmp (dev->media, "floppy_jaz") == 0)
243 icon_name = "media-floppy-jaz";
244 else if(g_str_has_prefix (dev->media, "flash"))
245 icon_name = "media-flash";
246 }
247 }
248 else if(dev->conn_iface && *dev->conn_iface) /* by connection interface */
249 {
250 if(g_str_has_prefix(dev->conn_iface, "ata"))
251 icon_name = dev->is_removable ? "drive-removable-media-ata" : "drive-harddisk-ata";
252 else if(g_str_has_prefix (dev->conn_iface, "scsi"))
253 icon_name = dev->is_removable ? "drive-removable-media-scsi" : "drive-harddisk-scsi";
254 else if(strcmp (dev->conn_iface, "usb") == 0)
255 icon_name = dev->is_removable ? "drive-removable-media-usb" : "drive-harddisk-usb";
256 else if (strcmp (dev->conn_iface, "firewire") == 0)
257 icon_name = dev->is_removable ? "drive-removable-media-ieee1394" : "drive-harddisk-ieee1394";
258 }
259
260 if(!icon_name)
261 {
262 if(dev->is_removable)
263 icon_name = "drive-removable-media";
264 else
265 icon_name = "drive-harddisk";
266 }
267 return icon_name;
268 }
269
g_udisks_device_get_disc_name(GUDisksDevice * dev)270 const char* g_udisks_device_get_disc_name(GUDisksDevice* dev)
271 {
272 const char* name = NULL;
273 if(!dev->is_optic_disc)
274 return NULL;
275 if(dev->media && *dev->media)
276 {
277 if(dev->num_audio_tracks > 0 && g_str_has_prefix(dev->media, "optical_cd"))
278 name = "Audio CD";
279 else
280 {
281 guint i;
282 for( i = 0; i < G_N_ELEMENTS(disc_data); ++i)
283 {
284 if(strcmp(dev->media, disc_data[i].disc_type) == 0)
285 {
286 if(dev->is_disc_blank)
287 name = disc_data[i].ui_name_blank;
288 else
289 name = disc_data[i].ui_name;
290 break;
291 }
292 }
293 }
294 }
295
296 if(!name)
297 {
298 if(dev->is_disc_blank)
299 name = _("Blank Optical Disc");
300 else
301 name = _("Optical Disc");
302 }
303 return name;
304 }
305
g_udisks_device_is_volume(GUDisksDevice * dev)306 gboolean g_udisks_device_is_volume(GUDisksDevice* dev)
307 {
308 /* also treat blank optical discs as volumes here to be compatible with gvfs.
309 * FIXME: this is useless unless we support burn:///
310 * So, should we support this? Personally I think it's a bad idea. */
311 return (g_strcmp0(dev->usage, "filesystem") == 0 || dev->is_disc_blank);
312 }
313
314