예제 #1
0
        private void NativeDiskDisappeared(IntPtr disk, IntPtr context)
        {
            if (this.DeviceDisappeared == null)
            {
                // if no-one subscribed to this event, do nothing
                return;
            }

            IntPtr device        = DiskArbitration.DADiskCopyIOMedia(disk);
            IntPtr propertiesRef = DiskArbitration.DADiskCopyDescription(disk);

            NSDictionary properties = new NSDictionary(propertiesRef);

            DeviceArguments deviceArguments = new DeviceArguments(properties, this);

            if (properties.HasKey("DADeviceProtocol") && properties.GetStringValue("DADeviceProtocol") == "USB")
            {
                OsxUsbData usb = new OsxUsbData(device);
                deviceArguments.UsbInfo = usb;
            }

            IOKit.IOObjectRelease(device);

            this.DeviceDisappeared(this, deviceArguments);
            GC.KeepAlive(this);
        }
예제 #2
0
        private void NativeDiskChanged(IntPtr disk, IntPtr keys, IntPtr context)
        {
            if (this.DeviceChanged == null)
            {
                // if no-one subscribed to this event, do nothing
                return;
            }

            IntPtr device        = DiskArbitration.DADiskCopyIOMedia(disk);
            IntPtr propertiesRef = DiskArbitration.DADiskCopyDescription(disk);

            // using MonoMac we can get a managed NSDictionary from the pointer
            NSDictionary    properties      = new NSDictionary(propertiesRef);
            DeviceArguments deviceArguments = new DeviceArguments(properties, this);

            if (properties.HasKey("DADeviceProtocol") && properties.GetStringValue("DADeviceProtocol") == "USB")
            {
                OsxUsbData usb = new OsxUsbData(device);
                deviceArguments.UsbInfo = usb;
            }

            IOKit.IOObjectRelease(device);

            // trigger the public event for any subscribers
            this.DeviceChanged(this, deviceArguments);
            GC.KeepAlive(this);
        }
예제 #3
0
        public void UnmountDisk(string volumePath)
        {
            CFUrl  url  = MonoMac.CoreFoundation.CFUrl.FromUrlString(volumePath, null);
            IntPtr disk = DiskArbitration.DADiskCreateFromVolumePath(IntPtr.Zero, da_session, url.Handle);

            if (disk == IntPtr.Zero)
            {
                return;
            }

            DiskArbitration.UnmountCallback cb = (IntPtr unmounted_disk, IntPtr dissenter, IntPtr context) => {
                Hyena.Log.DebugFormat("successfully unmounted {0}", volumePath);
            };
            DiskArbitration.DADiskUnmount(disk, 0, cb, IntPtr.Zero);
        }
예제 #4
0
        public void Dispose()
        {
            // unregister our callbacks
            DiskArbitration.DAUnregisterCallback(da_session, callback_appeared, IntPtr.Zero);
            DiskArbitration.DAUnregisterCallback(da_session, callback_changed, IntPtr.Zero);
            DiskArbitration.DAUnregisterCallback(da_session, callback_disappeared, IntPtr.Zero);

            var mode = MonoMac.CoreFoundation.CFRunLoop.CFDefaultRunLoopMode.Handle;

            DiskArbitration.DASessionUnscheduleFromRunLoop(da_session, runloop, mode);
            CoreFoundation.CFRelease(da_session);

            // stop the main run loop which blocks the thread
            CoreFoundation.CFRunLoopStop(runloop);
            listenThread.Join();
            GC.SuppressFinalize(this);
        }
예제 #5
0
        private void startArbiter()
        {
            diskAppearedCallback    disk_appeared_callback    = new diskAppearedCallback(NativeDiskAppeared);
            diskChangedCallback     disk_changed_callback     = new diskChangedCallback(NativeDiskChanged);
            diskDisappearedCallback disk_disappeared_callback = new diskDisappearedCallback(NativeDiskDisappeared);

            // create a DiskArbitration session
            IntPtr allocator = CoreFoundation.CFAllocatorGetDefault();

            da_session = DiskArbitration.DASessionCreate(allocator);

            this.callback_appeared    = Marshal.GetFunctionPointerForDelegate(disk_appeared_callback);
            this.callback_changed     = Marshal.GetFunctionPointerForDelegate(disk_changed_callback);
            this.callback_disappeared = Marshal.GetFunctionPointerForDelegate(disk_disappeared_callback);

            DiskArbitration.DARegisterDiskAppearedCallback(da_session, IntPtr.Zero, callback_appeared, IntPtr.Zero);
            DiskArbitration.DARegisterDiskDescriptionChangedCallback(da_session, IntPtr.Zero, IntPtr.Zero, callback_changed, IntPtr.Zero);
            DiskArbitration.DARegisterDiskDisappearedCallback(da_session, IntPtr.Zero, callback_disappeared, IntPtr.Zero);

            //IntPtr runloop = CFRunLoopGetCurrent ();
            runloop = MonoMac.CoreFoundation.CFRunLoop.Current.Handle;

            var mode = MonoMac.CoreFoundation.CFRunLoop.CFDefaultRunLoopMode.Handle;

            DiskArbitration.DASessionScheduleWithRunLoop(da_session, runloop, mode);

            // this blocks the thread
            CoreFoundation.CFRunLoopRun();

            // this code is actually never run, but keeps our native references
            // and callbacks alive to prevent the GC from removing it
            GC.KeepAlive(allocator);
            GC.KeepAlive(da_session);
            GC.KeepAlive(callback_changed);
            GC.KeepAlive(callback_appeared);
            GC.KeepAlive(callback_disappeared);
            GC.KeepAlive(disk_appeared_callback);
            GC.KeepAlive(disk_changed_callback);
            GC.KeepAlive(disk_disappeared_callback);
        }