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); }
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); }
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); }
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); }
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); }