Loading...
osfmk/UserNotification/KUNCUserNotifications.c xnu-12377.121.6 xnu-792
--- xnu/xnu-12377.121.6/osfmk/UserNotification/KUNCUserNotifications.c
+++ xnu/xnu-792/osfmk/UserNotification/KUNCUserNotifications.c
@@ -1,29 +1,23 @@
 /*
- * Copyright (c) 2000-2019 Apple Inc. All rights reserved.
+ * Copyright (c) 2000-2004 Apple Computer, Inc. All rights reserved.
  *
- * @APPLE_OSREFERENCE_LICENSE_HEADER_START@
- *
- * This file contains Original Code and/or Modifications of Original Code
- * as defined in and that are subject to the Apple Public Source License
- * Version 2.0 (the 'License'). You may not use this file except in
- * compliance with the License. The rights granted to you under the License
- * may not be used to create, or enable the creation or redistribution of,
- * unlawful or unlicensed copies of an Apple operating system, or to
- * circumvent, violate, or enable the circumvention or violation of, any
- * terms of an Apple operating system software license agreement.
- *
- * Please obtain a copy of the License at
- * http://www.opensource.apple.com/apsl/ and read it before using this file.
- *
- * The Original Code and all software distributed under the License are
- * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
+ * @APPLE_LICENSE_HEADER_START@
+ * 
+ * The contents of this file constitute Original Code as defined in and
+ * are subject to the Apple Public Source License Version 1.1 (the
+ * "License").  You may not use this file except in compliance with the
+ * License.  Please obtain a copy of the License at
+ * http://www.apple.com/publicsource and read it before using this file.
+ * 
+ * This Original Code and all software distributed under the License are
+ * distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY KIND, EITHER
  * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
  * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
- * Please see the License for the specific language governing rights and
- * limitations under the License.
- *
- * @APPLE_OSREFERENCE_LICENSE_HEADER_END@
+ * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT.  Please see the
+ * License for the specific language governing rights and limitations
+ * under the License.
+ * 
+ * @APPLE_LICENSE_HEADER_END@
  */
 
 #include <mach/port.h>
@@ -49,31 +43,44 @@
 #include <IOKit/IOCFUnserialize.h>
 #endif
 
-#if CONFIG_USER_NOTIFICATION
 /*
  * DEFINES AND STRUCTURES
  */
 
 struct UNDReply {
-	decl_lck_mtx_data(, lock);                               /* UNDReply lock */
-	int                             userLandNotificationKey;
-	KUNCUserNotificationCallBack    callback;
-	boolean_t                       inprogress;
-	ipc_port_t                      self_port;      /* Our port */
+	decl_mutex_data(,lock)				/* UNDReply lock */
+	int				userLandNotificationKey;
+	KUNCUserNotificationCallBack 	callback;
+	boolean_t			inprogress;
+	ipc_port_t			self_port;	/* Our port */
 };
 
-static void
-UNDReply_no_senders(ipc_port_t port, mach_port_mscount_t mscount);
-
-IPC_KOBJECT_DEFINE(IKOT_UND_REPLY,
-    .iko_op_movable_send = true,
-    .iko_op_stable     = true,
-    .iko_op_no_senders = UNDReply_no_senders);
-
-#define UNDReply_lock(reply)            lck_mtx_lock(&reply->lock)
-#define UNDReply_unlock(reply)          lck_mtx_unlock(&reply->lock)
-
-LCK_GRP_DECLARE(UNDLckGrp, "UND");
+#define UNDReply_lock(reply)		mutex_lock(&reply->lock)
+#define UNDReply_lock_try(reply)	mutex_lock_try(&(reply)->lock)
+#define UNDReply_unlock(reply)		mutex_unlock(&(reply)->lock)
+
+/* forward declarations */
+void UNDReply_deallocate(
+	UNDReplyRef		reply);
+
+
+void
+UNDReply_deallocate(
+	UNDReplyRef		reply)
+{
+	ipc_port_t port;
+
+	UNDReply_lock(reply);
+	port = reply->self_port;
+	assert(IP_VALID(port));
+	ipc_kobject_set(port, IKO_NULL, IKOT_NONE);
+	reply->self_port = IP_NULL;
+	UNDReply_unlock(reply);
+
+	ipc_port_dealloc_kernel(port);
+	kfree(reply, sizeof(struct UNDReply));
+	return;
+}
 
 static UNDServerRef
 UNDServer_reference(void)
@@ -88,45 +95,39 @@
 
 static void
 UNDServer_deallocate(
-	UNDServerRef    UNDServer)
-{
-	if (IP_VALID(UNDServer)) {
+	UNDServerRef	UNDServer)
+{
+	if (IP_VALID(UNDServer))
 		ipc_port_release_send(UNDServer);
-	}
-}
-
-/*
+}
+
+/* 
  * UND Mig Callbacks
- */
-
-kern_return_t
-UNDAlertCompletedWithResult_rpc(
-	UNDReplyRef             reply,
-	int                     result,
-	xmlData_t               keyRef,         /* raw XML bytes */
+*/
+
+kern_return_t
+UNDAlertCompletedWithResult_rpc (
+        UNDReplyRef 		reply,
+        int 			result,
+        xmlData_t		keyRef,		/* raw XML bytes */
+        mach_msg_type_number_t	keyLen)
+{
 #ifdef KERNEL_CF
-	mach_msg_type_number_t  keyLen)
-#else
-	__unused mach_msg_type_number_t keyLen)
-#endif
-{
-#ifdef KERNEL_CF
-	CFStringRef             xmlError = NULL;
-	CFDictionaryRef         dict = NULL;
+	CFStringRef		xmlError = NULL;
+	CFDictionaryRef 	dict = NULL;
 #else
 	const void *dict = (const void *)keyRef;
 #endif
 
-	if (reply == UND_REPLY_NULL || !reply->inprogress) {
-		return KERN_INVALID_ARGUMENT;
-	}
+	if (reply == UND_REPLY_NULL || !reply->inprogress)
+		return KERN_INVALID_ARGUMENT;
 
 	/*
 	 * JMM - No C vesion of the Unserialize code in-kernel
 	 * and no C type for a CFDictionary either.  For now,
 	 * just pass the raw keyRef through.
 	 */
-#ifdef KERNEL_CF
+#ifdef KERNEL_CF 
 	if (keyRef && keyLen) {
 		dict = IOCFUnserialize(keyRef, NULL, NULL, &xmlError);
 	}
@@ -138,14 +139,14 @@
 #endif /* KERNEL_CF */
 
 	if (reply->callback) {
-		(reply->callback)((int)(KUNCUserNotificationID)reply, result, dict);
+		(reply->callback)((KUNCUserNotificationID) reply, result, dict);
 	}
 
 	UNDReply_lock(reply);
 	reply->inprogress = FALSE;
 	reply->userLandNotificationKey = -1;
 	UNDReply_unlock(reply);
-
+	UNDReply_deallocate(reply);
 	return KERN_SUCCESS;
 }
 
@@ -158,13 +159,12 @@
  *		to identify that request.
  */
 kern_return_t
-UNDNotificationCreated_rpc(
-	UNDReplyRef     reply,
-	int             userLandNotificationKey)
-{
-	if (reply == UND_REPLY_NULL) {
-		return KERN_INVALID_ARGUMENT;
-	}
+UNDNotificationCreated_rpc (
+        UNDReplyRef	reply,
+        int		userLandNotificationKey)
+{
+	if (reply == UND_REPLY_NULL)
+		return KERN_INVALID_ARGUMENT;
 
 	UNDReply_lock(reply);
 	if (reply->inprogress || reply->userLandNotificationKey != -1) {
@@ -178,37 +178,36 @@
 
 /*
  * KUNC Functions
- */
+*/
 
 
 KUNCUserNotificationID
-KUNCGetNotificationID(void)
+KUNCGetNotificationID()
 {
 	UNDReplyRef reply;
 
-	reply = kalloc_type(struct UNDReply, Z_WAITOK | Z_ZERO | Z_NOFAIL);
-	reply->self_port = ipc_kobject_alloc_port((ipc_kobject_t)reply,
-	    IKOT_UND_REPLY, IPC_KOBJECT_ALLOC_NONE);
-	lck_mtx_init(&reply->lock, &UNDLckGrp, LCK_ATTR_NULL);
-	reply->userLandNotificationKey = -1;
-	reply->inprogress = FALSE;
-
+	reply = (UNDReplyRef) kalloc(sizeof(struct UNDReply));
+	if (reply != UND_REPLY_NULL) {
+		reply->self_port = ipc_port_alloc_kernel();
+		if (reply->self_port == IP_NULL) {
+			kfree(reply, sizeof(struct UNDReply));
+			reply = UND_REPLY_NULL;
+		} else {
+			mutex_init(&reply->lock, 0);
+			reply->userLandNotificationKey = -1;
+			reply->inprogress = FALSE;
+			ipc_kobject_set(reply->self_port,
+					(ipc_kobject_t)reply,
+					IKOT_UND_REPLY);
+		}
+	}
 	return (KUNCUserNotificationID) reply;
 }
 
-static void
-UNDReply_no_senders(ipc_port_t port, mach_port_mscount_t mscount)
-{
-	UNDReplyRef reply;
-
-	reply = ipc_kobject_dealloc_port(port, mscount, IKOT_UND_REPLY);
-	lck_mtx_destroy(&reply->lock, &UNDLckGrp);
-	kfree_type(struct UNDReply, reply);
-}
-
-kern_return_t
-KUNCExecute(char executionPath[1024], int uid, int gid)
-{
+
+kern_return_t KUNCExecute(char executionPath[1024], int uid, int gid)
+{
+
 	UNDServerRef UNDServer;
 
 	UNDServer = UNDServer_reference();
@@ -221,16 +220,53 @@
 	return MACH_SEND_INVALID_DEST;
 }
 
+kern_return_t KUNCUserNotificationCancel(
+	KUNCUserNotificationID id)
+{
+	UNDReplyRef reply = (UNDReplyRef)id;
+	kern_return_t kr;
+	int ulkey;
+
+	if (reply == UND_REPLY_NULL)
+		return KERN_INVALID_ARGUMENT;
+
+	UNDReply_lock(reply);
+	if (!reply->inprogress) {
+		UNDReply_unlock(reply);
+		return KERN_INVALID_ARGUMENT;
+	}
+
+	reply->inprogress = FALSE;
+	if ((ulkey = reply->userLandNotificationKey) != 0) {
+		UNDServerRef UNDServer;
+
+		reply->userLandNotificationKey = 0;
+		UNDReply_unlock(reply);
+
+		UNDServer = UNDServer_reference();
+		if (IP_VALID(UNDServer)) {
+			kr = UNDCancelNotification_rpc(UNDServer,ulkey);
+			UNDServer_deallocate(UNDServer);
+		} else
+			kr = MACH_SEND_INVALID_DEST;
+	} else {
+		UNDReply_unlock(reply);
+		kr = KERN_SUCCESS;
+	}
+	UNDReply_deallocate(reply);
+	return kr;
+}
+
 kern_return_t
 KUNCUserNotificationDisplayNotice(
-	int             noticeTimeout,
-	unsigned        flags,
-	char            *iconPath,
-	char            *soundPath,
-	char            *localizationPath,
-	char            *alertHeader,
-	char            *alertMessage,
-	char            *defaultButtonTitle)
+	int		noticeTimeout,
+	unsigned	flags,
+	char		*iconPath,
+	char		*soundPath,
+	char		*localizationPath,
+	char		*alertHeader,
+	char		*alertMessage,
+	char		*defaultButtonTitle)
 {
 	UNDServerRef UNDServer;
 
@@ -238,14 +274,14 @@
 	if (IP_VALID(UNDServer)) {
 		kern_return_t kr;
 		kr = UNDDisplayNoticeSimple_rpc(UNDServer,
-		    noticeTimeout,
-		    flags,
-		    iconPath,
-		    soundPath,
-		    localizationPath,
-		    alertHeader,
-		    alertMessage,
-		    defaultButtonTitle);
+					noticeTimeout,
+					flags,
+					iconPath,
+					soundPath,
+					localizationPath,
+					alertHeader,
+					alertMessage,
+					defaultButtonTitle);
 		UNDServer_deallocate(UNDServer);
 		return kr;
 	}
@@ -254,35 +290,35 @@
 
 kern_return_t
 KUNCUserNotificationDisplayAlert(
-	int             alertTimeout,
-	unsigned        flags,
-	char            *iconPath,
-	char            *soundPath,
-	char            *localizationPath,
-	char            *alertHeader,
-	char            *alertMessage,
-	char            *defaultButtonTitle,
-	char            *alternateButtonTitle,
-	char            *otherButtonTitle,
-	unsigned        *responseFlags)
-{
-	UNDServerRef    UNDServer;
-
+	int		alertTimeout,
+	unsigned	flags,
+	char		*iconPath,
+	char		*soundPath,
+	char		*localizationPath,
+	char		*alertHeader,
+	char		*alertMessage,
+	char		*defaultButtonTitle,
+	char		*alternateButtonTitle,
+	char		*otherButtonTitle,
+	unsigned	*responseFlags)
+{
+	UNDServerRef	UNDServer;
+	
 	UNDServer = UNDServer_reference();
 	if (IP_VALID(UNDServer)) {
-		kern_return_t   kr;
+		kern_return_t	kr;
 		kr = UNDDisplayAlertSimple_rpc(UNDServer,
-		    alertTimeout,
-		    flags,
-		    iconPath,
-		    soundPath,
-		    localizationPath,
-		    alertHeader,
-		    alertMessage,
-		    defaultButtonTitle,
-		    alternateButtonTitle,
-		    otherButtonTitle,
-		    responseFlags);
+				       alertTimeout,
+				       flags,
+				       iconPath,
+				       soundPath,
+				       localizationPath,
+				       alertHeader,
+				       alertMessage,
+				       defaultButtonTitle,
+				       alternateButtonTitle,
+				       otherButtonTitle,
+				       responseFlags);
 		UNDServer_deallocate(UNDServer);
 		return kr;
 	}
@@ -291,22 +327,21 @@
 
 kern_return_t
 KUNCUserNotificationDisplayFromBundle(
-	KUNCUserNotificationID       id,
-	char                         *bundlePath,
-	char                         *fileName,
-	char                         *fileExtension,
-	char                         *messageKey,
-	char                         *tokenString,
+	KUNCUserNotificationID	     id,
+	char 			     *bundlePath,
+	char			     *fileName,
+	char			     *fileExtension,
+	char			     *messageKey,
+	char			     *tokenString,
 	KUNCUserNotificationCallBack callback,
-	__unused int                    contextKey)
+	__unused int			contextKey)
 {
 	UNDReplyRef reply = (UNDReplyRef)id;
 	UNDServerRef UNDServer;
 	ipc_port_t reply_port;
 
-	if (reply == UND_REPLY_NULL) {
-		return KERN_INVALID_ARGUMENT;
-	}
+	if (reply == UND_REPLY_NULL)
+		return KERN_INVALID_ARGUMENT;
 	UNDReply_lock(reply);
 	if (reply->inprogress == TRUE || reply->userLandNotificationKey != -1) {
 		UNDReply_unlock(reply);
@@ -314,7 +349,7 @@
 	}
 	reply->inprogress = TRUE;
 	reply->callback = callback;
-	reply_port = ipc_kobject_make_send(reply->self_port, reply, IKOT_UND_REPLY);
+	reply_port = ipc_port_make_send(reply->self_port);
 	UNDReply_unlock(reply);
 
 	UNDServer = UNDServer_reference();
@@ -322,12 +357,12 @@
 		kern_return_t kr;
 
 		kr = UNDDisplayCustomFromBundle_rpc(UNDServer,
-		    reply_port,
-		    bundlePath,
-		    fileName,
-		    fileExtension,
-		    messageKey,
-		    tokenString);
+					    reply_port,
+					    bundlePath,
+					    fileName,
+					    fileExtension,
+					    messageKey,
+					    tokenString);
 		UNDServer_deallocate(UNDServer);
 		return kr;
 	}
@@ -347,14 +382,21 @@
 convert_port_to_UNDReply(
 	ipc_port_t port)
 {
-	UNDReplyRef reply = NULL;
 	if (IP_VALID(port)) {
-		reply = ipc_kobject_get_stable(port, IKOT_UND_REPLY);
-	}
-
-	return reply;
-}
-#endif
+		UNDReplyRef reply;
+
+		ip_lock(port);
+		if (!ip_active(port) || (ip_kotype(port) != IKOT_UND_REPLY)) {
+			ip_unlock(port);
+			return UND_REPLY_NULL;
+		}
+		reply = (UNDReplyRef) port->ip_kobject;
+		assert(reply != UND_REPLY_NULL);
+		ip_unlock(port);
+		return reply;
+	}
+	return UND_REPLY_NULL;
+}
 
 /*
  *      User interface for setting the host UserNotification Daemon port.
@@ -362,15 +404,10 @@
 
 kern_return_t
 host_set_UNDServer(
-	host_priv_t     host_priv,
-	UNDServerRef    server)
-{
-#if CONFIG_USER_NOTIFICATION
-	return host_set_user_notification_port(host_priv, server);
-#else
-#pragma unused(host_priv, server)
-	return KERN_NOT_SUPPORTED;
-#endif
+        host_priv_t     host_priv,
+        UNDServerRef    server)
+{
+	return (host_set_user_notification_port(host_priv, server));
 }
 
 /*
@@ -380,12 +417,7 @@
 kern_return_t
 host_get_UNDServer(
 	host_priv_t     host_priv,
-	UNDServerRef    *serverp)
-{
-#if CONFIG_USER_NOTIFICATION
-	return host_get_user_notification_port(host_priv, serverp);
-#else
-#pragma unused(host_priv, serverp)
-	return KERN_NOT_SUPPORTED;
-#endif
-}
+	UNDServerRef	*serverp)
+{
+	return (host_get_user_notification_port(host_priv, serverp));
+}