5
// Aaron Bockover <abockover@novell.com>
7
// Copyright (C) 2008 Novell, Inc.
9
// Permission is hereby granted, free of charge, to any person obtaining
10
// a copy of this software and associated documentation files (the
11
// "Software"), to deal in the Software without restriction, including
12
// without limitation the rights to use, copy, modify, merge, publish,
13
// distribute, sublicense, and/or sell copies of the Software, and to
14
// permit persons to whom the Software is furnished to do so, subject to
15
// the following conditions:
17
// The above copyright notice and this permission notice shall be
18
// included in all copies or substantial portions of the Software.
20
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
21
// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
22
// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
23
// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
24
// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
25
// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
26
// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
30
using System.Collections.Generic;
32
using Banshee.Hardware;
34
namespace Banshee.HalBackend
36
public class Volume : Device, IVolume
38
private static Dictionary<Hal.Device, Volume> mounted_volumes = new Dictionary<Hal.Device, Volume> ();
39
private static Dictionary<Hal.Device, Volume> unmounted_volumes = new Dictionary<Hal.Device, Volume> ();
41
internal static HardwareManager HardwareManager;
43
private const string method_names_property = "org.freedesktop.Hal.Device.Volume.method_names";
45
public static Volume Resolve (BlockDevice parent, Hal.Manager manager, Hal.Device device)
47
if (!device.IsVolume) {
52
Volume volume = (parent is ICdromDevice || (parent == null && device.QueryCapability ("volume.disc")))
53
? DiscVolume.Resolve (parent, manager, device)
54
: new Volume (parent, manager, device);
56
return CheckVolumeMounted (volume) ? volume : null;
57
} catch (Exception e) {
58
Hyena.Log.Exception (e);
64
private DkDisk dk_disk;
65
private BlockDevice parent;
66
private string [] method_names;
68
protected Volume (BlockDevice parent, Hal.Manager manager, Hal.Device device) : base (manager, device)
70
this.parent = parent ?? BlockDevice.Resolve<IBlockDevice> (manager, device.Parent);
71
dk_disk = DkDisk.FindByDevice (DeviceNode);
73
method_names = HalDevice.PropertyExists (method_names_property)
74
? device.GetPropertyStringList (method_names_property)
78
public string DeviceNode {
79
get { return HalDevice["block.device"]; }
82
public string MountPoint {
84
if (dk_disk != null && dk_disk.MountPoint != null) {
85
return dk_disk.MountPoint;
87
return HalDevice["volume.mount_point"];
92
public string FileSystem {
93
get { return HalDevice["volume.fstype"]; }
96
/*private string serial;
97
public override string Serial {
100
serial = String.IsNullOrEmpty (HalDevice["volume.uuid"])
102
: HalDevice["volume.uuid"];
109
public bool IsMounted {
110
get { return (dk_disk != null && dk_disk.IsMounted) || HalDevice.GetPropertyBoolean ("volume.is_mounted"); }
113
public bool ShouldIgnore {
114
get { return HalDevice.GetPropertyBoolean ("volume.ignore"); }
117
public bool IsReadOnly {
118
get { return (dk_disk != null && dk_disk.IsReadOnly) || HalDevice.GetPropertyBoolean ("volume.is_mounted_read_only"); }
121
public ulong Capacity {
122
get { return HalDevice.GetPropertyUInt64 ("volume.size"); }
125
public long Available {
131
// FIXME: maybe we should use UnixDriveInfo? Advantages?
134
Mono.Unix.Native.Statvfs statvfs_info;
135
if (Mono.Unix.Native.Syscall.statvfs (MountPoint, out statvfs_info) != -1) {
136
return ((long)statvfs_info.f_bavail) * ((long)statvfs_info.f_bsize);
145
public IBlockDevice Parent {
146
get { return parent; }
149
public bool CanEject {
150
get { return Array.IndexOf<string> (method_names, "Eject") >= 0; }
155
if (CanEject && HalDevice.IsVolume) {
156
HalDevice.Volume.Eject ();
160
public bool CanMount {
161
get { return Array.IndexOf <string>(method_names, "Mount") >= 0; }
164
public bool CanUnmount {
165
get { return Array.IndexOf<string> (method_names, "Unmount") >= 0; }
170
if (CanMount && HalDevice.IsVolume)
171
HalDevice.Volume.Mount ();
174
public void Unmount ()
176
if (CanUnmount && HalDevice.IsVolume) {
177
if (dk_disk != null) {
180
HalDevice.Volume.Unmount ();
185
public override string ToString ()
188
return String.Format ("`{0}': mounted {1} volume at {2} with {3} bytes free (of {4})",
189
Name, IsReadOnly ? "read only" : "read/write", MountPoint, Available, Capacity);
192
return String.Format ("`{0}': not mounted (capacity: {1} bytes)", Name, Capacity);
195
private static bool CheckVolumeMounted (Volume volume)
197
if (volume != null && !(volume is IDiscVolume)) {
198
lock (mounted_volumes) {
199
if (mounted_volumes.ContainsKey (volume.HalDevice)) {
201
} else if (unmounted_volumes.ContainsKey (volume.HalDevice)) {
205
volume.HalDevice.PropertyModified += HandleVolumeChanged;
207
if (!volume.IsMounted) {
208
unmounted_volumes[volume.HalDevice] = volume;
211
mounted_volumes[volume.HalDevice] = volume;
218
private static void HandleVolumeChanged (object o, Hal.PropertyModifiedArgs args)
220
Hal.Device device = o as Hal.Device;
221
if (device == null) {
225
lock (mounted_volumes) {
226
if (mounted_volumes.ContainsKey (device)) {
227
Volume volume = mounted_volumes[device];
228
bool mounted = false;
230
mounted = volume.IsMounted;
231
} catch (Exception) {}
234
mounted_volumes.Remove (device);
235
unmounted_volumes[device] = volume;
236
HardwareManager.OnDeviceRemoved (volume.Uuid);
238
} else if (unmounted_volumes.ContainsKey (device)) {
239
Volume volume = unmounted_volumes[device];
240
if (volume.IsMounted) {
241
unmounted_volumes.Remove (device);
242
mounted_volumes[device] = volume;
243
HardwareManager.OnHalDeviceAdded (volume);