2 * Copyright (c) 1998-2004 Apple Computer, Inc. All rights reserved.
4 * @APPLE_OSREFERENCE_LICENSE_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 License
10 * may not be used to create, or enable the creation or redistribution of,
11 * unlawful or unlicensed copies of an Apple operating system, or to
12 * circumvent, violate, or enable the circumvention or violation of, any
13 * terms of an Apple operating system software license agreement.
15 * Please obtain a copy of the License at
16 * http://www.opensource.apple.com/apsl/ and read it before using this file.
18 * The Original Code and all software distributed under the License are
19 * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
20 * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
21 * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
22 * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
23 * Please see the License for the specific language governing rights and
24 * limitations under the License.
26 * @APPLE_OSREFERENCE_LICENSE_HEADER_END@
30 #include <IOKit/IOKitServer.h>
31 #include <IOKit/IOKitKeysPrivate.h>
32 #include <IOKit/IOUserClient.h>
33 #include <IOKit/IOService.h>
34 #include <IOKit/IOService.h>
35 #include <IOKit/IORegistryEntry.h>
36 #include <IOKit/IOCatalogue.h>
37 #include <IOKit/IOMemoryDescriptor.h>
38 #include <IOKit/IOLib.h>
40 #include <IOKit/assert.h>
42 #include "IOServicePrivate.h"
44 /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
46 // definitions we should get from osfmk
48 //typedef struct ipc_port * ipc_port_t;
49 typedef natural_t ipc_kobject_type_t
;
51 #define IKOT_IOKIT_SPARE 27
52 #define IKOT_IOKIT_CONNECT 29
53 #define IKOT_IOKIT_OBJECT 30
57 extern ipc_port_t
iokit_alloc_object_port( io_object_t obj
,
58 ipc_kobject_type_t type
);
60 extern kern_return_t
iokit_destroy_object_port( ipc_port_t port
);
62 extern mach_port_name_t
iokit_make_send_right( task_t task
,
63 io_object_t obj
, ipc_kobject_type_t type
);
65 extern kern_return_t
iokit_mod_send_right( task_t task
, mach_port_name_t name
, mach_port_delta_t delta
);
67 extern io_object_t
iokit_lookup_connect_ref(io_object_t clientRef
, ipc_space_t task
);
69 extern io_object_t
iokit_lookup_connect_ref_current_task(io_object_t clientRef
);
71 extern ipc_port_t master_device_port
;
73 extern void iokit_retain_port( ipc_port_t port
);
74 extern void iokit_release_port( ipc_port_t port
);
76 extern kern_return_t
iokit_switch_object_port( ipc_port_t port
, io_object_t obj
, ipc_kobject_type_t type
);
78 #include <mach/mach_traps.h>
79 #include <vm/vm_map.h>
84 /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
86 // IOMachPort maps OSObjects to ports, avoiding adding an ivar to OSObject.
88 class IOMachPort
: public OSObject
90 OSDeclareDefaultStructors(IOMachPort
)
97 static IOMachPort
* portForObject( OSObject
* obj
,
98 ipc_kobject_type_t type
);
99 static bool noMoreSendersForObject( OSObject
* obj
,
100 ipc_kobject_type_t type
, mach_port_mscount_t
* mscount
);
101 static void releasePortForObject( OSObject
* obj
,
102 ipc_kobject_type_t type
);
103 static void setHoldDestroy( OSObject
* obj
, ipc_kobject_type_t type
);
105 static OSDictionary
* dictForType( ipc_kobject_type_t type
);
107 static mach_port_name_t
makeSendRightForTask( task_t task
,
108 io_object_t obj
, ipc_kobject_type_t type
);
113 #define super OSObject
114 OSDefineMetaClassAndStructors(IOMachPort
, OSObject
)
116 static IOLock
* gIOObjectPortLock
;
118 /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
120 // not in dictForType() for debugging ease
121 static OSDictionary
* gIOObjectPorts
;
122 static OSDictionary
* gIOConnectPorts
;
124 OSDictionary
* IOMachPort::dictForType( ipc_kobject_type_t type
)
126 OSDictionary
** dict
;
128 if( IKOT_IOKIT_OBJECT
== type
)
129 dict
= &gIOObjectPorts
;
130 else if( IKOT_IOKIT_CONNECT
== type
)
131 dict
= &gIOConnectPorts
;
136 *dict
= OSDictionary::withCapacity( 1 );
141 IOMachPort
* IOMachPort::portForObject ( OSObject
* obj
,
142 ipc_kobject_type_t type
)
144 IOMachPort
* inst
= 0;
147 IOTakeLock( gIOObjectPortLock
);
151 dict
= dictForType( type
);
155 if( (inst
= (IOMachPort
*)
156 dict
->getObject( (const OSSymbol
*) obj
))) {
162 inst
= new IOMachPort
;
163 if( inst
&& !inst
->init()) {
168 inst
->port
= iokit_alloc_object_port( obj
, type
);
171 dict
->setObject( (const OSSymbol
*) obj
, inst
);
181 IOUnlock( gIOObjectPortLock
);
186 bool IOMachPort::noMoreSendersForObject( OSObject
* obj
,
187 ipc_kobject_type_t type
, mach_port_mscount_t
* mscount
)
190 IOMachPort
* machPort
;
191 bool destroyed
= true;
193 IOTakeLock( gIOObjectPortLock
);
195 if( (dict
= dictForType( type
))) {
198 machPort
= (IOMachPort
*) dict
->getObject( (const OSSymbol
*) obj
);
200 destroyed
= (machPort
->mscount
== *mscount
);
202 dict
->removeObject( (const OSSymbol
*) obj
);
204 *mscount
= machPort
->mscount
;
209 IOUnlock( gIOObjectPortLock
);
214 void IOMachPort::releasePortForObject( OSObject
* obj
,
215 ipc_kobject_type_t type
)
218 IOMachPort
* machPort
;
220 IOTakeLock( gIOObjectPortLock
);
222 if( (dict
= dictForType( type
))) {
224 machPort
= (IOMachPort
*) dict
->getObject( (const OSSymbol
*) obj
);
225 if( machPort
&& !machPort
->holdDestroy
)
226 dict
->removeObject( (const OSSymbol
*) obj
);
230 IOUnlock( gIOObjectPortLock
);
233 void IOMachPort::setHoldDestroy( OSObject
* obj
, ipc_kobject_type_t type
)
236 IOMachPort
* machPort
;
238 IOLockLock( gIOObjectPortLock
);
240 if( (dict
= dictForType( type
))) {
241 machPort
= (IOMachPort
*) dict
->getObject( (const OSSymbol
*) obj
);
243 machPort
->holdDestroy
= true;
246 IOLockUnlock( gIOObjectPortLock
);
249 void IOUserClient::destroyUserReferences( OSObject
* obj
)
251 IOMachPort::releasePortForObject( obj
, IKOT_IOKIT_OBJECT
);
254 // IOMachPort::releasePortForObject( obj, IKOT_IOKIT_CONNECT );
258 IOTakeLock( gIOObjectPortLock
);
261 if( (dict
= IOMachPort::dictForType( IKOT_IOKIT_CONNECT
)))
264 port
= (IOMachPort
*) dict
->getObject( (const OSSymbol
*) obj
);
268 if ((uc
= OSDynamicCast(IOUserClient
, obj
)) && uc
->mappings
)
270 dict
->setObject((const OSSymbol
*) uc
->mappings
, port
);
271 iokit_switch_object_port(port
->port
, uc
->mappings
, IKOT_IOKIT_CONNECT
);
273 uc
->mappings
->release();
276 dict
->removeObject( (const OSSymbol
*) obj
);
280 IOUnlock( gIOObjectPortLock
);
283 mach_port_name_t
IOMachPort::makeSendRightForTask( task_t task
,
284 io_object_t obj
, ipc_kobject_type_t type
)
286 return( iokit_make_send_right( task
, obj
, type
));
289 void IOMachPort::free( void )
292 iokit_destroy_object_port( port
);
296 /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
298 class IOUserNotification
: public OSIterator
300 OSDeclareDefaultStructors(IOUserNotification
)
302 IONotifier
* holdNotify
;
307 virtual bool init( void );
310 virtual void setNotification( IONotifier
* obj
);
312 virtual void reset();
313 virtual bool isValid();
316 /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
320 // functions called from osfmk/device/iokit_rpc.c
323 iokit_add_reference( io_object_t obj
)
330 iokit_remove_reference( io_object_t obj
)
337 iokit_port_for_object( io_object_t obj
, ipc_kobject_type_t type
)
339 IOMachPort
* machPort
;
342 if( (machPort
= IOMachPort::portForObject( obj
, type
))) {
344 port
= machPort
->port
;
346 iokit_retain_port( port
);
357 iokit_client_died( io_object_t obj
, ipc_port_t
/* port */,
358 ipc_kobject_type_t type
, mach_port_mscount_t
* mscount
)
360 IOUserClient
* client
;
362 IOUserNotification
* notify
;
364 if( !IOMachPort::noMoreSendersForObject( obj
, type
, mscount
))
365 return( kIOReturnNotReady
);
367 if( IKOT_IOKIT_CONNECT
== type
)
369 if( (client
= OSDynamicCast( IOUserClient
, obj
)))
370 client
->clientDied();
372 else if( IKOT_IOKIT_OBJECT
== type
)
374 if( (map
= OSDynamicCast( IOMemoryMap
, obj
)))
376 else if( (notify
= OSDynamicCast( IOUserNotification
, obj
)))
377 notify
->setNotification( 0 );
380 return( kIOReturnSuccess
);
385 /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
387 class IOServiceUserNotification
: public IOUserNotification
389 OSDeclareDefaultStructors(IOServiceUserNotification
)
392 mach_msg_header_t msgHdr
;
393 OSNotificationHeader notifyHeader
;
396 enum { kMaxOutstanding
= 1024 };
401 OSObject
* lastEntry
;
406 virtual bool init( mach_port_t port
, natural_t type
,
407 OSAsyncReference reference
);
410 static bool _handler( void * target
,
411 void * ref
, IOService
* newService
);
412 virtual bool handler( void * ref
, IOService
* newService
);
414 virtual OSObject
* getNextObject();
417 class IOServiceMessageUserNotification
: public IOUserNotification
419 OSDeclareDefaultStructors(IOServiceMessageUserNotification
)
422 mach_msg_header_t msgHdr
;
423 mach_msg_body_t msgBody
;
424 mach_msg_port_descriptor_t ports
[1];
425 OSNotificationHeader notifyHeader
;
433 virtual bool init( mach_port_t port
, natural_t type
,
434 OSAsyncReference reference
, vm_size_t extraSize
);
437 static IOReturn
_handler( void * target
, void * ref
,
438 UInt32 messageType
, IOService
* provider
,
439 void * messageArgument
, vm_size_t argSize
);
440 virtual IOReturn
handler( void * ref
,
441 UInt32 messageType
, IOService
* provider
,
442 void * messageArgument
, vm_size_t argSize
);
444 virtual OSObject
* getNextObject();
447 /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
450 #define super OSIterator
451 OSDefineMetaClass( IOUserNotification
, OSIterator
)
452 OSDefineAbstractStructors( IOUserNotification
, OSIterator
)
454 /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
456 bool IOUserNotification::init( void )
461 lock
= IOLockAlloc();
468 void IOUserNotification::free( void )
471 holdNotify
->remove();
472 // can't be in handler now
481 void IOUserNotification::setNotification( IONotifier
* notify
)
483 IONotifier
* previousNotify
;
485 IOLockLock( gIOObjectPortLock
);
487 previousNotify
= holdNotify
;
490 IOLockUnlock( gIOObjectPortLock
);
493 previousNotify
->remove();
496 void IOUserNotification::reset()
501 bool IOUserNotification::isValid()
506 /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
509 #define super IOUserNotification
510 OSDefineMetaClassAndStructors(IOServiceUserNotification
, IOUserNotification
)
512 /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
514 bool IOServiceUserNotification::init( mach_port_t port
, natural_t type
,
515 OSAsyncReference reference
)
517 newSet
= OSArray::withCapacity( 1 );
521 msgSize
= sizeof( PingMsg
) + 0;
522 pingMsg
= (PingMsg
*) IOMalloc( msgSize
);
526 bzero( pingMsg
, msgSize
);
528 pingMsg
->msgHdr
.msgh_remote_port
= port
;
529 pingMsg
->msgHdr
.msgh_bits
= MACH_MSGH_BITS(
530 MACH_MSG_TYPE_COPY_SEND
/*remote*/,
531 MACH_MSG_TYPE_MAKE_SEND
/*local*/);
532 pingMsg
->msgHdr
.msgh_size
= msgSize
;
533 pingMsg
->msgHdr
.msgh_id
= kOSNotificationMessageID
;
535 pingMsg
->notifyHeader
.size
= 0;
536 pingMsg
->notifyHeader
.type
= type
;
537 bcopy( reference
, pingMsg
->notifyHeader
.reference
, sizeof(OSAsyncReference
) );
539 return( super::init() );
542 void IOServiceUserNotification::free( void )
547 OSObject
* _lastEntry
;
551 _lastEntry
= lastEntry
;
556 if( _pingMsg
&& _msgSize
)
557 IOFree( _pingMsg
, _msgSize
);
560 _lastEntry
->release();
566 bool IOServiceUserNotification::_handler( void * target
,
567 void * ref
, IOService
* newService
)
569 return( ((IOServiceUserNotification
*) target
)->handler( ref
, newService
));
572 bool IOServiceUserNotification::handler( void * ref
,
573 IOService
* newService
)
577 ipc_port_t port
= NULL
;
578 bool sendPing
= false;
582 count
= newSet
->getCount();
583 if( count
< kMaxOutstanding
) {
585 newSet
->setObject( newService
);
586 if( (sendPing
= (armed
&& (0 == count
))))
592 if( kIOServiceTerminatedNotificationType
== pingMsg
->notifyHeader
.type
)
593 IOMachPort::setHoldDestroy( newService
, IKOT_IOKIT_OBJECT
);
596 if( (port
= iokit_port_for_object( this, IKOT_IOKIT_OBJECT
) ))
597 pingMsg
->msgHdr
.msgh_local_port
= port
;
599 pingMsg
->msgHdr
.msgh_local_port
= NULL
;
601 kr
= mach_msg_send_from_kernel( &pingMsg
->msgHdr
,
602 pingMsg
->msgHdr
.msgh_size
);
604 iokit_release_port( port
);
606 if( KERN_SUCCESS
!= kr
)
607 IOLog("%s: mach_msg_send_from_kernel {%x}\n", __FILE__
, kr
);
613 OSObject
* IOServiceUserNotification::getNextObject()
621 lastEntry
->release();
623 count
= newSet
->getCount();
625 result
= newSet
->getObject( count
- 1 );
627 newSet
->removeObject( count
- 1);
639 /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
641 OSDefineMetaClassAndStructors(IOServiceMessageUserNotification
, IOUserNotification
)
643 /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
645 bool IOServiceMessageUserNotification::init( mach_port_t port
, natural_t type
,
646 OSAsyncReference reference
, vm_size_t extraSize
)
649 extraSize
+= sizeof(IOServiceInterestContent
);
650 msgSize
= sizeof( PingMsg
) + extraSize
;
651 pingMsg
= (PingMsg
*) IOMalloc( msgSize
);
655 bzero( pingMsg
, msgSize
);
657 pingMsg
->msgHdr
.msgh_remote_port
= port
;
658 pingMsg
->msgHdr
.msgh_bits
= MACH_MSGH_BITS_COMPLEX
660 MACH_MSG_TYPE_COPY_SEND
/*remote*/,
661 MACH_MSG_TYPE_MAKE_SEND
/*local*/);
662 pingMsg
->msgHdr
.msgh_size
= msgSize
;
663 pingMsg
->msgHdr
.msgh_id
= kOSNotificationMessageID
;
665 pingMsg
->msgBody
.msgh_descriptor_count
= 1;
667 pingMsg
->ports
[0].name
= 0;
668 pingMsg
->ports
[0].disposition
= MACH_MSG_TYPE_MAKE_SEND
;
669 pingMsg
->ports
[0].type
= MACH_MSG_PORT_DESCRIPTOR
;
671 pingMsg
->notifyHeader
.size
= extraSize
;
672 pingMsg
->notifyHeader
.type
= type
;
673 bcopy( reference
, pingMsg
->notifyHeader
.reference
, sizeof(OSAsyncReference
) );
675 return( super::init() );
678 void IOServiceMessageUserNotification::free( void )
688 if( _pingMsg
&& _msgSize
)
689 IOFree( _pingMsg
, _msgSize
);
692 IOReturn
IOServiceMessageUserNotification::_handler( void * target
, void * ref
,
693 UInt32 messageType
, IOService
* provider
,
694 void * argument
, vm_size_t argSize
)
696 return( ((IOServiceMessageUserNotification
*) target
)->handler(
697 ref
, messageType
, provider
, argument
, argSize
));
700 IOReturn
IOServiceMessageUserNotification::handler( void * ref
,
701 UInt32 messageType
, IOService
* provider
,
702 void * messageArgument
, vm_size_t argSize
)
705 ipc_port_t thisPort
, providerPort
;
706 IOServiceInterestContent
* data
= (IOServiceInterestContent
*)
707 pingMsg
->notifyHeader
.content
;
709 data
->messageType
= messageType
;
711 argSize
= sizeof( messageArgument
);
712 data
->messageArgument
[0] = messageArgument
;
714 if( argSize
> kIOUserNotifyMaxMessageSize
)
715 argSize
= kIOUserNotifyMaxMessageSize
;
716 bcopy( messageArgument
, data
->messageArgument
, argSize
);
718 pingMsg
->msgHdr
.msgh_size
= sizeof( PingMsg
)
719 + sizeof( IOServiceInterestContent
)
720 - sizeof( data
->messageArgument
)
723 providerPort
= iokit_port_for_object( provider
, IKOT_IOKIT_OBJECT
);
724 pingMsg
->ports
[0].name
= providerPort
;
725 thisPort
= iokit_port_for_object( this, IKOT_IOKIT_OBJECT
);
726 pingMsg
->msgHdr
.msgh_local_port
= thisPort
;
727 kr
= mach_msg_send_from_kernel( &pingMsg
->msgHdr
,
728 pingMsg
->msgHdr
.msgh_size
);
730 iokit_release_port( thisPort
);
732 iokit_release_port( providerPort
);
734 if( KERN_SUCCESS
!= kr
)
735 IOLog("%s: mach_msg_send_from_kernel {%x}\n", __FILE__
, kr
);
737 return( kIOReturnSuccess
);
740 OSObject
* IOServiceMessageUserNotification::getNextObject()
745 /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
748 #define super IOService
749 OSDefineMetaClassAndAbstractStructors( IOUserClient
, IOService
)
751 void IOUserClient::initialize( void )
753 gIOObjectPortLock
= IOLockAlloc();
755 assert( gIOObjectPortLock
);
758 void IOUserClient::setAsyncReference(OSAsyncReference asyncRef
,
759 mach_port_t wakePort
,
760 void *callback
, void *refcon
)
762 asyncRef
[kIOAsyncReservedIndex
] = (natural_t
) wakePort
;
763 asyncRef
[kIOAsyncCalloutFuncIndex
] = (natural_t
) callback
;
764 asyncRef
[kIOAsyncCalloutRefconIndex
] = (natural_t
) refcon
;
767 inline OSDictionary
* CopyConsoleUser(UInt32 uid
)
770 OSDictionary
* user
= 0;
772 if ((array
= OSDynamicCast(OSArray
,
773 IORegistryEntry::getRegistryRoot()->copyProperty(gIOConsoleUsersKey
))))
775 for (unsigned int idx
= 0;
776 (user
= OSDynamicCast(OSDictionary
, array
->getObject(idx
)));
780 if ((num
= OSDynamicCast(OSNumber
, user
->getObject(gIOConsoleSessionUIDKey
)))
781 && (uid
== num
->unsigned32BitValue())) {
791 IOReturn
IOUserClient::clientHasPrivilege( void * securityToken
,
792 const char * privilegeName
)
795 security_token_t token
;
796 mach_msg_type_number_t count
;
801 if ((secureConsole
= !strcmp(privilegeName
, kIOClientPrivilegeSecureConsoleProcess
)))
802 task
= (task_t
)((IOUCProcessToken
*)securityToken
)->token
;
804 task
= (task_t
)securityToken
;
806 count
= TASK_SECURITY_TOKEN_COUNT
;
807 kr
= task_info( task
, TASK_SECURITY_TOKEN
, (task_info_t
) &token
, &count
);
809 if (KERN_SUCCESS
!= kr
)
811 else if (!strcmp(privilegeName
, kIOClientPrivilegeAdministrator
)) {
812 if (0 != token
.val
[0])
813 kr
= kIOReturnNotPrivileged
;
814 } else if (!strcmp(privilegeName
, kIOClientPrivilegeLocalUser
)) {
815 user
= CopyConsoleUser(token
.val
[0]);
819 kr
= kIOReturnNotPrivileged
;
820 } else if (secureConsole
|| !strcmp(privilegeName
, kIOClientPrivilegeConsoleUser
)) {
821 user
= CopyConsoleUser(token
.val
[0]);
823 if (user
->getObject(gIOConsoleSessionOnConsoleKey
) != kOSBooleanTrue
)
824 kr
= kIOReturnNotPrivileged
;
825 else if ( secureConsole
) {
826 OSNumber
* pid
= OSDynamicCast(OSNumber
, user
->getObject(gIOConsoleSessionSecureInputPIDKey
));
827 if ( pid
&& pid
->unsigned32BitValue() != ((IOUCProcessToken
*)securityToken
)->pid
)
828 kr
= kIOReturnNotPrivileged
;
833 kr
= kIOReturnNotPrivileged
;
835 kr
= kIOReturnUnsupported
;
840 bool IOUserClient::initWithTask(task_t owningTask
,
844 if( getPropertyTable())
847 return super::init();
850 bool IOUserClient::initWithTask(task_t owningTask
,
853 OSDictionary
* properties
)
857 ok
= super::init( properties
);
858 ok
&= initWithTask( owningTask
, securityID
, type
);
863 void IOUserClient::free()
871 IOReturn
IOUserClient::clientDied( void )
873 return( clientClose());
876 IOReturn
IOUserClient::clientClose( void )
878 return( kIOReturnUnsupported
);
881 IOService
* IOUserClient::getService( void )
886 IOReturn
IOUserClient::registerNotificationPort(
887 mach_port_t
/* port */,
891 return( kIOReturnUnsupported
);
894 IOReturn
IOUserClient::getNotificationSemaphore( UInt32 notification_type
,
895 semaphore_t
* semaphore
)
897 return( kIOReturnUnsupported
);
900 IOReturn
IOUserClient::connectClient( IOUserClient
* /* client */ )
902 return( kIOReturnUnsupported
);
905 IOReturn
IOUserClient::clientMemoryForType( UInt32 type
,
906 IOOptionBits
* options
,
907 IOMemoryDescriptor
** memory
)
909 return( kIOReturnUnsupported
);
912 IOMemoryMap
* IOUserClient::mapClientMemory(
915 IOOptionBits mapFlags
,
916 IOVirtualAddress atAddress
)
919 IOOptionBits options
= 0;
920 IOMemoryDescriptor
* memory
;
921 IOMemoryMap
* map
= 0;
923 err
= clientMemoryForType( (UInt32
) type
, &options
, &memory
);
925 if( memory
&& (kIOReturnSuccess
== err
)) {
927 options
= (options
& ~kIOMapUserOptionsMask
)
928 | (mapFlags
& kIOMapUserOptionsMask
);
929 map
= memory
->map( task
, atAddress
, options
);
936 IOReturn
IOUserClient::exportObjectToClient(task_t task
,
937 OSObject
*obj
, io_object_t
*clientObj
)
939 mach_port_name_t name
;
941 name
= IOMachPort::makeSendRightForTask( task
, obj
, IKOT_IOKIT_OBJECT
);
944 *(mach_port_name_t
*)clientObj
= name
;
945 return kIOReturnSuccess
;
948 IOExternalMethod
* IOUserClient::getExternalMethodForIndex( UInt32
/* index */)
953 IOExternalAsyncMethod
* IOUserClient::getExternalAsyncMethodForIndex( UInt32
/* index */)
958 IOExternalMethod
* IOUserClient::
959 getTargetAndMethodForIndex(IOService
**targetP
, UInt32 index
)
961 IOExternalMethod
*method
= getExternalMethodForIndex(index
);
964 *targetP
= (IOService
*) method
->object
;
969 IOExternalAsyncMethod
* IOUserClient::
970 getAsyncTargetAndMethodForIndex(IOService
** targetP
, UInt32 index
)
972 IOExternalAsyncMethod
*method
= getExternalAsyncMethodForIndex(index
);
975 *targetP
= (IOService
*) method
->object
;
980 IOExternalTrap
* IOUserClient::
981 getExternalTrapForIndex(UInt32 index
)
986 IOExternalTrap
* IOUserClient::
987 getTargetAndTrapForIndex(IOService
** targetP
, UInt32 index
)
989 IOExternalTrap
*trap
= getExternalTrapForIndex(index
);
992 *targetP
= trap
->object
;
998 IOReturn
IOUserClient::sendAsyncResult(OSAsyncReference reference
,
999 IOReturn result
, void *args
[], UInt32 numArgs
)
1002 mach_msg_header_t msgHdr
;
1003 OSNotificationHeader notifyHdr
;
1004 IOAsyncCompletionContent asyncContent
;
1005 void * args
[kMaxAsyncArgs
];
1008 mach_port_t replyPort
;
1011 // If no reply port, do nothing.
1012 replyPort
= (mach_port_t
) reference
[0];
1013 if(replyPort
== MACH_PORT_NULL
)
1014 return kIOReturnSuccess
;
1016 if(numArgs
> kMaxAsyncArgs
)
1017 return kIOReturnMessageTooLarge
;
1018 replyMsg
.msgHdr
.msgh_bits
= MACH_MSGH_BITS(MACH_MSG_TYPE_COPY_SEND
/*remote*/,
1020 replyMsg
.msgHdr
.msgh_size
=
1021 sizeof(replyMsg
) - (kMaxAsyncArgs
-numArgs
)*sizeof(void *);
1022 replyMsg
.msgHdr
.msgh_remote_port
= replyPort
;
1023 replyMsg
.msgHdr
.msgh_local_port
= 0;
1024 replyMsg
.msgHdr
.msgh_id
= kOSNotificationMessageID
;
1026 replyMsg
.notifyHdr
.size
= sizeof(IOAsyncCompletionContent
)
1027 + numArgs
*sizeof(void *);
1028 replyMsg
.notifyHdr
.type
= kIOAsyncCompletionNotificationType
;
1029 bcopy( reference
, replyMsg
.notifyHdr
.reference
, sizeof(OSAsyncReference
));
1031 replyMsg
.asyncContent
.result
= result
;
1033 bcopy(args
, replyMsg
.args
, sizeof(void *)*numArgs
);
1034 kr
= mach_msg_send_from_kernel( &replyMsg
.msgHdr
,
1035 replyMsg
.msgHdr
.msgh_size
);
1036 if( KERN_SUCCESS
!= kr
)
1037 IOLog("%s: mach_msg_send_from_kernel {%x}\n", __FILE__
, kr
);
1041 /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
1045 #define CHECK(cls,obj,out) \
1047 if( !(out = OSDynamicCast( cls, obj))) \
1048 return( kIOReturnBadArgument )
1050 /* Routine io_object_get_class */
1051 kern_return_t
is_io_object_get_class(
1053 io_name_t className
)
1055 const OSMetaClass
* my_obj
= NULL
;
1058 return( kIOReturnBadArgument
);
1060 my_obj
= object
->getMetaClass();
1062 return (kIOReturnNotFound
);
1065 strcpy( className
, my_obj
->getClassName());
1066 return( kIOReturnSuccess
);
1069 /* Routine io_object_get_superclass */
1070 kern_return_t
is_io_object_get_superclass(
1071 mach_port_t master_port
,
1073 io_name_t class_name
)
1075 const OSMetaClass
* my_obj
= NULL
;
1076 const OSMetaClass
* superclass
= NULL
;
1077 const OSSymbol
*my_name
= NULL
;
1078 const char *my_cstr
= NULL
;
1080 if (!obj_name
|| !class_name
)
1081 return (kIOReturnBadArgument
);
1083 if( master_port
!= master_device_port
)
1084 return( kIOReturnNotPrivileged
);
1086 my_name
= OSSymbol::withCString(obj_name
);
1089 my_obj
= OSMetaClass::getMetaClassWithName(my_name
);
1093 superclass
= my_obj
->getSuperClass();
1097 return( kIOReturnNotFound
);
1100 my_cstr
= superclass
->getClassName();
1103 strncpy(class_name
, my_cstr
, sizeof(io_name_t
)-1);
1104 return( kIOReturnSuccess
);
1106 return (kIOReturnNotFound
);
1109 /* Routine io_object_get_bundle_identifier */
1110 kern_return_t
is_io_object_get_bundle_identifier(
1111 mach_port_t master_port
,
1113 io_name_t bundle_name
)
1115 const OSMetaClass
* my_obj
= NULL
;
1116 const OSSymbol
*my_name
= NULL
;
1117 const OSSymbol
*identifier
= NULL
;
1118 const char *my_cstr
= NULL
;
1120 if (!obj_name
|| !bundle_name
)
1121 return (kIOReturnBadArgument
);
1123 if( master_port
!= master_device_port
)
1124 return( kIOReturnNotPrivileged
);
1126 my_name
= OSSymbol::withCString(obj_name
);
1129 my_obj
= OSMetaClass::getMetaClassWithName(my_name
);
1134 identifier
= my_obj
->getKmodName();
1137 return( kIOReturnNotFound
);
1140 my_cstr
= identifier
->getCStringNoCopy();
1142 strncpy(bundle_name
, identifier
->getCStringNoCopy(), sizeof(io_name_t
)-1);
1143 return( kIOReturnSuccess
);
1146 return (kIOReturnBadArgument
);
1149 /* Routine io_object_conforms_to */
1150 kern_return_t
is_io_object_conforms_to(
1152 io_name_t className
,
1153 boolean_t
*conforms
)
1156 return( kIOReturnBadArgument
);
1158 *conforms
= (0 != object
->metaCast( className
));
1159 return( kIOReturnSuccess
);
1162 /* Routine io_object_get_retain_count */
1163 kern_return_t
is_io_object_get_retain_count(
1168 return( kIOReturnBadArgument
);
1170 *retainCount
= object
->getRetainCount();
1171 return( kIOReturnSuccess
);
1174 /* Routine io_iterator_next */
1175 kern_return_t
is_io_iterator_next(
1176 io_object_t iterator
,
1177 io_object_t
*object
)
1181 CHECK( OSIterator
, iterator
, iter
);
1183 obj
= iter
->getNextObject();
1187 return( kIOReturnSuccess
);
1189 return( kIOReturnNoDevice
);
1192 /* Routine io_iterator_reset */
1193 kern_return_t
is_io_iterator_reset(
1194 io_object_t iterator
)
1196 CHECK( OSIterator
, iterator
, iter
);
1200 return( kIOReturnSuccess
);
1203 /* Routine io_iterator_is_valid */
1204 kern_return_t
is_io_iterator_is_valid(
1205 io_object_t iterator
,
1206 boolean_t
*is_valid
)
1208 CHECK( OSIterator
, iterator
, iter
);
1210 *is_valid
= iter
->isValid();
1212 return( kIOReturnSuccess
);
1215 /* Routine io_service_match_property_table */
1216 kern_return_t
is_io_service_match_property_table(
1217 io_service_t _service
,
1218 io_string_t matching
,
1219 boolean_t
*matches
)
1221 CHECK( IOService
, _service
, service
);
1225 OSDictionary
* dict
;
1227 obj
= OSUnserializeXML( matching
);
1229 if( (dict
= OSDynamicCast( OSDictionary
, obj
))) {
1230 *matches
= service
->passiveMatch( dict
);
1231 kr
= kIOReturnSuccess
;
1233 kr
= kIOReturnBadArgument
;
1241 /* Routine io_service_match_property_table_ool */
1242 kern_return_t
is_io_service_match_property_table_ool(
1243 io_object_t service
,
1244 io_buf_ptr_t matching
,
1245 mach_msg_type_number_t matchingCnt
,
1247 boolean_t
*matches
)
1251 vm_map_offset_t map_data
;
1253 kr
= vm_map_copyout( kernel_map
, &map_data
, (vm_map_copy_t
) matching
);
1254 data
= CAST_DOWN(vm_offset_t
, map_data
);
1256 if( KERN_SUCCESS
== kr
) {
1257 // must return success after vm_map_copyout() succeeds
1258 *result
= is_io_service_match_property_table( service
,
1259 (char *) data
, matches
);
1260 vm_deallocate( kernel_map
, data
, matchingCnt
);
1266 /* Routine io_service_get_matching_services */
1267 kern_return_t
is_io_service_get_matching_services(
1268 mach_port_t master_port
,
1269 io_string_t matching
,
1270 io_iterator_t
*existing
)
1274 OSDictionary
* dict
;
1276 if( master_port
!= master_device_port
)
1277 return( kIOReturnNotPrivileged
);
1279 obj
= OSUnserializeXML( matching
);
1281 if( (dict
= OSDynamicCast( OSDictionary
, obj
))) {
1282 *existing
= IOService::getMatchingServices( dict
);
1283 kr
= kIOReturnSuccess
;
1285 kr
= kIOReturnBadArgument
;
1293 /* Routine io_service_get_matching_services_ool */
1294 kern_return_t
is_io_service_get_matching_services_ool(
1295 mach_port_t master_port
,
1296 io_buf_ptr_t matching
,
1297 mach_msg_type_number_t matchingCnt
,
1299 io_object_t
*existing
)
1303 vm_map_offset_t map_data
;
1305 kr
= vm_map_copyout( kernel_map
, &map_data
, (vm_map_copy_t
) matching
);
1306 data
= CAST_DOWN(vm_offset_t
, map_data
);
1308 if( KERN_SUCCESS
== kr
) {
1309 // must return success after vm_map_copyout() succeeds
1310 *result
= is_io_service_get_matching_services( master_port
,
1311 (char *) data
, existing
);
1312 vm_deallocate( kernel_map
, data
, matchingCnt
);
1318 /* Routine io_service_add_notification */
1319 kern_return_t
is_io_service_add_notification(
1320 mach_port_t master_port
,
1321 io_name_t notification_type
,
1322 io_string_t matching
,
1324 io_async_ref_t reference
,
1325 mach_msg_type_number_t referenceCnt
,
1326 io_object_t
* notification
)
1328 IOServiceUserNotification
* userNotify
= 0;
1329 IONotifier
* notify
= 0;
1330 const OSSymbol
* sym
;
1331 OSDictionary
* dict
;
1333 unsigned long int userMsgType
;
1336 if( master_port
!= master_device_port
)
1337 return( kIOReturnNotPrivileged
);
1340 err
= kIOReturnNoResources
;
1342 if( !(sym
= OSSymbol::withCString( notification_type
)))
1343 err
= kIOReturnNoResources
;
1345 if( !(dict
= OSDynamicCast( OSDictionary
,
1346 OSUnserializeXML( matching
)))) {
1347 err
= kIOReturnBadArgument
;
1351 if( (sym
== gIOPublishNotification
)
1352 || (sym
== gIOFirstPublishNotification
))
1353 userMsgType
= kIOServicePublishNotificationType
;
1354 else if( (sym
== gIOMatchedNotification
)
1355 || (sym
== gIOFirstMatchNotification
))
1356 userMsgType
= kIOServiceMatchedNotificationType
;
1357 else if( sym
== gIOTerminatedNotification
)
1358 userMsgType
= kIOServiceTerminatedNotificationType
;
1360 userMsgType
= kLastIOKitNotificationType
;
1362 userNotify
= new IOServiceUserNotification
;
1364 if( userNotify
&& !userNotify
->init( port
, userMsgType
,
1366 userNotify
->release();
1372 notify
= IOService::addNotification( sym
, dict
,
1373 &userNotify
->_handler
, userNotify
);
1376 *notification
= userNotify
;
1377 userNotify
->setNotification( notify
);
1378 err
= kIOReturnSuccess
;
1380 err
= kIOReturnUnsupported
;
1392 /* Routine io_service_add_notification_ool */
1393 kern_return_t
is_io_service_add_notification_ool(
1394 mach_port_t master_port
,
1395 io_name_t notification_type
,
1396 io_buf_ptr_t matching
,
1397 mach_msg_type_number_t matchingCnt
,
1398 mach_port_t wake_port
,
1399 io_async_ref_t reference
,
1400 mach_msg_type_number_t referenceCnt
,
1402 io_object_t
*notification
)
1406 vm_map_offset_t map_data
;
1408 kr
= vm_map_copyout( kernel_map
, &map_data
, (vm_map_copy_t
) matching
);
1409 data
= CAST_DOWN(vm_offset_t
, map_data
);
1411 if( KERN_SUCCESS
== kr
) {
1412 // must return success after vm_map_copyout() succeeds
1413 *result
= is_io_service_add_notification( master_port
, notification_type
,
1414 (char *) data
, wake_port
, reference
, referenceCnt
, notification
);
1415 vm_deallocate( kernel_map
, data
, matchingCnt
);
1422 /* Routine io_service_add_notification_old */
1423 kern_return_t
is_io_service_add_notification_old(
1424 mach_port_t master_port
,
1425 io_name_t notification_type
,
1426 io_string_t matching
,
1429 io_object_t
* notification
)
1431 return( is_io_service_add_notification( master_port
, notification_type
,
1432 matching
, port
, &ref
, 1, notification
));
1435 /* Routine io_service_add_message_notification */
1436 kern_return_t
is_io_service_add_interest_notification(
1437 io_object_t _service
,
1438 io_name_t type_of_interest
,
1440 io_async_ref_t reference
,
1441 mach_msg_type_number_t referenceCnt
,
1442 io_object_t
* notification
)
1445 IOServiceMessageUserNotification
* userNotify
= 0;
1446 IONotifier
* notify
= 0;
1447 const OSSymbol
* sym
;
1450 CHECK( IOService
, _service
, service
);
1452 err
= kIOReturnNoResources
;
1453 if( (sym
= OSSymbol::withCString( type_of_interest
))) do {
1455 userNotify
= new IOServiceMessageUserNotification
;
1457 if( userNotify
&& !userNotify
->init( port
, kIOServiceMessageNotificationType
,
1458 reference
, kIOUserNotifyMaxMessageSize
)) {
1459 userNotify
->release();
1465 notify
= service
->registerInterest( sym
,
1466 &userNotify
->_handler
, userNotify
);
1468 *notification
= userNotify
;
1469 userNotify
->setNotification( notify
);
1470 err
= kIOReturnSuccess
;
1472 err
= kIOReturnUnsupported
;
1481 /* Routine io_service_acknowledge_notification */
1482 kern_return_t
is_io_service_acknowledge_notification(
1483 io_object_t _service
,
1484 natural_t notify_ref
,
1485 natural_t response
)
1487 CHECK( IOService
, _service
, service
);
1489 return( service
->acknowledgeNotification( (IONotificationRef
) notify_ref
,
1490 (IOOptionBits
) response
));
1494 /* Routine io_connect_get_semaphore */
1495 kern_return_t
is_io_connect_get_notification_semaphore(
1496 io_connect_t connection
,
1497 natural_t notification_type
,
1498 semaphore_t
*semaphore
)
1500 CHECK( IOUserClient
, connection
, client
);
1502 return( client
->getNotificationSemaphore( (UInt32
) notification_type
,
1506 /* Routine io_registry_get_root_entry */
1507 kern_return_t
is_io_registry_get_root_entry(
1508 mach_port_t master_port
,
1511 IORegistryEntry
* entry
;
1513 if( master_port
!= master_device_port
)
1514 return( kIOReturnNotPrivileged
);
1516 entry
= IORegistryEntry::getRegistryRoot();
1521 return( kIOReturnSuccess
);
1524 /* Routine io_registry_create_iterator */
1525 kern_return_t
is_io_registry_create_iterator(
1526 mach_port_t master_port
,
1529 io_object_t
*iterator
)
1531 if( master_port
!= master_device_port
)
1532 return( kIOReturnNotPrivileged
);
1534 *iterator
= IORegistryIterator::iterateOver(
1535 IORegistryEntry::getPlane( plane
), options
);
1537 return( *iterator
? kIOReturnSuccess
: kIOReturnBadArgument
);
1540 /* Routine io_registry_entry_create_iterator */
1541 kern_return_t
is_io_registry_entry_create_iterator(
1542 io_object_t registry_entry
,
1545 io_object_t
*iterator
)
1547 CHECK( IORegistryEntry
, registry_entry
, entry
);
1549 *iterator
= IORegistryIterator::iterateOver( entry
,
1550 IORegistryEntry::getPlane( plane
), options
);
1552 return( *iterator
? kIOReturnSuccess
: kIOReturnBadArgument
);
1555 /* Routine io_registry_iterator_enter */
1556 kern_return_t
is_io_registry_iterator_enter_entry(
1557 io_object_t iterator
)
1559 CHECK( IORegistryIterator
, iterator
, iter
);
1563 return( kIOReturnSuccess
);
1566 /* Routine io_registry_iterator_exit */
1567 kern_return_t
is_io_registry_iterator_exit_entry(
1568 io_object_t iterator
)
1572 CHECK( IORegistryIterator
, iterator
, iter
);
1574 didIt
= iter
->exitEntry();
1576 return( didIt
? kIOReturnSuccess
: kIOReturnNoDevice
);
1579 /* Routine io_registry_entry_from_path */
1580 kern_return_t
is_io_registry_entry_from_path(
1581 mach_port_t master_port
,
1583 io_object_t
*registry_entry
)
1585 IORegistryEntry
* entry
;
1587 if( master_port
!= master_device_port
)
1588 return( kIOReturnNotPrivileged
);
1590 entry
= IORegistryEntry::fromPath( path
);
1592 *registry_entry
= entry
;
1594 return( kIOReturnSuccess
);
1597 /* Routine io_registry_entry_in_plane */
1598 kern_return_t
is_io_registry_entry_in_plane(
1599 io_object_t registry_entry
,
1601 boolean_t
*inPlane
)
1603 CHECK( IORegistryEntry
, registry_entry
, entry
);
1605 *inPlane
= entry
->inPlane( IORegistryEntry::getPlane( plane
));
1607 return( kIOReturnSuccess
);
1611 /* Routine io_registry_entry_get_path */
1612 kern_return_t
is_io_registry_entry_get_path(
1613 io_object_t registry_entry
,
1618 CHECK( IORegistryEntry
, registry_entry
, entry
);
1620 length
= sizeof( io_string_t
);
1621 if( entry
->getPath( path
, &length
, IORegistryEntry::getPlane( plane
)))
1622 return( kIOReturnSuccess
);
1624 return( kIOReturnBadArgument
);
1628 /* Routine io_registry_entry_get_name */
1629 kern_return_t
is_io_registry_entry_get_name(
1630 io_object_t registry_entry
,
1633 CHECK( IORegistryEntry
, registry_entry
, entry
);
1635 strncpy( name
, entry
->getName(), sizeof( io_name_t
));
1637 return( kIOReturnSuccess
);
1640 /* Routine io_registry_entry_get_name_in_plane */
1641 kern_return_t
is_io_registry_entry_get_name_in_plane(
1642 io_object_t registry_entry
,
1643 io_name_t planeName
,
1646 const IORegistryPlane
* plane
;
1647 CHECK( IORegistryEntry
, registry_entry
, entry
);
1650 plane
= IORegistryEntry::getPlane( planeName
);
1654 strncpy( name
, entry
->getName( plane
), sizeof( io_name_t
));
1656 return( kIOReturnSuccess
);
1659 /* Routine io_registry_entry_get_location_in_plane */
1660 kern_return_t
is_io_registry_entry_get_location_in_plane(
1661 io_object_t registry_entry
,
1662 io_name_t planeName
,
1663 io_name_t location
)
1665 const IORegistryPlane
* plane
;
1666 CHECK( IORegistryEntry
, registry_entry
, entry
);
1669 plane
= IORegistryEntry::getPlane( planeName
);
1673 const char * cstr
= entry
->getLocation( plane
);
1676 strncpy( location
, cstr
, sizeof( io_name_t
));
1677 return( kIOReturnSuccess
);
1679 return( kIOReturnNotFound
);
1682 // Create a vm_map_copy_t or kalloc'ed data for memory
1683 // to be copied out. ipc will free after the copyout.
1685 static kern_return_t
copyoutkdata( void * data
, vm_size_t len
,
1686 io_buf_ptr_t
* buf
)
1691 err
= vm_map_copyin( kernel_map
, CAST_USER_ADDR_T(data
), len
,
1692 false /* src_destroy */, ©
);
1694 assert( err
== KERN_SUCCESS
);
1695 if( err
== KERN_SUCCESS
)
1696 *buf
= (char *) copy
;
1701 /* Routine io_registry_entry_get_property */
1702 kern_return_t
is_io_registry_entry_get_property_bytes(
1703 io_object_t registry_entry
,
1704 io_name_t property_name
,
1705 io_scalar_inband_t buf
,
1706 mach_msg_type_number_t
*dataCnt
)
1714 unsigned int len
= 0;
1715 const void * bytes
= 0;
1716 IOReturn ret
= kIOReturnSuccess
;
1718 CHECK( IORegistryEntry
, registry_entry
, entry
);
1720 obj
= entry
->copyProperty(property_name
);
1722 return( kIOReturnNoResources
);
1724 // One day OSData will be a common container base class
1726 if( (data
= OSDynamicCast( OSData
, obj
))) {
1727 len
= data
->getLength();
1728 bytes
= data
->getBytesNoCopy();
1730 } else if( (str
= OSDynamicCast( OSString
, obj
))) {
1731 len
= str
->getLength() + 1;
1732 bytes
= str
->getCStringNoCopy();
1734 } else if( (boo
= OSDynamicCast( OSBoolean
, obj
))) {
1735 len
= boo
->isTrue() ? sizeof("Yes") : sizeof("No");
1736 bytes
= boo
->isTrue() ? "Yes" : "No";
1738 } else if( (off
= OSDynamicCast( OSNumber
, obj
))) {
1739 offsetBytes
= off
->unsigned64BitValue();
1740 len
= off
->numberOfBytes();
1741 bytes
= &offsetBytes
;
1742 #ifdef __BIG_ENDIAN__
1743 bytes
= (const void *)
1744 (((UInt32
) bytes
) + (sizeof( UInt64
) - len
));
1748 ret
= kIOReturnBadArgument
;
1752 ret
= kIOReturnIPCError
;
1755 bcopy( bytes
, buf
, len
);
1763 /* Routine io_registry_entry_get_property */
1764 kern_return_t
is_io_registry_entry_get_property(
1765 io_object_t registry_entry
,
1766 io_name_t property_name
,
1767 io_buf_ptr_t
*properties
,
1768 mach_msg_type_number_t
*propertiesCnt
)
1774 CHECK( IORegistryEntry
, registry_entry
, entry
);
1776 obj
= entry
->copyProperty(property_name
);
1778 return( kIOReturnNotFound
);
1780 OSSerialize
* s
= OSSerialize::withCapacity(4096);
1783 return( kIOReturnNoMemory
);
1787 if( obj
->serialize( s
)) {
1788 len
= s
->getLength();
1789 *propertiesCnt
= len
;
1790 err
= copyoutkdata( s
->text(), len
, properties
);
1793 err
= kIOReturnUnsupported
;
1801 /* Routine io_registry_entry_get_property_recursively */
1802 kern_return_t
is_io_registry_entry_get_property_recursively(
1803 io_object_t registry_entry
,
1805 io_name_t property_name
,
1807 io_buf_ptr_t
*properties
,
1808 mach_msg_type_number_t
*propertiesCnt
)
1814 CHECK( IORegistryEntry
, registry_entry
, entry
);
1816 obj
= entry
->copyProperty( property_name
,
1817 IORegistryEntry::getPlane( plane
), options
);
1819 return( kIOReturnNotFound
);
1821 OSSerialize
* s
= OSSerialize::withCapacity(4096);
1824 return( kIOReturnNoMemory
);
1829 if( obj
->serialize( s
)) {
1830 len
= s
->getLength();
1831 *propertiesCnt
= len
;
1832 err
= copyoutkdata( s
->text(), len
, properties
);
1835 err
= kIOReturnUnsupported
;
1843 /* Routine io_registry_entry_get_properties */
1844 kern_return_t
is_io_registry_entry_get_properties(
1845 io_object_t registry_entry
,
1846 io_buf_ptr_t
*properties
,
1847 mach_msg_type_number_t
*propertiesCnt
)
1852 CHECK( IORegistryEntry
, registry_entry
, entry
);
1854 OSSerialize
* s
= OSSerialize::withCapacity(4096);
1856 return( kIOReturnNoMemory
);
1860 if( entry
->serializeProperties( s
)) {
1861 len
= s
->getLength();
1862 *propertiesCnt
= len
;
1863 err
= copyoutkdata( s
->text(), len
, properties
);
1866 err
= kIOReturnUnsupported
;
1873 /* Routine io_registry_entry_set_properties */
1874 kern_return_t is_io_registry_entry_set_properties
1876 io_object_t registry_entry
,
1877 io_buf_ptr_t properties
,
1878 mach_msg_type_number_t propertiesCnt
,
1885 vm_map_offset_t map_data
;
1887 CHECK( IORegistryEntry
, registry_entry
, entry
);
1889 err
= vm_map_copyout( kernel_map
, &map_data
, (vm_map_copy_t
) properties
);
1890 data
= CAST_DOWN(vm_offset_t
, map_data
);
1892 if( KERN_SUCCESS
== err
) {
1894 // must return success after vm_map_copyout() succeeds
1895 obj
= OSUnserializeXML( (const char *) data
);
1896 vm_deallocate( kernel_map
, data
, propertiesCnt
);
1899 res
= entry
->setProperties( obj
);
1902 res
= kIOReturnBadArgument
;
1910 /* Routine io_registry_entry_get_child_iterator */
1911 kern_return_t
is_io_registry_entry_get_child_iterator(
1912 io_object_t registry_entry
,
1914 io_object_t
*iterator
)
1916 CHECK( IORegistryEntry
, registry_entry
, entry
);
1918 *iterator
= entry
->getChildIterator(
1919 IORegistryEntry::getPlane( plane
));
1921 return( kIOReturnSuccess
);
1924 /* Routine io_registry_entry_get_parent_iterator */
1925 kern_return_t
is_io_registry_entry_get_parent_iterator(
1926 io_object_t registry_entry
,
1928 io_object_t
*iterator
)
1930 CHECK( IORegistryEntry
, registry_entry
, entry
);
1932 *iterator
= entry
->getParentIterator(
1933 IORegistryEntry::getPlane( plane
));
1935 return( kIOReturnSuccess
);
1938 /* Routine io_service_get_busy_state */
1939 kern_return_t
is_io_service_get_busy_state(
1940 io_object_t _service
,
1943 CHECK( IOService
, _service
, service
);
1945 *busyState
= service
->getBusyState();
1947 return( kIOReturnSuccess
);
1950 /* Routine io_service_get_state */
1951 kern_return_t
is_io_service_get_state(
1952 io_object_t _service
,
1955 CHECK( IOService
, _service
, service
);
1957 *state
= service
->getState();
1959 return( kIOReturnSuccess
);
1962 /* Routine io_service_wait_quiet */
1963 kern_return_t
is_io_service_wait_quiet(
1964 io_object_t _service
,
1965 mach_timespec_t wait_time
)
1967 CHECK( IOService
, _service
, service
);
1969 return( service
->waitQuiet( &wait_time
));
1972 /* Routine io_service_request_probe */
1973 kern_return_t
is_io_service_request_probe(
1974 io_object_t _service
,
1977 CHECK( IOService
, _service
, service
);
1979 return( service
->requestProbe( options
));
1983 /* Routine io_service_open */
1984 kern_return_t
is_io_service_open(
1985 io_object_t _service
,
1988 io_object_t
*connection
)
1990 IOUserClient
* client
;
1993 CHECK( IOService
, _service
, service
);
1995 err
= service
->newUserClient( owningTask
, (void *) owningTask
,
1996 connect_type
, &client
);
1998 if( err
== kIOReturnSuccess
) {
1999 assert( OSDynamicCast(IOUserClient
, client
) );
2000 *connection
= client
;
2006 /* Routine io_service_close */
2007 kern_return_t
is_io_service_close(
2008 io_object_t connection
)
2011 if ((mappings
= OSDynamicCast(OSSet
, connection
)))
2012 return( kIOReturnSuccess
);
2014 CHECK( IOUserClient
, connection
, client
);
2016 client
->clientClose();
2018 return( kIOReturnSuccess
);
2021 /* Routine io_connect_get_service */
2022 kern_return_t
is_io_connect_get_service(
2023 io_object_t connection
,
2024 io_object_t
*service
)
2026 IOService
* theService
;
2028 CHECK( IOUserClient
, connection
, client
);
2030 theService
= client
->getService();
2032 theService
->retain();
2034 *service
= theService
;
2036 return( theService
? kIOReturnSuccess
: kIOReturnUnsupported
);
2039 /* Routine io_connect_set_notification_port */
2040 kern_return_t
is_io_connect_set_notification_port(
2041 io_object_t connection
,
2042 int notification_type
,
2046 CHECK( IOUserClient
, connection
, client
);
2048 return( client
->registerNotificationPort( port
, notification_type
,
2052 kern_return_t
is_io_connect_map_memory(
2053 io_object_t connect
,
2056 vm_address_t
* mapAddr
,
2057 vm_size_t
* mapSize
,
2063 CHECK( IOUserClient
, connect
, client
);
2065 map
= client
->mapClientMemory( type
, task
, flags
, *mapAddr
);
2068 *mapAddr
= map
->getVirtualAddress();
2070 *mapSize
= map
->getLength();
2072 if( task
!= current_task()) {
2073 // push a name out to the task owning the map,
2074 // so we can clean up maps
2076 mach_port_name_t name
=
2078 IOMachPort::makeSendRightForTask(
2079 task
, map
, IKOT_IOKIT_OBJECT
);
2083 // keep it with the user client
2084 IOLockLock( gIOObjectPortLock
);
2085 if( 0 == client
->mappings
)
2086 client
->mappings
= OSSet::withCapacity(2);
2087 if( client
->mappings
)
2088 client
->mappings
->setObject( map
);
2089 IOLockUnlock( gIOObjectPortLock
);
2092 err
= kIOReturnSuccess
;
2095 err
= kIOReturnBadArgument
;
2100 IOMemoryMap
* IOUserClient::removeMappingForDescriptor(IOMemoryDescriptor
* mem
)
2103 IOMemoryMap
* map
= 0;
2105 IOLockLock(gIOObjectPortLock
);
2107 iter
= OSCollectionIterator::withCollection(mappings
);
2110 while ((map
= OSDynamicCast(IOMemoryMap
, iter
->getNextObject())))
2112 if(mem
== map
->getMemoryDescriptor())
2115 mappings
->removeObject(map
);
2122 IOLockUnlock(gIOObjectPortLock
);
2127 kern_return_t
is_io_connect_unmap_memory(
2128 io_object_t connect
,
2131 vm_address_t mapAddr
)
2134 IOOptionBits options
= 0;
2135 IOMemoryDescriptor
* memory
;
2138 CHECK( IOUserClient
, connect
, client
);
2140 err
= client
->clientMemoryForType( (UInt32
) type
, &options
, &memory
);
2142 if( memory
&& (kIOReturnSuccess
== err
)) {
2144 options
= (options
& ~kIOMapUserOptionsMask
)
2145 | kIOMapAnywhere
| kIOMapReference
;
2147 map
= memory
->map( task
, mapAddr
, options
);
2151 IOLockLock( gIOObjectPortLock
);
2152 if( client
->mappings
)
2153 client
->mappings
->removeObject( map
);
2154 IOLockUnlock( gIOObjectPortLock
);
2156 mach_port_name_t name
= 0;
2157 if (task
!= current_task())
2158 name
= IOMachPort::makeSendRightForTask( task
, map
, IKOT_IOKIT_OBJECT
);
2162 err
= iokit_mod_send_right( task
, name
, -2 );
2163 err
= kIOReturnSuccess
;
2166 IOMachPort::releasePortForObject( map
, IKOT_IOKIT_OBJECT
);
2167 if (task
== current_task())
2171 err
= kIOReturnBadArgument
;
2178 /* Routine io_connect_add_client */
2179 kern_return_t
is_io_connect_add_client(
2180 io_object_t connection
,
2181 io_object_t connect_to
)
2183 CHECK( IOUserClient
, connection
, client
);
2184 CHECK( IOUserClient
, connect_to
, to
);
2186 return( client
->connectClient( to
) );
2190 /* Routine io_connect_set_properties */
2191 kern_return_t
is_io_connect_set_properties(
2192 io_object_t connection
,
2193 io_buf_ptr_t properties
,
2194 mach_msg_type_number_t propertiesCnt
,
2197 return( is_io_registry_entry_set_properties( connection
, properties
, propertiesCnt
, result
));
2201 /* Routine io_connect_method_scalarI_scalarO */
2202 kern_return_t
is_io_connect_method_scalarI_scalarO(
2203 io_object_t connect
,
2206 IOByteCount inputCount
,
2208 IOByteCount
* outputCount
)
2211 IOExternalMethod
* method
;
2215 CHECK( IOUserClient
, connect
, client
);
2216 if( (method
= client
->getTargetAndMethodForIndex(&object
, index
))) {
2218 err
= kIOReturnBadArgument
;
2219 if( kIOUCScalarIScalarO
!= (method
->flags
& kIOUCTypeMask
))
2221 if( inputCount
!= method
->count0
)
2223 if( *outputCount
!= method
->count1
)
2226 func
= method
->func
;
2228 switch( inputCount
) {
2231 err
= (object
->*func
)( input
[0], input
[1], input
[2],
2232 input
[3], input
[4], input
[5] );
2235 err
= (object
->*func
)( input
[0], input
[1], input
[2],
2240 err
= (object
->*func
)( input
[0], input
[1], input
[2],
2242 &output
[0], &output
[1] );
2245 err
= (object
->*func
)( input
[0], input
[1], input
[2],
2246 &output
[0], &output
[1], &output
[2] );
2249 err
= (object
->*func
)( input
[0], input
[1],
2250 &output
[0], &output
[1], &output
[2],
2254 err
= (object
->*func
)( input
[0],
2255 &output
[0], &output
[1], &output
[2],
2256 &output
[3], &output
[4] );
2259 err
= (object
->*func
)( &output
[0], &output
[1], &output
[2],
2260 &output
[3], &output
[4], &output
[5] );
2264 IOLog("%s: Bad method table\n", client
->getName());
2269 err
= kIOReturnUnsupported
;
2274 /* Routine io_connect_method_scalarI_structureO */
2275 kern_return_t
is_io_connect_method_scalarI_structureO(
2276 io_object_t connect
,
2279 IOByteCount inputCount
,
2281 IOByteCount
* outputCount
)
2284 IOExternalMethod
* method
;
2288 CHECK( IOUserClient
, connect
, client
);
2290 if( (method
= client
->getTargetAndMethodForIndex(&object
, index
)) ) {
2292 err
= kIOReturnBadArgument
;
2293 if( kIOUCScalarIStructO
!= (method
->flags
& kIOUCTypeMask
))
2295 if( inputCount
!= method
->count0
)
2297 if( (0xffffffff != method
->count1
)
2298 && (*outputCount
!= method
->count1
))
2301 func
= method
->func
;
2303 switch( inputCount
) {
2306 err
= (object
->*func
)( input
[0], input
[1], input
[2],
2311 err
= (object
->*func
)( input
[0], input
[1], input
[2],
2313 output
, (void *)outputCount
);
2316 err
= (object
->*func
)( input
[0], input
[1], input
[2],
2317 output
, (void *)outputCount
, 0 );
2320 err
= (object
->*func
)( input
[0], input
[1],
2321 output
, (void *)outputCount
, 0, 0 );
2324 err
= (object
->*func
)( input
[0],
2325 output
, (void *)outputCount
, 0, 0, 0 );
2328 err
= (object
->*func
)( output
, (void *)outputCount
, 0, 0, 0, 0 );
2332 IOLog("%s: Bad method table\n", client
->getName());
2337 err
= kIOReturnUnsupported
;
2342 /* Routine io_connect_method_scalarI_structureI */
2343 kern_return_t
is_io_connect_method_scalarI_structureI(
2344 io_connect_t connect
,
2347 IOByteCount inputCount
,
2348 UInt8
* inputStruct
,
2349 IOByteCount inputStructCount
)
2352 IOExternalMethod
* method
;
2356 CHECK( IOUserClient
, connect
, client
);
2358 if( (method
= client
->getTargetAndMethodForIndex(&object
, index
)) ) {
2360 err
= kIOReturnBadArgument
;
2361 if( kIOUCScalarIStructI
!= (method
->flags
& kIOUCTypeMask
))
2363 if( (0xffffffff != method
->count0
)
2364 && (inputCount
!= method
->count0
))
2366 if( (0xffffffff != method
->count1
)
2367 && (inputStructCount
!= method
->count1
))
2370 func
= method
->func
;
2372 switch( inputCount
) {
2375 err
= (object
->*func
)( input
[0], input
[1], input
[2],
2380 err
= (object
->*func
)( input
[0], input
[1], input
[2],
2382 inputStruct
, (void *)inputStructCount
);
2385 err
= (object
->*func
)( input
[0], input
[1], input
[2],
2386 inputStruct
, (void *)inputStructCount
,
2390 err
= (object
->*func
)( input
[0], input
[1],
2391 inputStruct
, (void *)inputStructCount
,
2395 err
= (object
->*func
)( input
[0],
2396 inputStruct
, (void *)inputStructCount
,
2400 err
= (object
->*func
)( inputStruct
, (void *)inputStructCount
,
2405 IOLog("%s: Bad method table\n", client
->getName());
2410 err
= kIOReturnUnsupported
;
2415 /* Routine io_connect_method_structureI_structureO */
2416 kern_return_t
is_io_connect_method_structureI_structureO(
2417 io_object_t connect
,
2420 IOByteCount inputCount
,
2422 IOByteCount
* outputCount
)
2425 IOExternalMethod
* method
;
2429 CHECK( IOUserClient
, connect
, client
);
2431 if( (method
= client
->getTargetAndMethodForIndex(&object
, index
)) ) {
2433 err
= kIOReturnBadArgument
;
2434 if( kIOUCStructIStructO
!= (method
->flags
& kIOUCTypeMask
))
2436 if( (0xffffffff != method
->count0
)
2437 && (inputCount
!= method
->count0
))
2439 if( (0xffffffff != method
->count1
)
2440 && (*outputCount
!= method
->count1
))
2443 func
= method
->func
;
2445 if( method
->count1
) {
2446 if( method
->count0
) {
2447 err
= (object
->*func
)( input
, output
,
2448 (void *)inputCount
, outputCount
, 0, 0 );
2450 err
= (object
->*func
)( output
, outputCount
, 0, 0, 0, 0 );
2453 err
= (object
->*func
)( input
, (void *)inputCount
, 0, 0, 0, 0 );
2459 err
= kIOReturnUnsupported
;
2464 kern_return_t
is_io_async_method_scalarI_scalarO(
2465 io_object_t connect
,
2466 mach_port_t wakePort
,
2467 io_async_ref_t reference
,
2468 mach_msg_type_number_t referenceCnt
,
2471 IOByteCount inputCount
,
2473 IOByteCount
* outputCount
)
2476 IOExternalAsyncMethod
*method
;
2480 CHECK( IOUserClient
, connect
, client
);
2481 if( (method
= client
->getAsyncTargetAndMethodForIndex(&object
, index
)) ) {
2483 err
= kIOReturnBadArgument
;
2484 if( kIOUCScalarIScalarO
!= (method
->flags
& kIOUCTypeMask
))
2486 if( inputCount
!= method
->count0
)
2488 if( *outputCount
!= method
->count1
)
2491 reference
[0] = (natural_t
) wakePort
;
2492 func
= method
->func
;
2494 switch( inputCount
) {
2497 err
= (object
->*func
)( reference
,
2498 input
[0], input
[1], input
[2],
2499 input
[3], input
[4], input
[5] );
2502 err
= (object
->*func
)( reference
,
2503 input
[0], input
[1], input
[2],
2508 err
= (object
->*func
)( reference
,
2509 input
[0], input
[1], input
[2],
2511 &output
[0], &output
[1] );
2514 err
= (object
->*func
)( reference
,
2515 input
[0], input
[1], input
[2],
2516 &output
[0], &output
[1], &output
[2] );
2519 err
= (object
->*func
)( reference
,
2521 &output
[0], &output
[1], &output
[2],
2525 err
= (object
->*func
)( reference
,
2527 &output
[0], &output
[1], &output
[2],
2528 &output
[3], &output
[4] );
2531 err
= (object
->*func
)( reference
,
2532 &output
[0], &output
[1], &output
[2],
2533 &output
[3], &output
[4], &output
[5] );
2537 IOLog("%s: Bad method table\n", client
->getName());
2542 err
= kIOReturnUnsupported
;
2547 kern_return_t
is_io_async_method_scalarI_structureO(
2548 io_object_t connect
,
2549 mach_port_t wakePort
,
2550 io_async_ref_t reference
,
2551 mach_msg_type_number_t referenceCnt
,
2554 IOByteCount inputCount
,
2556 IOByteCount
* outputCount
)
2559 IOExternalAsyncMethod
*method
;
2563 CHECK( IOUserClient
, connect
, client
);
2565 if( (method
= client
->getAsyncTargetAndMethodForIndex(&object
, index
)) ) {
2567 err
= kIOReturnBadArgument
;
2568 if( kIOUCScalarIStructO
!= (method
->flags
& kIOUCTypeMask
))
2570 if( inputCount
!= method
->count0
)
2572 if( (0xffffffff != method
->count1
)
2573 && (*outputCount
!= method
->count1
))
2576 reference
[0] = (natural_t
) wakePort
;
2577 func
= method
->func
;
2579 switch( inputCount
) {
2582 err
= (object
->*func
)( reference
,
2583 input
[0], input
[1], input
[2],
2588 err
= (object
->*func
)( reference
,
2589 input
[0], input
[1], input
[2],
2591 output
, (void *)outputCount
);
2594 err
= (object
->*func
)( reference
,
2595 input
[0], input
[1], input
[2],
2596 output
, (void *)outputCount
, 0 );
2599 err
= (object
->*func
)( reference
,
2601 output
, (void *)outputCount
, 0, 0 );
2604 err
= (object
->*func
)( reference
,
2606 output
, (void *)outputCount
, 0, 0, 0 );
2609 err
= (object
->*func
)( reference
,
2610 output
, (void *)outputCount
, 0, 0, 0, 0 );
2614 IOLog("%s: Bad method table\n", client
->getName());
2619 err
= kIOReturnUnsupported
;
2624 kern_return_t
is_io_async_method_scalarI_structureI(
2625 io_connect_t connect
,
2626 mach_port_t wakePort
,
2627 io_async_ref_t reference
,
2628 mach_msg_type_number_t referenceCnt
,
2631 IOByteCount inputCount
,
2632 UInt8
* inputStruct
,
2633 IOByteCount inputStructCount
)
2636 IOExternalAsyncMethod
*method
;
2640 CHECK( IOUserClient
, connect
, client
);
2642 if( (method
= client
->getAsyncTargetAndMethodForIndex(&object
, index
)) ) {
2644 err
= kIOReturnBadArgument
;
2645 if( kIOUCScalarIStructI
!= (method
->flags
& kIOUCTypeMask
))
2647 if( (0xffffffff != method
->count0
)
2648 && (inputCount
!= method
->count0
))
2650 if( (0xffffffff != method
->count1
)
2651 && (inputStructCount
!= method
->count1
))
2654 reference
[0] = (natural_t
) wakePort
;
2655 func
= method
->func
;
2657 switch( inputCount
) {
2660 err
= (object
->*func
)( reference
,
2661 input
[0], input
[1], input
[2],
2666 err
= (object
->*func
)( reference
,
2667 input
[0], input
[1], input
[2],
2669 inputStruct
, (void *)inputStructCount
);
2672 err
= (object
->*func
)( reference
,
2673 input
[0], input
[1], input
[2],
2674 inputStruct
, (void *)inputStructCount
,
2678 err
= (object
->*func
)( reference
,
2680 inputStruct
, (void *)inputStructCount
,
2684 err
= (object
->*func
)( reference
,
2686 inputStruct
, (void *)inputStructCount
,
2690 err
= (object
->*func
)( reference
,
2691 inputStruct
, (void *)inputStructCount
,
2696 IOLog("%s: Bad method table\n", client
->getName());
2701 err
= kIOReturnUnsupported
;
2706 kern_return_t
is_io_async_method_structureI_structureO(
2707 io_object_t connect
,
2708 mach_port_t wakePort
,
2709 io_async_ref_t reference
,
2710 mach_msg_type_number_t referenceCnt
,
2713 IOByteCount inputCount
,
2715 IOByteCount
* outputCount
)
2718 IOExternalAsyncMethod
*method
;
2722 CHECK( IOUserClient
, connect
, client
);
2724 if( (method
= client
->getAsyncTargetAndMethodForIndex(&object
, index
)) ) {
2726 err
= kIOReturnBadArgument
;
2727 if( kIOUCStructIStructO
!= (method
->flags
& kIOUCTypeMask
))
2729 if( (0xffffffff != method
->count0
)
2730 && (inputCount
!= method
->count0
))
2732 if( (0xffffffff != method
->count1
)
2733 && (*outputCount
!= method
->count1
))
2736 reference
[0] = (natural_t
) wakePort
;
2737 func
= method
->func
;
2739 if( method
->count1
) {
2740 if( method
->count0
) {
2741 err
= (object
->*func
)( reference
,
2743 (void *)inputCount
, outputCount
, 0, 0 );
2745 err
= (object
->*func
)( reference
,
2746 output
, outputCount
, 0, 0, 0, 0 );
2749 err
= (object
->*func
)( reference
,
2750 input
, (void *)inputCount
, 0, 0, 0, 0 );
2756 err
= kIOReturnUnsupported
;
2760 /* Routine io_make_matching */
2761 kern_return_t
is_io_make_matching(
2762 mach_port_t master_port
,
2764 IOOptionBits options
,
2766 IOByteCount inputCount
,
2767 io_string_t matching
)
2770 IOReturn err
= kIOReturnSuccess
;
2771 OSDictionary
* dict
;
2773 if( master_port
!= master_device_port
)
2774 return( kIOReturnNotPrivileged
);
2778 case kIOServiceMatching
:
2779 dict
= IOService::serviceMatching( gIOServiceKey
);
2782 case kIOBSDNameMatching
:
2783 dict
= IOBSDNameMatching( (const char *) input
);
2786 case kIOOFPathMatching
:
2787 dict
= IOOFPathMatching( (const char *) input
,
2788 matching
, sizeof( io_string_t
));
2796 return( kIOReturnUnsupported
);
2799 s
= OSSerialize::withCapacity(4096);
2801 err
= kIOReturnNoMemory
;
2805 if( !dict
->serialize( s
)) {
2806 err
= kIOReturnUnsupported
;
2810 if( s
->getLength() > sizeof( io_string_t
)) {
2811 err
= kIOReturnNoMemory
;
2814 strcpy( matching
, s
->text());
2826 /* Routine io_catalog_send_data */
2827 kern_return_t
is_io_catalog_send_data(
2828 mach_port_t master_port
,
2830 io_buf_ptr_t inData
,
2831 mach_msg_type_number_t inDataCount
,
2836 kern_return_t kr
= kIOReturnError
;
2838 //printf("io_catalog_send_data called. flag: %d\n", flag);
2840 if( master_port
!= master_device_port
)
2841 return kIOReturnNotPrivileged
;
2843 // FIXME: This is a hack. Should have own function for removeKernelLinker()
2844 if(flag
!= kIOCatalogRemoveKernelLinker
&& ( !inData
|| !inDataCount
) )
2845 return kIOReturnBadArgument
;
2848 vm_map_offset_t map_data
;
2850 kr
= vm_map_copyout( kernel_map
, &map_data
, (vm_map_copy_t
)inData
);
2851 data
= CAST_DOWN(vm_offset_t
, map_data
);
2853 if( kr
!= KERN_SUCCESS
)
2856 // must return success after vm_map_copyout() succeeds
2859 obj
= (OSObject
*)OSUnserializeXML((const char *)data
);
2860 vm_deallocate( kernel_map
, data
, inDataCount
);
2862 *result
= kIOReturnNoMemory
;
2863 return( KERN_SUCCESS
);
2869 case kIOCatalogAddDrivers
:
2870 case kIOCatalogAddDriversNoMatch
: {
2873 array
= OSDynamicCast(OSArray
, obj
);
2875 if ( !gIOCatalogue
->addDrivers( array
,
2876 flag
== kIOCatalogAddDrivers
) ) {
2877 kr
= kIOReturnError
;
2881 kr
= kIOReturnBadArgument
;
2886 case kIOCatalogRemoveDrivers
:
2887 case kIOCatalogRemoveDriversNoMatch
: {
2888 OSDictionary
* dict
;
2890 dict
= OSDynamicCast(OSDictionary
, obj
);
2892 if ( !gIOCatalogue
->removeDrivers( dict
,
2893 flag
== kIOCatalogRemoveDrivers
) ) {
2894 kr
= kIOReturnError
;
2898 kr
= kIOReturnBadArgument
;
2903 case kIOCatalogStartMatching
: {
2904 OSDictionary
* dict
;
2906 dict
= OSDynamicCast(OSDictionary
, obj
);
2908 if ( !gIOCatalogue
->startMatching( dict
) ) {
2909 kr
= kIOReturnError
;
2913 kr
= kIOReturnBadArgument
;
2918 case kIOCatalogRemoveKernelLinker
: {
2919 if (gIOCatalogue
->removeKernelLinker() != KERN_SUCCESS
) {
2920 kr
= kIOReturnError
;
2922 kr
= kIOReturnSuccess
;
2928 kr
= kIOReturnBadArgument
;
2932 if (obj
) obj
->release();
2935 return( KERN_SUCCESS
);
2938 /* Routine io_catalog_terminate */
2939 kern_return_t
is_io_catalog_terminate(
2940 mach_port_t master_port
,
2946 if( master_port
!= master_device_port
)
2947 return kIOReturnNotPrivileged
;
2949 kr
= IOUserClient::clientHasPrivilege( (void *) current_task(),
2950 kIOClientPrivilegeAdministrator
);
2951 if( kIOReturnSuccess
!= kr
)
2955 case kIOCatalogServiceTerminate
:
2957 IOService
* service
;
2959 iter
= IORegistryIterator::iterateOver(gIOServicePlane
,
2960 kIORegistryIterateRecursively
);
2962 return kIOReturnNoMemory
;
2966 while( (service
= (IOService
*)iter
->getNextObject()) ) {
2967 if( service
->metaCast(name
)) {
2968 if ( !service
->terminate( kIOServiceRequired
2969 | kIOServiceSynchronous
) ) {
2970 kr
= kIOReturnUnsupported
;
2975 } while( !service
&& !iter
->isValid());
2979 case kIOCatalogModuleUnload
:
2980 case kIOCatalogModuleTerminate
:
2981 kr
= gIOCatalogue
->terminateDriversForModule(name
,
2982 flag
== kIOCatalogModuleUnload
);
2986 kr
= kIOReturnBadArgument
;
2993 /* Routine io_catalog_get_data */
2994 kern_return_t
is_io_catalog_get_data(
2995 mach_port_t master_port
,
2997 io_buf_ptr_t
*outData
,
2998 mach_msg_type_number_t
*outDataCount
)
3000 kern_return_t kr
= kIOReturnSuccess
;
3003 if( master_port
!= master_device_port
)
3004 return kIOReturnNotPrivileged
;
3006 //printf("io_catalog_get_data called. flag: %d\n", flag);
3008 s
= OSSerialize::withCapacity(4096);
3010 return kIOReturnNoMemory
;
3014 kr
= gIOCatalogue
->serializeData(flag
, s
);
3016 if ( kr
== kIOReturnSuccess
) {
3021 size
= s
->getLength();
3022 kr
= vm_allocate(kernel_map
, &data
, size
, VM_FLAGS_ANYWHERE
);
3023 if ( kr
== kIOReturnSuccess
) {
3024 bcopy(s
->text(), (void *)data
, size
);
3025 kr
= vm_map_copyin(kernel_map
, (vm_map_address_t
)data
,
3026 (vm_map_size_t
)size
, true, ©
);
3027 *outData
= (char *)copy
;
3028 *outDataCount
= size
;
3037 /* Routine io_catalog_get_gen_count */
3038 kern_return_t
is_io_catalog_get_gen_count(
3039 mach_port_t master_port
,
3042 if( master_port
!= master_device_port
)
3043 return kIOReturnNotPrivileged
;
3045 //printf("io_catalog_get_gen_count called.\n");
3048 return kIOReturnBadArgument
;
3050 *genCount
= gIOCatalogue
->getGenerationCount();
3052 return kIOReturnSuccess
;
3055 /* Routine io_catalog_module_loaded */
3056 kern_return_t
is_io_catalog_module_loaded(
3057 mach_port_t master_port
,
3060 if( master_port
!= master_device_port
)
3061 return kIOReturnNotPrivileged
;
3063 //printf("io_catalog_module_loaded called. name %s\n", name);
3066 return kIOReturnBadArgument
;
3068 gIOCatalogue
->moduleHasLoaded(name
);
3070 return kIOReturnSuccess
;
3073 kern_return_t
is_io_catalog_reset(
3074 mach_port_t master_port
,
3077 if( master_port
!= master_device_port
)
3078 return kIOReturnNotPrivileged
;
3081 case kIOCatalogResetDefault
:
3082 gIOCatalogue
->reset();
3086 return kIOReturnBadArgument
;
3089 return kIOReturnSuccess
;
3092 kern_return_t
iokit_user_client_trap(struct iokit_user_client_trap_args
*args
)
3094 kern_return_t result
= kIOReturnBadArgument
;
3095 IOUserClient
*userClient
;
3097 if ((userClient
= OSDynamicCast(IOUserClient
,
3098 iokit_lookup_connect_ref_current_task((OSObject
*)(args
->userClientRef
))))) {
3099 IOExternalTrap
*trap
;
3100 IOService
*target
= NULL
;
3102 trap
= userClient
->getTargetAndTrapForIndex(&target
, args
->index
);
3104 if (trap
&& target
) {
3110 result
= (target
->*func
)(args
->p1
, args
->p2
, args
->p3
, args
->p4
, args
->p5
, args
->p6
);
3114 userClient
->release();
3122 OSMetaClassDefineReservedUnused(IOUserClient
, 0);
3123 OSMetaClassDefineReservedUnused(IOUserClient
, 1);
3124 OSMetaClassDefineReservedUnused(IOUserClient
, 2);
3125 OSMetaClassDefineReservedUnused(IOUserClient
, 3);
3126 OSMetaClassDefineReservedUnused(IOUserClient
, 4);
3127 OSMetaClassDefineReservedUnused(IOUserClient
, 5);
3128 OSMetaClassDefineReservedUnused(IOUserClient
, 6);
3129 OSMetaClassDefineReservedUnused(IOUserClient
, 7);
3130 OSMetaClassDefineReservedUnused(IOUserClient
, 8);
3131 OSMetaClassDefineReservedUnused(IOUserClient
, 9);
3132 OSMetaClassDefineReservedUnused(IOUserClient
, 10);
3133 OSMetaClassDefineReservedUnused(IOUserClient
, 11);
3134 OSMetaClassDefineReservedUnused(IOUserClient
, 12);
3135 OSMetaClassDefineReservedUnused(IOUserClient
, 13);
3136 OSMetaClassDefineReservedUnused(IOUserClient
, 14);
3137 OSMetaClassDefineReservedUnused(IOUserClient
, 15);