2 * Copyright (c) 1998-2004 Apple Computer, Inc. All rights reserved.
4 * @APPLE_LICENSE_HEADER_START@
6 * The contents of this file constitute Original Code as defined in and
7 * are subject to the Apple Public Source License Version 1.1 (the
8 * "License"). You may not use this file except in compliance with the
9 * License. Please obtain a copy of the License at
10 * http://www.apple.com/publicsource and read it before using this file.
12 * This Original Code and all software distributed under the License are
13 * distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY KIND, EITHER
14 * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
15 * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
16 * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT. Please see the
17 * License for the specific language governing rights and limitations
20 * @APPLE_LICENSE_HEADER_END@
24 #include <IOKit/IOKitServer.h>
25 #include <IOKit/IOUserClient.h>
26 #include <IOKit/IOService.h>
27 #include <IOKit/IOService.h>
28 #include <IOKit/IORegistryEntry.h>
29 #include <IOKit/IOCatalogue.h>
30 #include <IOKit/IOMemoryDescriptor.h>
31 #include <IOKit/IOLib.h>
33 #include <IOKit/assert.h>
35 #include "IOServicePrivate.h"
37 /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
39 // definitions we should get from osfmk
41 //typedef struct ipc_port * ipc_port_t;
42 typedef natural_t ipc_kobject_type_t
;
44 #define IKOT_IOKIT_SPARE 27
45 #define IKOT_IOKIT_CONNECT 29
46 #define IKOT_IOKIT_OBJECT 30
50 extern ipc_port_t
iokit_alloc_object_port( io_object_t obj
,
51 ipc_kobject_type_t type
);
53 extern kern_return_t
iokit_destroy_object_port( ipc_port_t port
);
55 extern mach_port_name_t
iokit_make_send_right( task_t task
,
56 io_object_t obj
, ipc_kobject_type_t type
);
58 extern kern_return_t
iokit_mod_send_right( task_t task
, mach_port_name_t name
, mach_port_delta_t delta
);
60 extern io_object_t
iokit_lookup_connect_ref(io_object_t clientRef
, ipc_space_t task
);
62 extern io_object_t
iokit_lookup_connect_ref_current_task(io_object_t clientRef
);
64 extern ipc_port_t master_device_port
;
66 extern void iokit_retain_port( ipc_port_t port
);
67 extern void iokit_release_port( ipc_port_t port
);
69 extern kern_return_t
iokit_switch_object_port( ipc_port_t port
, io_object_t obj
, ipc_kobject_type_t type
);
71 #include <mach/mach_traps.h>
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
= 1024 };
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
)
1021 const OSMetaClass
* my_obj
= NULL
;
1024 return( kIOReturnBadArgument
);
1026 my_obj
= object
->getMetaClass();
1028 return (kIOReturnNotFound
);
1031 strcpy( className
, my_obj
->getClassName());
1032 return( kIOReturnSuccess
);
1035 /* Routine io_object_get_superclass */
1036 kern_return_t
is_io_object_get_superclass(
1037 mach_port_t master_port
,
1039 io_name_t class_name
)
1041 const OSMetaClass
* my_obj
= NULL
;
1042 const OSMetaClass
* superclass
= NULL
;
1043 const OSSymbol
*my_name
= NULL
;
1044 const char *my_cstr
= NULL
;
1046 if (!obj_name
|| !class_name
)
1047 return (kIOReturnBadArgument
);
1049 if( master_port
!= master_device_port
)
1050 return( kIOReturnNotPrivileged
);
1052 my_name
= OSSymbol::withCString(obj_name
);
1055 my_obj
= OSMetaClass::getMetaClassWithName(my_name
);
1059 superclass
= my_obj
->getSuperClass();
1063 return( kIOReturnNotFound
);
1066 my_cstr
= superclass
->getClassName();
1069 strncpy(class_name
, my_cstr
, sizeof(io_name_t
)-1);
1070 return( kIOReturnSuccess
);
1072 return (kIOReturnNotFound
);
1075 /* Routine io_object_get_bundle_identifier */
1076 kern_return_t
is_io_object_get_bundle_identifier(
1077 mach_port_t master_port
,
1079 io_name_t bundle_name
)
1081 const OSMetaClass
* my_obj
= NULL
;
1082 const OSSymbol
*my_name
= NULL
;
1083 const OSSymbol
*identifier
= NULL
;
1084 const char *my_cstr
= NULL
;
1086 if (!obj_name
|| !bundle_name
)
1087 return (kIOReturnBadArgument
);
1089 if( master_port
!= master_device_port
)
1090 return( kIOReturnNotPrivileged
);
1092 my_name
= OSSymbol::withCString(obj_name
);
1095 my_obj
= OSMetaClass::getMetaClassWithName(my_name
);
1100 identifier
= my_obj
->getKmodName();
1103 return( kIOReturnNotFound
);
1106 my_cstr
= identifier
->getCStringNoCopy();
1108 strncpy(bundle_name
, identifier
->getCStringNoCopy(), sizeof(io_name_t
)-1);
1109 return( kIOReturnSuccess
);
1112 return (kIOReturnBadArgument
);
1115 /* Routine io_object_conforms_to */
1116 kern_return_t
is_io_object_conforms_to(
1118 io_name_t className
,
1119 boolean_t
*conforms
)
1122 return( kIOReturnBadArgument
);
1124 *conforms
= (0 != object
->metaCast( className
));
1125 return( kIOReturnSuccess
);
1128 /* Routine io_object_get_retain_count */
1129 kern_return_t
is_io_object_get_retain_count(
1134 return( kIOReturnBadArgument
);
1136 *retainCount
= object
->getRetainCount();
1137 return( kIOReturnSuccess
);
1140 /* Routine io_iterator_next */
1141 kern_return_t
is_io_iterator_next(
1142 io_object_t iterator
,
1143 io_object_t
*object
)
1147 CHECK( OSIterator
, iterator
, iter
);
1149 obj
= iter
->getNextObject();
1153 return( kIOReturnSuccess
);
1155 return( kIOReturnNoDevice
);
1158 /* Routine io_iterator_reset */
1159 kern_return_t
is_io_iterator_reset(
1160 io_object_t iterator
)
1162 CHECK( OSIterator
, iterator
, iter
);
1166 return( kIOReturnSuccess
);
1169 /* Routine io_iterator_is_valid */
1170 kern_return_t
is_io_iterator_is_valid(
1171 io_object_t iterator
,
1172 boolean_t
*is_valid
)
1174 CHECK( OSIterator
, iterator
, iter
);
1176 *is_valid
= iter
->isValid();
1178 return( kIOReturnSuccess
);
1181 /* Routine io_service_match_property_table */
1182 kern_return_t
is_io_service_match_property_table(
1183 io_service_t _service
,
1184 io_string_t matching
,
1185 boolean_t
*matches
)
1187 CHECK( IOService
, _service
, service
);
1191 OSDictionary
* dict
;
1193 obj
= OSUnserializeXML( matching
);
1195 if( (dict
= OSDynamicCast( OSDictionary
, obj
))) {
1196 *matches
= service
->passiveMatch( dict
);
1197 kr
= kIOReturnSuccess
;
1199 kr
= kIOReturnBadArgument
;
1207 /* Routine io_service_match_property_table_ool */
1208 kern_return_t
is_io_service_match_property_table_ool(
1209 io_object_t service
,
1210 io_buf_ptr_t matching
,
1211 mach_msg_type_number_t matchingCnt
,
1213 boolean_t
*matches
)
1217 vm_map_offset_t map_data
;
1219 kr
= vm_map_copyout( kernel_map
, &map_data
, (vm_map_copy_t
) matching
);
1220 data
= CAST_DOWN(vm_offset_t
, map_data
);
1222 if( KERN_SUCCESS
== kr
) {
1223 // must return success after vm_map_copyout() succeeds
1224 *result
= is_io_service_match_property_table( service
,
1225 (char *) data
, matches
);
1226 vm_deallocate( kernel_map
, data
, matchingCnt
);
1232 /* Routine io_service_get_matching_services */
1233 kern_return_t
is_io_service_get_matching_services(
1234 mach_port_t master_port
,
1235 io_string_t matching
,
1236 io_iterator_t
*existing
)
1240 OSDictionary
* dict
;
1242 if( master_port
!= master_device_port
)
1243 return( kIOReturnNotPrivileged
);
1245 obj
= OSUnserializeXML( matching
);
1247 if( (dict
= OSDynamicCast( OSDictionary
, obj
))) {
1248 *existing
= IOService::getMatchingServices( dict
);
1249 kr
= kIOReturnSuccess
;
1251 kr
= kIOReturnBadArgument
;
1259 /* Routine io_service_get_matching_services_ool */
1260 kern_return_t
is_io_service_get_matching_services_ool(
1261 mach_port_t master_port
,
1262 io_buf_ptr_t matching
,
1263 mach_msg_type_number_t matchingCnt
,
1265 io_object_t
*existing
)
1269 vm_map_offset_t map_data
;
1271 kr
= vm_map_copyout( kernel_map
, &map_data
, (vm_map_copy_t
) matching
);
1272 data
= CAST_DOWN(vm_offset_t
, map_data
);
1274 if( KERN_SUCCESS
== kr
) {
1275 // must return success after vm_map_copyout() succeeds
1276 *result
= is_io_service_get_matching_services( master_port
,
1277 (char *) data
, existing
);
1278 vm_deallocate( kernel_map
, data
, matchingCnt
);
1284 /* Routine io_service_add_notification */
1285 kern_return_t
is_io_service_add_notification(
1286 mach_port_t master_port
,
1287 io_name_t notification_type
,
1288 io_string_t matching
,
1290 io_async_ref_t reference
,
1291 mach_msg_type_number_t referenceCnt
,
1292 io_object_t
* notification
)
1294 IOServiceUserNotification
* userNotify
= 0;
1295 IONotifier
* notify
= 0;
1296 const OSSymbol
* sym
;
1297 OSDictionary
* dict
;
1299 unsigned long int userMsgType
;
1302 if( master_port
!= master_device_port
)
1303 return( kIOReturnNotPrivileged
);
1306 err
= kIOReturnNoResources
;
1308 if( !(sym
= OSSymbol::withCString( notification_type
)))
1309 err
= kIOReturnNoResources
;
1311 if( !(dict
= OSDynamicCast( OSDictionary
,
1312 OSUnserializeXML( matching
)))) {
1313 err
= kIOReturnBadArgument
;
1317 if( (sym
== gIOPublishNotification
)
1318 || (sym
== gIOFirstPublishNotification
))
1319 userMsgType
= kIOServicePublishNotificationType
;
1320 else if( (sym
== gIOMatchedNotification
)
1321 || (sym
== gIOFirstMatchNotification
))
1322 userMsgType
= kIOServiceMatchedNotificationType
;
1323 else if( sym
== gIOTerminatedNotification
)
1324 userMsgType
= kIOServiceTerminatedNotificationType
;
1326 userMsgType
= kLastIOKitNotificationType
;
1328 userNotify
= new IOServiceUserNotification
;
1330 if( userNotify
&& !userNotify
->init( port
, userMsgType
,
1332 userNotify
->release();
1338 notify
= IOService::addNotification( sym
, dict
,
1339 &userNotify
->_handler
, userNotify
);
1342 *notification
= userNotify
;
1343 userNotify
->setNotification( notify
);
1344 err
= kIOReturnSuccess
;
1346 err
= kIOReturnUnsupported
;
1358 /* Routine io_service_add_notification_ool */
1359 kern_return_t
is_io_service_add_notification_ool(
1360 mach_port_t master_port
,
1361 io_name_t notification_type
,
1362 io_buf_ptr_t matching
,
1363 mach_msg_type_number_t matchingCnt
,
1364 mach_port_t wake_port
,
1365 io_async_ref_t reference
,
1366 mach_msg_type_number_t referenceCnt
,
1368 io_object_t
*notification
)
1372 vm_map_offset_t map_data
;
1374 kr
= vm_map_copyout( kernel_map
, &map_data
, (vm_map_copy_t
) matching
);
1375 data
= CAST_DOWN(vm_offset_t
, map_data
);
1377 if( KERN_SUCCESS
== kr
) {
1378 // must return success after vm_map_copyout() succeeds
1379 *result
= is_io_service_add_notification( master_port
, notification_type
,
1380 (char *) data
, wake_port
, reference
, referenceCnt
, notification
);
1381 vm_deallocate( kernel_map
, data
, matchingCnt
);
1388 /* Routine io_service_add_notification_old */
1389 kern_return_t
is_io_service_add_notification_old(
1390 mach_port_t master_port
,
1391 io_name_t notification_type
,
1392 io_string_t matching
,
1395 io_object_t
* notification
)
1397 return( is_io_service_add_notification( master_port
, notification_type
,
1398 matching
, port
, &ref
, 1, notification
));
1401 /* Routine io_service_add_message_notification */
1402 kern_return_t
is_io_service_add_interest_notification(
1403 io_object_t _service
,
1404 io_name_t type_of_interest
,
1406 io_async_ref_t reference
,
1407 mach_msg_type_number_t referenceCnt
,
1408 io_object_t
* notification
)
1411 IOServiceMessageUserNotification
* userNotify
= 0;
1412 IONotifier
* notify
= 0;
1413 const OSSymbol
* sym
;
1416 CHECK( IOService
, _service
, service
);
1418 err
= kIOReturnNoResources
;
1419 if( (sym
= OSSymbol::withCString( type_of_interest
))) do {
1421 userNotify
= new IOServiceMessageUserNotification
;
1423 if( userNotify
&& !userNotify
->init( port
, kIOServiceMessageNotificationType
,
1424 reference
, kIOUserNotifyMaxMessageSize
)) {
1425 userNotify
->release();
1431 notify
= service
->registerInterest( sym
,
1432 &userNotify
->_handler
, userNotify
);
1434 *notification
= userNotify
;
1435 userNotify
->setNotification( notify
);
1436 err
= kIOReturnSuccess
;
1438 err
= kIOReturnUnsupported
;
1447 /* Routine io_service_acknowledge_notification */
1448 kern_return_t
is_io_service_acknowledge_notification(
1449 io_object_t _service
,
1450 natural_t notify_ref
,
1451 natural_t response
)
1453 CHECK( IOService
, _service
, service
);
1455 return( service
->acknowledgeNotification( (IONotificationRef
) notify_ref
,
1456 (IOOptionBits
) response
));
1460 /* Routine io_connect_get_semaphore */
1461 kern_return_t
is_io_connect_get_notification_semaphore(
1462 io_connect_t connection
,
1463 natural_t notification_type
,
1464 semaphore_t
*semaphore
)
1466 CHECK( IOUserClient
, connection
, client
);
1468 return( client
->getNotificationSemaphore( (UInt32
) notification_type
,
1472 /* Routine io_registry_get_root_entry */
1473 kern_return_t
is_io_registry_get_root_entry(
1474 mach_port_t master_port
,
1477 IORegistryEntry
* entry
;
1479 if( master_port
!= master_device_port
)
1480 return( kIOReturnNotPrivileged
);
1482 entry
= IORegistryEntry::getRegistryRoot();
1487 return( kIOReturnSuccess
);
1490 /* Routine io_registry_create_iterator */
1491 kern_return_t
is_io_registry_create_iterator(
1492 mach_port_t master_port
,
1495 io_object_t
*iterator
)
1497 if( master_port
!= master_device_port
)
1498 return( kIOReturnNotPrivileged
);
1500 *iterator
= IORegistryIterator::iterateOver(
1501 IORegistryEntry::getPlane( plane
), options
);
1503 return( *iterator
? kIOReturnSuccess
: kIOReturnBadArgument
);
1506 /* Routine io_registry_entry_create_iterator */
1507 kern_return_t
is_io_registry_entry_create_iterator(
1508 io_object_t registry_entry
,
1511 io_object_t
*iterator
)
1513 CHECK( IORegistryEntry
, registry_entry
, entry
);
1515 *iterator
= IORegistryIterator::iterateOver( entry
,
1516 IORegistryEntry::getPlane( plane
), options
);
1518 return( *iterator
? kIOReturnSuccess
: kIOReturnBadArgument
);
1521 /* Routine io_registry_iterator_enter */
1522 kern_return_t
is_io_registry_iterator_enter_entry(
1523 io_object_t iterator
)
1525 CHECK( IORegistryIterator
, iterator
, iter
);
1529 return( kIOReturnSuccess
);
1532 /* Routine io_registry_iterator_exit */
1533 kern_return_t
is_io_registry_iterator_exit_entry(
1534 io_object_t iterator
)
1538 CHECK( IORegistryIterator
, iterator
, iter
);
1540 didIt
= iter
->exitEntry();
1542 return( didIt
? kIOReturnSuccess
: kIOReturnNoDevice
);
1545 /* Routine io_registry_entry_from_path */
1546 kern_return_t
is_io_registry_entry_from_path(
1547 mach_port_t master_port
,
1549 io_object_t
*registry_entry
)
1551 IORegistryEntry
* entry
;
1553 if( master_port
!= master_device_port
)
1554 return( kIOReturnNotPrivileged
);
1556 entry
= IORegistryEntry::fromPath( path
);
1558 *registry_entry
= entry
;
1560 return( kIOReturnSuccess
);
1563 /* Routine io_registry_entry_in_plane */
1564 kern_return_t
is_io_registry_entry_in_plane(
1565 io_object_t registry_entry
,
1567 boolean_t
*inPlane
)
1569 CHECK( IORegistryEntry
, registry_entry
, entry
);
1571 *inPlane
= entry
->inPlane( IORegistryEntry::getPlane( plane
));
1573 return( kIOReturnSuccess
);
1577 /* Routine io_registry_entry_get_path */
1578 kern_return_t
is_io_registry_entry_get_path(
1579 io_object_t registry_entry
,
1584 CHECK( IORegistryEntry
, registry_entry
, entry
);
1586 length
= sizeof( io_string_t
);
1587 if( entry
->getPath( path
, &length
, IORegistryEntry::getPlane( plane
)))
1588 return( kIOReturnSuccess
);
1590 return( kIOReturnBadArgument
);
1594 /* Routine io_registry_entry_get_name */
1595 kern_return_t
is_io_registry_entry_get_name(
1596 io_object_t registry_entry
,
1599 CHECK( IORegistryEntry
, registry_entry
, entry
);
1601 strncpy( name
, entry
->getName(), sizeof( io_name_t
));
1603 return( kIOReturnSuccess
);
1606 /* Routine io_registry_entry_get_name_in_plane */
1607 kern_return_t
is_io_registry_entry_get_name_in_plane(
1608 io_object_t registry_entry
,
1609 io_name_t planeName
,
1612 const IORegistryPlane
* plane
;
1613 CHECK( IORegistryEntry
, registry_entry
, entry
);
1616 plane
= IORegistryEntry::getPlane( planeName
);
1620 strncpy( name
, entry
->getName( plane
), sizeof( io_name_t
));
1622 return( kIOReturnSuccess
);
1625 /* Routine io_registry_entry_get_location_in_plane */
1626 kern_return_t
is_io_registry_entry_get_location_in_plane(
1627 io_object_t registry_entry
,
1628 io_name_t planeName
,
1629 io_name_t location
)
1631 const IORegistryPlane
* plane
;
1632 CHECK( IORegistryEntry
, registry_entry
, entry
);
1635 plane
= IORegistryEntry::getPlane( planeName
);
1639 const char * cstr
= entry
->getLocation( plane
);
1642 strncpy( location
, cstr
, sizeof( io_name_t
));
1643 return( kIOReturnSuccess
);
1645 return( kIOReturnNotFound
);
1648 // Create a vm_map_copy_t or kalloc'ed data for memory
1649 // to be copied out. ipc will free after the copyout.
1651 static kern_return_t
copyoutkdata( void * data
, vm_size_t len
,
1652 io_buf_ptr_t
* buf
)
1657 err
= vm_map_copyin( kernel_map
, CAST_USER_ADDR_T(data
), len
,
1658 false /* src_destroy */, ©
);
1660 assert( err
== KERN_SUCCESS
);
1661 if( err
== KERN_SUCCESS
)
1662 *buf
= (char *) copy
;
1667 /* Routine io_registry_entry_get_property */
1668 kern_return_t
is_io_registry_entry_get_property_bytes(
1669 io_object_t registry_entry
,
1670 io_name_t property_name
,
1671 io_scalar_inband_t buf
,
1672 mach_msg_type_number_t
*dataCnt
)
1680 unsigned int len
= 0;
1681 const void * bytes
= 0;
1682 IOReturn ret
= kIOReturnSuccess
;
1684 CHECK( IORegistryEntry
, registry_entry
, entry
);
1686 obj
= entry
->copyProperty(property_name
);
1688 return( kIOReturnNoResources
);
1690 // One day OSData will be a common container base class
1692 if( (data
= OSDynamicCast( OSData
, obj
))) {
1693 len
= data
->getLength();
1694 bytes
= data
->getBytesNoCopy();
1696 } else if( (str
= OSDynamicCast( OSString
, obj
))) {
1697 len
= str
->getLength() + 1;
1698 bytes
= str
->getCStringNoCopy();
1700 } else if( (boo
= OSDynamicCast( OSBoolean
, obj
))) {
1701 len
= boo
->isTrue() ? sizeof("Yes") : sizeof("No");
1702 bytes
= boo
->isTrue() ? "Yes" : "No";
1704 } else if( (off
= OSDynamicCast( OSNumber
, obj
))) {
1705 offsetBytes
= off
->unsigned64BitValue();
1706 len
= off
->numberOfBytes();
1707 bytes
= &offsetBytes
;
1708 #ifdef __BIG_ENDIAN__
1709 bytes
= (const void *)
1710 (((UInt32
) bytes
) + (sizeof( UInt64
) - len
));
1714 ret
= kIOReturnBadArgument
;
1718 ret
= kIOReturnIPCError
;
1721 bcopy( bytes
, buf
, len
);
1729 /* Routine io_registry_entry_get_property */
1730 kern_return_t
is_io_registry_entry_get_property(
1731 io_object_t registry_entry
,
1732 io_name_t property_name
,
1733 io_buf_ptr_t
*properties
,
1734 mach_msg_type_number_t
*propertiesCnt
)
1740 CHECK( IORegistryEntry
, registry_entry
, entry
);
1742 obj
= entry
->copyProperty(property_name
);
1744 return( kIOReturnNotFound
);
1746 OSSerialize
* s
= OSSerialize::withCapacity(4096);
1749 return( kIOReturnNoMemory
);
1753 if( obj
->serialize( s
)) {
1754 len
= s
->getLength();
1755 *propertiesCnt
= len
;
1756 err
= copyoutkdata( s
->text(), len
, properties
);
1759 err
= kIOReturnUnsupported
;
1767 /* Routine io_registry_entry_get_property_recursively */
1768 kern_return_t
is_io_registry_entry_get_property_recursively(
1769 io_object_t registry_entry
,
1771 io_name_t property_name
,
1773 io_buf_ptr_t
*properties
,
1774 mach_msg_type_number_t
*propertiesCnt
)
1780 CHECK( IORegistryEntry
, registry_entry
, entry
);
1782 obj
= entry
->copyProperty( property_name
,
1783 IORegistryEntry::getPlane( plane
), options
);
1785 return( kIOReturnNotFound
);
1787 OSSerialize
* s
= OSSerialize::withCapacity(4096);
1790 return( kIOReturnNoMemory
);
1795 if( obj
->serialize( s
)) {
1796 len
= s
->getLength();
1797 *propertiesCnt
= len
;
1798 err
= copyoutkdata( s
->text(), len
, properties
);
1801 err
= kIOReturnUnsupported
;
1809 /* Routine io_registry_entry_get_properties */
1810 kern_return_t
is_io_registry_entry_get_properties(
1811 io_object_t registry_entry
,
1812 io_buf_ptr_t
*properties
,
1813 mach_msg_type_number_t
*propertiesCnt
)
1818 CHECK( IORegistryEntry
, registry_entry
, entry
);
1820 OSSerialize
* s
= OSSerialize::withCapacity(4096);
1822 return( kIOReturnNoMemory
);
1826 if( entry
->serializeProperties( s
)) {
1827 len
= s
->getLength();
1828 *propertiesCnt
= len
;
1829 err
= copyoutkdata( s
->text(), len
, properties
);
1832 err
= kIOReturnUnsupported
;
1839 /* Routine io_registry_entry_set_properties */
1840 kern_return_t is_io_registry_entry_set_properties
1842 io_object_t registry_entry
,
1843 io_buf_ptr_t properties
,
1844 mach_msg_type_number_t propertiesCnt
,
1851 vm_map_offset_t map_data
;
1853 CHECK( IORegistryEntry
, registry_entry
, entry
);
1855 err
= vm_map_copyout( kernel_map
, &map_data
, (vm_map_copy_t
) properties
);
1856 data
= CAST_DOWN(vm_offset_t
, map_data
);
1858 if( KERN_SUCCESS
== err
) {
1860 // must return success after vm_map_copyout() succeeds
1861 obj
= OSUnserializeXML( (const char *) data
);
1862 vm_deallocate( kernel_map
, data
, propertiesCnt
);
1865 res
= entry
->setProperties( obj
);
1868 res
= kIOReturnBadArgument
;
1876 /* Routine io_registry_entry_get_child_iterator */
1877 kern_return_t
is_io_registry_entry_get_child_iterator(
1878 io_object_t registry_entry
,
1880 io_object_t
*iterator
)
1882 CHECK( IORegistryEntry
, registry_entry
, entry
);
1884 *iterator
= entry
->getChildIterator(
1885 IORegistryEntry::getPlane( plane
));
1887 return( kIOReturnSuccess
);
1890 /* Routine io_registry_entry_get_parent_iterator */
1891 kern_return_t
is_io_registry_entry_get_parent_iterator(
1892 io_object_t registry_entry
,
1894 io_object_t
*iterator
)
1896 CHECK( IORegistryEntry
, registry_entry
, entry
);
1898 *iterator
= entry
->getParentIterator(
1899 IORegistryEntry::getPlane( plane
));
1901 return( kIOReturnSuccess
);
1904 /* Routine io_service_get_busy_state */
1905 kern_return_t
is_io_service_get_busy_state(
1906 io_object_t _service
,
1909 CHECK( IOService
, _service
, service
);
1911 *busyState
= service
->getBusyState();
1913 return( kIOReturnSuccess
);
1916 /* Routine io_service_get_state */
1917 kern_return_t
is_io_service_get_state(
1918 io_object_t _service
,
1921 CHECK( IOService
, _service
, service
);
1923 *state
= service
->getState();
1925 return( kIOReturnSuccess
);
1928 /* Routine io_service_wait_quiet */
1929 kern_return_t
is_io_service_wait_quiet(
1930 io_object_t _service
,
1931 mach_timespec_t wait_time
)
1933 CHECK( IOService
, _service
, service
);
1935 return( service
->waitQuiet( &wait_time
));
1938 /* Routine io_service_request_probe */
1939 kern_return_t
is_io_service_request_probe(
1940 io_object_t _service
,
1943 CHECK( IOService
, _service
, service
);
1945 return( service
->requestProbe( options
));
1949 /* Routine io_service_open */
1950 kern_return_t
is_io_service_open(
1951 io_object_t _service
,
1954 io_object_t
*connection
)
1956 IOUserClient
* client
;
1959 CHECK( IOService
, _service
, service
);
1961 err
= service
->newUserClient( owningTask
, (void *) owningTask
,
1962 connect_type
, &client
);
1964 if( err
== kIOReturnSuccess
) {
1965 assert( OSDynamicCast(IOUserClient
, client
) );
1966 *connection
= client
;
1972 /* Routine io_service_close */
1973 kern_return_t
is_io_service_close(
1974 io_object_t connection
)
1977 if ((mappings
= OSDynamicCast(OSSet
, connection
)))
1978 return( kIOReturnSuccess
);
1980 CHECK( IOUserClient
, connection
, client
);
1982 client
->clientClose();
1984 return( kIOReturnSuccess
);
1987 /* Routine io_connect_get_service */
1988 kern_return_t
is_io_connect_get_service(
1989 io_object_t connection
,
1990 io_object_t
*service
)
1992 IOService
* theService
;
1994 CHECK( IOUserClient
, connection
, client
);
1996 theService
= client
->getService();
1998 theService
->retain();
2000 *service
= theService
;
2002 return( theService
? kIOReturnSuccess
: kIOReturnUnsupported
);
2005 /* Routine io_connect_set_notification_port */
2006 kern_return_t
is_io_connect_set_notification_port(
2007 io_object_t connection
,
2008 int notification_type
,
2012 CHECK( IOUserClient
, connection
, client
);
2014 return( client
->registerNotificationPort( port
, notification_type
,
2018 kern_return_t
is_io_connect_map_memory(
2019 io_object_t connect
,
2022 vm_address_t
* mapAddr
,
2023 vm_size_t
* mapSize
,
2029 CHECK( IOUserClient
, connect
, client
);
2031 map
= client
->mapClientMemory( type
, task
, flags
, *mapAddr
);
2034 *mapAddr
= map
->getVirtualAddress();
2036 *mapSize
= map
->getLength();
2038 if( task
!= current_task()) {
2039 // push a name out to the task owning the map,
2040 // so we can clean up maps
2042 mach_port_name_t name
=
2044 IOMachPort::makeSendRightForTask(
2045 task
, map
, IKOT_IOKIT_OBJECT
);
2049 // keep it with the user client
2050 IOLockLock( gIOObjectPortLock
);
2051 if( 0 == client
->mappings
)
2052 client
->mappings
= OSSet::withCapacity(2);
2053 if( client
->mappings
)
2054 client
->mappings
->setObject( map
);
2055 IOLockUnlock( gIOObjectPortLock
);
2058 err
= kIOReturnSuccess
;
2061 err
= kIOReturnBadArgument
;
2066 IOMemoryMap
* IOUserClient::removeMappingForDescriptor(IOMemoryDescriptor
* mem
)
2069 IOMemoryMap
* map
= 0;
2071 IOLockLock(gIOObjectPortLock
);
2073 iter
= OSCollectionIterator::withCollection(mappings
);
2076 while ((map
= OSDynamicCast(IOMemoryMap
, iter
->getNextObject())))
2078 if(mem
== map
->getMemoryDescriptor())
2081 mappings
->removeObject(map
);
2088 IOLockUnlock(gIOObjectPortLock
);
2093 kern_return_t
is_io_connect_unmap_memory(
2094 io_object_t connect
,
2097 vm_address_t mapAddr
)
2100 IOOptionBits options
= 0;
2101 IOMemoryDescriptor
* memory
;
2104 CHECK( IOUserClient
, connect
, client
);
2106 err
= client
->clientMemoryForType( (UInt32
) type
, &options
, &memory
);
2108 if( memory
&& (kIOReturnSuccess
== err
)) {
2110 options
= (options
& ~kIOMapUserOptionsMask
)
2111 | kIOMapAnywhere
| kIOMapReference
;
2113 map
= memory
->map( task
, mapAddr
, options
);
2117 IOLockLock( gIOObjectPortLock
);
2118 if( client
->mappings
)
2119 client
->mappings
->removeObject( map
);
2120 IOLockUnlock( gIOObjectPortLock
);
2122 mach_port_name_t name
= 0;
2123 if (task
!= current_task())
2124 name
= IOMachPort::makeSendRightForTask( task
, map
, IKOT_IOKIT_OBJECT
);
2128 err
= iokit_mod_send_right( task
, name
, -2 );
2129 err
= kIOReturnSuccess
;
2132 IOMachPort::releasePortForObject( map
, IKOT_IOKIT_OBJECT
);
2133 if (task
== current_task())
2137 err
= kIOReturnBadArgument
;
2144 /* Routine io_connect_add_client */
2145 kern_return_t
is_io_connect_add_client(
2146 io_object_t connection
,
2147 io_object_t connect_to
)
2149 CHECK( IOUserClient
, connection
, client
);
2150 CHECK( IOUserClient
, connect_to
, to
);
2152 return( client
->connectClient( to
) );
2156 /* Routine io_connect_set_properties */
2157 kern_return_t
is_io_connect_set_properties(
2158 io_object_t connection
,
2159 io_buf_ptr_t properties
,
2160 mach_msg_type_number_t propertiesCnt
,
2163 return( is_io_registry_entry_set_properties( connection
, properties
, propertiesCnt
, result
));
2167 /* Routine io_connect_method_scalarI_scalarO */
2168 kern_return_t
is_io_connect_method_scalarI_scalarO(
2169 io_object_t connect
,
2172 IOByteCount inputCount
,
2174 IOByteCount
* outputCount
)
2177 IOExternalMethod
* method
;
2181 CHECK( IOUserClient
, connect
, client
);
2182 if( (method
= client
->getTargetAndMethodForIndex(&object
, index
))) {
2184 err
= kIOReturnBadArgument
;
2185 if( kIOUCScalarIScalarO
!= (method
->flags
& kIOUCTypeMask
))
2187 if( inputCount
!= method
->count0
)
2189 if( *outputCount
!= method
->count1
)
2192 func
= method
->func
;
2194 switch( inputCount
) {
2197 err
= (object
->*func
)( input
[0], input
[1], input
[2],
2198 input
[3], input
[4], input
[5] );
2201 err
= (object
->*func
)( input
[0], input
[1], input
[2],
2206 err
= (object
->*func
)( input
[0], input
[1], input
[2],
2208 &output
[0], &output
[1] );
2211 err
= (object
->*func
)( input
[0], input
[1], input
[2],
2212 &output
[0], &output
[1], &output
[2] );
2215 err
= (object
->*func
)( input
[0], input
[1],
2216 &output
[0], &output
[1], &output
[2],
2220 err
= (object
->*func
)( input
[0],
2221 &output
[0], &output
[1], &output
[2],
2222 &output
[3], &output
[4] );
2225 err
= (object
->*func
)( &output
[0], &output
[1], &output
[2],
2226 &output
[3], &output
[4], &output
[5] );
2230 IOLog("%s: Bad method table\n", client
->getName());
2235 err
= kIOReturnUnsupported
;
2240 /* Routine io_connect_method_scalarI_structureO */
2241 kern_return_t
is_io_connect_method_scalarI_structureO(
2242 io_object_t connect
,
2245 IOByteCount inputCount
,
2247 IOByteCount
* outputCount
)
2250 IOExternalMethod
* method
;
2254 CHECK( IOUserClient
, connect
, client
);
2256 if( (method
= client
->getTargetAndMethodForIndex(&object
, index
)) ) {
2258 err
= kIOReturnBadArgument
;
2259 if( kIOUCScalarIStructO
!= (method
->flags
& kIOUCTypeMask
))
2261 if( inputCount
!= method
->count0
)
2263 if( (0xffffffff != method
->count1
)
2264 && (*outputCount
!= method
->count1
))
2267 func
= method
->func
;
2269 switch( inputCount
) {
2272 err
= (object
->*func
)( input
[0], input
[1], input
[2],
2277 err
= (object
->*func
)( input
[0], input
[1], input
[2],
2279 output
, (void *)outputCount
);
2282 err
= (object
->*func
)( input
[0], input
[1], input
[2],
2283 output
, (void *)outputCount
, 0 );
2286 err
= (object
->*func
)( input
[0], input
[1],
2287 output
, (void *)outputCount
, 0, 0 );
2290 err
= (object
->*func
)( input
[0],
2291 output
, (void *)outputCount
, 0, 0, 0 );
2294 err
= (object
->*func
)( output
, (void *)outputCount
, 0, 0, 0, 0 );
2298 IOLog("%s: Bad method table\n", client
->getName());
2303 err
= kIOReturnUnsupported
;
2308 /* Routine io_connect_method_scalarI_structureI */
2309 kern_return_t
is_io_connect_method_scalarI_structureI(
2310 io_connect_t connect
,
2313 IOByteCount inputCount
,
2314 UInt8
* inputStruct
,
2315 IOByteCount inputStructCount
)
2318 IOExternalMethod
* method
;
2322 CHECK( IOUserClient
, connect
, client
);
2324 if( (method
= client
->getTargetAndMethodForIndex(&object
, index
)) ) {
2326 err
= kIOReturnBadArgument
;
2327 if( kIOUCScalarIStructI
!= (method
->flags
& kIOUCTypeMask
))
2329 if( (0xffffffff != method
->count0
)
2330 && (inputCount
!= method
->count0
))
2332 if( (0xffffffff != method
->count1
)
2333 && (inputStructCount
!= method
->count1
))
2336 func
= method
->func
;
2338 switch( inputCount
) {
2341 err
= (object
->*func
)( input
[0], input
[1], input
[2],
2346 err
= (object
->*func
)( input
[0], input
[1], input
[2],
2348 inputStruct
, (void *)inputStructCount
);
2351 err
= (object
->*func
)( input
[0], input
[1], input
[2],
2352 inputStruct
, (void *)inputStructCount
,
2356 err
= (object
->*func
)( input
[0], input
[1],
2357 inputStruct
, (void *)inputStructCount
,
2361 err
= (object
->*func
)( input
[0],
2362 inputStruct
, (void *)inputStructCount
,
2366 err
= (object
->*func
)( inputStruct
, (void *)inputStructCount
,
2371 IOLog("%s: Bad method table\n", client
->getName());
2376 err
= kIOReturnUnsupported
;
2381 /* Routine io_connect_method_structureI_structureO */
2382 kern_return_t
is_io_connect_method_structureI_structureO(
2383 io_object_t connect
,
2386 IOByteCount inputCount
,
2388 IOByteCount
* outputCount
)
2391 IOExternalMethod
* method
;
2395 CHECK( IOUserClient
, connect
, client
);
2397 if( (method
= client
->getTargetAndMethodForIndex(&object
, index
)) ) {
2399 err
= kIOReturnBadArgument
;
2400 if( kIOUCStructIStructO
!= (method
->flags
& kIOUCTypeMask
))
2402 if( (0xffffffff != method
->count0
)
2403 && (inputCount
!= method
->count0
))
2405 if( (0xffffffff != method
->count1
)
2406 && (*outputCount
!= method
->count1
))
2409 func
= method
->func
;
2411 if( method
->count1
) {
2412 if( method
->count0
) {
2413 err
= (object
->*func
)( input
, output
,
2414 (void *)inputCount
, outputCount
, 0, 0 );
2416 err
= (object
->*func
)( output
, outputCount
, 0, 0, 0, 0 );
2419 err
= (object
->*func
)( input
, (void *)inputCount
, 0, 0, 0, 0 );
2425 err
= kIOReturnUnsupported
;
2430 kern_return_t
is_io_async_method_scalarI_scalarO(
2431 io_object_t connect
,
2432 mach_port_t wakePort
,
2433 io_async_ref_t reference
,
2434 mach_msg_type_number_t referenceCnt
,
2437 IOByteCount inputCount
,
2439 IOByteCount
* outputCount
)
2442 IOExternalAsyncMethod
*method
;
2446 CHECK( IOUserClient
, connect
, client
);
2447 if( (method
= client
->getAsyncTargetAndMethodForIndex(&object
, index
)) ) {
2449 err
= kIOReturnBadArgument
;
2450 if( kIOUCScalarIScalarO
!= (method
->flags
& kIOUCTypeMask
))
2452 if( inputCount
!= method
->count0
)
2454 if( *outputCount
!= method
->count1
)
2457 reference
[0] = (natural_t
) wakePort
;
2458 func
= method
->func
;
2460 switch( inputCount
) {
2463 err
= (object
->*func
)( reference
,
2464 input
[0], input
[1], input
[2],
2465 input
[3], input
[4], input
[5] );
2468 err
= (object
->*func
)( reference
,
2469 input
[0], input
[1], input
[2],
2474 err
= (object
->*func
)( reference
,
2475 input
[0], input
[1], input
[2],
2477 &output
[0], &output
[1] );
2480 err
= (object
->*func
)( reference
,
2481 input
[0], input
[1], input
[2],
2482 &output
[0], &output
[1], &output
[2] );
2485 err
= (object
->*func
)( reference
,
2487 &output
[0], &output
[1], &output
[2],
2491 err
= (object
->*func
)( reference
,
2493 &output
[0], &output
[1], &output
[2],
2494 &output
[3], &output
[4] );
2497 err
= (object
->*func
)( reference
,
2498 &output
[0], &output
[1], &output
[2],
2499 &output
[3], &output
[4], &output
[5] );
2503 IOLog("%s: Bad method table\n", client
->getName());
2508 err
= kIOReturnUnsupported
;
2513 kern_return_t
is_io_async_method_scalarI_structureO(
2514 io_object_t connect
,
2515 mach_port_t wakePort
,
2516 io_async_ref_t reference
,
2517 mach_msg_type_number_t referenceCnt
,
2520 IOByteCount inputCount
,
2522 IOByteCount
* outputCount
)
2525 IOExternalAsyncMethod
*method
;
2529 CHECK( IOUserClient
, connect
, client
);
2531 if( (method
= client
->getAsyncTargetAndMethodForIndex(&object
, index
)) ) {
2533 err
= kIOReturnBadArgument
;
2534 if( kIOUCScalarIStructO
!= (method
->flags
& kIOUCTypeMask
))
2536 if( inputCount
!= method
->count0
)
2538 if( (0xffffffff != method
->count1
)
2539 && (*outputCount
!= method
->count1
))
2542 reference
[0] = (natural_t
) wakePort
;
2543 func
= method
->func
;
2545 switch( inputCount
) {
2548 err
= (object
->*func
)( reference
,
2549 input
[0], input
[1], input
[2],
2554 err
= (object
->*func
)( reference
,
2555 input
[0], input
[1], input
[2],
2557 output
, (void *)outputCount
);
2560 err
= (object
->*func
)( reference
,
2561 input
[0], input
[1], input
[2],
2562 output
, (void *)outputCount
, 0 );
2565 err
= (object
->*func
)( reference
,
2567 output
, (void *)outputCount
, 0, 0 );
2570 err
= (object
->*func
)( reference
,
2572 output
, (void *)outputCount
, 0, 0, 0 );
2575 err
= (object
->*func
)( reference
,
2576 output
, (void *)outputCount
, 0, 0, 0, 0 );
2580 IOLog("%s: Bad method table\n", client
->getName());
2585 err
= kIOReturnUnsupported
;
2590 kern_return_t
is_io_async_method_scalarI_structureI(
2591 io_connect_t connect
,
2592 mach_port_t wakePort
,
2593 io_async_ref_t reference
,
2594 mach_msg_type_number_t referenceCnt
,
2597 IOByteCount inputCount
,
2598 UInt8
* inputStruct
,
2599 IOByteCount inputStructCount
)
2602 IOExternalAsyncMethod
*method
;
2606 CHECK( IOUserClient
, connect
, client
);
2608 if( (method
= client
->getAsyncTargetAndMethodForIndex(&object
, index
)) ) {
2610 err
= kIOReturnBadArgument
;
2611 if( kIOUCScalarIStructI
!= (method
->flags
& kIOUCTypeMask
))
2613 if( (0xffffffff != method
->count0
)
2614 && (inputCount
!= method
->count0
))
2616 if( (0xffffffff != method
->count1
)
2617 && (inputStructCount
!= method
->count1
))
2620 reference
[0] = (natural_t
) wakePort
;
2621 func
= method
->func
;
2623 switch( inputCount
) {
2626 err
= (object
->*func
)( reference
,
2627 input
[0], input
[1], input
[2],
2632 err
= (object
->*func
)( reference
,
2633 input
[0], input
[1], input
[2],
2635 inputStruct
, (void *)inputStructCount
);
2638 err
= (object
->*func
)( reference
,
2639 input
[0], input
[1], input
[2],
2640 inputStruct
, (void *)inputStructCount
,
2644 err
= (object
->*func
)( reference
,
2646 inputStruct
, (void *)inputStructCount
,
2650 err
= (object
->*func
)( reference
,
2652 inputStruct
, (void *)inputStructCount
,
2656 err
= (object
->*func
)( reference
,
2657 inputStruct
, (void *)inputStructCount
,
2662 IOLog("%s: Bad method table\n", client
->getName());
2667 err
= kIOReturnUnsupported
;
2672 kern_return_t
is_io_async_method_structureI_structureO(
2673 io_object_t connect
,
2674 mach_port_t wakePort
,
2675 io_async_ref_t reference
,
2676 mach_msg_type_number_t referenceCnt
,
2679 IOByteCount inputCount
,
2681 IOByteCount
* outputCount
)
2684 IOExternalAsyncMethod
*method
;
2688 CHECK( IOUserClient
, connect
, client
);
2690 if( (method
= client
->getAsyncTargetAndMethodForIndex(&object
, index
)) ) {
2692 err
= kIOReturnBadArgument
;
2693 if( kIOUCStructIStructO
!= (method
->flags
& kIOUCTypeMask
))
2695 if( (0xffffffff != method
->count0
)
2696 && (inputCount
!= method
->count0
))
2698 if( (0xffffffff != method
->count1
)
2699 && (*outputCount
!= method
->count1
))
2702 reference
[0] = (natural_t
) wakePort
;
2703 func
= method
->func
;
2705 if( method
->count1
) {
2706 if( method
->count0
) {
2707 err
= (object
->*func
)( reference
,
2709 (void *)inputCount
, outputCount
, 0, 0 );
2711 err
= (object
->*func
)( reference
,
2712 output
, outputCount
, 0, 0, 0, 0 );
2715 err
= (object
->*func
)( reference
,
2716 input
, (void *)inputCount
, 0, 0, 0, 0 );
2722 err
= kIOReturnUnsupported
;
2726 /* Routine io_make_matching */
2727 kern_return_t
is_io_make_matching(
2728 mach_port_t master_port
,
2730 IOOptionBits options
,
2732 IOByteCount inputCount
,
2733 io_string_t matching
)
2736 IOReturn err
= kIOReturnSuccess
;
2737 OSDictionary
* dict
;
2739 if( master_port
!= master_device_port
)
2740 return( kIOReturnNotPrivileged
);
2744 case kIOServiceMatching
:
2745 dict
= IOService::serviceMatching( gIOServiceKey
);
2748 case kIOBSDNameMatching
:
2749 dict
= IOBSDNameMatching( (const char *) input
);
2752 case kIOOFPathMatching
:
2753 dict
= IOOFPathMatching( (const char *) input
,
2754 matching
, sizeof( io_string_t
));
2762 return( kIOReturnUnsupported
);
2765 s
= OSSerialize::withCapacity(4096);
2767 err
= kIOReturnNoMemory
;
2771 if( !dict
->serialize( s
)) {
2772 err
= kIOReturnUnsupported
;
2776 if( s
->getLength() > sizeof( io_string_t
)) {
2777 err
= kIOReturnNoMemory
;
2780 strcpy( matching
, s
->text());
2792 /* Routine io_catalog_send_data */
2793 kern_return_t
is_io_catalog_send_data(
2794 mach_port_t master_port
,
2796 io_buf_ptr_t inData
,
2797 mach_msg_type_number_t inDataCount
,
2802 kern_return_t kr
= kIOReturnError
;
2804 //printf("io_catalog_send_data called. flag: %d\n", flag);
2806 if( master_port
!= master_device_port
)
2807 return kIOReturnNotPrivileged
;
2809 // FIXME: This is a hack. Should have own function for removeKernelLinker()
2810 if(flag
!= kIOCatalogRemoveKernelLinker
&& ( !inData
|| !inDataCount
) )
2811 return kIOReturnBadArgument
;
2814 vm_map_offset_t map_data
;
2816 kr
= vm_map_copyout( kernel_map
, &map_data
, (vm_map_copy_t
)inData
);
2817 data
= CAST_DOWN(vm_offset_t
, map_data
);
2819 if( kr
!= KERN_SUCCESS
)
2822 // must return success after vm_map_copyout() succeeds
2825 obj
= (OSObject
*)OSUnserializeXML((const char *)data
);
2826 vm_deallocate( kernel_map
, data
, inDataCount
);
2828 *result
= kIOReturnNoMemory
;
2829 return( KERN_SUCCESS
);
2835 case kIOCatalogAddDrivers
:
2836 case kIOCatalogAddDriversNoMatch
: {
2839 array
= OSDynamicCast(OSArray
, obj
);
2841 if ( !gIOCatalogue
->addDrivers( array
,
2842 flag
== kIOCatalogAddDrivers
) ) {
2843 kr
= kIOReturnError
;
2847 kr
= kIOReturnBadArgument
;
2852 case kIOCatalogRemoveDrivers
:
2853 case kIOCatalogRemoveDriversNoMatch
: {
2854 OSDictionary
* dict
;
2856 dict
= OSDynamicCast(OSDictionary
, obj
);
2858 if ( !gIOCatalogue
->removeDrivers( dict
,
2859 flag
== kIOCatalogRemoveDrivers
) ) {
2860 kr
= kIOReturnError
;
2864 kr
= kIOReturnBadArgument
;
2869 case kIOCatalogStartMatching
: {
2870 OSDictionary
* dict
;
2872 dict
= OSDynamicCast(OSDictionary
, obj
);
2874 if ( !gIOCatalogue
->startMatching( dict
) ) {
2875 kr
= kIOReturnError
;
2879 kr
= kIOReturnBadArgument
;
2884 case kIOCatalogRemoveKernelLinker
: {
2885 if (gIOCatalogue
->removeKernelLinker() != KERN_SUCCESS
) {
2886 kr
= kIOReturnError
;
2888 kr
= kIOReturnSuccess
;
2894 kr
= kIOReturnBadArgument
;
2898 if (obj
) obj
->release();
2901 return( KERN_SUCCESS
);
2904 /* Routine io_catalog_terminate */
2905 kern_return_t
is_io_catalog_terminate(
2906 mach_port_t master_port
,
2912 if( master_port
!= master_device_port
)
2913 return kIOReturnNotPrivileged
;
2915 kr
= IOUserClient::clientHasPrivilege( (void *) current_task(),
2916 kIOClientPrivilegeAdministrator
);
2917 if( kIOReturnSuccess
!= kr
)
2921 case kIOCatalogServiceTerminate
:
2923 IOService
* service
;
2925 iter
= IORegistryIterator::iterateOver(gIOServicePlane
,
2926 kIORegistryIterateRecursively
);
2928 return kIOReturnNoMemory
;
2932 while( (service
= (IOService
*)iter
->getNextObject()) ) {
2933 if( service
->metaCast(name
)) {
2934 if ( !service
->terminate( kIOServiceRequired
2935 | kIOServiceSynchronous
) ) {
2936 kr
= kIOReturnUnsupported
;
2941 } while( !service
&& !iter
->isValid());
2945 case kIOCatalogModuleUnload
:
2946 case kIOCatalogModuleTerminate
:
2947 kr
= gIOCatalogue
->terminateDriversForModule(name
,
2948 flag
== kIOCatalogModuleUnload
);
2952 kr
= kIOReturnBadArgument
;
2959 /* Routine io_catalog_get_data */
2960 kern_return_t
is_io_catalog_get_data(
2961 mach_port_t master_port
,
2963 io_buf_ptr_t
*outData
,
2964 mach_msg_type_number_t
*outDataCount
)
2966 kern_return_t kr
= kIOReturnSuccess
;
2969 if( master_port
!= master_device_port
)
2970 return kIOReturnNotPrivileged
;
2972 //printf("io_catalog_get_data called. flag: %d\n", flag);
2974 s
= OSSerialize::withCapacity(4096);
2976 return kIOReturnNoMemory
;
2980 kr
= gIOCatalogue
->serializeData(flag
, s
);
2982 if ( kr
== kIOReturnSuccess
) {
2987 size
= s
->getLength();
2988 kr
= vm_allocate(kernel_map
, &data
, size
, VM_FLAGS_ANYWHERE
);
2989 if ( kr
== kIOReturnSuccess
) {
2990 bcopy(s
->text(), (void *)data
, size
);
2991 kr
= vm_map_copyin(kernel_map
, (vm_map_address_t
)data
,
2992 (vm_map_size_t
)size
, true, ©
);
2993 *outData
= (char *)copy
;
2994 *outDataCount
= size
;
3003 /* Routine io_catalog_get_gen_count */
3004 kern_return_t
is_io_catalog_get_gen_count(
3005 mach_port_t master_port
,
3008 if( master_port
!= master_device_port
)
3009 return kIOReturnNotPrivileged
;
3011 //printf("io_catalog_get_gen_count called.\n");
3014 return kIOReturnBadArgument
;
3016 *genCount
= gIOCatalogue
->getGenerationCount();
3018 return kIOReturnSuccess
;
3021 /* Routine io_catalog_module_loaded */
3022 kern_return_t
is_io_catalog_module_loaded(
3023 mach_port_t master_port
,
3026 if( master_port
!= master_device_port
)
3027 return kIOReturnNotPrivileged
;
3029 //printf("io_catalog_module_loaded called. name %s\n", name);
3032 return kIOReturnBadArgument
;
3034 gIOCatalogue
->moduleHasLoaded(name
);
3036 return kIOReturnSuccess
;
3039 kern_return_t
is_io_catalog_reset(
3040 mach_port_t master_port
,
3043 if( master_port
!= master_device_port
)
3044 return kIOReturnNotPrivileged
;
3047 case kIOCatalogResetDefault
:
3048 gIOCatalogue
->reset();
3052 return kIOReturnBadArgument
;
3055 return kIOReturnSuccess
;
3058 kern_return_t
iokit_user_client_trap(struct iokit_user_client_trap_args
*args
)
3060 kern_return_t result
= kIOReturnBadArgument
;
3061 IOUserClient
*userClient
;
3063 if ((userClient
= OSDynamicCast(IOUserClient
,
3064 iokit_lookup_connect_ref_current_task((OSObject
*)(args
->userClientRef
))))) {
3065 IOExternalTrap
*trap
;
3066 IOService
*target
= NULL
;
3068 trap
= userClient
->getTargetAndTrapForIndex(&target
, args
->index
);
3070 if (trap
&& target
) {
3076 result
= (target
->*func
)(args
->p1
, args
->p2
, args
->p3
, args
->p4
, args
->p5
, args
->p6
);
3080 userClient
->release();
3088 OSMetaClassDefineReservedUnused(IOUserClient
, 0);
3089 OSMetaClassDefineReservedUnused(IOUserClient
, 1);
3090 OSMetaClassDefineReservedUnused(IOUserClient
, 2);
3091 OSMetaClassDefineReservedUnused(IOUserClient
, 3);
3092 OSMetaClassDefineReservedUnused(IOUserClient
, 4);
3093 OSMetaClassDefineReservedUnused(IOUserClient
, 5);
3094 OSMetaClassDefineReservedUnused(IOUserClient
, 6);
3095 OSMetaClassDefineReservedUnused(IOUserClient
, 7);
3096 OSMetaClassDefineReservedUnused(IOUserClient
, 8);
3097 OSMetaClassDefineReservedUnused(IOUserClient
, 9);
3098 OSMetaClassDefineReservedUnused(IOUserClient
, 10);
3099 OSMetaClassDefineReservedUnused(IOUserClient
, 11);
3100 OSMetaClassDefineReservedUnused(IOUserClient
, 12);
3101 OSMetaClassDefineReservedUnused(IOUserClient
, 13);
3102 OSMetaClassDefineReservedUnused(IOUserClient
, 14);
3103 OSMetaClassDefineReservedUnused(IOUserClient
, 15);