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