2 * Copyright (c) 1998-2004 Apple Computer, Inc. All rights reserved.
4 * @APPLE_LICENSE_OSREFERENCE_HEADER_START@
6 * This file contains Original Code and/or Modifications of Original Code
7 * as defined in and that are subject to the Apple Public Source License
8 * Version 2.0 (the 'License'). You may not use this file except in
9 * compliance with the License. The rights granted to you under the
10 * License may not be used to create, or enable the creation or
11 * redistribution of, unlawful or unlicensed copies of an Apple operating
12 * system, or to circumvent, violate, or enable the circumvention or
13 * violation of, any terms of an Apple operating system software license
16 * Please obtain a copy of the License at
17 * http://www.opensource.apple.com/apsl/ and read it before using this
20 * The Original Code and all software distributed under the License are
21 * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
22 * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
23 * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
24 * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
25 * Please see the License for the specific language governing rights and
26 * limitations under the License.
28 * @APPLE_LICENSE_OSREFERENCE_HEADER_END@
32 #include <IOKit/IOKitServer.h>
33 #include <IOKit/IOUserClient.h>
34 #include <IOKit/IOService.h>
35 #include <IOKit/IOService.h>
36 #include <IOKit/IORegistryEntry.h>
37 #include <IOKit/IOCatalogue.h>
38 #include <IOKit/IOMemoryDescriptor.h>
39 #include <IOKit/IOLib.h>
41 #include <IOKit/assert.h>
43 #include "IOServicePrivate.h"
45 /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
47 // definitions we should get from osfmk
49 //typedef struct ipc_port * ipc_port_t;
50 typedef natural_t ipc_kobject_type_t
;
52 #define IKOT_IOKIT_SPARE 27
53 #define IKOT_IOKIT_CONNECT 29
54 #define IKOT_IOKIT_OBJECT 30
58 extern ipc_port_t
iokit_alloc_object_port( io_object_t obj
,
59 ipc_kobject_type_t type
);
61 extern kern_return_t
iokit_destroy_object_port( ipc_port_t port
);
63 extern mach_port_name_t
iokit_make_send_right( task_t task
,
64 io_object_t obj
, ipc_kobject_type_t type
);
66 extern kern_return_t
iokit_mod_send_right( task_t task
, mach_port_name_t name
, mach_port_delta_t delta
);
68 extern io_object_t
iokit_lookup_connect_ref(io_object_t clientRef
, ipc_space_t task
);
70 extern io_object_t
iokit_lookup_connect_ref_current_task(io_object_t clientRef
);
72 extern ipc_port_t master_device_port
;
74 extern void iokit_retain_port( ipc_port_t port
);
75 extern void iokit_release_port( ipc_port_t port
);
77 extern kern_return_t
iokit_switch_object_port( ipc_port_t port
, io_object_t obj
, ipc_kobject_type_t type
);
79 #include <mach/mach_traps.h>
80 #include <vm/vm_map.h>
85 /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
87 // IOMachPort maps OSObjects to ports, avoiding adding an ivar to OSObject.
89 class IOMachPort
: public OSObject
91 OSDeclareDefaultStructors(IOMachPort
)
98 static IOMachPort
* portForObject( OSObject
* obj
,
99 ipc_kobject_type_t type
);
100 static bool noMoreSendersForObject( OSObject
* obj
,
101 ipc_kobject_type_t type
, mach_port_mscount_t
* mscount
);
102 static void releasePortForObject( OSObject
* obj
,
103 ipc_kobject_type_t type
);
104 static void setHoldDestroy( OSObject
* obj
, ipc_kobject_type_t type
);
106 static OSDictionary
* dictForType( ipc_kobject_type_t type
);
108 static mach_port_name_t
makeSendRightForTask( task_t task
,
109 io_object_t obj
, ipc_kobject_type_t type
);
114 #define super OSObject
115 OSDefineMetaClassAndStructors(IOMachPort
, OSObject
)
117 static IOLock
* gIOObjectPortLock
;
119 /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
121 // not in dictForType() for debugging ease
122 static OSDictionary
* gIOObjectPorts
;
123 static OSDictionary
* gIOConnectPorts
;
125 OSDictionary
* IOMachPort::dictForType( ipc_kobject_type_t type
)
127 OSDictionary
** dict
;
129 if( IKOT_IOKIT_OBJECT
== type
)
130 dict
= &gIOObjectPorts
;
131 else if( IKOT_IOKIT_CONNECT
== type
)
132 dict
= &gIOConnectPorts
;
137 *dict
= OSDictionary::withCapacity( 1 );
142 IOMachPort
* IOMachPort::portForObject ( OSObject
* obj
,
143 ipc_kobject_type_t type
)
145 IOMachPort
* inst
= 0;
148 IOTakeLock( gIOObjectPortLock
);
152 dict
= dictForType( type
);
156 if( (inst
= (IOMachPort
*)
157 dict
->getObject( (const OSSymbol
*) obj
))) {
163 inst
= new IOMachPort
;
164 if( inst
&& !inst
->init()) {
169 inst
->port
= iokit_alloc_object_port( obj
, type
);
172 dict
->setObject( (const OSSymbol
*) obj
, inst
);
182 IOUnlock( gIOObjectPortLock
);
187 bool IOMachPort::noMoreSendersForObject( OSObject
* obj
,
188 ipc_kobject_type_t type
, mach_port_mscount_t
* mscount
)
191 IOMachPort
* machPort
;
192 bool destroyed
= true;
194 IOTakeLock( gIOObjectPortLock
);
196 if( (dict
= dictForType( type
))) {
199 machPort
= (IOMachPort
*) dict
->getObject( (const OSSymbol
*) obj
);
201 destroyed
= (machPort
->mscount
== *mscount
);
203 dict
->removeObject( (const OSSymbol
*) obj
);
205 *mscount
= machPort
->mscount
;
210 IOUnlock( gIOObjectPortLock
);
215 void IOMachPort::releasePortForObject( OSObject
* obj
,
216 ipc_kobject_type_t type
)
219 IOMachPort
* machPort
;
221 IOTakeLock( gIOObjectPortLock
);
223 if( (dict
= dictForType( type
))) {
225 machPort
= (IOMachPort
*) dict
->getObject( (const OSSymbol
*) obj
);
226 if( machPort
&& !machPort
->holdDestroy
)
227 dict
->removeObject( (const OSSymbol
*) obj
);
231 IOUnlock( gIOObjectPortLock
);
234 void IOMachPort::setHoldDestroy( OSObject
* obj
, ipc_kobject_type_t type
)
237 IOMachPort
* machPort
;
239 IOLockLock( gIOObjectPortLock
);
241 if( (dict
= dictForType( type
))) {
242 machPort
= (IOMachPort
*) dict
->getObject( (const OSSymbol
*) obj
);
244 machPort
->holdDestroy
= true;
247 IOLockUnlock( gIOObjectPortLock
);
250 void IOUserClient::destroyUserReferences( OSObject
* obj
)
252 IOMachPort::releasePortForObject( obj
, IKOT_IOKIT_OBJECT
);
255 // IOMachPort::releasePortForObject( obj, IKOT_IOKIT_CONNECT );
259 IOTakeLock( gIOObjectPortLock
);
262 if( (dict
= IOMachPort::dictForType( IKOT_IOKIT_CONNECT
)))
265 port
= (IOMachPort
*) dict
->getObject( (const OSSymbol
*) obj
);
269 if ((uc
= OSDynamicCast(IOUserClient
, obj
)) && uc
->mappings
)
271 dict
->setObject((const OSSymbol
*) uc
->mappings
, port
);
272 iokit_switch_object_port(port
->port
, uc
->mappings
, IKOT_IOKIT_CONNECT
);
274 uc
->mappings
->release();
277 dict
->removeObject( (const OSSymbol
*) obj
);
281 IOUnlock( gIOObjectPortLock
);
284 mach_port_name_t
IOMachPort::makeSendRightForTask( task_t task
,
285 io_object_t obj
, ipc_kobject_type_t type
)
287 return( iokit_make_send_right( task
, obj
, type
));
290 void IOMachPort::free( void )
293 iokit_destroy_object_port( port
);
297 /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
299 class IOUserNotification
: public OSIterator
301 OSDeclareDefaultStructors(IOUserNotification
)
303 IONotifier
* holdNotify
;
308 virtual bool init( void );
311 virtual void setNotification( IONotifier
* obj
);
313 virtual void reset();
314 virtual bool isValid();
317 /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
321 // functions called from osfmk/device/iokit_rpc.c
324 iokit_add_reference( io_object_t obj
)
331 iokit_remove_reference( io_object_t obj
)
338 iokit_port_for_object( io_object_t obj
, ipc_kobject_type_t type
)
340 IOMachPort
* machPort
;
343 if( (machPort
= IOMachPort::portForObject( obj
, type
))) {
345 port
= machPort
->port
;
347 iokit_retain_port( port
);
358 iokit_client_died( io_object_t obj
, ipc_port_t
/* port */,
359 ipc_kobject_type_t type
, mach_port_mscount_t
* mscount
)
361 IOUserClient
* client
;
363 IOUserNotification
* notify
;
365 if( !IOMachPort::noMoreSendersForObject( obj
, type
, mscount
))
366 return( kIOReturnNotReady
);
368 if( IKOT_IOKIT_CONNECT
== type
)
370 if( (client
= OSDynamicCast( IOUserClient
, obj
)))
371 client
->clientDied();
373 else if( IKOT_IOKIT_OBJECT
== type
)
375 if( (map
= OSDynamicCast( IOMemoryMap
, obj
)))
377 else if( (notify
= OSDynamicCast( IOUserNotification
, obj
)))
378 notify
->setNotification( 0 );
381 return( kIOReturnSuccess
);
386 /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
388 class IOServiceUserNotification
: public IOUserNotification
390 OSDeclareDefaultStructors(IOServiceUserNotification
)
393 mach_msg_header_t msgHdr
;
394 OSNotificationHeader notifyHeader
;
397 enum { kMaxOutstanding
= 1024 };
402 OSObject
* lastEntry
;
407 virtual bool init( mach_port_t port
, natural_t type
,
408 OSAsyncReference reference
);
411 static bool _handler( void * target
,
412 void * ref
, IOService
* newService
);
413 virtual bool handler( void * ref
, IOService
* newService
);
415 virtual OSObject
* getNextObject();
418 class IOServiceMessageUserNotification
: public IOUserNotification
420 OSDeclareDefaultStructors(IOServiceMessageUserNotification
)
423 mach_msg_header_t msgHdr
;
424 mach_msg_body_t msgBody
;
425 mach_msg_port_descriptor_t ports
[1];
426 OSNotificationHeader notifyHeader
;
434 virtual bool init( mach_port_t port
, natural_t type
,
435 OSAsyncReference reference
, vm_size_t extraSize
);
438 static IOReturn
_handler( void * target
, void * ref
,
439 UInt32 messageType
, IOService
* provider
,
440 void * messageArgument
, vm_size_t argSize
);
441 virtual IOReturn
handler( void * ref
,
442 UInt32 messageType
, IOService
* provider
,
443 void * messageArgument
, vm_size_t argSize
);
445 virtual OSObject
* getNextObject();
448 /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
451 #define super OSIterator
452 OSDefineMetaClass( IOUserNotification
, OSIterator
)
453 OSDefineAbstractStructors( IOUserNotification
, OSIterator
)
455 /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
457 bool IOUserNotification::init( void )
462 lock
= IOLockAlloc();
469 void IOUserNotification::free( void )
472 holdNotify
->remove();
473 // can't be in handler now
482 void IOUserNotification::setNotification( IONotifier
* notify
)
484 IONotifier
* previousNotify
;
486 IOLockLock( gIOObjectPortLock
);
488 previousNotify
= holdNotify
;
491 IOLockUnlock( gIOObjectPortLock
);
494 previousNotify
->remove();
497 void IOUserNotification::reset()
502 bool IOUserNotification::isValid()
507 /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
510 #define super IOUserNotification
511 OSDefineMetaClassAndStructors(IOServiceUserNotification
, IOUserNotification
)
513 /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
515 bool IOServiceUserNotification::init( mach_port_t port
, natural_t type
,
516 OSAsyncReference reference
)
518 newSet
= OSArray::withCapacity( 1 );
522 msgSize
= sizeof( PingMsg
) + 0;
523 pingMsg
= (PingMsg
*) IOMalloc( msgSize
);
527 bzero( pingMsg
, msgSize
);
529 pingMsg
->msgHdr
.msgh_remote_port
= port
;
530 pingMsg
->msgHdr
.msgh_bits
= MACH_MSGH_BITS(
531 MACH_MSG_TYPE_COPY_SEND
/*remote*/,
532 MACH_MSG_TYPE_MAKE_SEND
/*local*/);
533 pingMsg
->msgHdr
.msgh_size
= msgSize
;
534 pingMsg
->msgHdr
.msgh_id
= kOSNotificationMessageID
;
536 pingMsg
->notifyHeader
.size
= 0;
537 pingMsg
->notifyHeader
.type
= type
;
538 bcopy( reference
, pingMsg
->notifyHeader
.reference
, sizeof(OSAsyncReference
) );
540 return( super::init() );
543 void IOServiceUserNotification::free( void )
548 OSObject
* _lastEntry
;
552 _lastEntry
= lastEntry
;
557 if( _pingMsg
&& _msgSize
)
558 IOFree( _pingMsg
, _msgSize
);
561 _lastEntry
->release();
567 bool IOServiceUserNotification::_handler( void * target
,
568 void * ref
, IOService
* newService
)
570 return( ((IOServiceUserNotification
*) target
)->handler( ref
, newService
));
573 bool IOServiceUserNotification::handler( void * ref
,
574 IOService
* newService
)
578 ipc_port_t port
= NULL
;
579 bool sendPing
= false;
583 count
= newSet
->getCount();
584 if( count
< kMaxOutstanding
) {
586 newSet
->setObject( newService
);
587 if( (sendPing
= (armed
&& (0 == count
))))
593 if( kIOServiceTerminatedNotificationType
== pingMsg
->notifyHeader
.type
)
594 IOMachPort::setHoldDestroy( newService
, IKOT_IOKIT_OBJECT
);
597 if( (port
= iokit_port_for_object( this, IKOT_IOKIT_OBJECT
) ))
598 pingMsg
->msgHdr
.msgh_local_port
= port
;
600 pingMsg
->msgHdr
.msgh_local_port
= NULL
;
602 kr
= mach_msg_send_from_kernel( &pingMsg
->msgHdr
,
603 pingMsg
->msgHdr
.msgh_size
);
605 iokit_release_port( port
);
607 if( KERN_SUCCESS
!= kr
)
608 IOLog("%s: mach_msg_send_from_kernel {%x}\n", __FILE__
, kr
);
614 OSObject
* IOServiceUserNotification::getNextObject()
622 lastEntry
->release();
624 count
= newSet
->getCount();
626 result
= newSet
->getObject( count
- 1 );
628 newSet
->removeObject( count
- 1);
640 /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
642 OSDefineMetaClassAndStructors(IOServiceMessageUserNotification
, IOUserNotification
)
644 /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
646 bool IOServiceMessageUserNotification::init( mach_port_t port
, natural_t type
,
647 OSAsyncReference reference
, vm_size_t extraSize
)
650 extraSize
+= sizeof(IOServiceInterestContent
);
651 msgSize
= sizeof( PingMsg
) + extraSize
;
652 pingMsg
= (PingMsg
*) IOMalloc( msgSize
);
656 bzero( pingMsg
, msgSize
);
658 pingMsg
->msgHdr
.msgh_remote_port
= port
;
659 pingMsg
->msgHdr
.msgh_bits
= MACH_MSGH_BITS_COMPLEX
661 MACH_MSG_TYPE_COPY_SEND
/*remote*/,
662 MACH_MSG_TYPE_MAKE_SEND
/*local*/);
663 pingMsg
->msgHdr
.msgh_size
= msgSize
;
664 pingMsg
->msgHdr
.msgh_id
= kOSNotificationMessageID
;
666 pingMsg
->msgBody
.msgh_descriptor_count
= 1;
668 pingMsg
->ports
[0].name
= 0;
669 pingMsg
->ports
[0].disposition
= MACH_MSG_TYPE_MAKE_SEND
;
670 pingMsg
->ports
[0].type
= MACH_MSG_PORT_DESCRIPTOR
;
672 pingMsg
->notifyHeader
.size
= extraSize
;
673 pingMsg
->notifyHeader
.type
= type
;
674 bcopy( reference
, pingMsg
->notifyHeader
.reference
, sizeof(OSAsyncReference
) );
676 return( super::init() );
679 void IOServiceMessageUserNotification::free( void )
689 if( _pingMsg
&& _msgSize
)
690 IOFree( _pingMsg
, _msgSize
);
693 IOReturn
IOServiceMessageUserNotification::_handler( void * target
, void * ref
,
694 UInt32 messageType
, IOService
* provider
,
695 void * argument
, vm_size_t argSize
)
697 return( ((IOServiceMessageUserNotification
*) target
)->handler(
698 ref
, messageType
, provider
, argument
, argSize
));
701 IOReturn
IOServiceMessageUserNotification::handler( void * ref
,
702 UInt32 messageType
, IOService
* provider
,
703 void * messageArgument
, vm_size_t argSize
)
706 ipc_port_t thisPort
, providerPort
;
707 IOServiceInterestContent
* data
= (IOServiceInterestContent
*)
708 pingMsg
->notifyHeader
.content
;
710 data
->messageType
= messageType
;
712 argSize
= sizeof( messageArgument
);
713 data
->messageArgument
[0] = messageArgument
;
715 if( argSize
> kIOUserNotifyMaxMessageSize
)
716 argSize
= kIOUserNotifyMaxMessageSize
;
717 bcopy( messageArgument
, data
->messageArgument
, argSize
);
719 pingMsg
->msgHdr
.msgh_size
= sizeof( PingMsg
)
720 + sizeof( IOServiceInterestContent
)
721 - sizeof( data
->messageArgument
)
724 providerPort
= iokit_port_for_object( provider
, IKOT_IOKIT_OBJECT
);
725 pingMsg
->ports
[0].name
= providerPort
;
726 thisPort
= iokit_port_for_object( this, IKOT_IOKIT_OBJECT
);
727 pingMsg
->msgHdr
.msgh_local_port
= thisPort
;
728 kr
= mach_msg_send_from_kernel( &pingMsg
->msgHdr
,
729 pingMsg
->msgHdr
.msgh_size
);
731 iokit_release_port( thisPort
);
733 iokit_release_port( providerPort
);
735 if( KERN_SUCCESS
!= kr
)
736 IOLog("%s: mach_msg_send_from_kernel {%x}\n", __FILE__
, kr
);
738 return( kIOReturnSuccess
);
741 OSObject
* IOServiceMessageUserNotification::getNextObject()
746 /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
749 #define super IOService
750 OSDefineMetaClassAndAbstractStructors( IOUserClient
, IOService
)
752 void IOUserClient::initialize( void )
754 gIOObjectPortLock
= IOLockAlloc();
756 assert( gIOObjectPortLock
);
759 void IOUserClient::setAsyncReference(OSAsyncReference asyncRef
,
760 mach_port_t wakePort
,
761 void *callback
, void *refcon
)
763 asyncRef
[kIOAsyncReservedIndex
] = (natural_t
) wakePort
;
764 asyncRef
[kIOAsyncCalloutFuncIndex
] = (natural_t
) callback
;
765 asyncRef
[kIOAsyncCalloutRefconIndex
] = (natural_t
) refcon
;
768 IOReturn
IOUserClient::clientHasPrivilege( void * securityToken
,
769 const char * privilegeName
)
772 security_token_t token
;
773 mach_msg_type_number_t count
;
775 count
= TASK_SECURITY_TOKEN_COUNT
;
776 kr
= task_info( (task_t
) securityToken
, TASK_SECURITY_TOKEN
,
777 (task_info_t
) &token
, &count
);
779 if (KERN_SUCCESS
!= kr
)
781 else if (!strcmp(privilegeName
, kIOClientPrivilegeAdministrator
))
783 if (0 != token
.val
[0])
784 kr
= kIOReturnNotPrivileged
;
786 else if (!strcmp(privilegeName
, kIOClientPrivilegeLocalUser
))
789 OSDictionary
* user
= 0;
791 if ((array
= OSDynamicCast(OSArray
,
792 IORegistryEntry::getRegistryRoot()->copyProperty(gIOConsoleUsersKey
))))
794 for (unsigned int idx
= 0;
795 (user
= OSDynamicCast(OSDictionary
, array
->getObject(idx
)));
799 if ((num
= OSDynamicCast(OSNumber
, user
->getObject(gIOConsoleSessionUIDKey
)))
800 && (token
.val
[0] == num
->unsigned32BitValue()))
806 kr
= kIOReturnNotPrivileged
;
809 kr
= kIOReturnUnsupported
;
814 bool IOUserClient::initWithTask(task_t owningTask
,
818 if( getPropertyTable())
821 return super::init();
824 bool IOUserClient::initWithTask(task_t owningTask
,
827 OSDictionary
* properties
)
831 ok
= super::init( properties
);
832 ok
&= initWithTask( owningTask
, securityID
, type
);
837 void IOUserClient::free()
845 IOReturn
IOUserClient::clientDied( void )
847 return( clientClose());
850 IOReturn
IOUserClient::clientClose( void )
852 return( kIOReturnUnsupported
);
855 IOService
* IOUserClient::getService( void )
860 IOReturn
IOUserClient::registerNotificationPort(
861 mach_port_t
/* port */,
865 return( kIOReturnUnsupported
);
868 IOReturn
IOUserClient::getNotificationSemaphore( UInt32 notification_type
,
869 semaphore_t
* semaphore
)
871 return( kIOReturnUnsupported
);
874 IOReturn
IOUserClient::connectClient( IOUserClient
* /* client */ )
876 return( kIOReturnUnsupported
);
879 IOReturn
IOUserClient::clientMemoryForType( UInt32 type
,
880 IOOptionBits
* options
,
881 IOMemoryDescriptor
** memory
)
883 return( kIOReturnUnsupported
);
886 IOMemoryMap
* IOUserClient::mapClientMemory(
889 IOOptionBits mapFlags
,
890 IOVirtualAddress atAddress
)
893 IOOptionBits options
= 0;
894 IOMemoryDescriptor
* memory
;
895 IOMemoryMap
* map
= 0;
897 err
= clientMemoryForType( (UInt32
) type
, &options
, &memory
);
899 if( memory
&& (kIOReturnSuccess
== err
)) {
901 options
= (options
& ~kIOMapUserOptionsMask
)
902 | (mapFlags
& kIOMapUserOptionsMask
);
903 map
= memory
->map( task
, atAddress
, options
);
910 IOReturn
IOUserClient::exportObjectToClient(task_t task
,
911 OSObject
*obj
, io_object_t
*clientObj
)
913 mach_port_name_t name
;
915 name
= IOMachPort::makeSendRightForTask( task
, obj
, IKOT_IOKIT_OBJECT
);
918 *(mach_port_name_t
*)clientObj
= name
;
919 return kIOReturnSuccess
;
922 IOExternalMethod
* IOUserClient::getExternalMethodForIndex( UInt32
/* index */)
927 IOExternalAsyncMethod
* IOUserClient::getExternalAsyncMethodForIndex( UInt32
/* index */)
932 IOExternalMethod
* IOUserClient::
933 getTargetAndMethodForIndex(IOService
**targetP
, UInt32 index
)
935 IOExternalMethod
*method
= getExternalMethodForIndex(index
);
938 *targetP
= (IOService
*) method
->object
;
943 IOExternalAsyncMethod
* IOUserClient::
944 getAsyncTargetAndMethodForIndex(IOService
** targetP
, UInt32 index
)
946 IOExternalAsyncMethod
*method
= getExternalAsyncMethodForIndex(index
);
949 *targetP
= (IOService
*) method
->object
;
954 IOExternalTrap
* IOUserClient::
955 getExternalTrapForIndex(UInt32 index
)
960 IOExternalTrap
* IOUserClient::
961 getTargetAndTrapForIndex(IOService
** targetP
, UInt32 index
)
963 IOExternalTrap
*trap
= getExternalTrapForIndex(index
);
966 *targetP
= trap
->object
;
972 IOReturn
IOUserClient::sendAsyncResult(OSAsyncReference reference
,
973 IOReturn result
, void *args
[], UInt32 numArgs
)
976 mach_msg_header_t msgHdr
;
977 OSNotificationHeader notifyHdr
;
978 IOAsyncCompletionContent asyncContent
;
979 void * args
[kMaxAsyncArgs
];
982 mach_port_t replyPort
;
985 // If no reply port, do nothing.
986 replyPort
= (mach_port_t
) reference
[0];
987 if(replyPort
== MACH_PORT_NULL
)
988 return kIOReturnSuccess
;
990 if(numArgs
> kMaxAsyncArgs
)
991 return kIOReturnMessageTooLarge
;
992 replyMsg
.msgHdr
.msgh_bits
= MACH_MSGH_BITS(MACH_MSG_TYPE_COPY_SEND
/*remote*/,
994 replyMsg
.msgHdr
.msgh_size
=
995 sizeof(replyMsg
) - (kMaxAsyncArgs
-numArgs
)*sizeof(void *);
996 replyMsg
.msgHdr
.msgh_remote_port
= replyPort
;
997 replyMsg
.msgHdr
.msgh_local_port
= 0;
998 replyMsg
.msgHdr
.msgh_id
= kOSNotificationMessageID
;
1000 replyMsg
.notifyHdr
.size
= sizeof(IOAsyncCompletionContent
)
1001 + numArgs
*sizeof(void *);
1002 replyMsg
.notifyHdr
.type
= kIOAsyncCompletionNotificationType
;
1003 bcopy( reference
, replyMsg
.notifyHdr
.reference
, sizeof(OSAsyncReference
));
1005 replyMsg
.asyncContent
.result
= result
;
1007 bcopy(args
, replyMsg
.args
, sizeof(void *)*numArgs
);
1008 kr
= mach_msg_send_from_kernel( &replyMsg
.msgHdr
,
1009 replyMsg
.msgHdr
.msgh_size
);
1010 if( KERN_SUCCESS
!= kr
)
1011 IOLog("%s: mach_msg_send_from_kernel {%x}\n", __FILE__
, kr
);
1015 /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
1019 #define CHECK(cls,obj,out) \
1021 if( !(out = OSDynamicCast( cls, obj))) \
1022 return( kIOReturnBadArgument )
1024 /* Routine io_object_get_class */
1025 kern_return_t
is_io_object_get_class(
1027 io_name_t className
)
1029 const OSMetaClass
* my_obj
= NULL
;
1032 return( kIOReturnBadArgument
);
1034 my_obj
= object
->getMetaClass();
1036 return (kIOReturnNotFound
);
1039 strcpy( className
, my_obj
->getClassName());
1040 return( kIOReturnSuccess
);
1043 /* Routine io_object_get_superclass */
1044 kern_return_t
is_io_object_get_superclass(
1045 mach_port_t master_port
,
1047 io_name_t class_name
)
1049 const OSMetaClass
* my_obj
= NULL
;
1050 const OSMetaClass
* superclass
= NULL
;
1051 const OSSymbol
*my_name
= NULL
;
1052 const char *my_cstr
= NULL
;
1054 if (!obj_name
|| !class_name
)
1055 return (kIOReturnBadArgument
);
1057 if( master_port
!= master_device_port
)
1058 return( kIOReturnNotPrivileged
);
1060 my_name
= OSSymbol::withCString(obj_name
);
1063 my_obj
= OSMetaClass::getMetaClassWithName(my_name
);
1067 superclass
= my_obj
->getSuperClass();
1071 return( kIOReturnNotFound
);
1074 my_cstr
= superclass
->getClassName();
1077 strncpy(class_name
, my_cstr
, sizeof(io_name_t
)-1);
1078 return( kIOReturnSuccess
);
1080 return (kIOReturnNotFound
);
1083 /* Routine io_object_get_bundle_identifier */
1084 kern_return_t
is_io_object_get_bundle_identifier(
1085 mach_port_t master_port
,
1087 io_name_t bundle_name
)
1089 const OSMetaClass
* my_obj
= NULL
;
1090 const OSSymbol
*my_name
= NULL
;
1091 const OSSymbol
*identifier
= NULL
;
1092 const char *my_cstr
= NULL
;
1094 if (!obj_name
|| !bundle_name
)
1095 return (kIOReturnBadArgument
);
1097 if( master_port
!= master_device_port
)
1098 return( kIOReturnNotPrivileged
);
1100 my_name
= OSSymbol::withCString(obj_name
);
1103 my_obj
= OSMetaClass::getMetaClassWithName(my_name
);
1108 identifier
= my_obj
->getKmodName();
1111 return( kIOReturnNotFound
);
1114 my_cstr
= identifier
->getCStringNoCopy();
1116 strncpy(bundle_name
, identifier
->getCStringNoCopy(), sizeof(io_name_t
)-1);
1117 return( kIOReturnSuccess
);
1120 return (kIOReturnBadArgument
);
1123 /* Routine io_object_conforms_to */
1124 kern_return_t
is_io_object_conforms_to(
1126 io_name_t className
,
1127 boolean_t
*conforms
)
1130 return( kIOReturnBadArgument
);
1132 *conforms
= (0 != object
->metaCast( className
));
1133 return( kIOReturnSuccess
);
1136 /* Routine io_object_get_retain_count */
1137 kern_return_t
is_io_object_get_retain_count(
1142 return( kIOReturnBadArgument
);
1144 *retainCount
= object
->getRetainCount();
1145 return( kIOReturnSuccess
);
1148 /* Routine io_iterator_next */
1149 kern_return_t
is_io_iterator_next(
1150 io_object_t iterator
,
1151 io_object_t
*object
)
1155 CHECK( OSIterator
, iterator
, iter
);
1157 obj
= iter
->getNextObject();
1161 return( kIOReturnSuccess
);
1163 return( kIOReturnNoDevice
);
1166 /* Routine io_iterator_reset */
1167 kern_return_t
is_io_iterator_reset(
1168 io_object_t iterator
)
1170 CHECK( OSIterator
, iterator
, iter
);
1174 return( kIOReturnSuccess
);
1177 /* Routine io_iterator_is_valid */
1178 kern_return_t
is_io_iterator_is_valid(
1179 io_object_t iterator
,
1180 boolean_t
*is_valid
)
1182 CHECK( OSIterator
, iterator
, iter
);
1184 *is_valid
= iter
->isValid();
1186 return( kIOReturnSuccess
);
1189 /* Routine io_service_match_property_table */
1190 kern_return_t
is_io_service_match_property_table(
1191 io_service_t _service
,
1192 io_string_t matching
,
1193 boolean_t
*matches
)
1195 CHECK( IOService
, _service
, service
);
1199 OSDictionary
* dict
;
1201 obj
= OSUnserializeXML( matching
);
1203 if( (dict
= OSDynamicCast( OSDictionary
, obj
))) {
1204 *matches
= service
->passiveMatch( dict
);
1205 kr
= kIOReturnSuccess
;
1207 kr
= kIOReturnBadArgument
;
1215 /* Routine io_service_match_property_table_ool */
1216 kern_return_t
is_io_service_match_property_table_ool(
1217 io_object_t service
,
1218 io_buf_ptr_t matching
,
1219 mach_msg_type_number_t matchingCnt
,
1221 boolean_t
*matches
)
1225 vm_map_offset_t map_data
;
1227 kr
= vm_map_copyout( kernel_map
, &map_data
, (vm_map_copy_t
) matching
);
1228 data
= CAST_DOWN(vm_offset_t
, map_data
);
1230 if( KERN_SUCCESS
== kr
) {
1231 // must return success after vm_map_copyout() succeeds
1232 *result
= is_io_service_match_property_table( service
,
1233 (char *) data
, matches
);
1234 vm_deallocate( kernel_map
, data
, matchingCnt
);
1240 /* Routine io_service_get_matching_services */
1241 kern_return_t
is_io_service_get_matching_services(
1242 mach_port_t master_port
,
1243 io_string_t matching
,
1244 io_iterator_t
*existing
)
1248 OSDictionary
* dict
;
1250 if( master_port
!= master_device_port
)
1251 return( kIOReturnNotPrivileged
);
1253 obj
= OSUnserializeXML( matching
);
1255 if( (dict
= OSDynamicCast( OSDictionary
, obj
))) {
1256 *existing
= IOService::getMatchingServices( dict
);
1257 kr
= kIOReturnSuccess
;
1259 kr
= kIOReturnBadArgument
;
1267 /* Routine io_service_get_matching_services_ool */
1268 kern_return_t
is_io_service_get_matching_services_ool(
1269 mach_port_t master_port
,
1270 io_buf_ptr_t matching
,
1271 mach_msg_type_number_t matchingCnt
,
1273 io_object_t
*existing
)
1277 vm_map_offset_t map_data
;
1279 kr
= vm_map_copyout( kernel_map
, &map_data
, (vm_map_copy_t
) matching
);
1280 data
= CAST_DOWN(vm_offset_t
, map_data
);
1282 if( KERN_SUCCESS
== kr
) {
1283 // must return success after vm_map_copyout() succeeds
1284 *result
= is_io_service_get_matching_services( master_port
,
1285 (char *) data
, existing
);
1286 vm_deallocate( kernel_map
, data
, matchingCnt
);
1292 /* Routine io_service_add_notification */
1293 kern_return_t
is_io_service_add_notification(
1294 mach_port_t master_port
,
1295 io_name_t notification_type
,
1296 io_string_t matching
,
1298 io_async_ref_t reference
,
1299 mach_msg_type_number_t referenceCnt
,
1300 io_object_t
* notification
)
1302 IOServiceUserNotification
* userNotify
= 0;
1303 IONotifier
* notify
= 0;
1304 const OSSymbol
* sym
;
1305 OSDictionary
* dict
;
1307 unsigned long int userMsgType
;
1310 if( master_port
!= master_device_port
)
1311 return( kIOReturnNotPrivileged
);
1314 err
= kIOReturnNoResources
;
1316 if( !(sym
= OSSymbol::withCString( notification_type
)))
1317 err
= kIOReturnNoResources
;
1319 if( !(dict
= OSDynamicCast( OSDictionary
,
1320 OSUnserializeXML( matching
)))) {
1321 err
= kIOReturnBadArgument
;
1325 if( (sym
== gIOPublishNotification
)
1326 || (sym
== gIOFirstPublishNotification
))
1327 userMsgType
= kIOServicePublishNotificationType
;
1328 else if( (sym
== gIOMatchedNotification
)
1329 || (sym
== gIOFirstMatchNotification
))
1330 userMsgType
= kIOServiceMatchedNotificationType
;
1331 else if( sym
== gIOTerminatedNotification
)
1332 userMsgType
= kIOServiceTerminatedNotificationType
;
1334 userMsgType
= kLastIOKitNotificationType
;
1336 userNotify
= new IOServiceUserNotification
;
1338 if( userNotify
&& !userNotify
->init( port
, userMsgType
,
1340 userNotify
->release();
1346 notify
= IOService::addNotification( sym
, dict
,
1347 &userNotify
->_handler
, userNotify
);
1350 *notification
= userNotify
;
1351 userNotify
->setNotification( notify
);
1352 err
= kIOReturnSuccess
;
1354 err
= kIOReturnUnsupported
;
1366 /* Routine io_service_add_notification_ool */
1367 kern_return_t
is_io_service_add_notification_ool(
1368 mach_port_t master_port
,
1369 io_name_t notification_type
,
1370 io_buf_ptr_t matching
,
1371 mach_msg_type_number_t matchingCnt
,
1372 mach_port_t wake_port
,
1373 io_async_ref_t reference
,
1374 mach_msg_type_number_t referenceCnt
,
1376 io_object_t
*notification
)
1380 vm_map_offset_t map_data
;
1382 kr
= vm_map_copyout( kernel_map
, &map_data
, (vm_map_copy_t
) matching
);
1383 data
= CAST_DOWN(vm_offset_t
, map_data
);
1385 if( KERN_SUCCESS
== kr
) {
1386 // must return success after vm_map_copyout() succeeds
1387 *result
= is_io_service_add_notification( master_port
, notification_type
,
1388 (char *) data
, wake_port
, reference
, referenceCnt
, notification
);
1389 vm_deallocate( kernel_map
, data
, matchingCnt
);
1396 /* Routine io_service_add_notification_old */
1397 kern_return_t
is_io_service_add_notification_old(
1398 mach_port_t master_port
,
1399 io_name_t notification_type
,
1400 io_string_t matching
,
1403 io_object_t
* notification
)
1405 return( is_io_service_add_notification( master_port
, notification_type
,
1406 matching
, port
, &ref
, 1, notification
));
1409 /* Routine io_service_add_message_notification */
1410 kern_return_t
is_io_service_add_interest_notification(
1411 io_object_t _service
,
1412 io_name_t type_of_interest
,
1414 io_async_ref_t reference
,
1415 mach_msg_type_number_t referenceCnt
,
1416 io_object_t
* notification
)
1419 IOServiceMessageUserNotification
* userNotify
= 0;
1420 IONotifier
* notify
= 0;
1421 const OSSymbol
* sym
;
1424 CHECK( IOService
, _service
, service
);
1426 err
= kIOReturnNoResources
;
1427 if( (sym
= OSSymbol::withCString( type_of_interest
))) do {
1429 userNotify
= new IOServiceMessageUserNotification
;
1431 if( userNotify
&& !userNotify
->init( port
, kIOServiceMessageNotificationType
,
1432 reference
, kIOUserNotifyMaxMessageSize
)) {
1433 userNotify
->release();
1439 notify
= service
->registerInterest( sym
,
1440 &userNotify
->_handler
, userNotify
);
1442 *notification
= userNotify
;
1443 userNotify
->setNotification( notify
);
1444 err
= kIOReturnSuccess
;
1446 err
= kIOReturnUnsupported
;
1455 /* Routine io_service_acknowledge_notification */
1456 kern_return_t
is_io_service_acknowledge_notification(
1457 io_object_t _service
,
1458 natural_t notify_ref
,
1459 natural_t response
)
1461 CHECK( IOService
, _service
, service
);
1463 return( service
->acknowledgeNotification( (IONotificationRef
) notify_ref
,
1464 (IOOptionBits
) response
));
1468 /* Routine io_connect_get_semaphore */
1469 kern_return_t
is_io_connect_get_notification_semaphore(
1470 io_connect_t connection
,
1471 natural_t notification_type
,
1472 semaphore_t
*semaphore
)
1474 CHECK( IOUserClient
, connection
, client
);
1476 return( client
->getNotificationSemaphore( (UInt32
) notification_type
,
1480 /* Routine io_registry_get_root_entry */
1481 kern_return_t
is_io_registry_get_root_entry(
1482 mach_port_t master_port
,
1485 IORegistryEntry
* entry
;
1487 if( master_port
!= master_device_port
)
1488 return( kIOReturnNotPrivileged
);
1490 entry
= IORegistryEntry::getRegistryRoot();
1495 return( kIOReturnSuccess
);
1498 /* Routine io_registry_create_iterator */
1499 kern_return_t
is_io_registry_create_iterator(
1500 mach_port_t master_port
,
1503 io_object_t
*iterator
)
1505 if( master_port
!= master_device_port
)
1506 return( kIOReturnNotPrivileged
);
1508 *iterator
= IORegistryIterator::iterateOver(
1509 IORegistryEntry::getPlane( plane
), options
);
1511 return( *iterator
? kIOReturnSuccess
: kIOReturnBadArgument
);
1514 /* Routine io_registry_entry_create_iterator */
1515 kern_return_t
is_io_registry_entry_create_iterator(
1516 io_object_t registry_entry
,
1519 io_object_t
*iterator
)
1521 CHECK( IORegistryEntry
, registry_entry
, entry
);
1523 *iterator
= IORegistryIterator::iterateOver( entry
,
1524 IORegistryEntry::getPlane( plane
), options
);
1526 return( *iterator
? kIOReturnSuccess
: kIOReturnBadArgument
);
1529 /* Routine io_registry_iterator_enter */
1530 kern_return_t
is_io_registry_iterator_enter_entry(
1531 io_object_t iterator
)
1533 CHECK( IORegistryIterator
, iterator
, iter
);
1537 return( kIOReturnSuccess
);
1540 /* Routine io_registry_iterator_exit */
1541 kern_return_t
is_io_registry_iterator_exit_entry(
1542 io_object_t iterator
)
1546 CHECK( IORegistryIterator
, iterator
, iter
);
1548 didIt
= iter
->exitEntry();
1550 return( didIt
? kIOReturnSuccess
: kIOReturnNoDevice
);
1553 /* Routine io_registry_entry_from_path */
1554 kern_return_t
is_io_registry_entry_from_path(
1555 mach_port_t master_port
,
1557 io_object_t
*registry_entry
)
1559 IORegistryEntry
* entry
;
1561 if( master_port
!= master_device_port
)
1562 return( kIOReturnNotPrivileged
);
1564 entry
= IORegistryEntry::fromPath( path
);
1566 *registry_entry
= entry
;
1568 return( kIOReturnSuccess
);
1571 /* Routine io_registry_entry_in_plane */
1572 kern_return_t
is_io_registry_entry_in_plane(
1573 io_object_t registry_entry
,
1575 boolean_t
*inPlane
)
1577 CHECK( IORegistryEntry
, registry_entry
, entry
);
1579 *inPlane
= entry
->inPlane( IORegistryEntry::getPlane( plane
));
1581 return( kIOReturnSuccess
);
1585 /* Routine io_registry_entry_get_path */
1586 kern_return_t
is_io_registry_entry_get_path(
1587 io_object_t registry_entry
,
1592 CHECK( IORegistryEntry
, registry_entry
, entry
);
1594 length
= sizeof( io_string_t
);
1595 if( entry
->getPath( path
, &length
, IORegistryEntry::getPlane( plane
)))
1596 return( kIOReturnSuccess
);
1598 return( kIOReturnBadArgument
);
1602 /* Routine io_registry_entry_get_name */
1603 kern_return_t
is_io_registry_entry_get_name(
1604 io_object_t registry_entry
,
1607 CHECK( IORegistryEntry
, registry_entry
, entry
);
1609 strncpy( name
, entry
->getName(), sizeof( io_name_t
));
1611 return( kIOReturnSuccess
);
1614 /* Routine io_registry_entry_get_name_in_plane */
1615 kern_return_t
is_io_registry_entry_get_name_in_plane(
1616 io_object_t registry_entry
,
1617 io_name_t planeName
,
1620 const IORegistryPlane
* plane
;
1621 CHECK( IORegistryEntry
, registry_entry
, entry
);
1624 plane
= IORegistryEntry::getPlane( planeName
);
1628 strncpy( name
, entry
->getName( plane
), sizeof( io_name_t
));
1630 return( kIOReturnSuccess
);
1633 /* Routine io_registry_entry_get_location_in_plane */
1634 kern_return_t
is_io_registry_entry_get_location_in_plane(
1635 io_object_t registry_entry
,
1636 io_name_t planeName
,
1637 io_name_t location
)
1639 const IORegistryPlane
* plane
;
1640 CHECK( IORegistryEntry
, registry_entry
, entry
);
1643 plane
= IORegistryEntry::getPlane( planeName
);
1647 const char * cstr
= entry
->getLocation( plane
);
1650 strncpy( location
, cstr
, sizeof( io_name_t
));
1651 return( kIOReturnSuccess
);
1653 return( kIOReturnNotFound
);
1656 // Create a vm_map_copy_t or kalloc'ed data for memory
1657 // to be copied out. ipc will free after the copyout.
1659 static kern_return_t
copyoutkdata( void * data
, vm_size_t len
,
1660 io_buf_ptr_t
* buf
)
1665 err
= vm_map_copyin( kernel_map
, CAST_USER_ADDR_T(data
), len
,
1666 false /* src_destroy */, ©
);
1668 assert( err
== KERN_SUCCESS
);
1669 if( err
== KERN_SUCCESS
)
1670 *buf
= (char *) copy
;
1675 /* Routine io_registry_entry_get_property */
1676 kern_return_t
is_io_registry_entry_get_property_bytes(
1677 io_object_t registry_entry
,
1678 io_name_t property_name
,
1679 io_scalar_inband_t buf
,
1680 mach_msg_type_number_t
*dataCnt
)
1688 unsigned int len
= 0;
1689 const void * bytes
= 0;
1690 IOReturn ret
= kIOReturnSuccess
;
1692 CHECK( IORegistryEntry
, registry_entry
, entry
);
1694 obj
= entry
->copyProperty(property_name
);
1696 return( kIOReturnNoResources
);
1698 // One day OSData will be a common container base class
1700 if( (data
= OSDynamicCast( OSData
, obj
))) {
1701 len
= data
->getLength();
1702 bytes
= data
->getBytesNoCopy();
1704 } else if( (str
= OSDynamicCast( OSString
, obj
))) {
1705 len
= str
->getLength() + 1;
1706 bytes
= str
->getCStringNoCopy();
1708 } else if( (boo
= OSDynamicCast( OSBoolean
, obj
))) {
1709 len
= boo
->isTrue() ? sizeof("Yes") : sizeof("No");
1710 bytes
= boo
->isTrue() ? "Yes" : "No";
1712 } else if( (off
= OSDynamicCast( OSNumber
, obj
))) {
1713 offsetBytes
= off
->unsigned64BitValue();
1714 len
= off
->numberOfBytes();
1715 bytes
= &offsetBytes
;
1716 #ifdef __BIG_ENDIAN__
1717 bytes
= (const void *)
1718 (((UInt32
) bytes
) + (sizeof( UInt64
) - len
));
1722 ret
= kIOReturnBadArgument
;
1726 ret
= kIOReturnIPCError
;
1729 bcopy( bytes
, buf
, len
);
1737 /* Routine io_registry_entry_get_property */
1738 kern_return_t
is_io_registry_entry_get_property(
1739 io_object_t registry_entry
,
1740 io_name_t property_name
,
1741 io_buf_ptr_t
*properties
,
1742 mach_msg_type_number_t
*propertiesCnt
)
1748 CHECK( IORegistryEntry
, registry_entry
, entry
);
1750 obj
= entry
->copyProperty(property_name
);
1752 return( kIOReturnNotFound
);
1754 OSSerialize
* s
= OSSerialize::withCapacity(4096);
1757 return( kIOReturnNoMemory
);
1761 if( obj
->serialize( s
)) {
1762 len
= s
->getLength();
1763 *propertiesCnt
= len
;
1764 err
= copyoutkdata( s
->text(), len
, properties
);
1767 err
= kIOReturnUnsupported
;
1775 /* Routine io_registry_entry_get_property_recursively */
1776 kern_return_t
is_io_registry_entry_get_property_recursively(
1777 io_object_t registry_entry
,
1779 io_name_t property_name
,
1781 io_buf_ptr_t
*properties
,
1782 mach_msg_type_number_t
*propertiesCnt
)
1788 CHECK( IORegistryEntry
, registry_entry
, entry
);
1790 obj
= entry
->copyProperty( property_name
,
1791 IORegistryEntry::getPlane( plane
), options
);
1793 return( kIOReturnNotFound
);
1795 OSSerialize
* s
= OSSerialize::withCapacity(4096);
1798 return( kIOReturnNoMemory
);
1803 if( obj
->serialize( s
)) {
1804 len
= s
->getLength();
1805 *propertiesCnt
= len
;
1806 err
= copyoutkdata( s
->text(), len
, properties
);
1809 err
= kIOReturnUnsupported
;
1817 /* Routine io_registry_entry_get_properties */
1818 kern_return_t
is_io_registry_entry_get_properties(
1819 io_object_t registry_entry
,
1820 io_buf_ptr_t
*properties
,
1821 mach_msg_type_number_t
*propertiesCnt
)
1826 CHECK( IORegistryEntry
, registry_entry
, entry
);
1828 OSSerialize
* s
= OSSerialize::withCapacity(4096);
1830 return( kIOReturnNoMemory
);
1834 if( entry
->serializeProperties( s
)) {
1835 len
= s
->getLength();
1836 *propertiesCnt
= len
;
1837 err
= copyoutkdata( s
->text(), len
, properties
);
1840 err
= kIOReturnUnsupported
;
1847 /* Routine io_registry_entry_set_properties */
1848 kern_return_t is_io_registry_entry_set_properties
1850 io_object_t registry_entry
,
1851 io_buf_ptr_t properties
,
1852 mach_msg_type_number_t propertiesCnt
,
1859 vm_map_offset_t map_data
;
1861 CHECK( IORegistryEntry
, registry_entry
, entry
);
1863 err
= vm_map_copyout( kernel_map
, &map_data
, (vm_map_copy_t
) properties
);
1864 data
= CAST_DOWN(vm_offset_t
, map_data
);
1866 if( KERN_SUCCESS
== err
) {
1868 // must return success after vm_map_copyout() succeeds
1869 obj
= OSUnserializeXML( (const char *) data
);
1870 vm_deallocate( kernel_map
, data
, propertiesCnt
);
1873 res
= entry
->setProperties( obj
);
1876 res
= kIOReturnBadArgument
;
1884 /* Routine io_registry_entry_get_child_iterator */
1885 kern_return_t
is_io_registry_entry_get_child_iterator(
1886 io_object_t registry_entry
,
1888 io_object_t
*iterator
)
1890 CHECK( IORegistryEntry
, registry_entry
, entry
);
1892 *iterator
= entry
->getChildIterator(
1893 IORegistryEntry::getPlane( plane
));
1895 return( kIOReturnSuccess
);
1898 /* Routine io_registry_entry_get_parent_iterator */
1899 kern_return_t
is_io_registry_entry_get_parent_iterator(
1900 io_object_t registry_entry
,
1902 io_object_t
*iterator
)
1904 CHECK( IORegistryEntry
, registry_entry
, entry
);
1906 *iterator
= entry
->getParentIterator(
1907 IORegistryEntry::getPlane( plane
));
1909 return( kIOReturnSuccess
);
1912 /* Routine io_service_get_busy_state */
1913 kern_return_t
is_io_service_get_busy_state(
1914 io_object_t _service
,
1917 CHECK( IOService
, _service
, service
);
1919 *busyState
= service
->getBusyState();
1921 return( kIOReturnSuccess
);
1924 /* Routine io_service_get_state */
1925 kern_return_t
is_io_service_get_state(
1926 io_object_t _service
,
1929 CHECK( IOService
, _service
, service
);
1931 *state
= service
->getState();
1933 return( kIOReturnSuccess
);
1936 /* Routine io_service_wait_quiet */
1937 kern_return_t
is_io_service_wait_quiet(
1938 io_object_t _service
,
1939 mach_timespec_t wait_time
)
1941 CHECK( IOService
, _service
, service
);
1943 return( service
->waitQuiet( &wait_time
));
1946 /* Routine io_service_request_probe */
1947 kern_return_t
is_io_service_request_probe(
1948 io_object_t _service
,
1951 CHECK( IOService
, _service
, service
);
1953 return( service
->requestProbe( options
));
1957 /* Routine io_service_open */
1958 kern_return_t
is_io_service_open(
1959 io_object_t _service
,
1962 io_object_t
*connection
)
1964 IOUserClient
* client
;
1967 CHECK( IOService
, _service
, service
);
1969 err
= service
->newUserClient( owningTask
, (void *) owningTask
,
1970 connect_type
, &client
);
1972 if( err
== kIOReturnSuccess
) {
1973 assert( OSDynamicCast(IOUserClient
, client
) );
1974 *connection
= client
;
1980 /* Routine io_service_close */
1981 kern_return_t
is_io_service_close(
1982 io_object_t connection
)
1985 if ((mappings
= OSDynamicCast(OSSet
, connection
)))
1986 return( kIOReturnSuccess
);
1988 CHECK( IOUserClient
, connection
, client
);
1990 client
->clientClose();
1992 return( kIOReturnSuccess
);
1995 /* Routine io_connect_get_service */
1996 kern_return_t
is_io_connect_get_service(
1997 io_object_t connection
,
1998 io_object_t
*service
)
2000 IOService
* theService
;
2002 CHECK( IOUserClient
, connection
, client
);
2004 theService
= client
->getService();
2006 theService
->retain();
2008 *service
= theService
;
2010 return( theService
? kIOReturnSuccess
: kIOReturnUnsupported
);
2013 /* Routine io_connect_set_notification_port */
2014 kern_return_t
is_io_connect_set_notification_port(
2015 io_object_t connection
,
2016 int notification_type
,
2020 CHECK( IOUserClient
, connection
, client
);
2022 return( client
->registerNotificationPort( port
, notification_type
,
2026 kern_return_t
is_io_connect_map_memory(
2027 io_object_t connect
,
2030 vm_address_t
* mapAddr
,
2031 vm_size_t
* mapSize
,
2037 CHECK( IOUserClient
, connect
, client
);
2039 map
= client
->mapClientMemory( type
, task
, flags
, *mapAddr
);
2042 *mapAddr
= map
->getVirtualAddress();
2044 *mapSize
= map
->getLength();
2046 if( task
!= current_task()) {
2047 // push a name out to the task owning the map,
2048 // so we can clean up maps
2050 mach_port_name_t name
=
2052 IOMachPort::makeSendRightForTask(
2053 task
, map
, IKOT_IOKIT_OBJECT
);
2057 // keep it with the user client
2058 IOLockLock( gIOObjectPortLock
);
2059 if( 0 == client
->mappings
)
2060 client
->mappings
= OSSet::withCapacity(2);
2061 if( client
->mappings
)
2062 client
->mappings
->setObject( map
);
2063 IOLockUnlock( gIOObjectPortLock
);
2066 err
= kIOReturnSuccess
;
2069 err
= kIOReturnBadArgument
;
2074 IOMemoryMap
* IOUserClient::removeMappingForDescriptor(IOMemoryDescriptor
* mem
)
2077 IOMemoryMap
* map
= 0;
2079 IOLockLock(gIOObjectPortLock
);
2081 iter
= OSCollectionIterator::withCollection(mappings
);
2084 while ((map
= OSDynamicCast(IOMemoryMap
, iter
->getNextObject())))
2086 if(mem
== map
->getMemoryDescriptor())
2089 mappings
->removeObject(map
);
2096 IOLockUnlock(gIOObjectPortLock
);
2101 kern_return_t
is_io_connect_unmap_memory(
2102 io_object_t connect
,
2105 vm_address_t mapAddr
)
2108 IOOptionBits options
= 0;
2109 IOMemoryDescriptor
* memory
;
2112 CHECK( IOUserClient
, connect
, client
);
2114 err
= client
->clientMemoryForType( (UInt32
) type
, &options
, &memory
);
2116 if( memory
&& (kIOReturnSuccess
== err
)) {
2118 options
= (options
& ~kIOMapUserOptionsMask
)
2119 | kIOMapAnywhere
| kIOMapReference
;
2121 map
= memory
->map( task
, mapAddr
, options
);
2125 IOLockLock( gIOObjectPortLock
);
2126 if( client
->mappings
)
2127 client
->mappings
->removeObject( map
);
2128 IOLockUnlock( gIOObjectPortLock
);
2130 mach_port_name_t name
= 0;
2131 if (task
!= current_task())
2132 name
= IOMachPort::makeSendRightForTask( task
, map
, IKOT_IOKIT_OBJECT
);
2136 err
= iokit_mod_send_right( task
, name
, -2 );
2137 err
= kIOReturnSuccess
;
2140 IOMachPort::releasePortForObject( map
, IKOT_IOKIT_OBJECT
);
2141 if (task
== current_task())
2145 err
= kIOReturnBadArgument
;
2152 /* Routine io_connect_add_client */
2153 kern_return_t
is_io_connect_add_client(
2154 io_object_t connection
,
2155 io_object_t connect_to
)
2157 CHECK( IOUserClient
, connection
, client
);
2158 CHECK( IOUserClient
, connect_to
, to
);
2160 return( client
->connectClient( to
) );
2164 /* Routine io_connect_set_properties */
2165 kern_return_t
is_io_connect_set_properties(
2166 io_object_t connection
,
2167 io_buf_ptr_t properties
,
2168 mach_msg_type_number_t propertiesCnt
,
2171 return( is_io_registry_entry_set_properties( connection
, properties
, propertiesCnt
, result
));
2175 /* Routine io_connect_method_scalarI_scalarO */
2176 kern_return_t
is_io_connect_method_scalarI_scalarO(
2177 io_object_t connect
,
2180 IOByteCount inputCount
,
2182 IOByteCount
* outputCount
)
2185 IOExternalMethod
* method
;
2189 CHECK( IOUserClient
, connect
, client
);
2190 if( (method
= client
->getTargetAndMethodForIndex(&object
, index
))) {
2192 err
= kIOReturnBadArgument
;
2193 if( kIOUCScalarIScalarO
!= (method
->flags
& kIOUCTypeMask
))
2195 if( inputCount
!= method
->count0
)
2197 if( *outputCount
!= method
->count1
)
2200 func
= method
->func
;
2202 switch( inputCount
) {
2205 err
= (object
->*func
)( input
[0], input
[1], input
[2],
2206 input
[3], input
[4], input
[5] );
2209 err
= (object
->*func
)( input
[0], input
[1], input
[2],
2214 err
= (object
->*func
)( input
[0], input
[1], input
[2],
2216 &output
[0], &output
[1] );
2219 err
= (object
->*func
)( input
[0], input
[1], input
[2],
2220 &output
[0], &output
[1], &output
[2] );
2223 err
= (object
->*func
)( input
[0], input
[1],
2224 &output
[0], &output
[1], &output
[2],
2228 err
= (object
->*func
)( input
[0],
2229 &output
[0], &output
[1], &output
[2],
2230 &output
[3], &output
[4] );
2233 err
= (object
->*func
)( &output
[0], &output
[1], &output
[2],
2234 &output
[3], &output
[4], &output
[5] );
2238 IOLog("%s: Bad method table\n", client
->getName());
2243 err
= kIOReturnUnsupported
;
2248 /* Routine io_connect_method_scalarI_structureO */
2249 kern_return_t
is_io_connect_method_scalarI_structureO(
2250 io_object_t connect
,
2253 IOByteCount inputCount
,
2255 IOByteCount
* outputCount
)
2258 IOExternalMethod
* method
;
2262 CHECK( IOUserClient
, connect
, client
);
2264 if( (method
= client
->getTargetAndMethodForIndex(&object
, index
)) ) {
2266 err
= kIOReturnBadArgument
;
2267 if( kIOUCScalarIStructO
!= (method
->flags
& kIOUCTypeMask
))
2269 if( inputCount
!= method
->count0
)
2271 if( (0xffffffff != method
->count1
)
2272 && (*outputCount
!= method
->count1
))
2275 func
= method
->func
;
2277 switch( inputCount
) {
2280 err
= (object
->*func
)( input
[0], input
[1], input
[2],
2285 err
= (object
->*func
)( input
[0], input
[1], input
[2],
2287 output
, (void *)outputCount
);
2290 err
= (object
->*func
)( input
[0], input
[1], input
[2],
2291 output
, (void *)outputCount
, 0 );
2294 err
= (object
->*func
)( input
[0], input
[1],
2295 output
, (void *)outputCount
, 0, 0 );
2298 err
= (object
->*func
)( input
[0],
2299 output
, (void *)outputCount
, 0, 0, 0 );
2302 err
= (object
->*func
)( output
, (void *)outputCount
, 0, 0, 0, 0 );
2306 IOLog("%s: Bad method table\n", client
->getName());
2311 err
= kIOReturnUnsupported
;
2316 /* Routine io_connect_method_scalarI_structureI */
2317 kern_return_t
is_io_connect_method_scalarI_structureI(
2318 io_connect_t connect
,
2321 IOByteCount inputCount
,
2322 UInt8
* inputStruct
,
2323 IOByteCount inputStructCount
)
2326 IOExternalMethod
* method
;
2330 CHECK( IOUserClient
, connect
, client
);
2332 if( (method
= client
->getTargetAndMethodForIndex(&object
, index
)) ) {
2334 err
= kIOReturnBadArgument
;
2335 if( kIOUCScalarIStructI
!= (method
->flags
& kIOUCTypeMask
))
2337 if( (0xffffffff != method
->count0
)
2338 && (inputCount
!= method
->count0
))
2340 if( (0xffffffff != method
->count1
)
2341 && (inputStructCount
!= method
->count1
))
2344 func
= method
->func
;
2346 switch( inputCount
) {
2349 err
= (object
->*func
)( input
[0], input
[1], input
[2],
2354 err
= (object
->*func
)( input
[0], input
[1], input
[2],
2356 inputStruct
, (void *)inputStructCount
);
2359 err
= (object
->*func
)( input
[0], input
[1], input
[2],
2360 inputStruct
, (void *)inputStructCount
,
2364 err
= (object
->*func
)( input
[0], input
[1],
2365 inputStruct
, (void *)inputStructCount
,
2369 err
= (object
->*func
)( input
[0],
2370 inputStruct
, (void *)inputStructCount
,
2374 err
= (object
->*func
)( inputStruct
, (void *)inputStructCount
,
2379 IOLog("%s: Bad method table\n", client
->getName());
2384 err
= kIOReturnUnsupported
;
2389 /* Routine io_connect_method_structureI_structureO */
2390 kern_return_t
is_io_connect_method_structureI_structureO(
2391 io_object_t connect
,
2394 IOByteCount inputCount
,
2396 IOByteCount
* outputCount
)
2399 IOExternalMethod
* method
;
2403 CHECK( IOUserClient
, connect
, client
);
2405 if( (method
= client
->getTargetAndMethodForIndex(&object
, index
)) ) {
2407 err
= kIOReturnBadArgument
;
2408 if( kIOUCStructIStructO
!= (method
->flags
& kIOUCTypeMask
))
2410 if( (0xffffffff != method
->count0
)
2411 && (inputCount
!= method
->count0
))
2413 if( (0xffffffff != method
->count1
)
2414 && (*outputCount
!= method
->count1
))
2417 func
= method
->func
;
2419 if( method
->count1
) {
2420 if( method
->count0
) {
2421 err
= (object
->*func
)( input
, output
,
2422 (void *)inputCount
, outputCount
, 0, 0 );
2424 err
= (object
->*func
)( output
, outputCount
, 0, 0, 0, 0 );
2427 err
= (object
->*func
)( input
, (void *)inputCount
, 0, 0, 0, 0 );
2433 err
= kIOReturnUnsupported
;
2438 kern_return_t
is_io_async_method_scalarI_scalarO(
2439 io_object_t connect
,
2440 mach_port_t wakePort
,
2441 io_async_ref_t reference
,
2442 mach_msg_type_number_t referenceCnt
,
2445 IOByteCount inputCount
,
2447 IOByteCount
* outputCount
)
2450 IOExternalAsyncMethod
*method
;
2454 CHECK( IOUserClient
, connect
, client
);
2455 if( (method
= client
->getAsyncTargetAndMethodForIndex(&object
, index
)) ) {
2457 err
= kIOReturnBadArgument
;
2458 if( kIOUCScalarIScalarO
!= (method
->flags
& kIOUCTypeMask
))
2460 if( inputCount
!= method
->count0
)
2462 if( *outputCount
!= method
->count1
)
2465 reference
[0] = (natural_t
) wakePort
;
2466 func
= method
->func
;
2468 switch( inputCount
) {
2471 err
= (object
->*func
)( reference
,
2472 input
[0], input
[1], input
[2],
2473 input
[3], input
[4], input
[5] );
2476 err
= (object
->*func
)( reference
,
2477 input
[0], input
[1], input
[2],
2482 err
= (object
->*func
)( reference
,
2483 input
[0], input
[1], input
[2],
2485 &output
[0], &output
[1] );
2488 err
= (object
->*func
)( reference
,
2489 input
[0], input
[1], input
[2],
2490 &output
[0], &output
[1], &output
[2] );
2493 err
= (object
->*func
)( reference
,
2495 &output
[0], &output
[1], &output
[2],
2499 err
= (object
->*func
)( reference
,
2501 &output
[0], &output
[1], &output
[2],
2502 &output
[3], &output
[4] );
2505 err
= (object
->*func
)( reference
,
2506 &output
[0], &output
[1], &output
[2],
2507 &output
[3], &output
[4], &output
[5] );
2511 IOLog("%s: Bad method table\n", client
->getName());
2516 err
= kIOReturnUnsupported
;
2521 kern_return_t
is_io_async_method_scalarI_structureO(
2522 io_object_t connect
,
2523 mach_port_t wakePort
,
2524 io_async_ref_t reference
,
2525 mach_msg_type_number_t referenceCnt
,
2528 IOByteCount inputCount
,
2530 IOByteCount
* outputCount
)
2533 IOExternalAsyncMethod
*method
;
2537 CHECK( IOUserClient
, connect
, client
);
2539 if( (method
= client
->getAsyncTargetAndMethodForIndex(&object
, index
)) ) {
2541 err
= kIOReturnBadArgument
;
2542 if( kIOUCScalarIStructO
!= (method
->flags
& kIOUCTypeMask
))
2544 if( inputCount
!= method
->count0
)
2546 if( (0xffffffff != method
->count1
)
2547 && (*outputCount
!= method
->count1
))
2550 reference
[0] = (natural_t
) wakePort
;
2551 func
= method
->func
;
2553 switch( inputCount
) {
2556 err
= (object
->*func
)( reference
,
2557 input
[0], input
[1], input
[2],
2562 err
= (object
->*func
)( reference
,
2563 input
[0], input
[1], input
[2],
2565 output
, (void *)outputCount
);
2568 err
= (object
->*func
)( reference
,
2569 input
[0], input
[1], input
[2],
2570 output
, (void *)outputCount
, 0 );
2573 err
= (object
->*func
)( reference
,
2575 output
, (void *)outputCount
, 0, 0 );
2578 err
= (object
->*func
)( reference
,
2580 output
, (void *)outputCount
, 0, 0, 0 );
2583 err
= (object
->*func
)( reference
,
2584 output
, (void *)outputCount
, 0, 0, 0, 0 );
2588 IOLog("%s: Bad method table\n", client
->getName());
2593 err
= kIOReturnUnsupported
;
2598 kern_return_t
is_io_async_method_scalarI_structureI(
2599 io_connect_t connect
,
2600 mach_port_t wakePort
,
2601 io_async_ref_t reference
,
2602 mach_msg_type_number_t referenceCnt
,
2605 IOByteCount inputCount
,
2606 UInt8
* inputStruct
,
2607 IOByteCount inputStructCount
)
2610 IOExternalAsyncMethod
*method
;
2614 CHECK( IOUserClient
, connect
, client
);
2616 if( (method
= client
->getAsyncTargetAndMethodForIndex(&object
, index
)) ) {
2618 err
= kIOReturnBadArgument
;
2619 if( kIOUCScalarIStructI
!= (method
->flags
& kIOUCTypeMask
))
2621 if( (0xffffffff != method
->count0
)
2622 && (inputCount
!= method
->count0
))
2624 if( (0xffffffff != method
->count1
)
2625 && (inputStructCount
!= method
->count1
))
2628 reference
[0] = (natural_t
) wakePort
;
2629 func
= method
->func
;
2631 switch( inputCount
) {
2634 err
= (object
->*func
)( reference
,
2635 input
[0], input
[1], input
[2],
2640 err
= (object
->*func
)( reference
,
2641 input
[0], input
[1], input
[2],
2643 inputStruct
, (void *)inputStructCount
);
2646 err
= (object
->*func
)( reference
,
2647 input
[0], input
[1], input
[2],
2648 inputStruct
, (void *)inputStructCount
,
2652 err
= (object
->*func
)( reference
,
2654 inputStruct
, (void *)inputStructCount
,
2658 err
= (object
->*func
)( reference
,
2660 inputStruct
, (void *)inputStructCount
,
2664 err
= (object
->*func
)( reference
,
2665 inputStruct
, (void *)inputStructCount
,
2670 IOLog("%s: Bad method table\n", client
->getName());
2675 err
= kIOReturnUnsupported
;
2680 kern_return_t
is_io_async_method_structureI_structureO(
2681 io_object_t connect
,
2682 mach_port_t wakePort
,
2683 io_async_ref_t reference
,
2684 mach_msg_type_number_t referenceCnt
,
2687 IOByteCount inputCount
,
2689 IOByteCount
* outputCount
)
2692 IOExternalAsyncMethod
*method
;
2696 CHECK( IOUserClient
, connect
, client
);
2698 if( (method
= client
->getAsyncTargetAndMethodForIndex(&object
, index
)) ) {
2700 err
= kIOReturnBadArgument
;
2701 if( kIOUCStructIStructO
!= (method
->flags
& kIOUCTypeMask
))
2703 if( (0xffffffff != method
->count0
)
2704 && (inputCount
!= method
->count0
))
2706 if( (0xffffffff != method
->count1
)
2707 && (*outputCount
!= method
->count1
))
2710 reference
[0] = (natural_t
) wakePort
;
2711 func
= method
->func
;
2713 if( method
->count1
) {
2714 if( method
->count0
) {
2715 err
= (object
->*func
)( reference
,
2717 (void *)inputCount
, outputCount
, 0, 0 );
2719 err
= (object
->*func
)( reference
,
2720 output
, outputCount
, 0, 0, 0, 0 );
2723 err
= (object
->*func
)( reference
,
2724 input
, (void *)inputCount
, 0, 0, 0, 0 );
2730 err
= kIOReturnUnsupported
;
2734 /* Routine io_make_matching */
2735 kern_return_t
is_io_make_matching(
2736 mach_port_t master_port
,
2738 IOOptionBits options
,
2740 IOByteCount inputCount
,
2741 io_string_t matching
)
2744 IOReturn err
= kIOReturnSuccess
;
2745 OSDictionary
* dict
;
2747 if( master_port
!= master_device_port
)
2748 return( kIOReturnNotPrivileged
);
2752 case kIOServiceMatching
:
2753 dict
= IOService::serviceMatching( gIOServiceKey
);
2756 case kIOBSDNameMatching
:
2757 dict
= IOBSDNameMatching( (const char *) input
);
2760 case kIOOFPathMatching
:
2761 dict
= IOOFPathMatching( (const char *) input
,
2762 matching
, sizeof( io_string_t
));
2770 return( kIOReturnUnsupported
);
2773 s
= OSSerialize::withCapacity(4096);
2775 err
= kIOReturnNoMemory
;
2779 if( !dict
->serialize( s
)) {
2780 err
= kIOReturnUnsupported
;
2784 if( s
->getLength() > sizeof( io_string_t
)) {
2785 err
= kIOReturnNoMemory
;
2788 strcpy( matching
, s
->text());
2800 /* Routine io_catalog_send_data */
2801 kern_return_t
is_io_catalog_send_data(
2802 mach_port_t master_port
,
2804 io_buf_ptr_t inData
,
2805 mach_msg_type_number_t inDataCount
,
2810 kern_return_t kr
= kIOReturnError
;
2812 //printf("io_catalog_send_data called. flag: %d\n", flag);
2814 if( master_port
!= master_device_port
)
2815 return kIOReturnNotPrivileged
;
2817 // FIXME: This is a hack. Should have own function for removeKernelLinker()
2818 if(flag
!= kIOCatalogRemoveKernelLinker
&& ( !inData
|| !inDataCount
) )
2819 return kIOReturnBadArgument
;
2822 vm_map_offset_t map_data
;
2824 kr
= vm_map_copyout( kernel_map
, &map_data
, (vm_map_copy_t
)inData
);
2825 data
= CAST_DOWN(vm_offset_t
, map_data
);
2827 if( kr
!= KERN_SUCCESS
)
2830 // must return success after vm_map_copyout() succeeds
2833 obj
= (OSObject
*)OSUnserializeXML((const char *)data
);
2834 vm_deallocate( kernel_map
, data
, inDataCount
);
2836 *result
= kIOReturnNoMemory
;
2837 return( KERN_SUCCESS
);
2843 case kIOCatalogAddDrivers
:
2844 case kIOCatalogAddDriversNoMatch
: {
2847 array
= OSDynamicCast(OSArray
, obj
);
2849 if ( !gIOCatalogue
->addDrivers( array
,
2850 flag
== kIOCatalogAddDrivers
) ) {
2851 kr
= kIOReturnError
;
2855 kr
= kIOReturnBadArgument
;
2860 case kIOCatalogRemoveDrivers
:
2861 case kIOCatalogRemoveDriversNoMatch
: {
2862 OSDictionary
* dict
;
2864 dict
= OSDynamicCast(OSDictionary
, obj
);
2866 if ( !gIOCatalogue
->removeDrivers( dict
,
2867 flag
== kIOCatalogRemoveDrivers
) ) {
2868 kr
= kIOReturnError
;
2872 kr
= kIOReturnBadArgument
;
2877 case kIOCatalogStartMatching
: {
2878 OSDictionary
* dict
;
2880 dict
= OSDynamicCast(OSDictionary
, obj
);
2882 if ( !gIOCatalogue
->startMatching( dict
) ) {
2883 kr
= kIOReturnError
;
2887 kr
= kIOReturnBadArgument
;
2892 case kIOCatalogRemoveKernelLinker
: {
2893 if (gIOCatalogue
->removeKernelLinker() != KERN_SUCCESS
) {
2894 kr
= kIOReturnError
;
2896 kr
= kIOReturnSuccess
;
2902 kr
= kIOReturnBadArgument
;
2906 if (obj
) obj
->release();
2909 return( KERN_SUCCESS
);
2912 /* Routine io_catalog_terminate */
2913 kern_return_t
is_io_catalog_terminate(
2914 mach_port_t master_port
,
2920 if( master_port
!= master_device_port
)
2921 return kIOReturnNotPrivileged
;
2923 kr
= IOUserClient::clientHasPrivilege( (void *) current_task(),
2924 kIOClientPrivilegeAdministrator
);
2925 if( kIOReturnSuccess
!= kr
)
2929 case kIOCatalogServiceTerminate
:
2931 IOService
* service
;
2933 iter
= IORegistryIterator::iterateOver(gIOServicePlane
,
2934 kIORegistryIterateRecursively
);
2936 return kIOReturnNoMemory
;
2940 while( (service
= (IOService
*)iter
->getNextObject()) ) {
2941 if( service
->metaCast(name
)) {
2942 if ( !service
->terminate( kIOServiceRequired
2943 | kIOServiceSynchronous
) ) {
2944 kr
= kIOReturnUnsupported
;
2949 } while( !service
&& !iter
->isValid());
2953 case kIOCatalogModuleUnload
:
2954 case kIOCatalogModuleTerminate
:
2955 kr
= gIOCatalogue
->terminateDriversForModule(name
,
2956 flag
== kIOCatalogModuleUnload
);
2960 kr
= kIOReturnBadArgument
;
2967 /* Routine io_catalog_get_data */
2968 kern_return_t
is_io_catalog_get_data(
2969 mach_port_t master_port
,
2971 io_buf_ptr_t
*outData
,
2972 mach_msg_type_number_t
*outDataCount
)
2974 kern_return_t kr
= kIOReturnSuccess
;
2977 if( master_port
!= master_device_port
)
2978 return kIOReturnNotPrivileged
;
2980 //printf("io_catalog_get_data called. flag: %d\n", flag);
2982 s
= OSSerialize::withCapacity(4096);
2984 return kIOReturnNoMemory
;
2988 kr
= gIOCatalogue
->serializeData(flag
, s
);
2990 if ( kr
== kIOReturnSuccess
) {
2995 size
= s
->getLength();
2996 kr
= vm_allocate(kernel_map
, &data
, size
, VM_FLAGS_ANYWHERE
);
2997 if ( kr
== kIOReturnSuccess
) {
2998 bcopy(s
->text(), (void *)data
, size
);
2999 kr
= vm_map_copyin(kernel_map
, (vm_map_address_t
)data
,
3000 (vm_map_size_t
)size
, true, ©
);
3001 *outData
= (char *)copy
;
3002 *outDataCount
= size
;
3011 /* Routine io_catalog_get_gen_count */
3012 kern_return_t
is_io_catalog_get_gen_count(
3013 mach_port_t master_port
,
3016 if( master_port
!= master_device_port
)
3017 return kIOReturnNotPrivileged
;
3019 //printf("io_catalog_get_gen_count called.\n");
3022 return kIOReturnBadArgument
;
3024 *genCount
= gIOCatalogue
->getGenerationCount();
3026 return kIOReturnSuccess
;
3029 /* Routine io_catalog_module_loaded */
3030 kern_return_t
is_io_catalog_module_loaded(
3031 mach_port_t master_port
,
3034 if( master_port
!= master_device_port
)
3035 return kIOReturnNotPrivileged
;
3037 //printf("io_catalog_module_loaded called. name %s\n", name);
3040 return kIOReturnBadArgument
;
3042 gIOCatalogue
->moduleHasLoaded(name
);
3044 return kIOReturnSuccess
;
3047 kern_return_t
is_io_catalog_reset(
3048 mach_port_t master_port
,
3051 if( master_port
!= master_device_port
)
3052 return kIOReturnNotPrivileged
;
3055 case kIOCatalogResetDefault
:
3056 gIOCatalogue
->reset();
3060 return kIOReturnBadArgument
;
3063 return kIOReturnSuccess
;
3066 kern_return_t
iokit_user_client_trap(struct iokit_user_client_trap_args
*args
)
3068 kern_return_t result
= kIOReturnBadArgument
;
3069 IOUserClient
*userClient
;
3071 if ((userClient
= OSDynamicCast(IOUserClient
,
3072 iokit_lookup_connect_ref_current_task((OSObject
*)(args
->userClientRef
))))) {
3073 IOExternalTrap
*trap
;
3074 IOService
*target
= NULL
;
3076 trap
= userClient
->getTargetAndTrapForIndex(&target
, args
->index
);
3078 if (trap
&& target
) {
3084 result
= (target
->*func
)(args
->p1
, args
->p2
, args
->p3
, args
->p4
, args
->p5
, args
->p6
);
3088 userClient
->release();
3096 OSMetaClassDefineReservedUnused(IOUserClient
, 0);
3097 OSMetaClassDefineReservedUnused(IOUserClient
, 1);
3098 OSMetaClassDefineReservedUnused(IOUserClient
, 2);
3099 OSMetaClassDefineReservedUnused(IOUserClient
, 3);
3100 OSMetaClassDefineReservedUnused(IOUserClient
, 4);
3101 OSMetaClassDefineReservedUnused(IOUserClient
, 5);
3102 OSMetaClassDefineReservedUnused(IOUserClient
, 6);
3103 OSMetaClassDefineReservedUnused(IOUserClient
, 7);
3104 OSMetaClassDefineReservedUnused(IOUserClient
, 8);
3105 OSMetaClassDefineReservedUnused(IOUserClient
, 9);
3106 OSMetaClassDefineReservedUnused(IOUserClient
, 10);
3107 OSMetaClassDefineReservedUnused(IOUserClient
, 11);
3108 OSMetaClassDefineReservedUnused(IOUserClient
, 12);
3109 OSMetaClassDefineReservedUnused(IOUserClient
, 13);
3110 OSMetaClassDefineReservedUnused(IOUserClient
, 14);
3111 OSMetaClassDefineReservedUnused(IOUserClient
, 15);