]> git.saurik.com Git - apple/xnu.git/blobdiff - iokit/Kernel/IOUserClient.cpp
xnu-344.49.tar.gz
[apple/xnu.git] / iokit / Kernel / IOUserClient.cpp
index 06f700f5bb162d10f5e2f80cbdf9654f0b8e480f..446932b6ae5ee761a9fcd39a02ce616f03286a16 100644 (file)
@@ -3,19 +3,22 @@
  *
  * @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.
+ * Copyright (c) 1999-2003 Apple Computer, Inc.  All Rights Reserved.
  * 
- * This Original Code and all software distributed under the License are
- * distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY KIND, EITHER
+ * 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. 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
  * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
  * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT.  Please see the
- * License for the specific language governing rights and limitations
- * under the License.
+ * 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_LICENSE_HEADER_END@
  */
@@ -68,6 +71,8 @@ extern ipc_port_t master_device_port;
 extern void iokit_retain_port( ipc_port_t port );
 extern void iokit_release_port( ipc_port_t port );
 
+extern kern_return_t iokit_switch_object_port( ipc_port_t port, io_object_t obj, ipc_kobject_type_t type );
+
 #include <vm/vm_map.h>
 
 } /* extern "C" */
@@ -219,7 +224,36 @@ void IOMachPort::releasePortForObject( OSObject * obj,
 void IOUserClient::destroyUserReferences( OSObject * obj )
 {
     IOMachPort::releasePortForObject( obj, IKOT_IOKIT_OBJECT );
-    IOMachPort::releasePortForObject( obj, IKOT_IOKIT_CONNECT );
+
+    // panther, 3160200
+    // IOMachPort::releasePortForObject( obj, IKOT_IOKIT_CONNECT );
+
+    OSDictionary * dict;
+
+    IOTakeLock( gIOObjectPortLock);
+    obj->retain();
+
+    if( (dict = IOMachPort::dictForType( IKOT_IOKIT_CONNECT )))
+    {
+       IOMachPort * port;
+       port = (IOMachPort *) dict->getObject( (const OSSymbol *) obj );
+       if (port)
+       {
+           IOUserClient * uc;
+           if ((uc = OSDynamicCast(IOUserClient, obj)) && uc->mappings)
+           {
+               dict->setObject((const OSSymbol *) uc->mappings, port);
+               iokit_switch_object_port(port->port, uc->mappings, IKOT_IOKIT_CONNECT);
+
+               uc->mappings->release();
+               uc->mappings = 0;
+           }
+           dict->removeObject( (const OSSymbol *) obj );
+       }
+    }
+    obj->release();
+    IOUnlock( gIOObjectPortLock);
+
 }
 
 mach_port_name_t IOMachPort::makeSendRightForTask( task_t task,
@@ -288,8 +322,7 @@ iokit_client_died( io_object_t obj, ipc_port_t /* port */,
     if( (IKOT_IOKIT_CONNECT == type)
      && (client = OSDynamicCast( IOUserClient, obj )))
        client->clientDied();
-    else if( (IKOT_IOKIT_OBJECT == type)
-     && (map = OSDynamicCast( IOMemoryMap, obj )))
+    if( (map = OSDynamicCast( IOMemoryMap, obj )))
        map->taskDied();
 
     return( kIOReturnSuccess );
@@ -1642,6 +1675,10 @@ kern_return_t is_io_service_open(
 kern_return_t is_io_service_close(
        io_object_t connection )
 {
+    OSSet * mappings;
+    if ((mappings = OSDynamicCast(OSSet, connection)))
+       return( kIOReturnSuccess );
+
     CHECK( IOUserClient, connection, client );
 
     client->clientClose();