Example #1
0
        /// <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);
        }
Example #2
0
        /// <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);
        }
Example #3
0
        /// <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);
        }
Example #4
0
        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);
        }
Example #5
0
        /// <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));
            }
        }