/// <summary> /// Close a connection to an IOService and destroy the connect handle. This should be called /// via a custom dispose action installed when the IOKitObject was created, rather than directly. /// </summary> /// <param name="connect">The IOKit connection to close.</param> /// <returns>The result of the function call.</returns> public static int Close(IOKitObject connect) { var result = NativeMethods.IOServiceClose(connect.Handle); DebugOutput("IOService: Close() returned: " + result); // How to report if an error occurs? This is typically called from Dispose() -- throwing is a bad idea. return(result); }
/// <summary> /// Deregisters a notifier created via <see cref="IORegisterForSystemPower"/>. /// </summary> /// <param name="notifier">The notifier to de-register.</param> /// <returns>The result of the deregister operation.</returns> private static int IODeregisterForSystemPower(IOKitObject notifier) { var handle = notifier.Handle; var result = NativeMethods.IODeregisterForSystemPower(ref handle); DebugOutput("IOService: IODeregisterForSystemPower() returned: " + result); // Should we throw if an error occurs? Called from Dispose() -- would that be a bad idea? return(result); }
/// <summary> /// Move the iterator to point to the next element in the colleciton. /// </summary> /// <typeparam name="T">The type of objects being iterated over.</typeparam> /// <returns>The iterator to the next element, <c>null</c> if there isn't a next element.</returns> public T Next <T>() where T : IOKitObject, new() { T ioKitObject = null; var ioKitObjectHandle = NativeMethods.IOIteratorNext(Handle); if (ioKitObjectHandle != System.IntPtr.Zero) { ioKitObject = IOKitObject.CreateIOKitObject <T>(ioKitObjectHandle); } return(ioKitObject); }
private static IOConnect IORegisterForSystemPower(IOServiceInterestCallback systemPowerDelegate, NSObject refcon) { var ioNotificationPort = System.IntPtr.Zero; var notifierHandle = System.IntPtr.Zero; var callback = System.Runtime.InteropServices.Marshal.GetFunctionPointerForDelegate(systemPowerDelegate); var nativeIOConnect = NativeMethods.IORegisterForSystemPower(refcon.Handle, out ioNotificationPort, callback, out notifierHandle); var ioConnect = IOKitObject.CreateIOKitObject <IOConnect>(nativeIOConnect); ioConnect.NotificationPort = new IONotificationPort(ioNotificationPort); ioConnect.Notifier = IOKitObject.CreateIOKitObject <IOKitObject>(notifierHandle, n => IODeregisterForSystemPower(n)); return(ioConnect); }
/// <inheritdoc/> protected override void Dispose(bool disposing) { if (!Disposed) { DebugOutput("**** IOConnect.Dispose(bool) for " + GetType() + " marking disposed, RetainCount: " + RetainCount); Disposed = true; // The order of disposal here is based on the example at: // https://developer.apple.com/library/content/qa/qa1340/_index.html // Alternative ordering has not been tested. // Also, this code assumes that the NotificationPort has been removed from any run loops. // First, de-register the notifier. if (Notifier != null) { Notifier.Dispose(); } Notifier = null; // Now, close this IO connection. var handle = Handle; if (handle != System.IntPtr.Zero) { IOService.Close(this); ClearHandle(); } // Finally, destroy the notification port itself. if (NotificationPort != null) { NotificationPort.Dispose(); } NotificationPort = null; DebugOutput("**** IOConnect.Dispose(bool) for " + GetType() + " called IOServerClose, RetainCount: " + NativeMethods.IOObjectGetUserRetainCount(handle)); } }