2 * Copyright (c) 1998-2000 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 io_object_t
iokit_lookup_connect_ref(io_object_t clientRef
, ipc_space_t task
);
60 extern io_object_t
iokit_lookup_connect_ref_current_task(io_object_t clientRef
);
62 extern ipc_port_t master_device_port
;
64 extern void iokit_retain_port( ipc_port_t port
);
65 extern void iokit_release_port( ipc_port_t port
);
67 extern kern_return_t
iokit_switch_object_port( ipc_port_t port
, io_object_t obj
, ipc_kobject_type_t type
);
69 #include <vm/vm_map.h>
74 /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
76 // IOMachPort maps OSObjects to ports, avoiding adding an ivar to OSObject.
78 class IOMachPort
: public OSObject
80 OSDeclareDefaultStructors(IOMachPort
)
87 static IOMachPort
* portForObject( OSObject
* obj
,
88 ipc_kobject_type_t type
);
89 static bool noMoreSendersForObject( OSObject
* obj
,
90 ipc_kobject_type_t type
, mach_port_mscount_t
* mscount
);
91 static void releasePortForObject( OSObject
* obj
,
92 ipc_kobject_type_t type
);
93 static void setHoldDestroy( OSObject
* obj
, ipc_kobject_type_t type
);
95 static OSDictionary
* dictForType( ipc_kobject_type_t type
);
97 static mach_port_name_t
makeSendRightForTask( task_t task
,
98 io_object_t obj
, ipc_kobject_type_t type
);
103 #define super OSObject
104 OSDefineMetaClassAndStructors(IOMachPort
, OSObject
)
106 static IOLock
* gIOObjectPortLock
;
108 /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
110 // not in dictForType() for debugging ease
111 static OSDictionary
* gIOObjectPorts
;
112 static OSDictionary
* gIOConnectPorts
;
114 OSDictionary
* IOMachPort::dictForType( ipc_kobject_type_t type
)
116 OSDictionary
** dict
;
118 if( IKOT_IOKIT_OBJECT
== type
)
119 dict
= &gIOObjectPorts
;
120 else if( IKOT_IOKIT_CONNECT
== type
)
121 dict
= &gIOConnectPorts
;
126 *dict
= OSDictionary::withCapacity( 1 );
131 IOMachPort
* IOMachPort::portForObject ( OSObject
* obj
,
132 ipc_kobject_type_t type
)
134 IOMachPort
* inst
= 0;
137 IOTakeLock( gIOObjectPortLock
);
141 dict
= dictForType( type
);
145 if( (inst
= (IOMachPort
*)
146 dict
->getObject( (const OSSymbol
*) obj
))) {
152 inst
= new IOMachPort
;
153 if( inst
&& !inst
->init()) {
158 inst
->port
= iokit_alloc_object_port( obj
, type
);
161 dict
->setObject( (const OSSymbol
*) obj
, inst
);
171 IOUnlock( gIOObjectPortLock
);
176 bool IOMachPort::noMoreSendersForObject( OSObject
* obj
,
177 ipc_kobject_type_t type
, mach_port_mscount_t
* mscount
)
180 IOMachPort
* machPort
;
181 bool destroyed
= true;
183 IOTakeLock( gIOObjectPortLock
);
185 if( (dict
= dictForType( type
))) {
188 machPort
= (IOMachPort
*) dict
->getObject( (const OSSymbol
*) obj
);
190 destroyed
= (machPort
->mscount
== *mscount
);
192 dict
->removeObject( (const OSSymbol
*) obj
);
194 *mscount
= machPort
->mscount
;
199 IOUnlock( gIOObjectPortLock
);
204 void IOMachPort::releasePortForObject( OSObject
* obj
,
205 ipc_kobject_type_t type
)
208 IOMachPort
* machPort
;
210 IOTakeLock( gIOObjectPortLock
);
212 if( (dict
= dictForType( type
))) {
214 machPort
= (IOMachPort
*) dict
->getObject( (const OSSymbol
*) obj
);
215 if( machPort
&& !machPort
->holdDestroy
)
216 dict
->removeObject( (const OSSymbol
*) obj
);
220 IOUnlock( gIOObjectPortLock
);
223 void IOMachPort::setHoldDestroy( OSObject
* obj
, ipc_kobject_type_t type
)
226 IOMachPort
* machPort
;
228 IOLockLock( gIOObjectPortLock
);
230 if( (dict
= dictForType( type
))) {
231 machPort
= (IOMachPort
*) dict
->getObject( (const OSSymbol
*) obj
);
233 machPort
->holdDestroy
= true;
236 IOLockUnlock( gIOObjectPortLock
);
239 void IOUserClient::destroyUserReferences( OSObject
* obj
)
241 IOMachPort::releasePortForObject( obj
, IKOT_IOKIT_OBJECT
);
244 // IOMachPort::releasePortForObject( obj, IKOT_IOKIT_CONNECT );
248 IOTakeLock( gIOObjectPortLock
);
251 if( (dict
= IOMachPort::dictForType( IKOT_IOKIT_CONNECT
)))
254 port
= (IOMachPort
*) dict
->getObject( (const OSSymbol
*) obj
);
258 if ((uc
= OSDynamicCast(IOUserClient
, obj
)) && uc
->mappings
)
260 dict
->setObject((const OSSymbol
*) uc
->mappings
, port
);
261 iokit_switch_object_port(port
->port
, uc
->mappings
, IKOT_IOKIT_CONNECT
);
263 uc
->mappings
->release();
266 dict
->removeObject( (const OSSymbol
*) obj
);
270 IOUnlock( gIOObjectPortLock
);
273 mach_port_name_t
IOMachPort::makeSendRightForTask( task_t task
,
274 io_object_t obj
, ipc_kobject_type_t type
)
276 return( iokit_make_send_right( task
, obj
, type
));
279 void IOMachPort::free( void )
282 iokit_destroy_object_port( port
);
286 /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
288 class IOUserNotification
: public OSIterator
290 OSDeclareDefaultStructors(IOUserNotification
)
292 IONotifier
* holdNotify
;
297 virtual bool init( void );
300 virtual void setNotification( IONotifier
* obj
);
302 virtual void reset();
303 virtual bool isValid();
306 /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
310 // functions called from osfmk/device/iokit_rpc.c
313 iokit_add_reference( io_object_t obj
)
320 iokit_remove_reference( io_object_t obj
)
327 iokit_port_for_object( io_object_t obj
, ipc_kobject_type_t type
)
329 IOMachPort
* machPort
;
332 if( (machPort
= IOMachPort::portForObject( obj
, type
))) {
334 port
= machPort
->port
;
336 iokit_retain_port( port
);
347 iokit_client_died( io_object_t obj
, ipc_port_t
/* port */,
348 ipc_kobject_type_t type
, mach_port_mscount_t
* mscount
)
350 IOUserClient
* client
;
352 IOUserNotification
* notify
;
354 if( !IOMachPort::noMoreSendersForObject( obj
, type
, mscount
))
355 return( kIOReturnNotReady
);
357 if( IKOT_IOKIT_CONNECT
== type
)
359 if( (client
= OSDynamicCast( IOUserClient
, obj
)))
360 client
->clientDied();
362 else if( IKOT_IOKIT_OBJECT
== type
)
364 if( (map
= OSDynamicCast( IOMemoryMap
, obj
)))
366 else if( (notify
= OSDynamicCast( IOUserNotification
, obj
)))
367 notify
->setNotification( 0 );
370 return( kIOReturnSuccess
);
375 /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
377 class IOServiceUserNotification
: public IOUserNotification
379 OSDeclareDefaultStructors(IOServiceUserNotification
)
382 mach_msg_header_t msgHdr
;
383 OSNotificationHeader notifyHeader
;
386 enum { kMaxOutstanding
= 256 };
391 OSObject
* lastEntry
;
396 virtual bool init( mach_port_t port
, natural_t type
,
397 OSAsyncReference reference
);
400 static bool _handler( void * target
,
401 void * ref
, IOService
* newService
);
402 virtual bool handler( void * ref
, IOService
* newService
);
404 virtual OSObject
* getNextObject();
407 class IOServiceMessageUserNotification
: public IOUserNotification
409 OSDeclareDefaultStructors(IOServiceMessageUserNotification
)
412 mach_msg_header_t msgHdr
;
413 mach_msg_body_t msgBody
;
414 mach_msg_port_descriptor_t ports
[1];
415 OSNotificationHeader notifyHeader
;
423 virtual bool init( mach_port_t port
, natural_t type
,
424 OSAsyncReference reference
, vm_size_t extraSize
);
427 static IOReturn
_handler( void * target
, void * ref
,
428 UInt32 messageType
, IOService
* provider
,
429 void * messageArgument
, vm_size_t argSize
);
430 virtual IOReturn
handler( void * ref
,
431 UInt32 messageType
, IOService
* provider
,
432 void * messageArgument
, vm_size_t argSize
);
434 virtual OSObject
* getNextObject();
437 /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
440 #define super OSIterator
441 OSDefineMetaClass( IOUserNotification
, OSIterator
)
442 OSDefineAbstractStructors( IOUserNotification
, OSIterator
)
444 /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
446 bool IOUserNotification::init( void )
451 lock
= IOLockAlloc();
458 void IOUserNotification::free( void )
461 holdNotify
->remove();
462 // can't be in handler now
471 void IOUserNotification::setNotification( IONotifier
* notify
)
473 IONotifier
* previousNotify
;
475 IOLockLock( gIOObjectPortLock
);
477 previousNotify
= holdNotify
;
480 IOLockUnlock( gIOObjectPortLock
);
483 previousNotify
->remove();
486 void IOUserNotification::reset()
491 bool IOUserNotification::isValid()
496 /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
499 #define super IOUserNotification
500 OSDefineMetaClassAndStructors(IOServiceUserNotification
, IOUserNotification
)
502 /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
504 bool IOServiceUserNotification::init( mach_port_t port
, natural_t type
,
505 OSAsyncReference reference
)
507 newSet
= OSArray::withCapacity( 1 );
511 msgSize
= sizeof( PingMsg
) + 0;
512 pingMsg
= (PingMsg
*) IOMalloc( msgSize
);
516 bzero( pingMsg
, msgSize
);
518 pingMsg
->msgHdr
.msgh_remote_port
= port
;
519 pingMsg
->msgHdr
.msgh_bits
= MACH_MSGH_BITS(
520 MACH_MSG_TYPE_COPY_SEND
/*remote*/,
521 MACH_MSG_TYPE_MAKE_SEND
/*local*/);
522 pingMsg
->msgHdr
.msgh_size
= msgSize
;
523 pingMsg
->msgHdr
.msgh_id
= kOSNotificationMessageID
;
525 pingMsg
->notifyHeader
.size
= 0;
526 pingMsg
->notifyHeader
.type
= type
;
527 bcopy( reference
, pingMsg
->notifyHeader
.reference
, sizeof(OSAsyncReference
) );
529 return( super::init() );
532 void IOServiceUserNotification::free( void )
537 OSObject
* _lastEntry
;
541 _lastEntry
= lastEntry
;
546 if( _pingMsg
&& _msgSize
)
547 IOFree( _pingMsg
, _msgSize
);
550 _lastEntry
->release();
556 bool IOServiceUserNotification::_handler( void * target
,
557 void * ref
, IOService
* newService
)
559 return( ((IOServiceUserNotification
*) target
)->handler( ref
, newService
));
562 bool IOServiceUserNotification::handler( void * ref
,
563 IOService
* newService
)
567 ipc_port_t port
= NULL
;
568 bool sendPing
= false;
572 count
= newSet
->getCount();
573 if( count
< kMaxOutstanding
) {
575 newSet
->setObject( newService
);
576 if( (sendPing
= (armed
&& (0 == count
))))
582 if( kIOServiceTerminatedNotificationType
== pingMsg
->notifyHeader
.type
)
583 IOMachPort::setHoldDestroy( newService
, IKOT_IOKIT_OBJECT
);
586 if( (port
= iokit_port_for_object( this, IKOT_IOKIT_OBJECT
) ))
587 pingMsg
->msgHdr
.msgh_local_port
= port
;
589 pingMsg
->msgHdr
.msgh_local_port
= NULL
;
591 kr
= mach_msg_send_from_kernel( &pingMsg
->msgHdr
,
592 pingMsg
->msgHdr
.msgh_size
);
594 iokit_release_port( port
);
596 if( KERN_SUCCESS
!= kr
)
597 IOLog("%s: mach_msg_send_from_kernel {%x}\n", __FILE__
, kr
);
603 OSObject
* IOServiceUserNotification::getNextObject()
611 lastEntry
->release();
613 count
= newSet
->getCount();
615 result
= newSet
->getObject( count
- 1 );
617 newSet
->removeObject( count
- 1);
629 /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
631 OSDefineMetaClassAndStructors(IOServiceMessageUserNotification
, IOUserNotification
)
633 /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
635 bool IOServiceMessageUserNotification::init( mach_port_t port
, natural_t type
,
636 OSAsyncReference reference
, vm_size_t extraSize
)
639 extraSize
+= sizeof(IOServiceInterestContent
);
640 msgSize
= sizeof( PingMsg
) + extraSize
;
641 pingMsg
= (PingMsg
*) IOMalloc( msgSize
);
645 bzero( pingMsg
, msgSize
);
647 pingMsg
->msgHdr
.msgh_remote_port
= port
;
648 pingMsg
->msgHdr
.msgh_bits
= MACH_MSGH_BITS_COMPLEX
650 MACH_MSG_TYPE_COPY_SEND
/*remote*/,
651 MACH_MSG_TYPE_MAKE_SEND
/*local*/);
652 pingMsg
->msgHdr
.msgh_size
= msgSize
;
653 pingMsg
->msgHdr
.msgh_id
= kOSNotificationMessageID
;
655 pingMsg
->msgBody
.msgh_descriptor_count
= 1;
657 pingMsg
->ports
[0].name
= 0;
658 pingMsg
->ports
[0].disposition
= MACH_MSG_TYPE_MAKE_SEND
;
659 pingMsg
->ports
[0].type
= MACH_MSG_PORT_DESCRIPTOR
;
661 pingMsg
->notifyHeader
.size
= extraSize
;
662 pingMsg
->notifyHeader
.type
= type
;
663 bcopy( reference
, pingMsg
->notifyHeader
.reference
, sizeof(OSAsyncReference
) );
665 return( super::init() );
668 void IOServiceMessageUserNotification::free( void )
678 if( _pingMsg
&& _msgSize
)
679 IOFree( _pingMsg
, _msgSize
);
682 IOReturn
IOServiceMessageUserNotification::_handler( void * target
, void * ref
,
683 UInt32 messageType
, IOService
* provider
,
684 void * argument
, vm_size_t argSize
)
686 return( ((IOServiceMessageUserNotification
*) target
)->handler(
687 ref
, messageType
, provider
, argument
, argSize
));
690 IOReturn
IOServiceMessageUserNotification::handler( void * ref
,
691 UInt32 messageType
, IOService
* provider
,
692 void * messageArgument
, vm_size_t argSize
)
695 ipc_port_t thisPort
, providerPort
;
696 IOServiceInterestContent
* data
= (IOServiceInterestContent
*)
697 pingMsg
->notifyHeader
.content
;
699 data
->messageType
= messageType
;
701 argSize
= sizeof( messageArgument
);
702 data
->messageArgument
[0] = messageArgument
;
704 if( argSize
> kIOUserNotifyMaxMessageSize
)
705 argSize
= kIOUserNotifyMaxMessageSize
;
706 bcopy( messageArgument
, data
->messageArgument
, argSize
);
708 pingMsg
->msgHdr
.msgh_size
= sizeof( PingMsg
)
709 + sizeof( IOServiceInterestContent
)
710 - sizeof( data
->messageArgument
)
713 providerPort
= iokit_port_for_object( provider
, IKOT_IOKIT_OBJECT
);
714 pingMsg
->ports
[0].name
= providerPort
;
715 thisPort
= iokit_port_for_object( this, IKOT_IOKIT_OBJECT
);
716 pingMsg
->msgHdr
.msgh_local_port
= thisPort
;
717 kr
= mach_msg_send_from_kernel( &pingMsg
->msgHdr
,
718 pingMsg
->msgHdr
.msgh_size
);
720 iokit_release_port( thisPort
);
722 iokit_release_port( providerPort
);
724 if( KERN_SUCCESS
!= kr
)
725 IOLog("%s: mach_msg_send_from_kernel {%x}\n", __FILE__
, kr
);
727 return( kIOReturnSuccess
);
730 OSObject
* IOServiceMessageUserNotification::getNextObject()
735 /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
738 #define super IOService
739 OSDefineMetaClassAndAbstractStructors( IOUserClient
, IOService
)
741 void IOUserClient::initialize( void )
743 gIOObjectPortLock
= IOLockAlloc();
745 assert( gIOObjectPortLock
);
748 void IOUserClient::setAsyncReference(OSAsyncReference asyncRef
,
749 mach_port_t wakePort
,
750 void *callback
, void *refcon
)
752 asyncRef
[kIOAsyncReservedIndex
] = (natural_t
) wakePort
;
753 asyncRef
[kIOAsyncCalloutFuncIndex
] = (natural_t
) callback
;
754 asyncRef
[kIOAsyncCalloutRefconIndex
] = (natural_t
) refcon
;
757 IOReturn
IOUserClient::clientHasPrivilege( void * securityToken
,
758 const char * privilegeName
)
761 security_token_t token
;
762 mach_msg_type_number_t count
;
764 count
= TASK_SECURITY_TOKEN_COUNT
;
765 kr
= task_info( (task_t
) securityToken
, TASK_SECURITY_TOKEN
,
766 (task_info_t
) &token
, &count
);
768 if (KERN_SUCCESS
!= kr
)
770 else if (!strcmp(privilegeName
, kIOClientPrivilegeAdministrator
))
772 if (0 != token
.val
[0])
773 kr
= kIOReturnNotPrivileged
;
775 else if (!strcmp(privilegeName
, kIOClientPrivilegeLocalUser
))
778 OSDictionary
* user
= 0;
780 if ((array
= OSDynamicCast(OSArray
,
781 IORegistryEntry::getRegistryRoot()->copyProperty(gIOConsoleUsersKey
))))
783 for (unsigned int idx
= 0;
784 (user
= OSDynamicCast(OSDictionary
, array
->getObject(idx
)));
788 if ((num
= OSDynamicCast(OSNumber
, user
->getObject(gIOConsoleSessionUIDKey
)))
789 && (token
.val
[0] == num
->unsigned32BitValue()))
795 kr
= kIOReturnNotPrivileged
;
798 kr
= kIOReturnUnsupported
;
803 bool IOUserClient::initWithTask(task_t owningTask
,
807 if( getPropertyTable())
810 return super::init();
813 bool IOUserClient::initWithTask(task_t owningTask
,
816 OSDictionary
* properties
)
820 ok
= super::init( properties
);
821 ok
&= initWithTask( owningTask
, securityID
, type
);
826 void IOUserClient::free()
834 IOReturn
IOUserClient::clientDied( void )
836 return( clientClose());
839 IOReturn
IOUserClient::clientClose( void )
841 return( kIOReturnUnsupported
);
844 IOService
* IOUserClient::getService( void )
849 IOReturn
IOUserClient::registerNotificationPort(
850 mach_port_t
/* port */,
854 return( kIOReturnUnsupported
);
857 IOReturn
IOUserClient::getNotificationSemaphore( UInt32 notification_type
,
858 semaphore_t
* semaphore
)
860 return( kIOReturnUnsupported
);
863 IOReturn
IOUserClient::connectClient( IOUserClient
* /* client */ )
865 return( kIOReturnUnsupported
);
868 IOReturn
IOUserClient::clientMemoryForType( UInt32 type
,
869 IOOptionBits
* options
,
870 IOMemoryDescriptor
** memory
)
872 return( kIOReturnUnsupported
);
875 IOMemoryMap
* IOUserClient::mapClientMemory(
878 IOOptionBits mapFlags
,
879 IOVirtualAddress atAddress
)
882 IOOptionBits options
= 0;
883 IOMemoryDescriptor
* memory
;
884 IOMemoryMap
* map
= 0;
886 err
= clientMemoryForType( (UInt32
) type
, &options
, &memory
);
888 if( memory
&& (kIOReturnSuccess
== err
)) {
890 options
= (options
& ~kIOMapUserOptionsMask
)
891 | (mapFlags
& kIOMapUserOptionsMask
);
892 map
= memory
->map( task
, atAddress
, options
);
899 IOReturn
IOUserClient::exportObjectToClient(task_t task
,
900 OSObject
*obj
, io_object_t
*clientObj
)
902 mach_port_name_t name
;
904 name
= IOMachPort::makeSendRightForTask( task
, obj
, IKOT_IOKIT_OBJECT
);
907 *(mach_port_name_t
*)clientObj
= name
;
908 return kIOReturnSuccess
;
911 IOExternalMethod
* IOUserClient::getExternalMethodForIndex( UInt32
/* index */)
916 IOExternalAsyncMethod
* IOUserClient::getExternalAsyncMethodForIndex( UInt32
/* index */)
921 IOExternalMethod
* IOUserClient::
922 getTargetAndMethodForIndex(IOService
**targetP
, UInt32 index
)
924 IOExternalMethod
*method
= getExternalMethodForIndex(index
);
927 *targetP
= (IOService
*) method
->object
;
932 IOExternalAsyncMethod
* IOUserClient::
933 getAsyncTargetAndMethodForIndex(IOService
** targetP
, UInt32 index
)
935 IOExternalAsyncMethod
*method
= getExternalAsyncMethodForIndex(index
);
938 *targetP
= (IOService
*) method
->object
;
943 IOExternalTrap
* IOUserClient::
944 getExternalTrapForIndex(UInt32 index
)
949 IOExternalTrap
* IOUserClient::
950 getTargetAndTrapForIndex(IOService
** targetP
, UInt32 index
)
952 IOExternalTrap
*trap
= getExternalTrapForIndex(index
);
955 *targetP
= trap
->object
;
961 IOReturn
IOUserClient::sendAsyncResult(OSAsyncReference reference
,
962 IOReturn result
, void *args
[], UInt32 numArgs
)
965 mach_msg_header_t msgHdr
;
966 OSNotificationHeader notifyHdr
;
967 IOAsyncCompletionContent asyncContent
;
968 void * args
[kMaxAsyncArgs
];
971 mach_port_t replyPort
;
974 // If no reply port, do nothing.
975 replyPort
= (mach_port_t
) reference
[0];
976 if(replyPort
== MACH_PORT_NULL
)
977 return kIOReturnSuccess
;
979 if(numArgs
> kMaxAsyncArgs
)
980 return kIOReturnMessageTooLarge
;
981 replyMsg
.msgHdr
.msgh_bits
= MACH_MSGH_BITS(MACH_MSG_TYPE_COPY_SEND
/*remote*/,
983 replyMsg
.msgHdr
.msgh_size
=
984 sizeof(replyMsg
) - (kMaxAsyncArgs
-numArgs
)*sizeof(void *);
985 replyMsg
.msgHdr
.msgh_remote_port
= replyPort
;
986 replyMsg
.msgHdr
.msgh_local_port
= 0;
987 replyMsg
.msgHdr
.msgh_id
= kOSNotificationMessageID
;
989 replyMsg
.notifyHdr
.size
= sizeof(IOAsyncCompletionContent
)
990 + numArgs
*sizeof(void *);
991 replyMsg
.notifyHdr
.type
= kIOAsyncCompletionNotificationType
;
992 bcopy( reference
, replyMsg
.notifyHdr
.reference
, sizeof(OSAsyncReference
));
994 replyMsg
.asyncContent
.result
= result
;
996 bcopy(args
, replyMsg
.args
, sizeof(void *)*numArgs
);
997 kr
= mach_msg_send_from_kernel( &replyMsg
.msgHdr
,
998 replyMsg
.msgHdr
.msgh_size
);
999 if( KERN_SUCCESS
!= kr
)
1000 IOLog("%s: mach_msg_send_from_kernel {%x}\n", __FILE__
, kr
);
1004 /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
1008 #define CHECK(cls,obj,out) \
1010 if( !(out = OSDynamicCast( cls, obj))) \
1011 return( kIOReturnBadArgument )
1013 /* Routine io_object_get_class */
1014 kern_return_t
is_io_object_get_class(
1016 io_name_t className
)
1019 return( kIOReturnBadArgument
);
1021 strcpy( className
, object
->getMetaClass()->getClassName());
1022 return( kIOReturnSuccess
);
1025 /* Routine io_object_conforms_to */
1026 kern_return_t
is_io_object_conforms_to(
1028 io_name_t className
,
1029 boolean_t
*conforms
)
1032 return( kIOReturnBadArgument
);
1034 *conforms
= (0 != object
->metaCast( className
));
1035 return( kIOReturnSuccess
);
1038 /* Routine io_object_get_retain_count */
1039 kern_return_t
is_io_object_get_retain_count(
1044 return( kIOReturnBadArgument
);
1046 *retainCount
= object
->getRetainCount();
1047 return( kIOReturnSuccess
);
1050 /* Routine io_iterator_next */
1051 kern_return_t
is_io_iterator_next(
1052 io_object_t iterator
,
1053 io_object_t
*object
)
1057 CHECK( OSIterator
, iterator
, iter
);
1059 obj
= iter
->getNextObject();
1063 return( kIOReturnSuccess
);
1065 return( kIOReturnNoDevice
);
1068 /* Routine io_iterator_reset */
1069 kern_return_t
is_io_iterator_reset(
1070 io_object_t iterator
)
1072 CHECK( OSIterator
, iterator
, iter
);
1076 return( kIOReturnSuccess
);
1079 /* Routine io_iterator_is_valid */
1080 kern_return_t
is_io_iterator_is_valid(
1081 io_object_t iterator
,
1082 boolean_t
*is_valid
)
1084 CHECK( OSIterator
, iterator
, iter
);
1086 *is_valid
= iter
->isValid();
1088 return( kIOReturnSuccess
);
1091 /* Routine io_service_match_property_table */
1092 kern_return_t
is_io_service_match_property_table(
1093 io_service_t _service
,
1094 io_string_t matching
,
1095 boolean_t
*matches
)
1097 CHECK( IOService
, _service
, service
);
1101 OSDictionary
* dict
;
1103 obj
= OSUnserializeXML( matching
);
1105 if( (dict
= OSDynamicCast( OSDictionary
, obj
))) {
1106 *matches
= service
->passiveMatch( dict
);
1107 kr
= kIOReturnSuccess
;
1109 kr
= kIOReturnBadArgument
;
1117 /* Routine io_service_match_property_table_ool */
1118 kern_return_t
is_io_service_match_property_table_ool(
1119 io_object_t service
,
1120 io_buf_ptr_t matching
,
1121 mach_msg_type_number_t matchingCnt
,
1123 boolean_t
*matches
)
1128 kr
= vm_map_copyout( kernel_map
, &data
, (vm_map_copy_t
) matching
);
1130 if( KERN_SUCCESS
== kr
) {
1131 // must return success after vm_map_copyout() succeeds
1132 *result
= is_io_service_match_property_table( service
,
1133 (char *) data
, matches
);
1134 vm_deallocate( kernel_map
, data
, matchingCnt
);
1140 /* Routine io_service_get_matching_services */
1141 kern_return_t
is_io_service_get_matching_services(
1142 mach_port_t master_port
,
1143 io_string_t matching
,
1144 io_iterator_t
*existing
)
1148 OSDictionary
* dict
;
1150 if( master_port
!= master_device_port
)
1151 return( kIOReturnNotPrivileged
);
1153 obj
= OSUnserializeXML( matching
);
1155 if( (dict
= OSDynamicCast( OSDictionary
, obj
))) {
1156 *existing
= IOService::getMatchingServices( dict
);
1157 kr
= kIOReturnSuccess
;
1159 kr
= kIOReturnBadArgument
;
1167 /* Routine io_service_get_matching_services_ool */
1168 kern_return_t
is_io_service_get_matching_services_ool(
1169 mach_port_t master_port
,
1170 io_buf_ptr_t matching
,
1171 mach_msg_type_number_t matchingCnt
,
1173 io_object_t
*existing
)
1178 kr
= vm_map_copyout( kernel_map
, &data
, (vm_map_copy_t
) matching
);
1180 if( KERN_SUCCESS
== kr
) {
1181 // must return success after vm_map_copyout() succeeds
1182 *result
= is_io_service_get_matching_services( master_port
,
1183 (char *) data
, existing
);
1184 vm_deallocate( kernel_map
, data
, matchingCnt
);
1190 /* Routine io_service_add_notification */
1191 kern_return_t
is_io_service_add_notification(
1192 mach_port_t master_port
,
1193 io_name_t notification_type
,
1194 io_string_t matching
,
1196 io_async_ref_t reference
,
1197 mach_msg_type_number_t referenceCnt
,
1198 io_object_t
* notification
)
1200 IOServiceUserNotification
* userNotify
= 0;
1201 IONotifier
* notify
= 0;
1202 const OSSymbol
* sym
;
1203 OSDictionary
* dict
;
1205 unsigned long int userMsgType
;
1208 if( master_port
!= master_device_port
)
1209 return( kIOReturnNotPrivileged
);
1212 err
= kIOReturnNoResources
;
1214 if( !(sym
= OSSymbol::withCString( notification_type
)))
1215 err
= kIOReturnNoResources
;
1217 if( !(dict
= OSDynamicCast( OSDictionary
,
1218 OSUnserializeXML( matching
)))) {
1219 err
= kIOReturnBadArgument
;
1223 if( (sym
== gIOPublishNotification
)
1224 || (sym
== gIOFirstPublishNotification
))
1225 userMsgType
= kIOServicePublishNotificationType
;
1226 else if( (sym
== gIOMatchedNotification
)
1227 || (sym
== gIOFirstMatchNotification
))
1228 userMsgType
= kIOServiceMatchedNotificationType
;
1229 else if( sym
== gIOTerminatedNotification
)
1230 userMsgType
= kIOServiceTerminatedNotificationType
;
1232 userMsgType
= kLastIOKitNotificationType
;
1234 userNotify
= new IOServiceUserNotification
;
1236 if( userNotify
&& !userNotify
->init( port
, userMsgType
,
1238 userNotify
->release();
1244 notify
= IOService::addNotification( sym
, dict
,
1245 &userNotify
->_handler
, userNotify
);
1248 *notification
= userNotify
;
1249 userNotify
->setNotification( notify
);
1250 err
= kIOReturnSuccess
;
1252 err
= kIOReturnUnsupported
;
1264 /* Routine io_service_add_notification_ool */
1265 kern_return_t
is_io_service_add_notification_ool(
1266 mach_port_t master_port
,
1267 io_name_t notification_type
,
1268 io_buf_ptr_t matching
,
1269 mach_msg_type_number_t matchingCnt
,
1270 mach_port_t wake_port
,
1271 io_async_ref_t reference
,
1272 mach_msg_type_number_t referenceCnt
,
1274 io_object_t
*notification
)
1279 kr
= vm_map_copyout( kernel_map
, &data
, (vm_map_copy_t
) matching
);
1281 if( KERN_SUCCESS
== kr
) {
1282 // must return success after vm_map_copyout() succeeds
1283 *result
= is_io_service_add_notification( master_port
, notification_type
,
1284 (char *) data
, wake_port
, reference
, referenceCnt
, notification
);
1285 vm_deallocate( kernel_map
, data
, matchingCnt
);
1292 /* Routine io_service_add_notification_old */
1293 kern_return_t
is_io_service_add_notification_old(
1294 mach_port_t master_port
,
1295 io_name_t notification_type
,
1296 io_string_t matching
,
1299 io_object_t
* notification
)
1301 return( is_io_service_add_notification( master_port
, notification_type
,
1302 matching
, port
, &ref
, 1, notification
));
1305 /* Routine io_service_add_message_notification */
1306 kern_return_t
is_io_service_add_interest_notification(
1307 io_object_t _service
,
1308 io_name_t type_of_interest
,
1310 io_async_ref_t reference
,
1311 mach_msg_type_number_t referenceCnt
,
1312 io_object_t
* notification
)
1315 IOServiceMessageUserNotification
* userNotify
= 0;
1316 IONotifier
* notify
= 0;
1317 const OSSymbol
* sym
;
1320 CHECK( IOService
, _service
, service
);
1322 err
= kIOReturnNoResources
;
1323 if( (sym
= OSSymbol::withCString( type_of_interest
))) do {
1325 userNotify
= new IOServiceMessageUserNotification
;
1327 if( userNotify
&& !userNotify
->init( port
, kIOServiceMessageNotificationType
,
1328 reference
, kIOUserNotifyMaxMessageSize
)) {
1329 userNotify
->release();
1335 notify
= service
->registerInterest( sym
,
1336 &userNotify
->_handler
, userNotify
);
1338 *notification
= userNotify
;
1339 userNotify
->setNotification( notify
);
1340 err
= kIOReturnSuccess
;
1342 err
= kIOReturnUnsupported
;
1351 /* Routine io_service_acknowledge_notification */
1352 kern_return_t
is_io_service_acknowledge_notification(
1353 io_object_t _service
,
1354 natural_t notify_ref
,
1355 natural_t response
)
1357 CHECK( IOService
, _service
, service
);
1359 return( service
->acknowledgeNotification( (IONotificationRef
) notify_ref
,
1360 (IOOptionBits
) response
));
1364 /* Routine io_connect_get_semaphore */
1365 kern_return_t
is_io_connect_get_notification_semaphore(
1366 io_connect_t connection
,
1367 natural_t notification_type
,
1368 semaphore_t
*semaphore
)
1370 CHECK( IOUserClient
, connection
, client
);
1372 return( client
->getNotificationSemaphore( (UInt32
) notification_type
,
1376 /* Routine io_registry_get_root_entry */
1377 kern_return_t
is_io_registry_get_root_entry(
1378 mach_port_t master_port
,
1381 IORegistryEntry
* entry
;
1383 if( master_port
!= master_device_port
)
1384 return( kIOReturnNotPrivileged
);
1386 entry
= IORegistryEntry::getRegistryRoot();
1391 return( kIOReturnSuccess
);
1394 /* Routine io_registry_create_iterator */
1395 kern_return_t
is_io_registry_create_iterator(
1396 mach_port_t master_port
,
1399 io_object_t
*iterator
)
1401 if( master_port
!= master_device_port
)
1402 return( kIOReturnNotPrivileged
);
1404 *iterator
= IORegistryIterator::iterateOver(
1405 IORegistryEntry::getPlane( plane
), options
);
1407 return( *iterator
? kIOReturnSuccess
: kIOReturnBadArgument
);
1410 /* Routine io_registry_entry_create_iterator */
1411 kern_return_t
is_io_registry_entry_create_iterator(
1412 io_object_t registry_entry
,
1415 io_object_t
*iterator
)
1417 CHECK( IORegistryEntry
, registry_entry
, entry
);
1419 *iterator
= IORegistryIterator::iterateOver( entry
,
1420 IORegistryEntry::getPlane( plane
), options
);
1422 return( *iterator
? kIOReturnSuccess
: kIOReturnBadArgument
);
1425 /* Routine io_registry_iterator_enter */
1426 kern_return_t
is_io_registry_iterator_enter_entry(
1427 io_object_t iterator
)
1429 CHECK( IORegistryIterator
, iterator
, iter
);
1433 return( kIOReturnSuccess
);
1436 /* Routine io_registry_iterator_exit */
1437 kern_return_t
is_io_registry_iterator_exit_entry(
1438 io_object_t iterator
)
1442 CHECK( IORegistryIterator
, iterator
, iter
);
1444 didIt
= iter
->exitEntry();
1446 return( didIt
? kIOReturnSuccess
: kIOReturnNoDevice
);
1449 /* Routine io_registry_entry_from_path */
1450 kern_return_t
is_io_registry_entry_from_path(
1451 mach_port_t master_port
,
1453 io_object_t
*registry_entry
)
1455 IORegistryEntry
* entry
;
1457 if( master_port
!= master_device_port
)
1458 return( kIOReturnNotPrivileged
);
1460 entry
= IORegistryEntry::fromPath( path
);
1462 *registry_entry
= entry
;
1464 return( kIOReturnSuccess
);
1467 /* Routine io_registry_entry_in_plane */
1468 kern_return_t
is_io_registry_entry_in_plane(
1469 io_object_t registry_entry
,
1471 boolean_t
*inPlane
)
1473 CHECK( IORegistryEntry
, registry_entry
, entry
);
1475 *inPlane
= entry
->inPlane( IORegistryEntry::getPlane( plane
));
1477 return( kIOReturnSuccess
);
1481 /* Routine io_registry_entry_get_path */
1482 kern_return_t
is_io_registry_entry_get_path(
1483 io_object_t registry_entry
,
1488 CHECK( IORegistryEntry
, registry_entry
, entry
);
1490 length
= sizeof( io_string_t
);
1491 if( entry
->getPath( path
, &length
, IORegistryEntry::getPlane( plane
)))
1492 return( kIOReturnSuccess
);
1494 return( kIOReturnBadArgument
);
1498 /* Routine io_registry_entry_get_name */
1499 kern_return_t
is_io_registry_entry_get_name(
1500 io_object_t registry_entry
,
1503 CHECK( IORegistryEntry
, registry_entry
, entry
);
1505 strncpy( name
, entry
->getName(), sizeof( io_name_t
));
1507 return( kIOReturnSuccess
);
1510 /* Routine io_registry_entry_get_name_in_plane */
1511 kern_return_t
is_io_registry_entry_get_name_in_plane(
1512 io_object_t registry_entry
,
1513 io_name_t planeName
,
1516 const IORegistryPlane
* plane
;
1517 CHECK( IORegistryEntry
, registry_entry
, entry
);
1520 plane
= IORegistryEntry::getPlane( planeName
);
1524 strncpy( name
, entry
->getName( plane
), sizeof( io_name_t
));
1526 return( kIOReturnSuccess
);
1529 /* Routine io_registry_entry_get_location_in_plane */
1530 kern_return_t
is_io_registry_entry_get_location_in_plane(
1531 io_object_t registry_entry
,
1532 io_name_t planeName
,
1533 io_name_t location
)
1535 const IORegistryPlane
* plane
;
1536 CHECK( IORegistryEntry
, registry_entry
, entry
);
1539 plane
= IORegistryEntry::getPlane( planeName
);
1543 const char * cstr
= entry
->getLocation( plane
);
1546 strncpy( location
, cstr
, sizeof( io_name_t
));
1547 return( kIOReturnSuccess
);
1549 return( kIOReturnNotFound
);
1552 // Create a vm_map_copy_t or kalloc'ed data for memory
1553 // to be copied out. ipc will free after the copyout.
1555 static kern_return_t
copyoutkdata( void * data
, vm_size_t len
,
1556 io_buf_ptr_t
* buf
)
1561 err
= vm_map_copyin( kernel_map
, (vm_offset_t
) data
, len
,
1562 false /* src_destroy */, ©
);
1564 assert( err
== KERN_SUCCESS
);
1565 if( err
== KERN_SUCCESS
)
1566 *buf
= (char *) copy
;
1571 /* Routine io_registry_entry_get_property */
1572 kern_return_t
is_io_registry_entry_get_property_bytes(
1573 io_object_t registry_entry
,
1574 io_name_t property_name
,
1575 io_scalar_inband_t buf
,
1576 mach_msg_type_number_t
*dataCnt
)
1584 unsigned int len
= 0;
1585 const void * bytes
= 0;
1586 IOReturn ret
= kIOReturnSuccess
;
1588 CHECK( IORegistryEntry
, registry_entry
, entry
);
1590 obj
= entry
->copyProperty(property_name
);
1592 return( kIOReturnNoResources
);
1594 // One day OSData will be a common container base class
1596 if( (data
= OSDynamicCast( OSData
, obj
))) {
1597 len
= data
->getLength();
1598 bytes
= data
->getBytesNoCopy();
1600 } else if( (str
= OSDynamicCast( OSString
, obj
))) {
1601 len
= str
->getLength() + 1;
1602 bytes
= str
->getCStringNoCopy();
1604 } else if( (boo
= OSDynamicCast( OSBoolean
, obj
))) {
1605 len
= boo
->isTrue() ? sizeof("Yes") : sizeof("No");
1606 bytes
= boo
->isTrue() ? "Yes" : "No";
1608 } else if( (off
= OSDynamicCast( OSNumber
, obj
))) {
1609 offsetBytes
= off
->unsigned64BitValue();
1610 len
= off
->numberOfBytes();
1611 bytes
= &offsetBytes
;
1612 #ifdef __BIG_ENDIAN__
1613 bytes
= (const void *)
1614 (((UInt32
) bytes
) + (sizeof( UInt64
) - len
));
1618 ret
= kIOReturnBadArgument
;
1622 ret
= kIOReturnIPCError
;
1625 bcopy( bytes
, buf
, len
);
1633 /* Routine io_registry_entry_get_property */
1634 kern_return_t
is_io_registry_entry_get_property(
1635 io_object_t registry_entry
,
1636 io_name_t property_name
,
1637 io_buf_ptr_t
*properties
,
1638 mach_msg_type_number_t
*propertiesCnt
)
1644 CHECK( IORegistryEntry
, registry_entry
, entry
);
1646 obj
= entry
->copyProperty(property_name
);
1648 return( kIOReturnNotFound
);
1650 OSSerialize
* s
= OSSerialize::withCapacity(4096);
1653 return( kIOReturnNoMemory
);
1657 if( obj
->serialize( s
)) {
1658 len
= s
->getLength();
1659 *propertiesCnt
= len
;
1660 err
= copyoutkdata( s
->text(), len
, properties
);
1663 err
= kIOReturnUnsupported
;
1671 /* Routine io_registry_entry_get_property_recursively */
1672 kern_return_t
is_io_registry_entry_get_property_recursively(
1673 io_object_t registry_entry
,
1675 io_name_t property_name
,
1677 io_buf_ptr_t
*properties
,
1678 mach_msg_type_number_t
*propertiesCnt
)
1684 CHECK( IORegistryEntry
, registry_entry
, entry
);
1686 obj
= entry
->copyProperty( property_name
,
1687 IORegistryEntry::getPlane( plane
), options
);
1689 return( kIOReturnNotFound
);
1691 OSSerialize
* s
= OSSerialize::withCapacity(4096);
1694 return( kIOReturnNoMemory
);
1699 if( obj
->serialize( s
)) {
1700 len
= s
->getLength();
1701 *propertiesCnt
= len
;
1702 err
= copyoutkdata( s
->text(), len
, properties
);
1705 err
= kIOReturnUnsupported
;
1713 /* Routine io_registry_entry_get_properties */
1714 kern_return_t
is_io_registry_entry_get_properties(
1715 io_object_t registry_entry
,
1716 io_buf_ptr_t
*properties
,
1717 mach_msg_type_number_t
*propertiesCnt
)
1722 CHECK( IORegistryEntry
, registry_entry
, entry
);
1724 OSSerialize
* s
= OSSerialize::withCapacity(4096);
1726 return( kIOReturnNoMemory
);
1730 if( entry
->serializeProperties( s
)) {
1731 len
= s
->getLength();
1732 *propertiesCnt
= len
;
1733 err
= copyoutkdata( s
->text(), len
, properties
);
1736 err
= kIOReturnUnsupported
;
1743 /* Routine io_registry_entry_set_properties */
1744 kern_return_t is_io_registry_entry_set_properties
1746 io_object_t registry_entry
,
1747 io_buf_ptr_t properties
,
1748 mach_msg_type_number_t propertiesCnt
,
1756 CHECK( IORegistryEntry
, registry_entry
, entry
);
1758 err
= vm_map_copyout( kernel_map
, &data
, (vm_map_copy_t
) properties
);
1760 if( KERN_SUCCESS
== err
) {
1762 // must return success after vm_map_copyout() succeeds
1763 obj
= OSUnserializeXML( (const char *) data
);
1764 vm_deallocate( kernel_map
, data
, propertiesCnt
);
1767 res
= entry
->setProperties( obj
);
1770 res
= kIOReturnBadArgument
;
1778 /* Routine io_registry_entry_get_child_iterator */
1779 kern_return_t
is_io_registry_entry_get_child_iterator(
1780 io_object_t registry_entry
,
1782 io_object_t
*iterator
)
1784 CHECK( IORegistryEntry
, registry_entry
, entry
);
1786 *iterator
= entry
->getChildIterator(
1787 IORegistryEntry::getPlane( plane
));
1789 return( kIOReturnSuccess
);
1792 /* Routine io_registry_entry_get_parent_iterator */
1793 kern_return_t
is_io_registry_entry_get_parent_iterator(
1794 io_object_t registry_entry
,
1796 io_object_t
*iterator
)
1798 CHECK( IORegistryEntry
, registry_entry
, entry
);
1800 *iterator
= entry
->getParentIterator(
1801 IORegistryEntry::getPlane( plane
));
1803 return( kIOReturnSuccess
);
1806 /* Routine io_service_get_busy_state */
1807 kern_return_t
is_io_service_get_busy_state(
1808 io_object_t _service
,
1811 CHECK( IOService
, _service
, service
);
1813 *busyState
= service
->getBusyState();
1815 return( kIOReturnSuccess
);
1818 /* Routine io_service_get_state */
1819 kern_return_t
is_io_service_get_state(
1820 io_object_t _service
,
1823 CHECK( IOService
, _service
, service
);
1825 *state
= service
->getState();
1827 return( kIOReturnSuccess
);
1830 /* Routine io_service_wait_quiet */
1831 kern_return_t
is_io_service_wait_quiet(
1832 io_object_t _service
,
1833 mach_timespec_t wait_time
)
1835 CHECK( IOService
, _service
, service
);
1837 return( service
->waitQuiet( &wait_time
));
1840 /* Routine io_service_request_probe */
1841 kern_return_t
is_io_service_request_probe(
1842 io_object_t _service
,
1845 CHECK( IOService
, _service
, service
);
1847 return( service
->requestProbe( options
));
1851 /* Routine io_service_open */
1852 kern_return_t
is_io_service_open(
1853 io_object_t _service
,
1856 io_object_t
*connection
)
1858 IOUserClient
* client
;
1861 CHECK( IOService
, _service
, service
);
1863 err
= service
->newUserClient( owningTask
, (void *) owningTask
,
1864 connect_type
, &client
);
1866 if( err
== kIOReturnSuccess
) {
1867 assert( OSDynamicCast(IOUserClient
, client
) );
1868 *connection
= client
;
1874 /* Routine io_service_close */
1875 kern_return_t
is_io_service_close(
1876 io_object_t connection
)
1879 if ((mappings
= OSDynamicCast(OSSet
, connection
)))
1880 return( kIOReturnSuccess
);
1882 CHECK( IOUserClient
, connection
, client
);
1884 client
->clientClose();
1886 return( kIOReturnSuccess
);
1889 /* Routine io_connect_get_service */
1890 kern_return_t
is_io_connect_get_service(
1891 io_object_t connection
,
1892 io_object_t
*service
)
1894 IOService
* theService
;
1896 CHECK( IOUserClient
, connection
, client
);
1898 theService
= client
->getService();
1900 theService
->retain();
1902 *service
= theService
;
1904 return( theService
? kIOReturnSuccess
: kIOReturnUnsupported
);
1907 /* Routine io_connect_set_notification_port */
1908 kern_return_t
is_io_connect_set_notification_port(
1909 io_object_t connection
,
1910 int notification_type
,
1914 CHECK( IOUserClient
, connection
, client
);
1916 return( client
->registerNotificationPort( port
, notification_type
,
1920 kern_return_t
is_io_connect_map_memory(
1921 io_object_t connect
,
1924 vm_address_t
* mapAddr
,
1925 vm_size_t
* mapSize
,
1931 CHECK( IOUserClient
, connect
, client
);
1933 map
= client
->mapClientMemory( type
, task
, flags
, *mapAddr
);
1936 *mapAddr
= map
->getVirtualAddress();
1938 *mapSize
= map
->getLength();
1940 if( task
!= current_task()) {
1941 // push a name out to the task owning the map,
1942 // so we can clean up maps
1944 mach_port_name_t name
=
1946 IOMachPort::makeSendRightForTask(
1947 task
, map
, IKOT_IOKIT_OBJECT
);
1951 // keep it with the user client
1952 IOLockLock( gIOObjectPortLock
);
1953 if( 0 == client
->mappings
)
1954 client
->mappings
= OSSet::withCapacity(2);
1955 if( client
->mappings
)
1956 client
->mappings
->setObject( map
);
1957 IOLockUnlock( gIOObjectPortLock
);
1960 err
= kIOReturnSuccess
;
1963 err
= kIOReturnBadArgument
;
1968 IOMemoryMap
* IOUserClient::removeMappingForDescriptor(IOMemoryDescriptor
* mem
)
1971 IOMemoryMap
* map
= 0;
1973 IOLockLock(gIOObjectPortLock
);
1975 iter
= OSCollectionIterator::withCollection(mappings
);
1978 while ((map
= OSDynamicCast(IOMemoryMap
, iter
->getNextObject())))
1980 if(mem
== map
->getMemoryDescriptor())
1983 mappings
->removeObject(map
);
1990 IOLockUnlock(gIOObjectPortLock
);
1995 kern_return_t
is_io_connect_unmap_memory(
1996 io_object_t connect
,
1999 vm_address_t mapAddr
)
2002 IOOptionBits options
= 0;
2003 IOMemoryDescriptor
* memory
;
2006 CHECK( IOUserClient
, connect
, client
);
2008 err
= client
->clientMemoryForType( (UInt32
) type
, &options
, &memory
);
2010 if( memory
&& (kIOReturnSuccess
== err
)) {
2012 options
= (options
& ~kIOMapUserOptionsMask
)
2013 | kIOMapAnywhere
| kIOMapReference
;
2015 map
= memory
->map( task
, mapAddr
, options
);
2018 IOLockLock( gIOObjectPortLock
);
2019 if( client
->mappings
)
2020 client
->mappings
->removeObject( map
);
2021 IOLockUnlock( gIOObjectPortLock
);
2022 IOMachPort::releasePortForObject( map
, IKOT_IOKIT_OBJECT
);
2025 err
= kIOReturnBadArgument
;
2032 /* Routine io_connect_add_client */
2033 kern_return_t
is_io_connect_add_client(
2034 io_object_t connection
,
2035 io_object_t connect_to
)
2037 CHECK( IOUserClient
, connection
, client
);
2038 CHECK( IOUserClient
, connect_to
, to
);
2040 return( client
->connectClient( to
) );
2044 /* Routine io_connect_set_properties */
2045 kern_return_t
is_io_connect_set_properties(
2046 io_object_t connection
,
2047 io_buf_ptr_t properties
,
2048 mach_msg_type_number_t propertiesCnt
,
2051 return( is_io_registry_entry_set_properties( connection
, properties
, propertiesCnt
, result
));
2055 /* Routine io_connect_method_scalarI_scalarO */
2056 kern_return_t
is_io_connect_method_scalarI_scalarO(
2057 io_object_t connect
,
2060 IOByteCount inputCount
,
2062 IOByteCount
* outputCount
)
2065 IOExternalMethod
* method
;
2069 CHECK( IOUserClient
, connect
, client
);
2070 if( (method
= client
->getTargetAndMethodForIndex(&object
, index
))) {
2072 err
= kIOReturnBadArgument
;
2073 if( kIOUCScalarIScalarO
!= (method
->flags
& kIOUCTypeMask
))
2075 if( inputCount
!= method
->count0
)
2077 if( *outputCount
!= method
->count1
)
2080 func
= method
->func
;
2082 switch( inputCount
) {
2085 err
= (object
->*func
)( input
[0], input
[1], input
[2],
2086 input
[3], input
[4], input
[5] );
2089 err
= (object
->*func
)( input
[0], input
[1], input
[2],
2094 err
= (object
->*func
)( input
[0], input
[1], input
[2],
2096 &output
[0], &output
[1] );
2099 err
= (object
->*func
)( input
[0], input
[1], input
[2],
2100 &output
[0], &output
[1], &output
[2] );
2103 err
= (object
->*func
)( input
[0], input
[1],
2104 &output
[0], &output
[1], &output
[2],
2108 err
= (object
->*func
)( input
[0],
2109 &output
[0], &output
[1], &output
[2],
2110 &output
[3], &output
[4] );
2113 err
= (object
->*func
)( &output
[0], &output
[1], &output
[2],
2114 &output
[3], &output
[4], &output
[5] );
2118 IOLog("%s: Bad method table\n", client
->getName());
2123 err
= kIOReturnUnsupported
;
2128 /* Routine io_connect_method_scalarI_structureO */
2129 kern_return_t
is_io_connect_method_scalarI_structureO(
2130 io_object_t connect
,
2133 IOByteCount inputCount
,
2135 IOByteCount
* outputCount
)
2138 IOExternalMethod
* method
;
2142 CHECK( IOUserClient
, connect
, client
);
2144 if( (method
= client
->getTargetAndMethodForIndex(&object
, index
)) ) {
2146 err
= kIOReturnBadArgument
;
2147 if( kIOUCScalarIStructO
!= (method
->flags
& kIOUCTypeMask
))
2149 if( inputCount
!= method
->count0
)
2151 if( (0xffffffff != method
->count1
)
2152 && (*outputCount
!= method
->count1
))
2155 func
= method
->func
;
2157 switch( inputCount
) {
2160 err
= (object
->*func
)( input
[0], input
[1], input
[2],
2165 err
= (object
->*func
)( input
[0], input
[1], input
[2],
2167 output
, (void *)outputCount
);
2170 err
= (object
->*func
)( input
[0], input
[1], input
[2],
2171 output
, (void *)outputCount
, 0 );
2174 err
= (object
->*func
)( input
[0], input
[1],
2175 output
, (void *)outputCount
, 0, 0 );
2178 err
= (object
->*func
)( input
[0],
2179 output
, (void *)outputCount
, 0, 0, 0 );
2182 err
= (object
->*func
)( output
, (void *)outputCount
, 0, 0, 0, 0 );
2186 IOLog("%s: Bad method table\n", client
->getName());
2191 err
= kIOReturnUnsupported
;
2196 /* Routine io_connect_method_scalarI_structureI */
2197 kern_return_t
is_io_connect_method_scalarI_structureI(
2198 io_connect_t connect
,
2201 IOByteCount inputCount
,
2202 UInt8
* inputStruct
,
2203 IOByteCount inputStructCount
)
2206 IOExternalMethod
* method
;
2210 CHECK( IOUserClient
, connect
, client
);
2212 if( (method
= client
->getTargetAndMethodForIndex(&object
, index
)) ) {
2214 err
= kIOReturnBadArgument
;
2215 if( kIOUCScalarIStructI
!= (method
->flags
& kIOUCTypeMask
))
2217 if( (0xffffffff != method
->count0
)
2218 && (inputCount
!= method
->count0
))
2220 if( (0xffffffff != method
->count1
)
2221 && (inputStructCount
!= method
->count1
))
2224 func
= method
->func
;
2226 switch( inputCount
) {
2229 err
= (object
->*func
)( input
[0], input
[1], input
[2],
2234 err
= (object
->*func
)( input
[0], input
[1], input
[2],
2236 inputStruct
, (void *)inputStructCount
);
2239 err
= (object
->*func
)( input
[0], input
[1], input
[2],
2240 inputStruct
, (void *)inputStructCount
,
2244 err
= (object
->*func
)( input
[0], input
[1],
2245 inputStruct
, (void *)inputStructCount
,
2249 err
= (object
->*func
)( input
[0],
2250 inputStruct
, (void *)inputStructCount
,
2254 err
= (object
->*func
)( inputStruct
, (void *)inputStructCount
,
2259 IOLog("%s: Bad method table\n", client
->getName());
2264 err
= kIOReturnUnsupported
;
2269 /* Routine io_connect_method_structureI_structureO */
2270 kern_return_t
is_io_connect_method_structureI_structureO(
2271 io_object_t connect
,
2274 IOByteCount inputCount
,
2276 IOByteCount
* outputCount
)
2279 IOExternalMethod
* method
;
2283 CHECK( IOUserClient
, connect
, client
);
2285 if( (method
= client
->getTargetAndMethodForIndex(&object
, index
)) ) {
2287 err
= kIOReturnBadArgument
;
2288 if( kIOUCStructIStructO
!= (method
->flags
& kIOUCTypeMask
))
2290 if( (0xffffffff != method
->count0
)
2291 && (inputCount
!= method
->count0
))
2293 if( (0xffffffff != method
->count1
)
2294 && (*outputCount
!= method
->count1
))
2297 func
= method
->func
;
2299 if( method
->count1
) {
2300 if( method
->count0
) {
2301 err
= (object
->*func
)( input
, output
,
2302 (void *)inputCount
, outputCount
, 0, 0 );
2304 err
= (object
->*func
)( output
, outputCount
, 0, 0, 0, 0 );
2307 err
= (object
->*func
)( input
, (void *)inputCount
, 0, 0, 0, 0 );
2313 err
= kIOReturnUnsupported
;
2318 kern_return_t
is_io_async_method_scalarI_scalarO(
2319 io_object_t connect
,
2320 mach_port_t wakePort
,
2321 io_async_ref_t reference
,
2322 mach_msg_type_number_t referenceCnt
,
2325 IOByteCount inputCount
,
2327 IOByteCount
* outputCount
)
2330 IOExternalAsyncMethod
*method
;
2334 CHECK( IOUserClient
, connect
, client
);
2335 if( (method
= client
->getAsyncTargetAndMethodForIndex(&object
, index
)) ) {
2337 err
= kIOReturnBadArgument
;
2338 if( kIOUCScalarIScalarO
!= (method
->flags
& kIOUCTypeMask
))
2340 if( inputCount
!= method
->count0
)
2342 if( *outputCount
!= method
->count1
)
2345 reference
[0] = (natural_t
) wakePort
;
2346 func
= method
->func
;
2348 switch( inputCount
) {
2351 err
= (object
->*func
)( reference
,
2352 input
[0], input
[1], input
[2],
2353 input
[3], input
[4], input
[5] );
2356 err
= (object
->*func
)( reference
,
2357 input
[0], input
[1], input
[2],
2362 err
= (object
->*func
)( reference
,
2363 input
[0], input
[1], input
[2],
2365 &output
[0], &output
[1] );
2368 err
= (object
->*func
)( reference
,
2369 input
[0], input
[1], input
[2],
2370 &output
[0], &output
[1], &output
[2] );
2373 err
= (object
->*func
)( reference
,
2375 &output
[0], &output
[1], &output
[2],
2379 err
= (object
->*func
)( reference
,
2381 &output
[0], &output
[1], &output
[2],
2382 &output
[3], &output
[4] );
2385 err
= (object
->*func
)( reference
,
2386 &output
[0], &output
[1], &output
[2],
2387 &output
[3], &output
[4], &output
[5] );
2391 IOLog("%s: Bad method table\n", client
->getName());
2396 err
= kIOReturnUnsupported
;
2401 kern_return_t
is_io_async_method_scalarI_structureO(
2402 io_object_t connect
,
2403 mach_port_t wakePort
,
2404 io_async_ref_t reference
,
2405 mach_msg_type_number_t referenceCnt
,
2408 IOByteCount inputCount
,
2410 IOByteCount
* outputCount
)
2413 IOExternalAsyncMethod
*method
;
2417 CHECK( IOUserClient
, connect
, client
);
2419 if( (method
= client
->getAsyncTargetAndMethodForIndex(&object
, index
)) ) {
2421 err
= kIOReturnBadArgument
;
2422 if( kIOUCScalarIStructO
!= (method
->flags
& kIOUCTypeMask
))
2424 if( inputCount
!= method
->count0
)
2426 if( (0xffffffff != method
->count1
)
2427 && (*outputCount
!= method
->count1
))
2430 reference
[0] = (natural_t
) wakePort
;
2431 func
= method
->func
;
2433 switch( inputCount
) {
2436 err
= (object
->*func
)( reference
,
2437 input
[0], input
[1], input
[2],
2442 err
= (object
->*func
)( reference
,
2443 input
[0], input
[1], input
[2],
2445 output
, (void *)outputCount
);
2448 err
= (object
->*func
)( reference
,
2449 input
[0], input
[1], input
[2],
2450 output
, (void *)outputCount
, 0 );
2453 err
= (object
->*func
)( reference
,
2455 output
, (void *)outputCount
, 0, 0 );
2458 err
= (object
->*func
)( reference
,
2460 output
, (void *)outputCount
, 0, 0, 0 );
2463 err
= (object
->*func
)( reference
,
2464 output
, (void *)outputCount
, 0, 0, 0, 0 );
2468 IOLog("%s: Bad method table\n", client
->getName());
2473 err
= kIOReturnUnsupported
;
2478 kern_return_t
is_io_async_method_scalarI_structureI(
2479 io_connect_t connect
,
2480 mach_port_t wakePort
,
2481 io_async_ref_t reference
,
2482 mach_msg_type_number_t referenceCnt
,
2485 IOByteCount inputCount
,
2486 UInt8
* inputStruct
,
2487 IOByteCount inputStructCount
)
2490 IOExternalAsyncMethod
*method
;
2494 CHECK( IOUserClient
, connect
, client
);
2496 if( (method
= client
->getAsyncTargetAndMethodForIndex(&object
, index
)) ) {
2498 err
= kIOReturnBadArgument
;
2499 if( kIOUCScalarIStructI
!= (method
->flags
& kIOUCTypeMask
))
2501 if( (0xffffffff != method
->count0
)
2502 && (inputCount
!= method
->count0
))
2504 if( (0xffffffff != method
->count1
)
2505 && (inputStructCount
!= method
->count1
))
2508 reference
[0] = (natural_t
) wakePort
;
2509 func
= method
->func
;
2511 switch( inputCount
) {
2514 err
= (object
->*func
)( reference
,
2515 input
[0], input
[1], input
[2],
2520 err
= (object
->*func
)( reference
,
2521 input
[0], input
[1], input
[2],
2523 inputStruct
, (void *)inputStructCount
);
2526 err
= (object
->*func
)( reference
,
2527 input
[0], input
[1], input
[2],
2528 inputStruct
, (void *)inputStructCount
,
2532 err
= (object
->*func
)( reference
,
2534 inputStruct
, (void *)inputStructCount
,
2538 err
= (object
->*func
)( reference
,
2540 inputStruct
, (void *)inputStructCount
,
2544 err
= (object
->*func
)( reference
,
2545 inputStruct
, (void *)inputStructCount
,
2550 IOLog("%s: Bad method table\n", client
->getName());
2555 err
= kIOReturnUnsupported
;
2560 kern_return_t
is_io_async_method_structureI_structureO(
2561 io_object_t connect
,
2562 mach_port_t wakePort
,
2563 io_async_ref_t reference
,
2564 mach_msg_type_number_t referenceCnt
,
2567 IOByteCount inputCount
,
2569 IOByteCount
* outputCount
)
2572 IOExternalAsyncMethod
*method
;
2576 CHECK( IOUserClient
, connect
, client
);
2578 if( (method
= client
->getAsyncTargetAndMethodForIndex(&object
, index
)) ) {
2580 err
= kIOReturnBadArgument
;
2581 if( kIOUCStructIStructO
!= (method
->flags
& kIOUCTypeMask
))
2583 if( (0xffffffff != method
->count0
)
2584 && (inputCount
!= method
->count0
))
2586 if( (0xffffffff != method
->count1
)
2587 && (*outputCount
!= method
->count1
))
2590 reference
[0] = (natural_t
) wakePort
;
2591 func
= method
->func
;
2593 if( method
->count1
) {
2594 if( method
->count0
) {
2595 err
= (object
->*func
)( reference
,
2597 (void *)inputCount
, outputCount
, 0, 0 );
2599 err
= (object
->*func
)( reference
,
2600 output
, outputCount
, 0, 0, 0, 0 );
2603 err
= (object
->*func
)( reference
,
2604 input
, (void *)inputCount
, 0, 0, 0, 0 );
2610 err
= kIOReturnUnsupported
;
2614 /* Routine io_make_matching */
2615 kern_return_t
is_io_make_matching(
2616 mach_port_t master_port
,
2618 IOOptionBits options
,
2620 IOByteCount inputCount
,
2621 io_string_t matching
)
2624 IOReturn err
= kIOReturnSuccess
;
2625 OSDictionary
* dict
;
2627 if( master_port
!= master_device_port
)
2628 return( kIOReturnNotPrivileged
);
2632 case kIOServiceMatching
:
2633 dict
= IOService::serviceMatching( gIOServiceKey
);
2636 case kIOBSDNameMatching
:
2637 dict
= IOBSDNameMatching( (const char *) input
);
2640 case kIOOFPathMatching
:
2641 dict
= IOOFPathMatching( (const char *) input
,
2642 matching
, sizeof( io_string_t
));
2650 return( kIOReturnUnsupported
);
2653 s
= OSSerialize::withCapacity(4096);
2655 err
= kIOReturnNoMemory
;
2659 if( !dict
->serialize( s
)) {
2660 err
= kIOReturnUnsupported
;
2664 if( s
->getLength() > sizeof( io_string_t
)) {
2665 err
= kIOReturnNoMemory
;
2668 strcpy( matching
, s
->text());
2680 /* Routine io_catalog_send_data */
2681 kern_return_t
is_io_catalog_send_data(
2682 mach_port_t master_port
,
2684 io_buf_ptr_t inData
,
2685 mach_msg_type_number_t inDataCount
,
2690 kern_return_t kr
= kIOReturnError
;
2692 //printf("io_catalog_send_data called. flag: %d\n", flag);
2694 if( master_port
!= master_device_port
)
2695 return kIOReturnNotPrivileged
;
2697 // FIXME: This is a hack. Should have own function for removeKernelLinker()
2698 if(flag
!= kIOCatalogRemoveKernelLinker
&& ( !inData
|| !inDataCount
) )
2699 return kIOReturnBadArgument
;
2702 kr
= vm_map_copyout( kernel_map
, &data
, (vm_map_copy_t
)inData
);
2703 if( kr
!= KERN_SUCCESS
)
2706 // must return success after vm_map_copyout() succeeds
2709 obj
= (OSObject
*)OSUnserializeXML((const char *)data
);
2710 vm_deallocate( kernel_map
, data
, inDataCount
);
2712 *result
= kIOReturnNoMemory
;
2713 return( KERN_SUCCESS
);
2719 case kIOCatalogAddDrivers
:
2720 case kIOCatalogAddDriversNoMatch
: {
2723 array
= OSDynamicCast(OSArray
, obj
);
2725 if ( !gIOCatalogue
->addDrivers( array
,
2726 flag
== kIOCatalogAddDrivers
) ) {
2727 kr
= kIOReturnError
;
2731 kr
= kIOReturnBadArgument
;
2736 case kIOCatalogRemoveDrivers
:
2737 case kIOCatalogRemoveDriversNoMatch
: {
2738 OSDictionary
* dict
;
2740 dict
= OSDynamicCast(OSDictionary
, obj
);
2742 if ( !gIOCatalogue
->removeDrivers( dict
,
2743 flag
== kIOCatalogRemoveDrivers
) ) {
2744 kr
= kIOReturnError
;
2748 kr
= kIOReturnBadArgument
;
2753 case kIOCatalogStartMatching
: {
2754 OSDictionary
* dict
;
2756 dict
= OSDynamicCast(OSDictionary
, obj
);
2758 if ( !gIOCatalogue
->startMatching( dict
) ) {
2759 kr
= kIOReturnError
;
2763 kr
= kIOReturnBadArgument
;
2768 case kIOCatalogRemoveKernelLinker
: {
2769 if (gIOCatalogue
->removeKernelLinker() != KERN_SUCCESS
) {
2770 kr
= kIOReturnError
;
2772 kr
= kIOReturnSuccess
;
2778 kr
= kIOReturnBadArgument
;
2782 if (obj
) obj
->release();
2785 return( KERN_SUCCESS
);
2788 /* Routine io_catalog_terminate */
2789 kern_return_t
is_io_catalog_terminate(
2790 mach_port_t master_port
,
2796 if( master_port
!= master_device_port
)
2797 return kIOReturnNotPrivileged
;
2799 kr
= IOUserClient::clientHasPrivilege( (void *) current_task(),
2800 kIOClientPrivilegeAdministrator
);
2801 if( kIOReturnSuccess
!= kr
)
2805 case kIOCatalogServiceTerminate
:
2807 IOService
* service
;
2809 iter
= IORegistryIterator::iterateOver(gIOServicePlane
,
2810 kIORegistryIterateRecursively
);
2812 return kIOReturnNoMemory
;
2816 while( (service
= (IOService
*)iter
->getNextObject()) ) {
2817 if( service
->metaCast(name
)) {
2818 if ( !service
->terminate( kIOServiceRequired
2819 | kIOServiceSynchronous
) ) {
2820 kr
= kIOReturnUnsupported
;
2825 } while( !service
&& !iter
->isValid());
2829 case kIOCatalogModuleUnload
:
2830 case kIOCatalogModuleTerminate
:
2831 kr
= gIOCatalogue
->terminateDriversForModule(name
,
2832 flag
== kIOCatalogModuleUnload
);
2836 kr
= kIOReturnBadArgument
;
2843 /* Routine io_catalog_get_data */
2844 kern_return_t
is_io_catalog_get_data(
2845 mach_port_t master_port
,
2847 io_buf_ptr_t
*outData
,
2848 mach_msg_type_number_t
*outDataCount
)
2850 kern_return_t kr
= kIOReturnSuccess
;
2853 if( master_port
!= master_device_port
)
2854 return kIOReturnNotPrivileged
;
2856 //printf("io_catalog_get_data called. flag: %d\n", flag);
2858 s
= OSSerialize::withCapacity(4096);
2860 return kIOReturnNoMemory
;
2864 kr
= gIOCatalogue
->serializeData(flag
, s
);
2866 if ( kr
== kIOReturnSuccess
) {
2871 size
= s
->getLength();
2872 kr
= vm_allocate(kernel_map
, &data
, size
, true);
2873 if ( kr
== kIOReturnSuccess
) {
2874 bcopy(s
->text(), (void *)data
, size
);
2875 kr
= vm_map_copyin(kernel_map
, data
, size
, true, ©
);
2876 *outData
= (char *)copy
;
2877 *outDataCount
= size
;
2886 /* Routine io_catalog_get_gen_count */
2887 kern_return_t
is_io_catalog_get_gen_count(
2888 mach_port_t master_port
,
2891 if( master_port
!= master_device_port
)
2892 return kIOReturnNotPrivileged
;
2894 //printf("io_catalog_get_gen_count called.\n");
2897 return kIOReturnBadArgument
;
2899 *genCount
= gIOCatalogue
->getGenerationCount();
2901 return kIOReturnSuccess
;
2904 /* Routine io_catalog_module_loaded */
2905 kern_return_t
is_io_catalog_module_loaded(
2906 mach_port_t master_port
,
2909 if( master_port
!= master_device_port
)
2910 return kIOReturnNotPrivileged
;
2912 //printf("io_catalog_module_loaded called. name %s\n", name);
2915 return kIOReturnBadArgument
;
2917 gIOCatalogue
->moduleHasLoaded(name
);
2919 return kIOReturnSuccess
;
2922 kern_return_t
is_io_catalog_reset(
2923 mach_port_t master_port
,
2926 if( master_port
!= master_device_port
)
2927 return kIOReturnNotPrivileged
;
2930 case kIOCatalogResetDefault
:
2931 gIOCatalogue
->reset();
2935 return kIOReturnBadArgument
;
2938 return kIOReturnSuccess
;
2941 kern_return_t
iokit_user_client_trap(io_object_t userClientRef
, UInt32 index
,
2942 void *p1
, void *p2
, void *p3
,
2943 void *p4
, void *p5
, void *p6
)
2945 kern_return_t result
= kIOReturnBadArgument
;
2946 IOUserClient
*userClient
;
2948 if ((userClient
= OSDynamicCast(IOUserClient
,
2949 iokit_lookup_connect_ref_current_task(userClientRef
)))) {
2950 IOExternalTrap
*trap
;
2951 IOService
*target
= NULL
;
2953 trap
= userClient
->getTargetAndTrapForIndex(&target
, index
);
2955 if (trap
&& target
) {
2961 result
= (target
->*func
)(p1
, p2
, p3
, p4
, p5
, p6
);
2965 userClient
->release();
2973 OSMetaClassDefineReservedUnused(IOUserClient
, 0);
2974 OSMetaClassDefineReservedUnused(IOUserClient
, 1);
2975 OSMetaClassDefineReservedUnused(IOUserClient
, 2);
2976 OSMetaClassDefineReservedUnused(IOUserClient
, 3);
2977 OSMetaClassDefineReservedUnused(IOUserClient
, 4);
2978 OSMetaClassDefineReservedUnused(IOUserClient
, 5);
2979 OSMetaClassDefineReservedUnused(IOUserClient
, 6);
2980 OSMetaClassDefineReservedUnused(IOUserClient
, 7);
2981 OSMetaClassDefineReservedUnused(IOUserClient
, 8);
2982 OSMetaClassDefineReservedUnused(IOUserClient
, 9);
2983 OSMetaClassDefineReservedUnused(IOUserClient
, 10);
2984 OSMetaClassDefineReservedUnused(IOUserClient
, 11);
2985 OSMetaClassDefineReservedUnused(IOUserClient
, 12);
2986 OSMetaClassDefineReservedUnused(IOUserClient
, 13);
2987 OSMetaClassDefineReservedUnused(IOUserClient
, 14);
2988 OSMetaClassDefineReservedUnused(IOUserClient
, 15);