2 * Copyright (c) 1998-2000 Apple Computer, Inc. All rights reserved.
4 * @APPLE_LICENSE_HEADER_START@
6 * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved.
8 * This file contains Original Code and/or Modifications of Original Code
9 * as defined in and that are subject to the Apple Public Source License
10 * Version 2.0 (the 'License'). You may not use this file except in
11 * compliance with the License. Please obtain a copy of the License at
12 * http://www.opensource.apple.com/apsl/ and read it before using this
15 * The Original Code and all software distributed under the License are
16 * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
17 * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
18 * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
19 * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
20 * Please see the License for the specific language governing rights and
21 * limitations under the License.
23 * @APPLE_LICENSE_HEADER_END@
27 #include <IOKit/IOKitServer.h>
28 #include <IOKit/IOUserClient.h>
29 #include <IOKit/IOService.h>
30 #include <IOKit/IOService.h>
31 #include <IOKit/IORegistryEntry.h>
32 #include <IOKit/IOCatalogue.h>
33 #include <IOKit/IOMemoryDescriptor.h>
34 #include <IOKit/IOLib.h>
36 #include <IOKit/assert.h>
38 #include "IOServicePrivate.h"
40 /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
42 // definitions we should get from osfmk
44 //typedef struct ipc_port * ipc_port_t;
45 typedef natural_t ipc_kobject_type_t
;
47 #define IKOT_IOKIT_SPARE 27
48 #define IKOT_IOKIT_CONNECT 29
49 #define IKOT_IOKIT_OBJECT 30
53 extern ipc_port_t
iokit_alloc_object_port( io_object_t obj
,
54 ipc_kobject_type_t type
);
56 extern kern_return_t
iokit_destroy_object_port( ipc_port_t port
);
58 extern mach_port_name_t
iokit_make_send_right( task_t task
,
59 io_object_t obj
, ipc_kobject_type_t type
);
61 extern io_object_t
iokit_lookup_connect_ref(io_object_t clientRef
, ipc_space_t task
);
63 extern io_object_t
iokit_lookup_connect_ref_current_task(io_object_t clientRef
);
65 extern ipc_port_t master_device_port
;
67 extern void iokit_retain_port( ipc_port_t port
);
68 extern void iokit_release_port( ipc_port_t port
);
70 extern kern_return_t
iokit_switch_object_port( ipc_port_t port
, io_object_t obj
, ipc_kobject_type_t type
);
72 #include <vm/vm_map.h>
77 /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
79 // IOMachPort maps OSObjects to ports, avoiding adding an ivar to OSObject.
81 class IOMachPort
: public OSObject
83 OSDeclareDefaultStructors(IOMachPort
)
90 static IOMachPort
* portForObject( OSObject
* obj
,
91 ipc_kobject_type_t type
);
92 static bool noMoreSendersForObject( OSObject
* obj
,
93 ipc_kobject_type_t type
, mach_port_mscount_t
* mscount
);
94 static void releasePortForObject( OSObject
* obj
,
95 ipc_kobject_type_t type
);
96 static void setHoldDestroy( OSObject
* obj
, ipc_kobject_type_t type
);
98 static OSDictionary
* dictForType( ipc_kobject_type_t type
);
100 static mach_port_name_t
makeSendRightForTask( task_t task
,
101 io_object_t obj
, ipc_kobject_type_t type
);
106 #define super OSObject
107 OSDefineMetaClassAndStructors(IOMachPort
, OSObject
)
109 static IOLock
* gIOObjectPortLock
;
111 /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
113 // not in dictForType() for debugging ease
114 static OSDictionary
* gIOObjectPorts
;
115 static OSDictionary
* gIOConnectPorts
;
117 OSDictionary
* IOMachPort::dictForType( ipc_kobject_type_t type
)
119 OSDictionary
** dict
;
121 if( IKOT_IOKIT_OBJECT
== type
)
122 dict
= &gIOObjectPorts
;
123 else if( IKOT_IOKIT_CONNECT
== type
)
124 dict
= &gIOConnectPorts
;
129 *dict
= OSDictionary::withCapacity( 1 );
134 IOMachPort
* IOMachPort::portForObject ( OSObject
* obj
,
135 ipc_kobject_type_t type
)
137 IOMachPort
* inst
= 0;
140 IOTakeLock( gIOObjectPortLock
);
144 dict
= dictForType( type
);
148 if( (inst
= (IOMachPort
*)
149 dict
->getObject( (const OSSymbol
*) obj
))) {
155 inst
= new IOMachPort
;
156 if( inst
&& !inst
->init()) {
161 inst
->port
= iokit_alloc_object_port( obj
, type
);
164 dict
->setObject( (const OSSymbol
*) obj
, inst
);
174 IOUnlock( gIOObjectPortLock
);
179 bool IOMachPort::noMoreSendersForObject( OSObject
* obj
,
180 ipc_kobject_type_t type
, mach_port_mscount_t
* mscount
)
183 IOMachPort
* machPort
;
184 bool destroyed
= true;
186 IOTakeLock( gIOObjectPortLock
);
188 if( (dict
= dictForType( type
))) {
191 machPort
= (IOMachPort
*) dict
->getObject( (const OSSymbol
*) obj
);
193 destroyed
= (machPort
->mscount
== *mscount
);
195 dict
->removeObject( (const OSSymbol
*) obj
);
197 *mscount
= machPort
->mscount
;
202 IOUnlock( gIOObjectPortLock
);
207 void IOMachPort::releasePortForObject( OSObject
* obj
,
208 ipc_kobject_type_t type
)
211 IOMachPort
* machPort
;
213 IOTakeLock( gIOObjectPortLock
);
215 if( (dict
= dictForType( type
))) {
217 machPort
= (IOMachPort
*) dict
->getObject( (const OSSymbol
*) obj
);
218 if( machPort
&& !machPort
->holdDestroy
)
219 dict
->removeObject( (const OSSymbol
*) obj
);
223 IOUnlock( gIOObjectPortLock
);
226 void IOMachPort::setHoldDestroy( OSObject
* obj
, ipc_kobject_type_t type
)
229 IOMachPort
* machPort
;
231 IOLockLock( gIOObjectPortLock
);
233 if( (dict
= dictForType( type
))) {
234 machPort
= (IOMachPort
*) dict
->getObject( (const OSSymbol
*) obj
);
236 machPort
->holdDestroy
= true;
239 IOLockUnlock( gIOObjectPortLock
);
242 void IOUserClient::destroyUserReferences( OSObject
* obj
)
244 IOMachPort::releasePortForObject( obj
, IKOT_IOKIT_OBJECT
);
247 // IOMachPort::releasePortForObject( obj, IKOT_IOKIT_CONNECT );
251 IOTakeLock( gIOObjectPortLock
);
254 if( (dict
= IOMachPort::dictForType( IKOT_IOKIT_CONNECT
)))
257 port
= (IOMachPort
*) dict
->getObject( (const OSSymbol
*) obj
);
261 if ((uc
= OSDynamicCast(IOUserClient
, obj
)) && uc
->mappings
)
263 dict
->setObject((const OSSymbol
*) uc
->mappings
, port
);
264 iokit_switch_object_port(port
->port
, uc
->mappings
, IKOT_IOKIT_CONNECT
);
266 uc
->mappings
->release();
269 dict
->removeObject( (const OSSymbol
*) obj
);
273 IOUnlock( gIOObjectPortLock
);
276 mach_port_name_t
IOMachPort::makeSendRightForTask( task_t task
,
277 io_object_t obj
, ipc_kobject_type_t type
)
279 return( iokit_make_send_right( task
, obj
, type
));
282 void IOMachPort::free( void )
285 iokit_destroy_object_port( port
);
289 /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
291 class IOUserNotification
: public OSIterator
293 OSDeclareDefaultStructors(IOUserNotification
)
295 IONotifier
* holdNotify
;
300 virtual bool init( void );
303 virtual void setNotification( IONotifier
* obj
);
305 virtual void reset();
306 virtual bool isValid();
309 /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
313 // functions called from osfmk/device/iokit_rpc.c
316 iokit_add_reference( io_object_t obj
)
323 iokit_remove_reference( io_object_t obj
)
330 iokit_port_for_object( io_object_t obj
, ipc_kobject_type_t type
)
332 IOMachPort
* machPort
;
335 if( (machPort
= IOMachPort::portForObject( obj
, type
))) {
337 port
= machPort
->port
;
339 iokit_retain_port( port
);
350 iokit_client_died( io_object_t obj
, ipc_port_t
/* port */,
351 ipc_kobject_type_t type
, mach_port_mscount_t
* mscount
)
353 IOUserClient
* client
;
355 IOUserNotification
* notify
;
357 if( !IOMachPort::noMoreSendersForObject( obj
, type
, mscount
))
358 return( kIOReturnNotReady
);
360 if( IKOT_IOKIT_CONNECT
== type
)
362 if( (client
= OSDynamicCast( IOUserClient
, obj
)))
363 client
->clientDied();
365 else if( IKOT_IOKIT_OBJECT
== type
)
367 if( (map
= OSDynamicCast( IOMemoryMap
, obj
)))
369 else if( (notify
= OSDynamicCast( IOUserNotification
, obj
)))
370 notify
->setNotification( 0 );
373 return( kIOReturnSuccess
);
378 /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
380 class IOServiceUserNotification
: public IOUserNotification
382 OSDeclareDefaultStructors(IOServiceUserNotification
)
385 mach_msg_header_t msgHdr
;
386 OSNotificationHeader notifyHeader
;
389 enum { kMaxOutstanding
= 256 };
394 OSObject
* lastEntry
;
399 virtual bool init( mach_port_t port
, natural_t type
,
400 OSAsyncReference reference
);
403 static bool _handler( void * target
,
404 void * ref
, IOService
* newService
);
405 virtual bool handler( void * ref
, IOService
* newService
);
407 virtual OSObject
* getNextObject();
410 class IOServiceMessageUserNotification
: public IOUserNotification
412 OSDeclareDefaultStructors(IOServiceMessageUserNotification
)
415 mach_msg_header_t msgHdr
;
416 mach_msg_body_t msgBody
;
417 mach_msg_port_descriptor_t ports
[1];
418 OSNotificationHeader notifyHeader
;
426 virtual bool init( mach_port_t port
, natural_t type
,
427 OSAsyncReference reference
, vm_size_t extraSize
);
430 static IOReturn
_handler( void * target
, void * ref
,
431 UInt32 messageType
, IOService
* provider
,
432 void * messageArgument
, vm_size_t argSize
);
433 virtual IOReturn
handler( void * ref
,
434 UInt32 messageType
, IOService
* provider
,
435 void * messageArgument
, vm_size_t argSize
);
437 virtual OSObject
* getNextObject();
440 /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
443 #define super OSIterator
444 OSDefineMetaClass( IOUserNotification
, OSIterator
)
445 OSDefineAbstractStructors( IOUserNotification
, OSIterator
)
447 /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
449 bool IOUserNotification::init( void )
454 lock
= IOLockAlloc();
461 void IOUserNotification::free( void )
464 holdNotify
->remove();
465 // can't be in handler now
474 void IOUserNotification::setNotification( IONotifier
* notify
)
476 IONotifier
* previousNotify
;
478 IOLockLock( gIOObjectPortLock
);
480 previousNotify
= holdNotify
;
483 IOLockUnlock( gIOObjectPortLock
);
486 previousNotify
->remove();
489 void IOUserNotification::reset()
494 bool IOUserNotification::isValid()
499 /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
502 #define super IOUserNotification
503 OSDefineMetaClassAndStructors(IOServiceUserNotification
, IOUserNotification
)
505 /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
507 bool IOServiceUserNotification::init( mach_port_t port
, natural_t type
,
508 OSAsyncReference reference
)
510 newSet
= OSArray::withCapacity( 1 );
514 msgSize
= sizeof( PingMsg
) + 0;
515 pingMsg
= (PingMsg
*) IOMalloc( msgSize
);
519 bzero( pingMsg
, msgSize
);
521 pingMsg
->msgHdr
.msgh_remote_port
= port
;
522 pingMsg
->msgHdr
.msgh_bits
= MACH_MSGH_BITS(
523 MACH_MSG_TYPE_COPY_SEND
/*remote*/,
524 MACH_MSG_TYPE_MAKE_SEND
/*local*/);
525 pingMsg
->msgHdr
.msgh_size
= msgSize
;
526 pingMsg
->msgHdr
.msgh_id
= kOSNotificationMessageID
;
528 pingMsg
->notifyHeader
.size
= 0;
529 pingMsg
->notifyHeader
.type
= type
;
530 bcopy( reference
, pingMsg
->notifyHeader
.reference
, sizeof(OSAsyncReference
) );
532 return( super::init() );
535 void IOServiceUserNotification::free( void )
540 OSObject
* _lastEntry
;
544 _lastEntry
= lastEntry
;
549 if( _pingMsg
&& _msgSize
)
550 IOFree( _pingMsg
, _msgSize
);
553 _lastEntry
->release();
559 bool IOServiceUserNotification::_handler( void * target
,
560 void * ref
, IOService
* newService
)
562 return( ((IOServiceUserNotification
*) target
)->handler( ref
, newService
));
565 bool IOServiceUserNotification::handler( void * ref
,
566 IOService
* newService
)
570 ipc_port_t port
= NULL
;
571 bool sendPing
= false;
575 count
= newSet
->getCount();
576 if( count
< kMaxOutstanding
) {
578 newSet
->setObject( newService
);
579 if( (sendPing
= (armed
&& (0 == count
))))
585 if( kIOServiceTerminatedNotificationType
== pingMsg
->notifyHeader
.type
)
586 IOMachPort::setHoldDestroy( newService
, IKOT_IOKIT_OBJECT
);
589 if( (port
= iokit_port_for_object( this, IKOT_IOKIT_OBJECT
) ))
590 pingMsg
->msgHdr
.msgh_local_port
= port
;
592 pingMsg
->msgHdr
.msgh_local_port
= NULL
;
594 kr
= mach_msg_send_from_kernel( &pingMsg
->msgHdr
,
595 pingMsg
->msgHdr
.msgh_size
);
597 iokit_release_port( port
);
599 if( KERN_SUCCESS
!= kr
)
600 IOLog("%s: mach_msg_send_from_kernel {%x}\n", __FILE__
, kr
);
606 OSObject
* IOServiceUserNotification::getNextObject()
614 lastEntry
->release();
616 count
= newSet
->getCount();
618 result
= newSet
->getObject( count
- 1 );
620 newSet
->removeObject( count
- 1);
632 /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
634 OSDefineMetaClassAndStructors(IOServiceMessageUserNotification
, IOUserNotification
)
636 /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
638 bool IOServiceMessageUserNotification::init( mach_port_t port
, natural_t type
,
639 OSAsyncReference reference
, vm_size_t extraSize
)
642 extraSize
+= sizeof(IOServiceInterestContent
);
643 msgSize
= sizeof( PingMsg
) + extraSize
;
644 pingMsg
= (PingMsg
*) IOMalloc( msgSize
);
648 bzero( pingMsg
, msgSize
);
650 pingMsg
->msgHdr
.msgh_remote_port
= port
;
651 pingMsg
->msgHdr
.msgh_bits
= MACH_MSGH_BITS_COMPLEX
653 MACH_MSG_TYPE_COPY_SEND
/*remote*/,
654 MACH_MSG_TYPE_MAKE_SEND
/*local*/);
655 pingMsg
->msgHdr
.msgh_size
= msgSize
;
656 pingMsg
->msgHdr
.msgh_id
= kOSNotificationMessageID
;
658 pingMsg
->msgBody
.msgh_descriptor_count
= 1;
660 pingMsg
->ports
[0].name
= 0;
661 pingMsg
->ports
[0].disposition
= MACH_MSG_TYPE_MAKE_SEND
;
662 pingMsg
->ports
[0].type
= MACH_MSG_PORT_DESCRIPTOR
;
664 pingMsg
->notifyHeader
.size
= extraSize
;
665 pingMsg
->notifyHeader
.type
= type
;
666 bcopy( reference
, pingMsg
->notifyHeader
.reference
, sizeof(OSAsyncReference
) );
668 return( super::init() );
671 void IOServiceMessageUserNotification::free( void )
681 if( _pingMsg
&& _msgSize
)
682 IOFree( _pingMsg
, _msgSize
);
685 IOReturn
IOServiceMessageUserNotification::_handler( void * target
, void * ref
,
686 UInt32 messageType
, IOService
* provider
,
687 void * argument
, vm_size_t argSize
)
689 return( ((IOServiceMessageUserNotification
*) target
)->handler(
690 ref
, messageType
, provider
, argument
, argSize
));
693 IOReturn
IOServiceMessageUserNotification::handler( void * ref
,
694 UInt32 messageType
, IOService
* provider
,
695 void * messageArgument
, vm_size_t argSize
)
698 ipc_port_t thisPort
, providerPort
;
699 IOServiceInterestContent
* data
= (IOServiceInterestContent
*)
700 pingMsg
->notifyHeader
.content
;
702 data
->messageType
= messageType
;
704 argSize
= sizeof( messageArgument
);
705 data
->messageArgument
[0] = messageArgument
;
707 if( argSize
> kIOUserNotifyMaxMessageSize
)
708 argSize
= kIOUserNotifyMaxMessageSize
;
709 bcopy( messageArgument
, data
->messageArgument
, argSize
);
711 pingMsg
->msgHdr
.msgh_size
= sizeof( PingMsg
)
712 + sizeof( IOServiceInterestContent
)
713 - sizeof( data
->messageArgument
)
716 providerPort
= iokit_port_for_object( provider
, IKOT_IOKIT_OBJECT
);
717 pingMsg
->ports
[0].name
= providerPort
;
718 thisPort
= iokit_port_for_object( this, IKOT_IOKIT_OBJECT
);
719 pingMsg
->msgHdr
.msgh_local_port
= thisPort
;
720 kr
= mach_msg_send_from_kernel( &pingMsg
->msgHdr
,
721 pingMsg
->msgHdr
.msgh_size
);
723 iokit_release_port( thisPort
);
725 iokit_release_port( providerPort
);
727 if( KERN_SUCCESS
!= kr
)
728 IOLog("%s: mach_msg_send_from_kernel {%x}\n", __FILE__
, kr
);
730 return( kIOReturnSuccess
);
733 OSObject
* IOServiceMessageUserNotification::getNextObject()
738 /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
741 #define super IOService
742 OSDefineMetaClassAndAbstractStructors( IOUserClient
, IOService
)
744 void IOUserClient::initialize( void )
746 gIOObjectPortLock
= IOLockAlloc();
748 assert( gIOObjectPortLock
);
751 void IOUserClient::setAsyncReference(OSAsyncReference asyncRef
,
752 mach_port_t wakePort
,
753 void *callback
, void *refcon
)
755 asyncRef
[kIOAsyncReservedIndex
] = (natural_t
) wakePort
;
756 asyncRef
[kIOAsyncCalloutFuncIndex
] = (natural_t
) callback
;
757 asyncRef
[kIOAsyncCalloutRefconIndex
] = (natural_t
) refcon
;
760 IOReturn
IOUserClient::clientHasPrivilege( void * securityToken
,
761 const char * privilegeName
)
764 security_token_t token
;
765 mach_msg_type_number_t count
;
767 count
= TASK_SECURITY_TOKEN_COUNT
;
768 kr
= task_info( (task_t
) securityToken
, TASK_SECURITY_TOKEN
,
769 (task_info_t
) &token
, &count
);
771 if (KERN_SUCCESS
!= kr
)
773 else if (!strcmp(privilegeName
, kIOClientPrivilegeAdministrator
))
775 if (0 != token
.val
[0])
776 kr
= kIOReturnNotPrivileged
;
778 else if (!strcmp(privilegeName
, kIOClientPrivilegeLocalUser
))
781 OSDictionary
* user
= 0;
783 if ((array
= OSDynamicCast(OSArray
,
784 IORegistryEntry::getRegistryRoot()->copyProperty(gIOConsoleUsersKey
))))
786 for (unsigned int idx
= 0;
787 (user
= OSDynamicCast(OSDictionary
, array
->getObject(idx
)));
791 if ((num
= OSDynamicCast(OSNumber
, user
->getObject(gIOConsoleSessionUIDKey
)))
792 && (token
.val
[0] == num
->unsigned32BitValue()))
798 kr
= kIOReturnNotPrivileged
;
801 kr
= kIOReturnUnsupported
;
806 bool IOUserClient::initWithTask(task_t owningTask
,
810 if( getPropertyTable())
813 return super::init();
816 bool IOUserClient::initWithTask(task_t owningTask
,
819 OSDictionary
* properties
)
823 ok
= super::init( properties
);
824 ok
&= initWithTask( owningTask
, securityID
, type
);
829 void IOUserClient::free()
837 IOReturn
IOUserClient::clientDied( void )
839 return( clientClose());
842 IOReturn
IOUserClient::clientClose( void )
844 return( kIOReturnUnsupported
);
847 IOService
* IOUserClient::getService( void )
852 IOReturn
IOUserClient::registerNotificationPort(
853 mach_port_t
/* port */,
857 return( kIOReturnUnsupported
);
860 IOReturn
IOUserClient::getNotificationSemaphore( UInt32 notification_type
,
861 semaphore_t
* semaphore
)
863 return( kIOReturnUnsupported
);
866 IOReturn
IOUserClient::connectClient( IOUserClient
* /* client */ )
868 return( kIOReturnUnsupported
);
871 IOReturn
IOUserClient::clientMemoryForType( UInt32 type
,
872 IOOptionBits
* options
,
873 IOMemoryDescriptor
** memory
)
875 return( kIOReturnUnsupported
);
878 IOMemoryMap
* IOUserClient::mapClientMemory(
881 IOOptionBits mapFlags
,
882 IOVirtualAddress atAddress
)
885 IOOptionBits options
= 0;
886 IOMemoryDescriptor
* memory
;
887 IOMemoryMap
* map
= 0;
889 err
= clientMemoryForType( (UInt32
) type
, &options
, &memory
);
891 if( memory
&& (kIOReturnSuccess
== err
)) {
893 options
= (options
& ~kIOMapUserOptionsMask
)
894 | (mapFlags
& kIOMapUserOptionsMask
);
895 map
= memory
->map( task
, atAddress
, options
);
902 IOReturn
IOUserClient::exportObjectToClient(task_t task
,
903 OSObject
*obj
, io_object_t
*clientObj
)
905 mach_port_name_t name
;
907 name
= IOMachPort::makeSendRightForTask( task
, obj
, IKOT_IOKIT_OBJECT
);
910 *(mach_port_name_t
*)clientObj
= name
;
911 return kIOReturnSuccess
;
914 IOExternalMethod
* IOUserClient::getExternalMethodForIndex( UInt32
/* index */)
919 IOExternalAsyncMethod
* IOUserClient::getExternalAsyncMethodForIndex( UInt32
/* index */)
924 IOExternalMethod
* IOUserClient::
925 getTargetAndMethodForIndex(IOService
**targetP
, UInt32 index
)
927 IOExternalMethod
*method
= getExternalMethodForIndex(index
);
930 *targetP
= (IOService
*) method
->object
;
935 IOExternalAsyncMethod
* IOUserClient::
936 getAsyncTargetAndMethodForIndex(IOService
** targetP
, UInt32 index
)
938 IOExternalAsyncMethod
*method
= getExternalAsyncMethodForIndex(index
);
941 *targetP
= (IOService
*) method
->object
;
946 IOExternalTrap
* IOUserClient::
947 getExternalTrapForIndex(UInt32 index
)
952 IOExternalTrap
* IOUserClient::
953 getTargetAndTrapForIndex(IOService
** targetP
, UInt32 index
)
955 IOExternalTrap
*trap
= getExternalTrapForIndex(index
);
958 *targetP
= trap
->object
;
964 IOReturn
IOUserClient::sendAsyncResult(OSAsyncReference reference
,
965 IOReturn result
, void *args
[], UInt32 numArgs
)
968 mach_msg_header_t msgHdr
;
969 OSNotificationHeader notifyHdr
;
970 IOAsyncCompletionContent asyncContent
;
971 void * args
[kMaxAsyncArgs
];
974 mach_port_t replyPort
;
977 // If no reply port, do nothing.
978 replyPort
= (mach_port_t
) reference
[0];
979 if(replyPort
== MACH_PORT_NULL
)
980 return kIOReturnSuccess
;
982 if(numArgs
> kMaxAsyncArgs
)
983 return kIOReturnMessageTooLarge
;
984 replyMsg
.msgHdr
.msgh_bits
= MACH_MSGH_BITS(MACH_MSG_TYPE_COPY_SEND
/*remote*/,
986 replyMsg
.msgHdr
.msgh_size
=
987 sizeof(replyMsg
) - (kMaxAsyncArgs
-numArgs
)*sizeof(void *);
988 replyMsg
.msgHdr
.msgh_remote_port
= replyPort
;
989 replyMsg
.msgHdr
.msgh_local_port
= 0;
990 replyMsg
.msgHdr
.msgh_id
= kOSNotificationMessageID
;
992 replyMsg
.notifyHdr
.size
= sizeof(IOAsyncCompletionContent
)
993 + numArgs
*sizeof(void *);
994 replyMsg
.notifyHdr
.type
= kIOAsyncCompletionNotificationType
;
995 bcopy( reference
, replyMsg
.notifyHdr
.reference
, sizeof(OSAsyncReference
));
997 replyMsg
.asyncContent
.result
= result
;
999 bcopy(args
, replyMsg
.args
, sizeof(void *)*numArgs
);
1000 kr
= mach_msg_send_from_kernel( &replyMsg
.msgHdr
,
1001 replyMsg
.msgHdr
.msgh_size
);
1002 if( KERN_SUCCESS
!= kr
)
1003 IOLog("%s: mach_msg_send_from_kernel {%x}\n", __FILE__
, kr
);
1007 /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
1011 #define CHECK(cls,obj,out) \
1013 if( !(out = OSDynamicCast( cls, obj))) \
1014 return( kIOReturnBadArgument )
1016 /* Routine io_object_get_class */
1017 kern_return_t
is_io_object_get_class(
1019 io_name_t className
)
1022 return( kIOReturnBadArgument
);
1024 strcpy( className
, object
->getMetaClass()->getClassName());
1025 return( kIOReturnSuccess
);
1028 /* Routine io_object_conforms_to */
1029 kern_return_t
is_io_object_conforms_to(
1031 io_name_t className
,
1032 boolean_t
*conforms
)
1035 return( kIOReturnBadArgument
);
1037 *conforms
= (0 != object
->metaCast( className
));
1038 return( kIOReturnSuccess
);
1041 /* Routine io_object_get_retain_count */
1042 kern_return_t
is_io_object_get_retain_count(
1047 return( kIOReturnBadArgument
);
1049 *retainCount
= object
->getRetainCount();
1050 return( kIOReturnSuccess
);
1053 /* Routine io_iterator_next */
1054 kern_return_t
is_io_iterator_next(
1055 io_object_t iterator
,
1056 io_object_t
*object
)
1060 CHECK( OSIterator
, iterator
, iter
);
1062 obj
= iter
->getNextObject();
1066 return( kIOReturnSuccess
);
1068 return( kIOReturnNoDevice
);
1071 /* Routine io_iterator_reset */
1072 kern_return_t
is_io_iterator_reset(
1073 io_object_t iterator
)
1075 CHECK( OSIterator
, iterator
, iter
);
1079 return( kIOReturnSuccess
);
1082 /* Routine io_iterator_is_valid */
1083 kern_return_t
is_io_iterator_is_valid(
1084 io_object_t iterator
,
1085 boolean_t
*is_valid
)
1087 CHECK( OSIterator
, iterator
, iter
);
1089 *is_valid
= iter
->isValid();
1091 return( kIOReturnSuccess
);
1094 /* Routine io_service_match_property_table */
1095 kern_return_t
is_io_service_match_property_table(
1096 io_service_t _service
,
1097 io_string_t matching
,
1098 boolean_t
*matches
)
1100 CHECK( IOService
, _service
, service
);
1104 OSDictionary
* dict
;
1106 obj
= OSUnserializeXML( matching
);
1108 if( (dict
= OSDynamicCast( OSDictionary
, obj
))) {
1109 *matches
= service
->passiveMatch( dict
);
1110 kr
= kIOReturnSuccess
;
1112 kr
= kIOReturnBadArgument
;
1120 /* Routine io_service_match_property_table_ool */
1121 kern_return_t
is_io_service_match_property_table_ool(
1122 io_object_t service
,
1123 io_buf_ptr_t matching
,
1124 mach_msg_type_number_t matchingCnt
,
1126 boolean_t
*matches
)
1131 kr
= vm_map_copyout( kernel_map
, &data
, (vm_map_copy_t
) matching
);
1133 if( KERN_SUCCESS
== kr
) {
1134 // must return success after vm_map_copyout() succeeds
1135 *result
= is_io_service_match_property_table( service
,
1136 (char *) data
, matches
);
1137 vm_deallocate( kernel_map
, data
, matchingCnt
);
1143 /* Routine io_service_get_matching_services */
1144 kern_return_t
is_io_service_get_matching_services(
1145 mach_port_t master_port
,
1146 io_string_t matching
,
1147 io_iterator_t
*existing
)
1151 OSDictionary
* dict
;
1153 if( master_port
!= master_device_port
)
1154 return( kIOReturnNotPrivileged
);
1156 obj
= OSUnserializeXML( matching
);
1158 if( (dict
= OSDynamicCast( OSDictionary
, obj
))) {
1159 *existing
= IOService::getMatchingServices( dict
);
1160 kr
= kIOReturnSuccess
;
1162 kr
= kIOReturnBadArgument
;
1170 /* Routine io_service_get_matching_services_ool */
1171 kern_return_t
is_io_service_get_matching_services_ool(
1172 mach_port_t master_port
,
1173 io_buf_ptr_t matching
,
1174 mach_msg_type_number_t matchingCnt
,
1176 io_object_t
*existing
)
1181 kr
= vm_map_copyout( kernel_map
, &data
, (vm_map_copy_t
) matching
);
1183 if( KERN_SUCCESS
== kr
) {
1184 // must return success after vm_map_copyout() succeeds
1185 *result
= is_io_service_get_matching_services( master_port
,
1186 (char *) data
, existing
);
1187 vm_deallocate( kernel_map
, data
, matchingCnt
);
1193 /* Routine io_service_add_notification */
1194 kern_return_t
is_io_service_add_notification(
1195 mach_port_t master_port
,
1196 io_name_t notification_type
,
1197 io_string_t matching
,
1199 io_async_ref_t reference
,
1200 mach_msg_type_number_t referenceCnt
,
1201 io_object_t
* notification
)
1203 IOServiceUserNotification
* userNotify
= 0;
1204 IONotifier
* notify
= 0;
1205 const OSSymbol
* sym
;
1206 OSDictionary
* dict
;
1208 unsigned long int userMsgType
;
1211 if( master_port
!= master_device_port
)
1212 return( kIOReturnNotPrivileged
);
1215 err
= kIOReturnNoResources
;
1217 if( !(sym
= OSSymbol::withCString( notification_type
)))
1218 err
= kIOReturnNoResources
;
1220 if( !(dict
= OSDynamicCast( OSDictionary
,
1221 OSUnserializeXML( matching
)))) {
1222 err
= kIOReturnBadArgument
;
1226 if( (sym
== gIOPublishNotification
)
1227 || (sym
== gIOFirstPublishNotification
))
1228 userMsgType
= kIOServicePublishNotificationType
;
1229 else if( (sym
== gIOMatchedNotification
)
1230 || (sym
== gIOFirstMatchNotification
))
1231 userMsgType
= kIOServiceMatchedNotificationType
;
1232 else if( sym
== gIOTerminatedNotification
)
1233 userMsgType
= kIOServiceTerminatedNotificationType
;
1235 userMsgType
= kLastIOKitNotificationType
;
1237 userNotify
= new IOServiceUserNotification
;
1239 if( userNotify
&& !userNotify
->init( port
, userMsgType
,
1241 userNotify
->release();
1247 notify
= IOService::addNotification( sym
, dict
,
1248 &userNotify
->_handler
, userNotify
);
1251 *notification
= userNotify
;
1252 userNotify
->setNotification( notify
);
1253 err
= kIOReturnSuccess
;
1255 err
= kIOReturnUnsupported
;
1267 /* Routine io_service_add_notification_ool */
1268 kern_return_t
is_io_service_add_notification_ool(
1269 mach_port_t master_port
,
1270 io_name_t notification_type
,
1271 io_buf_ptr_t matching
,
1272 mach_msg_type_number_t matchingCnt
,
1273 mach_port_t wake_port
,
1274 io_async_ref_t reference
,
1275 mach_msg_type_number_t referenceCnt
,
1277 io_object_t
*notification
)
1282 kr
= vm_map_copyout( kernel_map
, &data
, (vm_map_copy_t
) matching
);
1284 if( KERN_SUCCESS
== kr
) {
1285 // must return success after vm_map_copyout() succeeds
1286 *result
= is_io_service_add_notification( master_port
, notification_type
,
1287 (char *) data
, wake_port
, reference
, referenceCnt
, notification
);
1288 vm_deallocate( kernel_map
, data
, matchingCnt
);
1295 /* Routine io_service_add_notification_old */
1296 kern_return_t
is_io_service_add_notification_old(
1297 mach_port_t master_port
,
1298 io_name_t notification_type
,
1299 io_string_t matching
,
1302 io_object_t
* notification
)
1304 return( is_io_service_add_notification( master_port
, notification_type
,
1305 matching
, port
, &ref
, 1, notification
));
1308 /* Routine io_service_add_message_notification */
1309 kern_return_t
is_io_service_add_interest_notification(
1310 io_object_t _service
,
1311 io_name_t type_of_interest
,
1313 io_async_ref_t reference
,
1314 mach_msg_type_number_t referenceCnt
,
1315 io_object_t
* notification
)
1318 IOServiceMessageUserNotification
* userNotify
= 0;
1319 IONotifier
* notify
= 0;
1320 const OSSymbol
* sym
;
1323 CHECK( IOService
, _service
, service
);
1325 err
= kIOReturnNoResources
;
1326 if( (sym
= OSSymbol::withCString( type_of_interest
))) do {
1328 userNotify
= new IOServiceMessageUserNotification
;
1330 if( userNotify
&& !userNotify
->init( port
, kIOServiceMessageNotificationType
,
1331 reference
, kIOUserNotifyMaxMessageSize
)) {
1332 userNotify
->release();
1338 notify
= service
->registerInterest( sym
,
1339 &userNotify
->_handler
, userNotify
);
1341 *notification
= userNotify
;
1342 userNotify
->setNotification( notify
);
1343 err
= kIOReturnSuccess
;
1345 err
= kIOReturnUnsupported
;
1354 /* Routine io_service_acknowledge_notification */
1355 kern_return_t
is_io_service_acknowledge_notification(
1356 io_object_t _service
,
1357 natural_t notify_ref
,
1358 natural_t response
)
1360 CHECK( IOService
, _service
, service
);
1362 return( service
->acknowledgeNotification( (IONotificationRef
) notify_ref
,
1363 (IOOptionBits
) response
));
1367 /* Routine io_connect_get_semaphore */
1368 kern_return_t
is_io_connect_get_notification_semaphore(
1369 io_connect_t connection
,
1370 natural_t notification_type
,
1371 semaphore_t
*semaphore
)
1373 CHECK( IOUserClient
, connection
, client
);
1375 return( client
->getNotificationSemaphore( (UInt32
) notification_type
,
1379 /* Routine io_registry_get_root_entry */
1380 kern_return_t
is_io_registry_get_root_entry(
1381 mach_port_t master_port
,
1384 IORegistryEntry
* entry
;
1386 if( master_port
!= master_device_port
)
1387 return( kIOReturnNotPrivileged
);
1389 entry
= IORegistryEntry::getRegistryRoot();
1394 return( kIOReturnSuccess
);
1397 /* Routine io_registry_create_iterator */
1398 kern_return_t
is_io_registry_create_iterator(
1399 mach_port_t master_port
,
1402 io_object_t
*iterator
)
1404 if( master_port
!= master_device_port
)
1405 return( kIOReturnNotPrivileged
);
1407 *iterator
= IORegistryIterator::iterateOver(
1408 IORegistryEntry::getPlane( plane
), options
);
1410 return( *iterator
? kIOReturnSuccess
: kIOReturnBadArgument
);
1413 /* Routine io_registry_entry_create_iterator */
1414 kern_return_t
is_io_registry_entry_create_iterator(
1415 io_object_t registry_entry
,
1418 io_object_t
*iterator
)
1420 CHECK( IORegistryEntry
, registry_entry
, entry
);
1422 *iterator
= IORegistryIterator::iterateOver( entry
,
1423 IORegistryEntry::getPlane( plane
), options
);
1425 return( *iterator
? kIOReturnSuccess
: kIOReturnBadArgument
);
1428 /* Routine io_registry_iterator_enter */
1429 kern_return_t
is_io_registry_iterator_enter_entry(
1430 io_object_t iterator
)
1432 CHECK( IORegistryIterator
, iterator
, iter
);
1436 return( kIOReturnSuccess
);
1439 /* Routine io_registry_iterator_exit */
1440 kern_return_t
is_io_registry_iterator_exit_entry(
1441 io_object_t iterator
)
1445 CHECK( IORegistryIterator
, iterator
, iter
);
1447 didIt
= iter
->exitEntry();
1449 return( didIt
? kIOReturnSuccess
: kIOReturnNoDevice
);
1452 /* Routine io_registry_entry_from_path */
1453 kern_return_t
is_io_registry_entry_from_path(
1454 mach_port_t master_port
,
1456 io_object_t
*registry_entry
)
1458 IORegistryEntry
* entry
;
1460 if( master_port
!= master_device_port
)
1461 return( kIOReturnNotPrivileged
);
1463 entry
= IORegistryEntry::fromPath( path
);
1465 *registry_entry
= entry
;
1467 return( kIOReturnSuccess
);
1470 /* Routine io_registry_entry_in_plane */
1471 kern_return_t
is_io_registry_entry_in_plane(
1472 io_object_t registry_entry
,
1474 boolean_t
*inPlane
)
1476 CHECK( IORegistryEntry
, registry_entry
, entry
);
1478 *inPlane
= entry
->inPlane( IORegistryEntry::getPlane( plane
));
1480 return( kIOReturnSuccess
);
1484 /* Routine io_registry_entry_get_path */
1485 kern_return_t
is_io_registry_entry_get_path(
1486 io_object_t registry_entry
,
1491 CHECK( IORegistryEntry
, registry_entry
, entry
);
1493 length
= sizeof( io_string_t
);
1494 if( entry
->getPath( path
, &length
, IORegistryEntry::getPlane( plane
)))
1495 return( kIOReturnSuccess
);
1497 return( kIOReturnBadArgument
);
1501 /* Routine io_registry_entry_get_name */
1502 kern_return_t
is_io_registry_entry_get_name(
1503 io_object_t registry_entry
,
1506 CHECK( IORegistryEntry
, registry_entry
, entry
);
1508 strncpy( name
, entry
->getName(), sizeof( io_name_t
));
1510 return( kIOReturnSuccess
);
1513 /* Routine io_registry_entry_get_name_in_plane */
1514 kern_return_t
is_io_registry_entry_get_name_in_plane(
1515 io_object_t registry_entry
,
1516 io_name_t planeName
,
1519 const IORegistryPlane
* plane
;
1520 CHECK( IORegistryEntry
, registry_entry
, entry
);
1523 plane
= IORegistryEntry::getPlane( planeName
);
1527 strncpy( name
, entry
->getName( plane
), sizeof( io_name_t
));
1529 return( kIOReturnSuccess
);
1532 /* Routine io_registry_entry_get_location_in_plane */
1533 kern_return_t
is_io_registry_entry_get_location_in_plane(
1534 io_object_t registry_entry
,
1535 io_name_t planeName
,
1536 io_name_t location
)
1538 const IORegistryPlane
* plane
;
1539 CHECK( IORegistryEntry
, registry_entry
, entry
);
1542 plane
= IORegistryEntry::getPlane( planeName
);
1546 const char * cstr
= entry
->getLocation( plane
);
1549 strncpy( location
, cstr
, sizeof( io_name_t
));
1550 return( kIOReturnSuccess
);
1552 return( kIOReturnNotFound
);
1555 // Create a vm_map_copy_t or kalloc'ed data for memory
1556 // to be copied out. ipc will free after the copyout.
1558 static kern_return_t
copyoutkdata( void * data
, vm_size_t len
,
1559 io_buf_ptr_t
* buf
)
1564 err
= vm_map_copyin( kernel_map
, (vm_offset_t
) data
, len
,
1565 false /* src_destroy */, ©
);
1567 assert( err
== KERN_SUCCESS
);
1568 if( err
== KERN_SUCCESS
)
1569 *buf
= (char *) copy
;
1574 /* Routine io_registry_entry_get_property */
1575 kern_return_t
is_io_registry_entry_get_property_bytes(
1576 io_object_t registry_entry
,
1577 io_name_t property_name
,
1578 io_scalar_inband_t buf
,
1579 mach_msg_type_number_t
*dataCnt
)
1587 unsigned int len
= 0;
1588 const void * bytes
= 0;
1589 IOReturn ret
= kIOReturnSuccess
;
1591 CHECK( IORegistryEntry
, registry_entry
, entry
);
1593 obj
= entry
->copyProperty(property_name
);
1595 return( kIOReturnNoResources
);
1597 // One day OSData will be a common container base class
1599 if( (data
= OSDynamicCast( OSData
, obj
))) {
1600 len
= data
->getLength();
1601 bytes
= data
->getBytesNoCopy();
1603 } else if( (str
= OSDynamicCast( OSString
, obj
))) {
1604 len
= str
->getLength() + 1;
1605 bytes
= str
->getCStringNoCopy();
1607 } else if( (boo
= OSDynamicCast( OSBoolean
, obj
))) {
1608 len
= boo
->isTrue() ? sizeof("Yes") : sizeof("No");
1609 bytes
= boo
->isTrue() ? "Yes" : "No";
1611 } else if( (off
= OSDynamicCast( OSNumber
, obj
))) {
1612 offsetBytes
= off
->unsigned64BitValue();
1613 len
= off
->numberOfBytes();
1614 bytes
= &offsetBytes
;
1615 #ifdef __BIG_ENDIAN__
1616 bytes
= (const void *)
1617 (((UInt32
) bytes
) + (sizeof( UInt64
) - len
));
1621 ret
= kIOReturnBadArgument
;
1625 ret
= kIOReturnIPCError
;
1628 bcopy( bytes
, buf
, len
);
1636 /* Routine io_registry_entry_get_property */
1637 kern_return_t
is_io_registry_entry_get_property(
1638 io_object_t registry_entry
,
1639 io_name_t property_name
,
1640 io_buf_ptr_t
*properties
,
1641 mach_msg_type_number_t
*propertiesCnt
)
1647 CHECK( IORegistryEntry
, registry_entry
, entry
);
1649 obj
= entry
->copyProperty(property_name
);
1651 return( kIOReturnNotFound
);
1653 OSSerialize
* s
= OSSerialize::withCapacity(4096);
1656 return( kIOReturnNoMemory
);
1660 if( obj
->serialize( s
)) {
1661 len
= s
->getLength();
1662 *propertiesCnt
= len
;
1663 err
= copyoutkdata( s
->text(), len
, properties
);
1666 err
= kIOReturnUnsupported
;
1674 /* Routine io_registry_entry_get_property_recursively */
1675 kern_return_t
is_io_registry_entry_get_property_recursively(
1676 io_object_t registry_entry
,
1678 io_name_t property_name
,
1680 io_buf_ptr_t
*properties
,
1681 mach_msg_type_number_t
*propertiesCnt
)
1687 CHECK( IORegistryEntry
, registry_entry
, entry
);
1689 obj
= entry
->copyProperty( property_name
,
1690 IORegistryEntry::getPlane( plane
), options
);
1692 return( kIOReturnNotFound
);
1694 OSSerialize
* s
= OSSerialize::withCapacity(4096);
1697 return( kIOReturnNoMemory
);
1702 if( obj
->serialize( s
)) {
1703 len
= s
->getLength();
1704 *propertiesCnt
= len
;
1705 err
= copyoutkdata( s
->text(), len
, properties
);
1708 err
= kIOReturnUnsupported
;
1716 /* Routine io_registry_entry_get_properties */
1717 kern_return_t
is_io_registry_entry_get_properties(
1718 io_object_t registry_entry
,
1719 io_buf_ptr_t
*properties
,
1720 mach_msg_type_number_t
*propertiesCnt
)
1725 CHECK( IORegistryEntry
, registry_entry
, entry
);
1727 OSSerialize
* s
= OSSerialize::withCapacity(4096);
1729 return( kIOReturnNoMemory
);
1733 if( entry
->serializeProperties( s
)) {
1734 len
= s
->getLength();
1735 *propertiesCnt
= len
;
1736 err
= copyoutkdata( s
->text(), len
, properties
);
1739 err
= kIOReturnUnsupported
;
1746 /* Routine io_registry_entry_set_properties */
1747 kern_return_t is_io_registry_entry_set_properties
1749 io_object_t registry_entry
,
1750 io_buf_ptr_t properties
,
1751 mach_msg_type_number_t propertiesCnt
,
1759 CHECK( IORegistryEntry
, registry_entry
, entry
);
1761 err
= vm_map_copyout( kernel_map
, &data
, (vm_map_copy_t
) properties
);
1763 if( KERN_SUCCESS
== err
) {
1765 // must return success after vm_map_copyout() succeeds
1766 obj
= OSUnserializeXML( (const char *) data
);
1767 vm_deallocate( kernel_map
, data
, propertiesCnt
);
1770 res
= entry
->setProperties( obj
);
1773 res
= kIOReturnBadArgument
;
1781 /* Routine io_registry_entry_get_child_iterator */
1782 kern_return_t
is_io_registry_entry_get_child_iterator(
1783 io_object_t registry_entry
,
1785 io_object_t
*iterator
)
1787 CHECK( IORegistryEntry
, registry_entry
, entry
);
1789 *iterator
= entry
->getChildIterator(
1790 IORegistryEntry::getPlane( plane
));
1792 return( kIOReturnSuccess
);
1795 /* Routine io_registry_entry_get_parent_iterator */
1796 kern_return_t
is_io_registry_entry_get_parent_iterator(
1797 io_object_t registry_entry
,
1799 io_object_t
*iterator
)
1801 CHECK( IORegistryEntry
, registry_entry
, entry
);
1803 *iterator
= entry
->getParentIterator(
1804 IORegistryEntry::getPlane( plane
));
1806 return( kIOReturnSuccess
);
1809 /* Routine io_service_get_busy_state */
1810 kern_return_t
is_io_service_get_busy_state(
1811 io_object_t _service
,
1814 CHECK( IOService
, _service
, service
);
1816 *busyState
= service
->getBusyState();
1818 return( kIOReturnSuccess
);
1821 /* Routine io_service_get_state */
1822 kern_return_t
is_io_service_get_state(
1823 io_object_t _service
,
1826 CHECK( IOService
, _service
, service
);
1828 *state
= service
->getState();
1830 return( kIOReturnSuccess
);
1833 /* Routine io_service_wait_quiet */
1834 kern_return_t
is_io_service_wait_quiet(
1835 io_object_t _service
,
1836 mach_timespec_t wait_time
)
1838 CHECK( IOService
, _service
, service
);
1840 return( service
->waitQuiet( &wait_time
));
1843 /* Routine io_service_request_probe */
1844 kern_return_t
is_io_service_request_probe(
1845 io_object_t _service
,
1848 CHECK( IOService
, _service
, service
);
1850 return( service
->requestProbe( options
));
1854 /* Routine io_service_open */
1855 kern_return_t
is_io_service_open(
1856 io_object_t _service
,
1859 io_object_t
*connection
)
1861 IOUserClient
* client
;
1864 CHECK( IOService
, _service
, service
);
1866 err
= service
->newUserClient( owningTask
, (void *) owningTask
,
1867 connect_type
, &client
);
1869 if( err
== kIOReturnSuccess
) {
1870 assert( OSDynamicCast(IOUserClient
, client
) );
1871 *connection
= client
;
1877 /* Routine io_service_close */
1878 kern_return_t
is_io_service_close(
1879 io_object_t connection
)
1882 if ((mappings
= OSDynamicCast(OSSet
, connection
)))
1883 return( kIOReturnSuccess
);
1885 CHECK( IOUserClient
, connection
, client
);
1887 client
->clientClose();
1889 return( kIOReturnSuccess
);
1892 /* Routine io_connect_get_service */
1893 kern_return_t
is_io_connect_get_service(
1894 io_object_t connection
,
1895 io_object_t
*service
)
1897 IOService
* theService
;
1899 CHECK( IOUserClient
, connection
, client
);
1901 theService
= client
->getService();
1903 theService
->retain();
1905 *service
= theService
;
1907 return( theService
? kIOReturnSuccess
: kIOReturnUnsupported
);
1910 /* Routine io_connect_set_notification_port */
1911 kern_return_t
is_io_connect_set_notification_port(
1912 io_object_t connection
,
1913 int notification_type
,
1917 CHECK( IOUserClient
, connection
, client
);
1919 return( client
->registerNotificationPort( port
, notification_type
,
1923 kern_return_t
is_io_connect_map_memory(
1924 io_object_t connect
,
1927 vm_address_t
* mapAddr
,
1928 vm_size_t
* mapSize
,
1934 CHECK( IOUserClient
, connect
, client
);
1936 map
= client
->mapClientMemory( type
, task
, flags
, *mapAddr
);
1939 *mapAddr
= map
->getVirtualAddress();
1941 *mapSize
= map
->getLength();
1943 if( task
!= current_task()) {
1944 // push a name out to the task owning the map,
1945 // so we can clean up maps
1947 mach_port_name_t name
=
1949 IOMachPort::makeSendRightForTask(
1950 task
, map
, IKOT_IOKIT_OBJECT
);
1954 // keep it with the user client
1955 IOLockLock( gIOObjectPortLock
);
1956 if( 0 == client
->mappings
)
1957 client
->mappings
= OSSet::withCapacity(2);
1958 if( client
->mappings
)
1959 client
->mappings
->setObject( map
);
1960 IOLockUnlock( gIOObjectPortLock
);
1963 err
= kIOReturnSuccess
;
1966 err
= kIOReturnBadArgument
;
1971 kern_return_t
is_io_connect_unmap_memory(
1972 io_object_t connect
,
1975 vm_address_t mapAddr
)
1978 IOOptionBits options
= 0;
1979 IOMemoryDescriptor
* memory
;
1982 CHECK( IOUserClient
, connect
, client
);
1984 err
= client
->clientMemoryForType( (UInt32
) type
, &options
, &memory
);
1986 if( memory
&& (kIOReturnSuccess
== err
)) {
1988 options
= (options
& ~kIOMapUserOptionsMask
)
1989 | kIOMapAnywhere
| kIOMapReference
;
1991 map
= memory
->map( task
, mapAddr
, options
);
1994 IOLockLock( gIOObjectPortLock
);
1995 if( client
->mappings
)
1996 client
->mappings
->removeObject( map
);
1997 IOLockUnlock( gIOObjectPortLock
);
1998 IOMachPort::releasePortForObject( map
, IKOT_IOKIT_OBJECT
);
2001 err
= kIOReturnBadArgument
;
2008 /* Routine io_connect_add_client */
2009 kern_return_t
is_io_connect_add_client(
2010 io_object_t connection
,
2011 io_object_t connect_to
)
2013 CHECK( IOUserClient
, connection
, client
);
2014 CHECK( IOUserClient
, connect_to
, to
);
2016 return( client
->connectClient( to
) );
2020 /* Routine io_connect_set_properties */
2021 kern_return_t
is_io_connect_set_properties(
2022 io_object_t connection
,
2023 io_buf_ptr_t properties
,
2024 mach_msg_type_number_t propertiesCnt
,
2027 return( is_io_registry_entry_set_properties( connection
, properties
, propertiesCnt
, result
));
2031 /* Routine io_connect_method_scalarI_scalarO */
2032 kern_return_t
is_io_connect_method_scalarI_scalarO(
2033 io_object_t connect
,
2036 IOByteCount inputCount
,
2038 IOByteCount
* outputCount
)
2041 IOExternalMethod
* method
;
2045 CHECK( IOUserClient
, connect
, client
);
2046 if( (method
= client
->getTargetAndMethodForIndex(&object
, index
))) {
2048 err
= kIOReturnBadArgument
;
2049 if( kIOUCScalarIScalarO
!= (method
->flags
& kIOUCTypeMask
))
2051 if( inputCount
!= method
->count0
)
2053 if( *outputCount
!= method
->count1
)
2056 func
= method
->func
;
2058 switch( inputCount
) {
2061 err
= (object
->*func
)( input
[0], input
[1], input
[2],
2062 input
[3], input
[4], input
[5] );
2065 err
= (object
->*func
)( input
[0], input
[1], input
[2],
2070 err
= (object
->*func
)( input
[0], input
[1], input
[2],
2072 &output
[0], &output
[1] );
2075 err
= (object
->*func
)( input
[0], input
[1], input
[2],
2076 &output
[0], &output
[1], &output
[2] );
2079 err
= (object
->*func
)( input
[0], input
[1],
2080 &output
[0], &output
[1], &output
[2],
2084 err
= (object
->*func
)( input
[0],
2085 &output
[0], &output
[1], &output
[2],
2086 &output
[3], &output
[4] );
2089 err
= (object
->*func
)( &output
[0], &output
[1], &output
[2],
2090 &output
[3], &output
[4], &output
[5] );
2094 IOLog("%s: Bad method table\n", client
->getName());
2099 err
= kIOReturnUnsupported
;
2104 /* Routine io_connect_method_scalarI_structureO */
2105 kern_return_t
is_io_connect_method_scalarI_structureO(
2106 io_object_t connect
,
2109 IOByteCount inputCount
,
2111 IOByteCount
* outputCount
)
2114 IOExternalMethod
* method
;
2118 CHECK( IOUserClient
, connect
, client
);
2120 if( (method
= client
->getTargetAndMethodForIndex(&object
, index
)) ) {
2122 err
= kIOReturnBadArgument
;
2123 if( kIOUCScalarIStructO
!= (method
->flags
& kIOUCTypeMask
))
2125 if( inputCount
!= method
->count0
)
2127 if( (0xffffffff != method
->count1
)
2128 && (*outputCount
!= method
->count1
))
2131 func
= method
->func
;
2133 switch( inputCount
) {
2136 err
= (object
->*func
)( input
[0], input
[1], input
[2],
2141 err
= (object
->*func
)( input
[0], input
[1], input
[2],
2143 output
, (void *)outputCount
);
2146 err
= (object
->*func
)( input
[0], input
[1], input
[2],
2147 output
, (void *)outputCount
, 0 );
2150 err
= (object
->*func
)( input
[0], input
[1],
2151 output
, (void *)outputCount
, 0, 0 );
2154 err
= (object
->*func
)( input
[0],
2155 output
, (void *)outputCount
, 0, 0, 0 );
2158 err
= (object
->*func
)( output
, (void *)outputCount
, 0, 0, 0, 0 );
2162 IOLog("%s: Bad method table\n", client
->getName());
2167 err
= kIOReturnUnsupported
;
2172 /* Routine io_connect_method_scalarI_structureI */
2173 kern_return_t
is_io_connect_method_scalarI_structureI(
2174 io_connect_t connect
,
2177 IOByteCount inputCount
,
2178 UInt8
* inputStruct
,
2179 IOByteCount inputStructCount
)
2182 IOExternalMethod
* method
;
2186 CHECK( IOUserClient
, connect
, client
);
2188 if( (method
= client
->getTargetAndMethodForIndex(&object
, index
)) ) {
2190 err
= kIOReturnBadArgument
;
2191 if( kIOUCScalarIStructI
!= (method
->flags
& kIOUCTypeMask
))
2193 if( (0xffffffff != method
->count0
)
2194 && (inputCount
!= method
->count0
))
2196 if( (0xffffffff != method
->count1
)
2197 && (inputStructCount
!= method
->count1
))
2200 func
= method
->func
;
2202 switch( inputCount
) {
2205 err
= (object
->*func
)( input
[0], input
[1], input
[2],
2210 err
= (object
->*func
)( input
[0], input
[1], input
[2],
2212 inputStruct
, (void *)inputStructCount
);
2215 err
= (object
->*func
)( input
[0], input
[1], input
[2],
2216 inputStruct
, (void *)inputStructCount
,
2220 err
= (object
->*func
)( input
[0], input
[1],
2221 inputStruct
, (void *)inputStructCount
,
2225 err
= (object
->*func
)( input
[0],
2226 inputStruct
, (void *)inputStructCount
,
2230 err
= (object
->*func
)( inputStruct
, (void *)inputStructCount
,
2235 IOLog("%s: Bad method table\n", client
->getName());
2240 err
= kIOReturnUnsupported
;
2245 /* Routine io_connect_method_structureI_structureO */
2246 kern_return_t
is_io_connect_method_structureI_structureO(
2247 io_object_t connect
,
2250 IOByteCount inputCount
,
2252 IOByteCount
* outputCount
)
2255 IOExternalMethod
* method
;
2259 CHECK( IOUserClient
, connect
, client
);
2261 if( (method
= client
->getTargetAndMethodForIndex(&object
, index
)) ) {
2263 err
= kIOReturnBadArgument
;
2264 if( kIOUCStructIStructO
!= (method
->flags
& kIOUCTypeMask
))
2266 if( (0xffffffff != method
->count0
)
2267 && (inputCount
!= method
->count0
))
2269 if( (0xffffffff != method
->count1
)
2270 && (*outputCount
!= method
->count1
))
2273 func
= method
->func
;
2275 if( method
->count1
) {
2276 if( method
->count0
) {
2277 err
= (object
->*func
)( input
, output
,
2278 (void *)inputCount
, outputCount
, 0, 0 );
2280 err
= (object
->*func
)( output
, outputCount
, 0, 0, 0, 0 );
2283 err
= (object
->*func
)( input
, (void *)inputCount
, 0, 0, 0, 0 );
2289 err
= kIOReturnUnsupported
;
2294 kern_return_t
is_io_async_method_scalarI_scalarO(
2295 io_object_t connect
,
2296 mach_port_t wakePort
,
2297 io_async_ref_t reference
,
2298 mach_msg_type_number_t referenceCnt
,
2301 IOByteCount inputCount
,
2303 IOByteCount
* outputCount
)
2306 IOExternalAsyncMethod
*method
;
2310 CHECK( IOUserClient
, connect
, client
);
2311 if( (method
= client
->getAsyncTargetAndMethodForIndex(&object
, index
)) ) {
2313 err
= kIOReturnBadArgument
;
2314 if( kIOUCScalarIScalarO
!= (method
->flags
& kIOUCTypeMask
))
2316 if( inputCount
!= method
->count0
)
2318 if( *outputCount
!= method
->count1
)
2321 reference
[0] = (natural_t
) wakePort
;
2322 func
= method
->func
;
2324 switch( inputCount
) {
2327 err
= (object
->*func
)( reference
,
2328 input
[0], input
[1], input
[2],
2329 input
[3], input
[4], input
[5] );
2332 err
= (object
->*func
)( reference
,
2333 input
[0], input
[1], input
[2],
2338 err
= (object
->*func
)( reference
,
2339 input
[0], input
[1], input
[2],
2341 &output
[0], &output
[1] );
2344 err
= (object
->*func
)( reference
,
2345 input
[0], input
[1], input
[2],
2346 &output
[0], &output
[1], &output
[2] );
2349 err
= (object
->*func
)( reference
,
2351 &output
[0], &output
[1], &output
[2],
2355 err
= (object
->*func
)( reference
,
2357 &output
[0], &output
[1], &output
[2],
2358 &output
[3], &output
[4] );
2361 err
= (object
->*func
)( reference
,
2362 &output
[0], &output
[1], &output
[2],
2363 &output
[3], &output
[4], &output
[5] );
2367 IOLog("%s: Bad method table\n", client
->getName());
2372 err
= kIOReturnUnsupported
;
2377 kern_return_t
is_io_async_method_scalarI_structureO(
2378 io_object_t connect
,
2379 mach_port_t wakePort
,
2380 io_async_ref_t reference
,
2381 mach_msg_type_number_t referenceCnt
,
2384 IOByteCount inputCount
,
2386 IOByteCount
* outputCount
)
2389 IOExternalAsyncMethod
*method
;
2393 CHECK( IOUserClient
, connect
, client
);
2395 if( (method
= client
->getAsyncTargetAndMethodForIndex(&object
, index
)) ) {
2397 err
= kIOReturnBadArgument
;
2398 if( kIOUCScalarIStructO
!= (method
->flags
& kIOUCTypeMask
))
2400 if( inputCount
!= method
->count0
)
2402 if( (0xffffffff != method
->count1
)
2403 && (*outputCount
!= method
->count1
))
2406 reference
[0] = (natural_t
) wakePort
;
2407 func
= method
->func
;
2409 switch( inputCount
) {
2412 err
= (object
->*func
)( reference
,
2413 input
[0], input
[1], input
[2],
2418 err
= (object
->*func
)( reference
,
2419 input
[0], input
[1], input
[2],
2421 output
, (void *)outputCount
);
2424 err
= (object
->*func
)( reference
,
2425 input
[0], input
[1], input
[2],
2426 output
, (void *)outputCount
, 0 );
2429 err
= (object
->*func
)( reference
,
2431 output
, (void *)outputCount
, 0, 0 );
2434 err
= (object
->*func
)( reference
,
2436 output
, (void *)outputCount
, 0, 0, 0 );
2439 err
= (object
->*func
)( reference
,
2440 output
, (void *)outputCount
, 0, 0, 0, 0 );
2444 IOLog("%s: Bad method table\n", client
->getName());
2449 err
= kIOReturnUnsupported
;
2454 kern_return_t
is_io_async_method_scalarI_structureI(
2455 io_connect_t connect
,
2456 mach_port_t wakePort
,
2457 io_async_ref_t reference
,
2458 mach_msg_type_number_t referenceCnt
,
2461 IOByteCount inputCount
,
2462 UInt8
* inputStruct
,
2463 IOByteCount inputStructCount
)
2466 IOExternalAsyncMethod
*method
;
2470 CHECK( IOUserClient
, connect
, client
);
2472 if( (method
= client
->getAsyncTargetAndMethodForIndex(&object
, index
)) ) {
2474 err
= kIOReturnBadArgument
;
2475 if( kIOUCScalarIStructI
!= (method
->flags
& kIOUCTypeMask
))
2477 if( (0xffffffff != method
->count0
)
2478 && (inputCount
!= method
->count0
))
2480 if( (0xffffffff != method
->count1
)
2481 && (inputStructCount
!= method
->count1
))
2484 reference
[0] = (natural_t
) wakePort
;
2485 func
= method
->func
;
2487 switch( inputCount
) {
2490 err
= (object
->*func
)( reference
,
2491 input
[0], input
[1], input
[2],
2496 err
= (object
->*func
)( reference
,
2497 input
[0], input
[1], input
[2],
2499 inputStruct
, (void *)inputStructCount
);
2502 err
= (object
->*func
)( reference
,
2503 input
[0], input
[1], input
[2],
2504 inputStruct
, (void *)inputStructCount
,
2508 err
= (object
->*func
)( reference
,
2510 inputStruct
, (void *)inputStructCount
,
2514 err
= (object
->*func
)( reference
,
2516 inputStruct
, (void *)inputStructCount
,
2520 err
= (object
->*func
)( reference
,
2521 inputStruct
, (void *)inputStructCount
,
2526 IOLog("%s: Bad method table\n", client
->getName());
2531 err
= kIOReturnUnsupported
;
2536 kern_return_t
is_io_async_method_structureI_structureO(
2537 io_object_t connect
,
2538 mach_port_t wakePort
,
2539 io_async_ref_t reference
,
2540 mach_msg_type_number_t referenceCnt
,
2543 IOByteCount inputCount
,
2545 IOByteCount
* outputCount
)
2548 IOExternalAsyncMethod
*method
;
2552 CHECK( IOUserClient
, connect
, client
);
2554 if( (method
= client
->getAsyncTargetAndMethodForIndex(&object
, index
)) ) {
2556 err
= kIOReturnBadArgument
;
2557 if( kIOUCStructIStructO
!= (method
->flags
& kIOUCTypeMask
))
2559 if( (0xffffffff != method
->count0
)
2560 && (inputCount
!= method
->count0
))
2562 if( (0xffffffff != method
->count1
)
2563 && (*outputCount
!= method
->count1
))
2566 reference
[0] = (natural_t
) wakePort
;
2567 func
= method
->func
;
2569 if( method
->count1
) {
2570 if( method
->count0
) {
2571 err
= (object
->*func
)( reference
,
2573 (void *)inputCount
, outputCount
, 0, 0 );
2575 err
= (object
->*func
)( reference
,
2576 output
, outputCount
, 0, 0, 0, 0 );
2579 err
= (object
->*func
)( reference
,
2580 input
, (void *)inputCount
, 0, 0, 0, 0 );
2586 err
= kIOReturnUnsupported
;
2590 /* Routine io_make_matching */
2591 kern_return_t
is_io_make_matching(
2592 mach_port_t master_port
,
2594 IOOptionBits options
,
2596 IOByteCount inputCount
,
2597 io_string_t matching
)
2600 IOReturn err
= kIOReturnSuccess
;
2601 OSDictionary
* dict
;
2603 if( master_port
!= master_device_port
)
2604 return( kIOReturnNotPrivileged
);
2608 case kIOServiceMatching
:
2609 dict
= IOService::serviceMatching( gIOServiceKey
);
2612 case kIOBSDNameMatching
:
2613 dict
= IOBSDNameMatching( (const char *) input
);
2616 case kIOOFPathMatching
:
2617 dict
= IOOFPathMatching( (const char *) input
,
2618 matching
, sizeof( io_string_t
));
2626 return( kIOReturnUnsupported
);
2629 s
= OSSerialize::withCapacity(4096);
2631 err
= kIOReturnNoMemory
;
2635 if( !dict
->serialize( s
)) {
2636 err
= kIOReturnUnsupported
;
2640 if( s
->getLength() > sizeof( io_string_t
)) {
2641 err
= kIOReturnNoMemory
;
2644 strcpy( matching
, s
->text());
2656 /* Routine io_catalog_send_data */
2657 kern_return_t
is_io_catalog_send_data(
2658 mach_port_t master_port
,
2660 io_buf_ptr_t inData
,
2661 mach_msg_type_number_t inDataCount
,
2666 kern_return_t kr
= kIOReturnError
;
2668 //printf("io_catalog_send_data called. flag: %d\n", flag);
2670 if( master_port
!= master_device_port
)
2671 return kIOReturnNotPrivileged
;
2673 // FIXME: This is a hack. Should have own function for removeKernelLinker()
2674 if(flag
!= kIOCatalogRemoveKernelLinker
&& ( !inData
|| !inDataCount
) )
2675 return kIOReturnBadArgument
;
2678 kr
= vm_map_copyout( kernel_map
, &data
, (vm_map_copy_t
)inData
);
2679 if( kr
!= KERN_SUCCESS
)
2682 // must return success after vm_map_copyout() succeeds
2685 obj
= (OSObject
*)OSUnserializeXML((const char *)data
);
2686 vm_deallocate( kernel_map
, data
, inDataCount
);
2688 *result
= kIOReturnNoMemory
;
2689 return( KERN_SUCCESS
);
2695 case kIOCatalogAddDrivers
:
2696 case kIOCatalogAddDriversNoMatch
: {
2699 array
= OSDynamicCast(OSArray
, obj
);
2701 if ( !gIOCatalogue
->addDrivers( array
,
2702 flag
== kIOCatalogAddDrivers
) ) {
2703 kr
= kIOReturnError
;
2707 kr
= kIOReturnBadArgument
;
2712 case kIOCatalogRemoveDrivers
:
2713 case kIOCatalogRemoveDriversNoMatch
: {
2714 OSDictionary
* dict
;
2716 dict
= OSDynamicCast(OSDictionary
, obj
);
2718 if ( !gIOCatalogue
->removeDrivers( dict
,
2719 flag
== kIOCatalogRemoveDrivers
) ) {
2720 kr
= kIOReturnError
;
2724 kr
= kIOReturnBadArgument
;
2729 case kIOCatalogStartMatching
: {
2730 OSDictionary
* dict
;
2732 dict
= OSDynamicCast(OSDictionary
, obj
);
2734 if ( !gIOCatalogue
->startMatching( dict
) ) {
2735 kr
= kIOReturnError
;
2739 kr
= kIOReturnBadArgument
;
2744 case kIOCatalogRemoveKernelLinker
: {
2745 if (gIOCatalogue
->removeKernelLinker() != KERN_SUCCESS
) {
2746 kr
= kIOReturnError
;
2748 kr
= kIOReturnSuccess
;
2754 kr
= kIOReturnBadArgument
;
2758 if (obj
) obj
->release();
2761 return( KERN_SUCCESS
);
2764 /* Routine io_catalog_terminate */
2765 kern_return_t
is_io_catalog_terminate(
2766 mach_port_t master_port
,
2772 if( master_port
!= master_device_port
)
2773 return kIOReturnNotPrivileged
;
2775 kr
= IOUserClient::clientHasPrivilege( (void *) current_task(),
2776 kIOClientPrivilegeAdministrator
);
2777 if( kIOReturnSuccess
!= kr
)
2781 case kIOCatalogServiceTerminate
:
2783 IOService
* service
;
2785 iter
= IORegistryIterator::iterateOver(gIOServicePlane
,
2786 kIORegistryIterateRecursively
);
2788 return kIOReturnNoMemory
;
2792 while( (service
= (IOService
*)iter
->getNextObject()) ) {
2793 if( service
->metaCast(name
)) {
2794 if ( !service
->terminate( kIOServiceRequired
2795 | kIOServiceSynchronous
) ) {
2796 kr
= kIOReturnUnsupported
;
2801 } while( !service
&& !iter
->isValid());
2805 case kIOCatalogModuleUnload
:
2806 case kIOCatalogModuleTerminate
:
2807 kr
= gIOCatalogue
->terminateDriversForModule(name
,
2808 flag
== kIOCatalogModuleUnload
);
2812 kr
= kIOReturnBadArgument
;
2819 /* Routine io_catalog_get_data */
2820 kern_return_t
is_io_catalog_get_data(
2821 mach_port_t master_port
,
2823 io_buf_ptr_t
*outData
,
2824 mach_msg_type_number_t
*outDataCount
)
2826 kern_return_t kr
= kIOReturnSuccess
;
2829 if( master_port
!= master_device_port
)
2830 return kIOReturnNotPrivileged
;
2832 //printf("io_catalog_get_data called. flag: %d\n", flag);
2834 s
= OSSerialize::withCapacity(4096);
2836 return kIOReturnNoMemory
;
2840 kr
= gIOCatalogue
->serializeData(flag
, s
);
2842 if ( kr
== kIOReturnSuccess
) {
2847 size
= s
->getLength();
2848 kr
= vm_allocate(kernel_map
, &data
, size
, true);
2849 if ( kr
== kIOReturnSuccess
) {
2850 bcopy(s
->text(), (void *)data
, size
);
2851 kr
= vm_map_copyin(kernel_map
, data
, size
, true, ©
);
2852 *outData
= (char *)copy
;
2853 *outDataCount
= size
;
2862 /* Routine io_catalog_get_gen_count */
2863 kern_return_t
is_io_catalog_get_gen_count(
2864 mach_port_t master_port
,
2867 if( master_port
!= master_device_port
)
2868 return kIOReturnNotPrivileged
;
2870 //printf("io_catalog_get_gen_count called.\n");
2873 return kIOReturnBadArgument
;
2875 *genCount
= gIOCatalogue
->getGenerationCount();
2877 return kIOReturnSuccess
;
2880 /* Routine io_catalog_module_loaded */
2881 kern_return_t
is_io_catalog_module_loaded(
2882 mach_port_t master_port
,
2885 if( master_port
!= master_device_port
)
2886 return kIOReturnNotPrivileged
;
2888 //printf("io_catalog_module_loaded called. name %s\n", name);
2891 return kIOReturnBadArgument
;
2893 gIOCatalogue
->moduleHasLoaded(name
);
2895 return kIOReturnSuccess
;
2898 kern_return_t
is_io_catalog_reset(
2899 mach_port_t master_port
,
2902 if( master_port
!= master_device_port
)
2903 return kIOReturnNotPrivileged
;
2906 case kIOCatalogResetDefault
:
2907 gIOCatalogue
->reset();
2911 return kIOReturnBadArgument
;
2914 return kIOReturnSuccess
;
2917 kern_return_t
iokit_user_client_trap(io_object_t userClientRef
, UInt32 index
,
2918 void *p1
, void *p2
, void *p3
,
2919 void *p4
, void *p5
, void *p6
)
2921 kern_return_t result
= kIOReturnBadArgument
;
2922 IOUserClient
*userClient
;
2924 if ((userClient
= OSDynamicCast(IOUserClient
,
2925 iokit_lookup_connect_ref_current_task(userClientRef
)))) {
2926 IOExternalTrap
*trap
;
2927 IOService
*target
= NULL
;
2929 trap
= userClient
->getTargetAndTrapForIndex(&target
, index
);
2931 if (trap
&& target
) {
2937 result
= (target
->*func
)(p1
, p2
, p3
, p4
, p5
, p6
);
2941 userClient
->release();
2949 OSMetaClassDefineReservedUnused(IOUserClient
, 0);
2950 OSMetaClassDefineReservedUnused(IOUserClient
, 1);
2951 OSMetaClassDefineReservedUnused(IOUserClient
, 2);
2952 OSMetaClassDefineReservedUnused(IOUserClient
, 3);
2953 OSMetaClassDefineReservedUnused(IOUserClient
, 4);
2954 OSMetaClassDefineReservedUnused(IOUserClient
, 5);
2955 OSMetaClassDefineReservedUnused(IOUserClient
, 6);
2956 OSMetaClassDefineReservedUnused(IOUserClient
, 7);
2957 OSMetaClassDefineReservedUnused(IOUserClient
, 8);
2958 OSMetaClassDefineReservedUnused(IOUserClient
, 9);
2959 OSMetaClassDefineReservedUnused(IOUserClient
, 10);
2960 OSMetaClassDefineReservedUnused(IOUserClient
, 11);
2961 OSMetaClassDefineReservedUnused(IOUserClient
, 12);
2962 OSMetaClassDefineReservedUnused(IOUserClient
, 13);
2963 OSMetaClassDefineReservedUnused(IOUserClient
, 14);
2964 OSMetaClassDefineReservedUnused(IOUserClient
, 15);