2 * Copyright (c) 1998-2008 Apple 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 <libkern/c++/OSKext.h>
31 #include <IOKit/IOKitServer.h>
32 #include <IOKit/IOKitKeysPrivate.h>
33 #include <IOKit/IOUserClient.h>
34 #include <IOKit/IOService.h>
35 #include <IOKit/IORegistryEntry.h>
36 #include <IOKit/IOCatalogue.h>
37 #include <IOKit/IOMemoryDescriptor.h>
38 #include <IOKit/IOBufferMemoryDescriptor.h>
39 #include <IOKit/IOLib.h>
40 #include <IOKit/IOStatisticsPrivate.h>
41 #include <IOKit/IOTimeStamp.h>
42 #include <libkern/OSDebug.h>
44 #include <sys/kauth.h>
49 #include <security/mac_framework.h>
51 #include <sys/kauth.h>
55 #endif /* CONFIG_MACF */
57 #include <IOKit/assert.h>
59 #include "IOServicePrivate.h"
60 #include "IOKitKernelInternal.h"
62 #define SCALAR64(x) ((io_user_scalar_t)((unsigned int)x))
63 #define SCALAR32(x) ((uint32_t )x)
64 #define ARG32(x) ((void *)SCALAR32(x))
65 #define REF64(x) ((io_user_reference_t)((UInt64)(x)))
66 #define REF32(x) ((int)(x))
70 kIOUCAsync0Flags
= 3ULL,
71 kIOUCAsync64Flag
= 1ULL
76 #define IOStatisticsRegisterCounter() \
78 reserved->counter = IOStatistics::registerUserClient(this); \
81 #define IOStatisticsUnregisterCounter() \
84 IOStatistics::unregisterUserClient(reserved->counter); \
87 #define IOStatisticsClientCall() \
89 IOStatistics::countUserClientCall(client); \
94 #define IOStatisticsRegisterCounter()
95 #define IOStatisticsUnregisterCounter()
96 #define IOStatisticsClientCall()
98 #endif /* IOKITSTATS */
100 /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
102 // definitions we should get from osfmk
104 //typedef struct ipc_port * ipc_port_t;
105 typedef natural_t ipc_kobject_type_t
;
107 #define IKOT_IOKIT_SPARE 27
108 #define IKOT_IOKIT_CONNECT 29
109 #define IKOT_IOKIT_OBJECT 30
113 extern ipc_port_t
iokit_alloc_object_port( io_object_t obj
,
114 ipc_kobject_type_t type
);
116 extern kern_return_t
iokit_destroy_object_port( ipc_port_t port
);
118 extern mach_port_name_t
iokit_make_send_right( task_t task
,
119 io_object_t obj
, ipc_kobject_type_t type
);
121 extern kern_return_t
iokit_mod_send_right( task_t task
, mach_port_name_t name
, mach_port_delta_t delta
);
123 extern io_object_t
iokit_lookup_connect_ref(io_object_t clientRef
, ipc_space_t task
);
125 extern io_object_t
iokit_lookup_connect_ref_current_task(io_object_t clientRef
);
127 extern ipc_port_t master_device_port
;
129 extern void iokit_retain_port( ipc_port_t port
);
130 extern void iokit_release_port( ipc_port_t port
);
131 extern void iokit_release_port_send( ipc_port_t port
);
133 extern kern_return_t
iokit_switch_object_port( ipc_port_t port
, io_object_t obj
, ipc_kobject_type_t type
);
135 #include <mach/mach_traps.h>
136 #include <vm/vm_map.h>
141 /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
143 // IOMachPort maps OSObjects to ports, avoiding adding an ivar to OSObject.
145 class IOMachPort
: public OSObject
147 OSDeclareDefaultStructors(IOMachPort
)
154 static IOMachPort
* portForObject( OSObject
* obj
,
155 ipc_kobject_type_t type
);
156 static bool noMoreSendersForObject( OSObject
* obj
,
157 ipc_kobject_type_t type
, mach_port_mscount_t
* mscount
);
158 static void releasePortForObject( OSObject
* obj
,
159 ipc_kobject_type_t type
);
160 static void setHoldDestroy( OSObject
* obj
, ipc_kobject_type_t type
);
162 static OSDictionary
* dictForType( ipc_kobject_type_t type
);
164 static mach_port_name_t
makeSendRightForTask( task_t task
,
165 io_object_t obj
, ipc_kobject_type_t type
);
170 #define super OSObject
171 OSDefineMetaClassAndStructors(IOMachPort
, OSObject
)
173 static IOLock
* gIOObjectPortLock
;
175 /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
177 // not in dictForType() for debugging ease
178 static OSDictionary
* gIOObjectPorts
;
179 static OSDictionary
* gIOConnectPorts
;
181 OSDictionary
* IOMachPort::dictForType( ipc_kobject_type_t type
)
183 OSDictionary
** dict
;
185 if( IKOT_IOKIT_OBJECT
== type
)
186 dict
= &gIOObjectPorts
;
187 else if( IKOT_IOKIT_CONNECT
== type
)
188 dict
= &gIOConnectPorts
;
193 *dict
= OSDictionary::withCapacity( 1 );
198 IOMachPort
* IOMachPort::portForObject ( OSObject
* obj
,
199 ipc_kobject_type_t type
)
201 IOMachPort
* inst
= 0;
204 IOTakeLock( gIOObjectPortLock
);
208 dict
= dictForType( type
);
212 if( (inst
= (IOMachPort
*)
213 dict
->getObject( (const OSSymbol
*) obj
))) {
219 inst
= new IOMachPort
;
220 if( inst
&& !inst
->init()) {
225 inst
->port
= iokit_alloc_object_port( obj
, type
);
228 dict
->setObject( (const OSSymbol
*) obj
, inst
);
238 IOUnlock( gIOObjectPortLock
);
243 bool IOMachPort::noMoreSendersForObject( OSObject
* obj
,
244 ipc_kobject_type_t type
, mach_port_mscount_t
* mscount
)
247 IOMachPort
* machPort
;
248 bool destroyed
= true;
250 IOTakeLock( gIOObjectPortLock
);
252 if( (dict
= dictForType( type
))) {
255 machPort
= (IOMachPort
*) dict
->getObject( (const OSSymbol
*) obj
);
257 destroyed
= (machPort
->mscount
<= *mscount
);
259 dict
->removeObject( (const OSSymbol
*) obj
);
261 *mscount
= machPort
->mscount
;
266 IOUnlock( gIOObjectPortLock
);
271 void IOMachPort::releasePortForObject( OSObject
* obj
,
272 ipc_kobject_type_t type
)
275 IOMachPort
* machPort
;
277 IOTakeLock( gIOObjectPortLock
);
279 if( (dict
= dictForType( type
))) {
281 machPort
= (IOMachPort
*) dict
->getObject( (const OSSymbol
*) obj
);
282 if( machPort
&& !machPort
->holdDestroy
)
283 dict
->removeObject( (const OSSymbol
*) obj
);
287 IOUnlock( gIOObjectPortLock
);
290 void IOMachPort::setHoldDestroy( OSObject
* obj
, ipc_kobject_type_t type
)
293 IOMachPort
* machPort
;
295 IOLockLock( gIOObjectPortLock
);
297 if( (dict
= dictForType( type
))) {
298 machPort
= (IOMachPort
*) dict
->getObject( (const OSSymbol
*) obj
);
300 machPort
->holdDestroy
= true;
303 IOLockUnlock( gIOObjectPortLock
);
306 void IOUserClient::destroyUserReferences( OSObject
* obj
)
308 IOMachPort::releasePortForObject( obj
, IKOT_IOKIT_OBJECT
);
311 // IOMachPort::releasePortForObject( obj, IKOT_IOKIT_CONNECT );
315 IOTakeLock( gIOObjectPortLock
);
318 if( (dict
= IOMachPort::dictForType( IKOT_IOKIT_CONNECT
)))
321 port
= (IOMachPort
*) dict
->getObject( (const OSSymbol
*) obj
);
325 if ((uc
= OSDynamicCast(IOUserClient
, obj
)) && uc
->mappings
)
327 dict
->setObject((const OSSymbol
*) uc
->mappings
, port
);
328 iokit_switch_object_port(port
->port
, uc
->mappings
, IKOT_IOKIT_CONNECT
);
330 uc
->mappings
->release();
333 dict
->removeObject( (const OSSymbol
*) obj
);
337 IOUnlock( gIOObjectPortLock
);
340 mach_port_name_t
IOMachPort::makeSendRightForTask( task_t task
,
341 io_object_t obj
, ipc_kobject_type_t type
)
343 return( iokit_make_send_right( task
, obj
, type
));
346 void IOMachPort::free( void )
349 iokit_destroy_object_port( port
);
353 /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
355 class IOUserNotification
: public OSIterator
357 OSDeclareDefaultStructors(IOUserNotification
)
359 IONotifier
* holdNotify
;
364 virtual bool init( void );
367 virtual void setNotification( IONotifier
* obj
);
369 virtual void reset();
370 virtual bool isValid();
373 /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
377 // functions called from osfmk/device/iokit_rpc.c
380 iokit_add_reference( io_object_t obj
)
387 iokit_remove_reference( io_object_t obj
)
394 iokit_port_for_object( io_object_t obj
, ipc_kobject_type_t type
)
396 IOMachPort
* machPort
;
399 if( (machPort
= IOMachPort::portForObject( obj
, type
))) {
401 port
= machPort
->port
;
403 iokit_retain_port( port
);
414 iokit_client_died( io_object_t obj
, ipc_port_t
/* port */,
415 ipc_kobject_type_t type
, mach_port_mscount_t
* mscount
)
417 IOUserClient
* client
;
419 IOUserNotification
* notify
;
421 if( !IOMachPort::noMoreSendersForObject( obj
, type
, mscount
))
422 return( kIOReturnNotReady
);
424 if( IKOT_IOKIT_CONNECT
== type
)
426 if( (client
= OSDynamicCast( IOUserClient
, obj
))) {
427 IOStatisticsClientCall();
428 client
->clientDied();
431 else if( IKOT_IOKIT_OBJECT
== type
)
433 if( (map
= OSDynamicCast( IOMemoryMap
, obj
)))
435 else if( (notify
= OSDynamicCast( IOUserNotification
, obj
)))
436 notify
->setNotification( 0 );
439 return( kIOReturnSuccess
);
444 /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
446 class IOServiceUserNotification
: public IOUserNotification
448 OSDeclareDefaultStructors(IOServiceUserNotification
)
451 mach_msg_header_t msgHdr
;
452 OSNotificationHeader64 notifyHeader
;
455 enum { kMaxOutstanding
= 1024 };
460 OSObject
* lastEntry
;
465 virtual bool init( mach_port_t port
, natural_t type
,
466 void * reference
, vm_size_t referenceSize
,
470 static bool _handler( void * target
,
471 void * ref
, IOService
* newService
, IONotifier
* notifier
);
472 virtual bool handler( void * ref
, IOService
* newService
);
474 virtual OSObject
* getNextObject();
477 class IOServiceMessageUserNotification
: public IOUserNotification
479 OSDeclareDefaultStructors(IOServiceMessageUserNotification
)
482 mach_msg_header_t msgHdr
;
483 mach_msg_body_t msgBody
;
484 mach_msg_port_descriptor_t ports
[1];
485 OSNotificationHeader64 notifyHeader
__attribute__ ((packed
));
495 virtual bool init( mach_port_t port
, natural_t type
,
496 void * reference
, vm_size_t referenceSize
,
502 static IOReturn
_handler( void * target
, void * ref
,
503 UInt32 messageType
, IOService
* provider
,
504 void * messageArgument
, vm_size_t argSize
);
505 virtual IOReturn
handler( void * ref
,
506 UInt32 messageType
, IOService
* provider
,
507 void * messageArgument
, vm_size_t argSize
);
509 virtual OSObject
* getNextObject();
512 /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
515 #define super OSIterator
516 OSDefineMetaClass( IOUserNotification
, OSIterator
)
517 OSDefineAbstractStructors( IOUserNotification
, OSIterator
)
519 /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
521 bool IOUserNotification::init( void )
526 lock
= IOLockAlloc();
533 void IOUserNotification::free( void )
536 holdNotify
->remove();
537 // can't be in handler now
546 void IOUserNotification::setNotification( IONotifier
* notify
)
548 IONotifier
* previousNotify
;
550 IOLockLock( gIOObjectPortLock
);
552 previousNotify
= holdNotify
;
555 IOLockUnlock( gIOObjectPortLock
);
558 previousNotify
->remove();
561 void IOUserNotification::reset()
566 bool IOUserNotification::isValid()
571 /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
574 #define super IOUserNotification
575 OSDefineMetaClassAndStructors(IOServiceUserNotification
, IOUserNotification
)
577 /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
579 bool IOServiceUserNotification::init( mach_port_t port
, natural_t type
,
580 void * reference
, vm_size_t referenceSize
,
583 newSet
= OSArray::withCapacity( 1 );
587 if (referenceSize
> sizeof(OSAsyncReference64
))
590 msgSize
= sizeof(PingMsg
) - sizeof(OSAsyncReference64
) + referenceSize
;
591 pingMsg
= (PingMsg
*) IOMalloc( msgSize
);
595 bzero( pingMsg
, msgSize
);
597 pingMsg
->msgHdr
.msgh_remote_port
= port
;
598 pingMsg
->msgHdr
.msgh_bits
= MACH_MSGH_BITS(
599 MACH_MSG_TYPE_COPY_SEND
/*remote*/,
600 MACH_MSG_TYPE_MAKE_SEND
/*local*/);
601 pingMsg
->msgHdr
.msgh_size
= msgSize
;
602 pingMsg
->msgHdr
.msgh_id
= kOSNotificationMessageID
;
604 pingMsg
->notifyHeader
.size
= 0;
605 pingMsg
->notifyHeader
.type
= type
;
606 bcopy( reference
, pingMsg
->notifyHeader
.reference
, referenceSize
);
608 return( super::init() );
611 void IOServiceUserNotification::free( void )
616 OSObject
* _lastEntry
;
620 _lastEntry
= lastEntry
;
625 if( _pingMsg
&& _msgSize
)
626 IOFree( _pingMsg
, _msgSize
);
629 _lastEntry
->release();
635 bool IOServiceUserNotification::_handler( void * target
,
636 void * ref
, IOService
* newService
, IONotifier
* notifier
)
638 return( ((IOServiceUserNotification
*) target
)->handler( ref
, newService
));
641 bool IOServiceUserNotification::handler( void * ref
,
642 IOService
* newService
)
646 ipc_port_t port
= NULL
;
647 bool sendPing
= false;
651 count
= newSet
->getCount();
652 if( count
< kMaxOutstanding
) {
654 newSet
->setObject( newService
);
655 if( (sendPing
= (armed
&& (0 == count
))))
661 if( kIOServiceTerminatedNotificationType
== pingMsg
->notifyHeader
.type
)
662 IOMachPort::setHoldDestroy( newService
, IKOT_IOKIT_OBJECT
);
665 if( (port
= iokit_port_for_object( this, IKOT_IOKIT_OBJECT
) ))
666 pingMsg
->msgHdr
.msgh_local_port
= port
;
668 pingMsg
->msgHdr
.msgh_local_port
= NULL
;
670 kr
= mach_msg_send_from_kernel_proper( &pingMsg
->msgHdr
,
671 pingMsg
->msgHdr
.msgh_size
);
673 iokit_release_port( port
);
675 if( KERN_SUCCESS
!= kr
)
676 IOLog("%s: mach_msg_send_from_kernel_proper {%x}\n", __FILE__
, kr
);
682 OSObject
* IOServiceUserNotification::getNextObject()
690 lastEntry
->release();
692 count
= newSet
->getCount();
694 result
= newSet
->getObject( count
- 1 );
696 newSet
->removeObject( count
- 1);
708 /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
710 OSDefineMetaClassAndStructors(IOServiceMessageUserNotification
, IOUserNotification
)
712 /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
714 bool IOServiceMessageUserNotification::init( mach_port_t port
, natural_t type
,
715 void * reference
, vm_size_t referenceSize
, vm_size_t extraSize
,
719 if (referenceSize
> sizeof(OSAsyncReference64
))
722 clientIs64
= client64
;
724 owningPID
= proc_selfpid();
726 extraSize
+= sizeof(IOServiceInterestContent64
);
727 msgSize
= sizeof(PingMsg
) - sizeof(OSAsyncReference64
) + referenceSize
+ extraSize
;
728 pingMsg
= (PingMsg
*) IOMalloc( msgSize
);
732 bzero( pingMsg
, msgSize
);
734 pingMsg
->msgHdr
.msgh_remote_port
= port
;
735 pingMsg
->msgHdr
.msgh_bits
= MACH_MSGH_BITS_COMPLEX
737 MACH_MSG_TYPE_COPY_SEND
/*remote*/,
738 MACH_MSG_TYPE_MAKE_SEND
/*local*/);
739 pingMsg
->msgHdr
.msgh_size
= msgSize
;
740 pingMsg
->msgHdr
.msgh_id
= kOSNotificationMessageID
;
742 pingMsg
->msgBody
.msgh_descriptor_count
= 1;
744 pingMsg
->ports
[0].name
= 0;
745 pingMsg
->ports
[0].disposition
= MACH_MSG_TYPE_MAKE_SEND
;
746 pingMsg
->ports
[0].type
= MACH_MSG_PORT_DESCRIPTOR
;
748 pingMsg
->notifyHeader
.size
= extraSize
;
749 pingMsg
->notifyHeader
.type
= type
;
750 bcopy( reference
, pingMsg
->notifyHeader
.reference
, referenceSize
);
752 return( super::init() );
755 void IOServiceMessageUserNotification::free( void )
765 if( _pingMsg
&& _msgSize
)
766 IOFree( _pingMsg
, _msgSize
);
769 IOReturn
IOServiceMessageUserNotification::_handler( void * target
, void * ref
,
770 UInt32 messageType
, IOService
* provider
,
771 void * argument
, vm_size_t argSize
)
773 return( ((IOServiceMessageUserNotification
*) target
)->handler(
774 ref
, messageType
, provider
, argument
, argSize
));
777 IOReturn
IOServiceMessageUserNotification::handler( void * ref
,
778 UInt32 messageType
, IOService
* provider
,
779 void * messageArgument
, vm_size_t argSize
)
782 ipc_port_t thisPort
, providerPort
;
783 IOServiceInterestContent64
* data
= (IOServiceInterestContent64
*)
784 ((((uint8_t *) pingMsg
) + msgSize
) - pingMsg
->notifyHeader
.size
);
785 // == pingMsg->notifyHeader.content;
787 if (kIOMessageCopyClientID
== messageType
)
789 *((void **) messageArgument
) = IOCopyLogNameForPID(owningPID
);
790 return (kIOReturnSuccess
);
793 data
->messageType
= messageType
;
797 data
->messageArgument
[0] = (io_user_reference_t
) messageArgument
;
799 argSize
= sizeof(data
->messageArgument
[0]);
802 data
->messageArgument
[0] |= (data
->messageArgument
[0] << 32);
803 argSize
= sizeof(uint32_t);
808 if( argSize
> kIOUserNotifyMaxMessageSize
)
809 argSize
= kIOUserNotifyMaxMessageSize
;
810 bcopy( messageArgument
, data
->messageArgument
, argSize
);
812 pingMsg
->msgHdr
.msgh_size
= msgSize
- pingMsg
->notifyHeader
.size
813 + sizeof( IOServiceInterestContent64
)
814 - sizeof( data
->messageArgument
)
817 providerPort
= iokit_port_for_object( provider
, IKOT_IOKIT_OBJECT
);
818 pingMsg
->ports
[0].name
= providerPort
;
819 thisPort
= iokit_port_for_object( this, IKOT_IOKIT_OBJECT
);
820 pingMsg
->msgHdr
.msgh_local_port
= thisPort
;
821 kr
= mach_msg_send_from_kernel_proper( &pingMsg
->msgHdr
,
822 pingMsg
->msgHdr
.msgh_size
);
824 iokit_release_port( thisPort
);
826 iokit_release_port( providerPort
);
828 if( KERN_SUCCESS
!= kr
)
829 IOLog("%s: mach_msg_send_from_kernel_proper {%x}\n", __FILE__
, kr
);
831 return( kIOReturnSuccess
);
834 OSObject
* IOServiceMessageUserNotification::getNextObject()
839 /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
842 #define super IOService
843 OSDefineMetaClassAndAbstractStructors( IOUserClient
, IOService
)
845 void IOUserClient::initialize( void )
847 gIOObjectPortLock
= IOLockAlloc();
849 assert( gIOObjectPortLock
);
852 void IOUserClient::setAsyncReference(OSAsyncReference asyncRef
,
853 mach_port_t wakePort
,
854 void *callback
, void *refcon
)
856 asyncRef
[kIOAsyncReservedIndex
] = ((uintptr_t) wakePort
)
857 | (kIOUCAsync0Flags
& asyncRef
[kIOAsyncReservedIndex
]);
858 asyncRef
[kIOAsyncCalloutFuncIndex
] = (uintptr_t) callback
;
859 asyncRef
[kIOAsyncCalloutRefconIndex
] = (uintptr_t) refcon
;
862 void IOUserClient::setAsyncReference64(OSAsyncReference64 asyncRef
,
863 mach_port_t wakePort
,
864 mach_vm_address_t callback
, io_user_reference_t refcon
)
866 asyncRef
[kIOAsyncReservedIndex
] = ((io_user_reference_t
) wakePort
)
867 | (kIOUCAsync0Flags
& asyncRef
[kIOAsyncReservedIndex
]);
868 asyncRef
[kIOAsyncCalloutFuncIndex
] = (io_user_reference_t
) callback
;
869 asyncRef
[kIOAsyncCalloutRefconIndex
] = refcon
;
872 static OSDictionary
* CopyConsoleUser(UInt32 uid
)
875 OSDictionary
* user
= 0;
877 if ((array
= OSDynamicCast(OSArray
,
878 IORegistryEntry::getRegistryRoot()->copyProperty(gIOConsoleUsersKey
))))
880 for (unsigned int idx
= 0;
881 (user
= OSDynamicCast(OSDictionary
, array
->getObject(idx
)));
885 if ((num
= OSDynamicCast(OSNumber
, user
->getObject(gIOConsoleSessionUIDKey
)))
886 && (uid
== num
->unsigned32BitValue())) {
896 static OSDictionary
* CopyUserOnConsole(void)
899 OSDictionary
* user
= 0;
901 if ((array
= OSDynamicCast(OSArray
,
902 IORegistryEntry::getRegistryRoot()->copyProperty(gIOConsoleUsersKey
))))
904 for (unsigned int idx
= 0;
905 (user
= OSDynamicCast(OSDictionary
, array
->getObject(idx
)));
908 if (kOSBooleanTrue
== user
->getObject(gIOConsoleSessionOnConsoleKey
))
919 IOReturn
IOUserClient::clientHasPrivilege( void * securityToken
,
920 const char * privilegeName
)
923 security_token_t token
;
924 mach_msg_type_number_t count
;
930 if (!strncmp(privilegeName
, kIOClientPrivilegeForeground
,
931 sizeof(kIOClientPrivilegeForeground
)))
933 /* is graphics access denied for current task? */
934 if (proc_get_task_selfgpuacc_deny() != 0)
935 return (kIOReturnNotPrivileged
);
937 return (kIOReturnSuccess
);
940 if (!strncmp(privilegeName
, kIOClientPrivilegeConsoleSession
,
941 sizeof(kIOClientPrivilegeConsoleSession
)))
946 task
= (task_t
) securityToken
;
948 task
= current_task();
949 p
= (proc_t
) get_bsdtask_info(task
);
950 kr
= kIOReturnNotPrivileged
;
952 if (p
&& (cred
= kauth_cred_proc_ref(p
)))
954 user
= CopyUserOnConsole();
958 if ((num
= OSDynamicCast(OSNumber
, user
->getObject(gIOConsoleSessionAuditIDKey
)))
959 && (cred
->cr_audit
.as_aia_p
->ai_asid
== (au_asid_t
) num
->unsigned32BitValue()))
961 kr
= kIOReturnSuccess
;
965 kauth_cred_unref(&cred
);
970 if ((secureConsole
= !strncmp(privilegeName
, kIOClientPrivilegeSecureConsoleProcess
,
971 sizeof(kIOClientPrivilegeSecureConsoleProcess
))))
972 task
= (task_t
)((IOUCProcessToken
*)securityToken
)->token
;
974 task
= (task_t
)securityToken
;
976 count
= TASK_SECURITY_TOKEN_COUNT
;
977 kr
= task_info( task
, TASK_SECURITY_TOKEN
, (task_info_t
) &token
, &count
);
979 if (KERN_SUCCESS
!= kr
)
981 else if (!strncmp(privilegeName
, kIOClientPrivilegeAdministrator
,
982 sizeof(kIOClientPrivilegeAdministrator
))) {
983 if (0 != token
.val
[0])
984 kr
= kIOReturnNotPrivileged
;
985 } else if (!strncmp(privilegeName
, kIOClientPrivilegeLocalUser
,
986 sizeof(kIOClientPrivilegeLocalUser
))) {
987 user
= CopyConsoleUser(token
.val
[0]);
991 kr
= kIOReturnNotPrivileged
;
992 } else if (secureConsole
|| !strncmp(privilegeName
, kIOClientPrivilegeConsoleUser
,
993 sizeof(kIOClientPrivilegeConsoleUser
))) {
994 user
= CopyConsoleUser(token
.val
[0]);
996 if (user
->getObject(gIOConsoleSessionOnConsoleKey
) != kOSBooleanTrue
)
997 kr
= kIOReturnNotPrivileged
;
998 else if ( secureConsole
) {
999 OSNumber
* pid
= OSDynamicCast(OSNumber
, user
->getObject(gIOConsoleSessionSecureInputPIDKey
));
1000 if ( pid
&& pid
->unsigned32BitValue() != ((IOUCProcessToken
*)securityToken
)->pid
)
1001 kr
= kIOReturnNotPrivileged
;
1006 kr
= kIOReturnNotPrivileged
;
1008 kr
= kIOReturnUnsupported
;
1013 bool IOUserClient::init()
1015 if (getPropertyTable() || super::init())
1021 bool IOUserClient::init(OSDictionary
* dictionary
)
1023 if (getPropertyTable() || super::init(dictionary
))
1029 bool IOUserClient::initWithTask(task_t owningTask
,
1033 if (getPropertyTable() || super::init())
1039 bool IOUserClient::initWithTask(task_t owningTask
,
1042 OSDictionary
* properties
)
1046 ok
= super::init( properties
);
1047 ok
&= initWithTask( owningTask
, securityID
, type
);
1052 bool IOUserClient::reserve()
1055 reserved
= IONew(ExpansionData
, 1);
1061 IOStatisticsRegisterCounter();
1066 void IOUserClient::free()
1069 mappings
->release();
1071 IOStatisticsUnregisterCounter();
1074 IODelete(reserved
, ExpansionData
, 1);
1079 IOReturn
IOUserClient::clientDied( void )
1081 return( clientClose());
1084 IOReturn
IOUserClient::clientClose( void )
1086 return( kIOReturnUnsupported
);
1089 IOService
* IOUserClient::getService( void )
1094 IOReturn
IOUserClient::registerNotificationPort(
1095 mach_port_t
/* port */,
1097 UInt32
/* refCon */)
1099 return( kIOReturnUnsupported
);
1102 IOReturn
IOUserClient::registerNotificationPort(
1105 io_user_reference_t refCon
)
1107 return (registerNotificationPort(port
, type
, (UInt32
) refCon
));
1110 IOReturn
IOUserClient::getNotificationSemaphore( UInt32 notification_type
,
1111 semaphore_t
* semaphore
)
1113 return( kIOReturnUnsupported
);
1116 IOReturn
IOUserClient::connectClient( IOUserClient
* /* client */ )
1118 return( kIOReturnUnsupported
);
1121 IOReturn
IOUserClient::clientMemoryForType( UInt32 type
,
1122 IOOptionBits
* options
,
1123 IOMemoryDescriptor
** memory
)
1125 return( kIOReturnUnsupported
);
1129 IOMemoryMap
* IOUserClient::mapClientMemory(
1132 IOOptionBits mapFlags
,
1133 IOVirtualAddress atAddress
)
1139 IOMemoryMap
* IOUserClient::mapClientMemory64(
1142 IOOptionBits mapFlags
,
1143 mach_vm_address_t atAddress
)
1146 IOOptionBits options
= 0;
1147 IOMemoryDescriptor
* memory
;
1148 IOMemoryMap
* map
= 0;
1150 err
= clientMemoryForType( (UInt32
) type
, &options
, &memory
);
1152 if( memory
&& (kIOReturnSuccess
== err
)) {
1154 options
= (options
& ~kIOMapUserOptionsMask
)
1155 | (mapFlags
& kIOMapUserOptionsMask
);
1156 map
= memory
->createMappingInTask( task
, atAddress
, options
);
1163 IOReturn
IOUserClient::exportObjectToClient(task_t task
,
1164 OSObject
*obj
, io_object_t
*clientObj
)
1166 mach_port_name_t name
;
1168 name
= IOMachPort::makeSendRightForTask( task
, obj
, IKOT_IOKIT_OBJECT
);
1171 *(mach_port_name_t
*)clientObj
= name
;
1172 return kIOReturnSuccess
;
1175 IOExternalMethod
* IOUserClient::getExternalMethodForIndex( UInt32
/* index */)
1180 IOExternalAsyncMethod
* IOUserClient::getExternalAsyncMethodForIndex( UInt32
/* index */)
1185 IOExternalMethod
* IOUserClient::
1186 getTargetAndMethodForIndex(IOService
**targetP
, UInt32 index
)
1188 IOExternalMethod
*method
= getExternalMethodForIndex(index
);
1191 *targetP
= (IOService
*) method
->object
;
1196 IOExternalAsyncMethod
* IOUserClient::
1197 getAsyncTargetAndMethodForIndex(IOService
** targetP
, UInt32 index
)
1199 IOExternalAsyncMethod
*method
= getExternalAsyncMethodForIndex(index
);
1202 *targetP
= (IOService
*) method
->object
;
1207 IOExternalTrap
* IOUserClient::
1208 getExternalTrapForIndex(UInt32 index
)
1213 IOExternalTrap
* IOUserClient::
1214 getTargetAndTrapForIndex(IOService
** targetP
, UInt32 index
)
1216 IOExternalTrap
*trap
= getExternalTrapForIndex(index
);
1219 *targetP
= trap
->object
;
1225 IOReturn
IOUserClient::releaseAsyncReference64(OSAsyncReference64 reference
)
1228 port
= (mach_port_t
) (reference
[0] & ~kIOUCAsync0Flags
);
1230 if (MACH_PORT_NULL
!= port
)
1231 iokit_release_port_send(port
);
1233 return (kIOReturnSuccess
);
1236 IOReturn
IOUserClient::releaseNotificationPort(mach_port_t port
)
1238 if (MACH_PORT_NULL
!= port
)
1239 iokit_release_port_send(port
);
1241 return (kIOReturnSuccess
);
1244 IOReturn
IOUserClient::sendAsyncResult(OSAsyncReference reference
,
1245 IOReturn result
, void *args
[], UInt32 numArgs
)
1247 OSAsyncReference64 reference64
;
1248 io_user_reference_t args64
[kMaxAsyncArgs
];
1251 if (numArgs
> kMaxAsyncArgs
)
1252 return kIOReturnMessageTooLarge
;
1254 for (idx
= 0; idx
< kOSAsyncRef64Count
; idx
++)
1255 reference64
[idx
] = REF64(reference
[idx
]);
1257 for (idx
= 0; idx
< numArgs
; idx
++)
1258 args64
[idx
] = REF64(args
[idx
]);
1260 return (sendAsyncResult64(reference64
, result
, args64
, numArgs
));
1263 IOReturn
IOUserClient::sendAsyncResult64(OSAsyncReference64 reference
,
1264 IOReturn result
, io_user_reference_t args
[], UInt32 numArgs
)
1268 mach_msg_header_t msgHdr
;
1273 OSNotificationHeader notifyHdr
;
1274 IOAsyncCompletionContent asyncContent
;
1275 uint32_t args
[kMaxAsyncArgs
];
1279 OSNotificationHeader64 notifyHdr
;
1280 IOAsyncCompletionContent asyncContent
;
1281 io_user_reference_t args
[kMaxAsyncArgs
] __attribute__ ((packed
));
1286 mach_port_t replyPort
;
1289 // If no reply port, do nothing.
1290 replyPort
= (mach_port_t
) (reference
[0] & ~kIOUCAsync0Flags
);
1291 if (replyPort
== MACH_PORT_NULL
)
1292 return kIOReturnSuccess
;
1294 if (numArgs
> kMaxAsyncArgs
)
1295 return kIOReturnMessageTooLarge
;
1297 replyMsg
.msgHdr
.msgh_bits
= MACH_MSGH_BITS(MACH_MSG_TYPE_COPY_SEND
/*remote*/,
1299 replyMsg
.msgHdr
.msgh_remote_port
= replyPort
;
1300 replyMsg
.msgHdr
.msgh_local_port
= 0;
1301 replyMsg
.msgHdr
.msgh_id
= kOSNotificationMessageID
;
1302 if (kIOUCAsync64Flag
& reference
[0])
1304 replyMsg
.msgHdr
.msgh_size
=
1305 sizeof(replyMsg
.msgHdr
) + sizeof(replyMsg
.m
.msg64
)
1306 - (kMaxAsyncArgs
- numArgs
) * sizeof(io_user_reference_t
);
1307 replyMsg
.m
.msg64
.notifyHdr
.size
= sizeof(IOAsyncCompletionContent
)
1308 + numArgs
* sizeof(io_user_reference_t
);
1309 replyMsg
.m
.msg64
.notifyHdr
.type
= kIOAsyncCompletionNotificationType
;
1310 bcopy(reference
, replyMsg
.m
.msg64
.notifyHdr
.reference
, sizeof(OSAsyncReference64
));
1312 replyMsg
.m
.msg64
.asyncContent
.result
= result
;
1314 bcopy(args
, replyMsg
.m
.msg64
.args
, numArgs
* sizeof(io_user_reference_t
));
1320 replyMsg
.msgHdr
.msgh_size
=
1321 sizeof(replyMsg
.msgHdr
) + sizeof(replyMsg
.m
.msg32
)
1322 - (kMaxAsyncArgs
- numArgs
) * sizeof(uint32_t);
1324 replyMsg
.m
.msg32
.notifyHdr
.size
= sizeof(IOAsyncCompletionContent
)
1325 + numArgs
* sizeof(uint32_t);
1326 replyMsg
.m
.msg32
.notifyHdr
.type
= kIOAsyncCompletionNotificationType
;
1328 for (idx
= 0; idx
< kOSAsyncRefCount
; idx
++)
1329 replyMsg
.m
.msg32
.notifyHdr
.reference
[idx
] = REF32(reference
[idx
]);
1331 replyMsg
.m
.msg32
.asyncContent
.result
= result
;
1333 for (idx
= 0; idx
< numArgs
; idx
++)
1334 replyMsg
.m
.msg32
.args
[idx
] = REF32(args
[idx
]);
1337 kr
= mach_msg_send_from_kernel_proper( &replyMsg
.msgHdr
,
1338 replyMsg
.msgHdr
.msgh_size
);
1339 if( KERN_SUCCESS
!= kr
)
1340 IOLog("%s: mach_msg_send_from_kernel_proper {%x}\n", __FILE__
, kr
);
1345 /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
1349 #define CHECK(cls,obj,out) \
1351 if( !(out = OSDynamicCast( cls, obj))) \
1352 return( kIOReturnBadArgument )
1354 /* Routine io_object_get_class */
1355 kern_return_t
is_io_object_get_class(
1357 io_name_t className
)
1359 const OSMetaClass
* my_obj
= NULL
;
1362 return( kIOReturnBadArgument
);
1364 my_obj
= object
->getMetaClass();
1366 return (kIOReturnNotFound
);
1369 strlcpy( className
, my_obj
->getClassName(), sizeof(io_name_t
));
1370 return( kIOReturnSuccess
);
1373 /* Routine io_object_get_superclass */
1374 kern_return_t
is_io_object_get_superclass(
1375 mach_port_t master_port
,
1377 io_name_t class_name
)
1379 const OSMetaClass
* my_obj
= NULL
;
1380 const OSMetaClass
* superclass
= NULL
;
1381 const OSSymbol
*my_name
= NULL
;
1382 const char *my_cstr
= NULL
;
1384 if (!obj_name
|| !class_name
)
1385 return (kIOReturnBadArgument
);
1387 if( master_port
!= master_device_port
)
1388 return( kIOReturnNotPrivileged
);
1390 my_name
= OSSymbol::withCString(obj_name
);
1393 my_obj
= OSMetaClass::getMetaClassWithName(my_name
);
1397 superclass
= my_obj
->getSuperClass();
1401 return( kIOReturnNotFound
);
1404 my_cstr
= superclass
->getClassName();
1407 strlcpy(class_name
, my_cstr
, sizeof(io_name_t
));
1408 return( kIOReturnSuccess
);
1410 return (kIOReturnNotFound
);
1413 /* Routine io_object_get_bundle_identifier */
1414 kern_return_t
is_io_object_get_bundle_identifier(
1415 mach_port_t master_port
,
1417 io_name_t bundle_name
)
1419 const OSMetaClass
* my_obj
= NULL
;
1420 const OSSymbol
*my_name
= NULL
;
1421 const OSSymbol
*identifier
= NULL
;
1422 const char *my_cstr
= NULL
;
1424 if (!obj_name
|| !bundle_name
)
1425 return (kIOReturnBadArgument
);
1427 if( master_port
!= master_device_port
)
1428 return( kIOReturnNotPrivileged
);
1430 my_name
= OSSymbol::withCString(obj_name
);
1433 my_obj
= OSMetaClass::getMetaClassWithName(my_name
);
1438 identifier
= my_obj
->getKmodName();
1441 return( kIOReturnNotFound
);
1444 my_cstr
= identifier
->getCStringNoCopy();
1446 strlcpy(bundle_name
, identifier
->getCStringNoCopy(), sizeof(io_name_t
));
1447 return( kIOReturnSuccess
);
1450 return (kIOReturnBadArgument
);
1453 /* Routine io_object_conforms_to */
1454 kern_return_t
is_io_object_conforms_to(
1456 io_name_t className
,
1457 boolean_t
*conforms
)
1460 return( kIOReturnBadArgument
);
1462 *conforms
= (0 != object
->metaCast( className
));
1463 return( kIOReturnSuccess
);
1466 /* Routine io_object_get_retain_count */
1467 kern_return_t
is_io_object_get_retain_count(
1469 uint32_t *retainCount
)
1472 return( kIOReturnBadArgument
);
1474 *retainCount
= object
->getRetainCount();
1475 return( kIOReturnSuccess
);
1478 /* Routine io_iterator_next */
1479 kern_return_t
is_io_iterator_next(
1480 io_object_t iterator
,
1481 io_object_t
*object
)
1485 CHECK( OSIterator
, iterator
, iter
);
1487 obj
= iter
->getNextObject();
1491 return( kIOReturnSuccess
);
1493 return( kIOReturnNoDevice
);
1496 /* Routine io_iterator_reset */
1497 kern_return_t
is_io_iterator_reset(
1498 io_object_t iterator
)
1500 CHECK( OSIterator
, iterator
, iter
);
1504 return( kIOReturnSuccess
);
1507 /* Routine io_iterator_is_valid */
1508 kern_return_t
is_io_iterator_is_valid(
1509 io_object_t iterator
,
1510 boolean_t
*is_valid
)
1512 CHECK( OSIterator
, iterator
, iter
);
1514 *is_valid
= iter
->isValid();
1516 return( kIOReturnSuccess
);
1519 /* Routine io_service_match_property_table */
1520 kern_return_t
is_io_service_match_property_table(
1521 io_service_t _service
,
1522 io_string_t matching
,
1523 boolean_t
*matches
)
1525 CHECK( IOService
, _service
, service
);
1529 OSDictionary
* dict
;
1531 obj
= OSUnserializeXML( matching
);
1533 if( (dict
= OSDynamicCast( OSDictionary
, obj
))) {
1534 *matches
= service
->passiveMatch( dict
);
1535 kr
= kIOReturnSuccess
;
1537 kr
= kIOReturnBadArgument
;
1545 /* Routine io_service_match_property_table_ool */
1546 kern_return_t
is_io_service_match_property_table_ool(
1547 io_object_t service
,
1548 io_buf_ptr_t matching
,
1549 mach_msg_type_number_t matchingCnt
,
1550 kern_return_t
*result
,
1551 boolean_t
*matches
)
1555 vm_map_offset_t map_data
;
1557 kr
= vm_map_copyout( kernel_map
, &map_data
, (vm_map_copy_t
) matching
);
1558 data
= CAST_DOWN(vm_offset_t
, map_data
);
1560 if( KERN_SUCCESS
== kr
) {
1561 // must return success after vm_map_copyout() succeeds
1562 *result
= is_io_service_match_property_table( service
,
1563 (char *) data
, matches
);
1564 vm_deallocate( kernel_map
, data
, matchingCnt
);
1570 /* Routine io_service_get_matching_services */
1571 kern_return_t
is_io_service_get_matching_services(
1572 mach_port_t master_port
,
1573 io_string_t matching
,
1574 io_iterator_t
*existing
)
1578 OSDictionary
* dict
;
1580 if( master_port
!= master_device_port
)
1581 return( kIOReturnNotPrivileged
);
1583 obj
= OSUnserializeXML( matching
);
1585 if( (dict
= OSDynamicCast( OSDictionary
, obj
))) {
1586 *existing
= IOService::getMatchingServices( dict
);
1587 kr
= kIOReturnSuccess
;
1589 kr
= kIOReturnBadArgument
;
1597 /* Routine io_service_get_matching_services_ool */
1598 kern_return_t
is_io_service_get_matching_services_ool(
1599 mach_port_t master_port
,
1600 io_buf_ptr_t matching
,
1601 mach_msg_type_number_t matchingCnt
,
1602 kern_return_t
*result
,
1603 io_object_t
*existing
)
1607 vm_map_offset_t map_data
;
1609 kr
= vm_map_copyout( kernel_map
, &map_data
, (vm_map_copy_t
) matching
);
1610 data
= CAST_DOWN(vm_offset_t
, map_data
);
1612 if( KERN_SUCCESS
== kr
) {
1613 // must return success after vm_map_copyout() succeeds
1614 *result
= is_io_service_get_matching_services( master_port
,
1615 (char *) data
, existing
);
1616 vm_deallocate( kernel_map
, data
, matchingCnt
);
1622 static kern_return_t
internal_io_service_add_notification(
1623 mach_port_t master_port
,
1624 io_name_t notification_type
,
1625 io_string_t matching
,
1628 vm_size_t referenceSize
,
1630 io_object_t
* notification
)
1632 IOServiceUserNotification
* userNotify
= 0;
1633 IONotifier
* notify
= 0;
1634 const OSSymbol
* sym
;
1635 OSDictionary
* dict
;
1637 unsigned long int userMsgType
;
1640 if( master_port
!= master_device_port
)
1641 return( kIOReturnNotPrivileged
);
1644 err
= kIOReturnNoResources
;
1646 if( !(sym
= OSSymbol::withCString( notification_type
)))
1647 err
= kIOReturnNoResources
;
1649 if( !(dict
= OSDynamicCast( OSDictionary
,
1650 OSUnserializeXML( matching
)))) {
1651 err
= kIOReturnBadArgument
;
1655 if( (sym
== gIOPublishNotification
)
1656 || (sym
== gIOFirstPublishNotification
))
1657 userMsgType
= kIOServicePublishNotificationType
;
1658 else if( (sym
== gIOMatchedNotification
)
1659 || (sym
== gIOFirstMatchNotification
))
1660 userMsgType
= kIOServiceMatchedNotificationType
;
1661 else if( sym
== gIOTerminatedNotification
)
1662 userMsgType
= kIOServiceTerminatedNotificationType
;
1664 userMsgType
= kLastIOKitNotificationType
;
1666 userNotify
= new IOServiceUserNotification
;
1668 if( userNotify
&& !userNotify
->init( port
, userMsgType
,
1669 reference
, referenceSize
, client64
)) {
1670 userNotify
->release();
1676 notify
= IOService::addMatchingNotification( sym
, dict
,
1677 &userNotify
->_handler
, userNotify
);
1679 *notification
= userNotify
;
1680 userNotify
->setNotification( notify
);
1681 err
= kIOReturnSuccess
;
1683 err
= kIOReturnUnsupported
;
1696 /* Routine io_service_add_notification */
1697 kern_return_t
is_io_service_add_notification(
1698 mach_port_t master_port
,
1699 io_name_t notification_type
,
1700 io_string_t matching
,
1702 io_async_ref_t reference
,
1703 mach_msg_type_number_t referenceCnt
,
1704 io_object_t
* notification
)
1706 return (internal_io_service_add_notification(master_port
, notification_type
,
1707 matching
, port
, &reference
[0], sizeof(io_async_ref_t
),
1708 false, notification
));
1711 /* Routine io_service_add_notification_64 */
1712 kern_return_t
is_io_service_add_notification_64(
1713 mach_port_t master_port
,
1714 io_name_t notification_type
,
1715 io_string_t matching
,
1716 mach_port_t wake_port
,
1717 io_async_ref64_t reference
,
1718 mach_msg_type_number_t referenceCnt
,
1719 io_object_t
*notification
)
1721 return (internal_io_service_add_notification(master_port
, notification_type
,
1722 matching
, wake_port
, &reference
[0], sizeof(io_async_ref64_t
),
1723 true, notification
));
1727 static kern_return_t
internal_io_service_add_notification_ool(
1728 mach_port_t master_port
,
1729 io_name_t notification_type
,
1730 io_buf_ptr_t matching
,
1731 mach_msg_type_number_t matchingCnt
,
1732 mach_port_t wake_port
,
1734 vm_size_t referenceSize
,
1736 kern_return_t
*result
,
1737 io_object_t
*notification
)
1741 vm_map_offset_t map_data
;
1743 kr
= vm_map_copyout( kernel_map
, &map_data
, (vm_map_copy_t
) matching
);
1744 data
= CAST_DOWN(vm_offset_t
, map_data
);
1746 if( KERN_SUCCESS
== kr
) {
1747 // must return success after vm_map_copyout() succeeds
1748 *result
= internal_io_service_add_notification( master_port
, notification_type
,
1749 (char *) data
, wake_port
, reference
, referenceSize
, client64
, notification
);
1750 vm_deallocate( kernel_map
, data
, matchingCnt
);
1756 /* Routine io_service_add_notification_ool */
1757 kern_return_t
is_io_service_add_notification_ool(
1758 mach_port_t master_port
,
1759 io_name_t notification_type
,
1760 io_buf_ptr_t matching
,
1761 mach_msg_type_number_t matchingCnt
,
1762 mach_port_t wake_port
,
1763 io_async_ref_t reference
,
1764 mach_msg_type_number_t referenceCnt
,
1765 kern_return_t
*result
,
1766 io_object_t
*notification
)
1768 return (internal_io_service_add_notification_ool(master_port
, notification_type
,
1769 matching
, matchingCnt
, wake_port
, &reference
[0], sizeof(io_async_ref_t
),
1770 false, result
, notification
));
1773 /* Routine io_service_add_notification_ool_64 */
1774 kern_return_t
is_io_service_add_notification_ool_64(
1775 mach_port_t master_port
,
1776 io_name_t notification_type
,
1777 io_buf_ptr_t matching
,
1778 mach_msg_type_number_t matchingCnt
,
1779 mach_port_t wake_port
,
1780 io_async_ref64_t reference
,
1781 mach_msg_type_number_t referenceCnt
,
1782 kern_return_t
*result
,
1783 io_object_t
*notification
)
1785 return (internal_io_service_add_notification_ool(master_port
, notification_type
,
1786 matching
, matchingCnt
, wake_port
, &reference
[0], sizeof(io_async_ref64_t
),
1787 true, result
, notification
));
1790 /* Routine io_service_add_notification_old */
1791 kern_return_t
is_io_service_add_notification_old(
1792 mach_port_t master_port
,
1793 io_name_t notification_type
,
1794 io_string_t matching
,
1796 // for binary compatibility reasons, this must be natural_t for ILP32
1798 io_object_t
* notification
)
1800 return( is_io_service_add_notification( master_port
, notification_type
,
1801 matching
, port
, &ref
, 1, notification
));
1805 static kern_return_t
internal_io_service_add_interest_notification(
1806 io_object_t _service
,
1807 io_name_t type_of_interest
,
1810 vm_size_t referenceSize
,
1812 io_object_t
* notification
)
1815 IOServiceMessageUserNotification
* userNotify
= 0;
1816 IONotifier
* notify
= 0;
1817 const OSSymbol
* sym
;
1820 CHECK( IOService
, _service
, service
);
1822 err
= kIOReturnNoResources
;
1823 if( (sym
= OSSymbol::withCString( type_of_interest
))) do {
1825 userNotify
= new IOServiceMessageUserNotification
;
1827 if( userNotify
&& !userNotify
->init( port
, kIOServiceMessageNotificationType
,
1828 reference
, referenceSize
,
1829 kIOUserNotifyMaxMessageSize
,
1831 userNotify
->release();
1837 notify
= service
->registerInterest( sym
,
1838 &userNotify
->_handler
, userNotify
);
1840 *notification
= userNotify
;
1841 userNotify
->setNotification( notify
);
1842 err
= kIOReturnSuccess
;
1844 err
= kIOReturnUnsupported
;
1853 /* Routine io_service_add_message_notification */
1854 kern_return_t
is_io_service_add_interest_notification(
1855 io_object_t service
,
1856 io_name_t type_of_interest
,
1858 io_async_ref_t reference
,
1859 mach_msg_type_number_t referenceCnt
,
1860 io_object_t
* notification
)
1862 return (internal_io_service_add_interest_notification(service
, type_of_interest
,
1863 port
, &reference
[0], sizeof(io_async_ref_t
), false, notification
));
1866 /* Routine io_service_add_interest_notification_64 */
1867 kern_return_t
is_io_service_add_interest_notification_64(
1868 io_object_t service
,
1869 io_name_t type_of_interest
,
1870 mach_port_t wake_port
,
1871 io_async_ref64_t reference
,
1872 mach_msg_type_number_t referenceCnt
,
1873 io_object_t
*notification
)
1875 return (internal_io_service_add_interest_notification(service
, type_of_interest
,
1876 wake_port
, &reference
[0], sizeof(io_async_ref64_t
), true, notification
));
1880 /* Routine io_service_acknowledge_notification */
1881 kern_return_t
is_io_service_acknowledge_notification(
1882 io_object_t _service
,
1883 natural_t notify_ref
,
1884 natural_t response
)
1886 CHECK( IOService
, _service
, service
);
1888 return( service
->acknowledgeNotification( (IONotificationRef
) notify_ref
,
1889 (IOOptionBits
) response
));
1893 /* Routine io_connect_get_semaphore */
1894 kern_return_t
is_io_connect_get_notification_semaphore(
1895 io_connect_t connection
,
1896 natural_t notification_type
,
1897 semaphore_t
*semaphore
)
1899 CHECK( IOUserClient
, connection
, client
);
1901 IOStatisticsClientCall();
1902 return( client
->getNotificationSemaphore( (UInt32
) notification_type
,
1906 /* Routine io_registry_get_root_entry */
1907 kern_return_t
is_io_registry_get_root_entry(
1908 mach_port_t master_port
,
1911 IORegistryEntry
* entry
;
1913 if( master_port
!= master_device_port
)
1914 return( kIOReturnNotPrivileged
);
1916 entry
= IORegistryEntry::getRegistryRoot();
1921 return( kIOReturnSuccess
);
1924 /* Routine io_registry_create_iterator */
1925 kern_return_t
is_io_registry_create_iterator(
1926 mach_port_t master_port
,
1929 io_object_t
*iterator
)
1931 if( master_port
!= master_device_port
)
1932 return( kIOReturnNotPrivileged
);
1934 *iterator
= IORegistryIterator::iterateOver(
1935 IORegistryEntry::getPlane( plane
), options
);
1937 return( *iterator
? kIOReturnSuccess
: kIOReturnBadArgument
);
1940 /* Routine io_registry_entry_create_iterator */
1941 kern_return_t
is_io_registry_entry_create_iterator(
1942 io_object_t registry_entry
,
1945 io_object_t
*iterator
)
1947 CHECK( IORegistryEntry
, registry_entry
, entry
);
1949 *iterator
= IORegistryIterator::iterateOver( entry
,
1950 IORegistryEntry::getPlane( plane
), options
);
1952 return( *iterator
? kIOReturnSuccess
: kIOReturnBadArgument
);
1955 /* Routine io_registry_iterator_enter */
1956 kern_return_t
is_io_registry_iterator_enter_entry(
1957 io_object_t iterator
)
1959 CHECK( IORegistryIterator
, iterator
, iter
);
1963 return( kIOReturnSuccess
);
1966 /* Routine io_registry_iterator_exit */
1967 kern_return_t
is_io_registry_iterator_exit_entry(
1968 io_object_t iterator
)
1972 CHECK( IORegistryIterator
, iterator
, iter
);
1974 didIt
= iter
->exitEntry();
1976 return( didIt
? kIOReturnSuccess
: kIOReturnNoDevice
);
1979 /* Routine io_registry_entry_from_path */
1980 kern_return_t
is_io_registry_entry_from_path(
1981 mach_port_t master_port
,
1983 io_object_t
*registry_entry
)
1985 IORegistryEntry
* entry
;
1987 if( master_port
!= master_device_port
)
1988 return( kIOReturnNotPrivileged
);
1990 entry
= IORegistryEntry::fromPath( path
);
1992 *registry_entry
= entry
;
1994 return( kIOReturnSuccess
);
1997 /* Routine io_registry_entry_in_plane */
1998 kern_return_t
is_io_registry_entry_in_plane(
1999 io_object_t registry_entry
,
2001 boolean_t
*inPlane
)
2003 CHECK( IORegistryEntry
, registry_entry
, entry
);
2005 *inPlane
= entry
->inPlane( IORegistryEntry::getPlane( plane
));
2007 return( kIOReturnSuccess
);
2011 /* Routine io_registry_entry_get_path */
2012 kern_return_t
is_io_registry_entry_get_path(
2013 io_object_t registry_entry
,
2018 CHECK( IORegistryEntry
, registry_entry
, entry
);
2020 length
= sizeof( io_string_t
);
2021 if( entry
->getPath( path
, &length
, IORegistryEntry::getPlane( plane
)))
2022 return( kIOReturnSuccess
);
2024 return( kIOReturnBadArgument
);
2028 /* Routine io_registry_entry_get_name */
2029 kern_return_t
is_io_registry_entry_get_name(
2030 io_object_t registry_entry
,
2033 CHECK( IORegistryEntry
, registry_entry
, entry
);
2035 strncpy( name
, entry
->getName(), sizeof( io_name_t
));
2037 return( kIOReturnSuccess
);
2040 /* Routine io_registry_entry_get_name_in_plane */
2041 kern_return_t
is_io_registry_entry_get_name_in_plane(
2042 io_object_t registry_entry
,
2043 io_name_t planeName
,
2046 const IORegistryPlane
* plane
;
2047 CHECK( IORegistryEntry
, registry_entry
, entry
);
2050 plane
= IORegistryEntry::getPlane( planeName
);
2054 strncpy( name
, entry
->getName( plane
), sizeof( io_name_t
));
2056 return( kIOReturnSuccess
);
2059 /* Routine io_registry_entry_get_location_in_plane */
2060 kern_return_t
is_io_registry_entry_get_location_in_plane(
2061 io_object_t registry_entry
,
2062 io_name_t planeName
,
2063 io_name_t location
)
2065 const IORegistryPlane
* plane
;
2066 CHECK( IORegistryEntry
, registry_entry
, entry
);
2069 plane
= IORegistryEntry::getPlane( planeName
);
2073 const char * cstr
= entry
->getLocation( plane
);
2076 strncpy( location
, cstr
, sizeof( io_name_t
));
2077 return( kIOReturnSuccess
);
2079 return( kIOReturnNotFound
);
2082 /* Routine io_registry_entry_get_registry_entry_id */
2083 kern_return_t
is_io_registry_entry_get_registry_entry_id(
2084 io_object_t registry_entry
,
2085 uint64_t *entry_id
)
2087 CHECK( IORegistryEntry
, registry_entry
, entry
);
2089 *entry_id
= entry
->getRegistryEntryID();
2091 return (kIOReturnSuccess
);
2094 // Create a vm_map_copy_t or kalloc'ed data for memory
2095 // to be copied out. ipc will free after the copyout.
2097 static kern_return_t
copyoutkdata( const void * data
, vm_size_t len
,
2098 io_buf_ptr_t
* buf
)
2103 err
= vm_map_copyin( kernel_map
, CAST_USER_ADDR_T(data
), len
,
2104 false /* src_destroy */, ©
);
2106 assert( err
== KERN_SUCCESS
);
2107 if( err
== KERN_SUCCESS
)
2108 *buf
= (char *) copy
;
2113 /* Routine io_registry_entry_get_property */
2114 kern_return_t
is_io_registry_entry_get_property_bytes(
2115 io_object_t registry_entry
,
2116 io_name_t property_name
,
2117 io_struct_inband_t buf
,
2118 mach_msg_type_number_t
*dataCnt
)
2126 unsigned int len
= 0;
2127 const void * bytes
= 0;
2128 IOReturn ret
= kIOReturnSuccess
;
2130 CHECK( IORegistryEntry
, registry_entry
, entry
);
2132 obj
= entry
->copyProperty(property_name
);
2134 return( kIOReturnNoResources
);
2136 // One day OSData will be a common container base class
2138 if( (data
= OSDynamicCast( OSData
, obj
))) {
2139 len
= data
->getLength();
2140 bytes
= data
->getBytesNoCopy();
2142 } else if( (str
= OSDynamicCast( OSString
, obj
))) {
2143 len
= str
->getLength() + 1;
2144 bytes
= str
->getCStringNoCopy();
2146 } else if( (boo
= OSDynamicCast( OSBoolean
, obj
))) {
2147 len
= boo
->isTrue() ? sizeof("Yes") : sizeof("No");
2148 bytes
= boo
->isTrue() ? "Yes" : "No";
2150 } else if( (off
= OSDynamicCast( OSNumber
, obj
))) {
2151 offsetBytes
= off
->unsigned64BitValue();
2152 len
= off
->numberOfBytes();
2153 bytes
= &offsetBytes
;
2154 #ifdef __BIG_ENDIAN__
2155 bytes
= (const void *)
2156 (((UInt32
) bytes
) + (sizeof( UInt64
) - len
));
2160 ret
= kIOReturnBadArgument
;
2164 ret
= kIOReturnIPCError
;
2167 bcopy( bytes
, buf
, len
);
2176 /* Routine io_registry_entry_get_property */
2177 kern_return_t
is_io_registry_entry_get_property(
2178 io_object_t registry_entry
,
2179 io_name_t property_name
,
2180 io_buf_ptr_t
*properties
,
2181 mach_msg_type_number_t
*propertiesCnt
)
2187 CHECK( IORegistryEntry
, registry_entry
, entry
);
2189 obj
= entry
->copyProperty(property_name
);
2191 return( kIOReturnNotFound
);
2193 OSSerialize
* s
= OSSerialize::withCapacity(4096);
2196 return( kIOReturnNoMemory
);
2200 if( obj
->serialize( s
)) {
2201 len
= s
->getLength();
2202 *propertiesCnt
= len
;
2203 err
= copyoutkdata( s
->text(), len
, properties
);
2206 err
= kIOReturnUnsupported
;
2214 /* Routine io_registry_entry_get_property_recursively */
2215 kern_return_t
is_io_registry_entry_get_property_recursively(
2216 io_object_t registry_entry
,
2218 io_name_t property_name
,
2220 io_buf_ptr_t
*properties
,
2221 mach_msg_type_number_t
*propertiesCnt
)
2227 CHECK( IORegistryEntry
, registry_entry
, entry
);
2229 obj
= entry
->copyProperty( property_name
,
2230 IORegistryEntry::getPlane( plane
), options
);
2232 return( kIOReturnNotFound
);
2234 OSSerialize
* s
= OSSerialize::withCapacity(4096);
2237 return( kIOReturnNoMemory
);
2242 if( obj
->serialize( s
)) {
2243 len
= s
->getLength();
2244 *propertiesCnt
= len
;
2245 err
= copyoutkdata( s
->text(), len
, properties
);
2248 err
= kIOReturnUnsupported
;
2256 /* Routine io_registry_entry_get_properties */
2257 kern_return_t
is_io_registry_entry_get_properties(
2258 io_object_t registry_entry
,
2259 io_buf_ptr_t
*properties
,
2260 mach_msg_type_number_t
*propertiesCnt
)
2265 CHECK( IORegistryEntry
, registry_entry
, entry
);
2267 OSSerialize
* s
= OSSerialize::withCapacity(4096);
2269 return( kIOReturnNoMemory
);
2273 if( entry
->serializeProperties( s
)) {
2274 len
= s
->getLength();
2275 *propertiesCnt
= len
;
2276 err
= copyoutkdata( s
->text(), len
, properties
);
2279 err
= kIOReturnUnsupported
;
2286 /* Routine io_registry_entry_set_properties */
2287 kern_return_t is_io_registry_entry_set_properties
2289 io_object_t registry_entry
,
2290 io_buf_ptr_t properties
,
2291 mach_msg_type_number_t propertiesCnt
,
2292 kern_return_t
* result
)
2298 vm_map_offset_t map_data
;
2300 CHECK( IORegistryEntry
, registry_entry
, entry
);
2302 err
= vm_map_copyout( kernel_map
, &map_data
, (vm_map_copy_t
) properties
);
2303 data
= CAST_DOWN(vm_offset_t
, map_data
);
2305 if( KERN_SUCCESS
== err
) {
2307 // must return success after vm_map_copyout() succeeds
2308 obj
= OSUnserializeXML( (const char *) data
);
2309 vm_deallocate( kernel_map
, data
, propertiesCnt
);
2312 res
= kIOReturnBadArgument
;
2314 else if (0 != mac_iokit_check_set_properties(kauth_cred_get(),
2315 registry_entry
, obj
))
2316 res
= kIOReturnNotPermitted
;
2319 res
= entry
->setProperties( obj
);
2329 /* Routine io_registry_entry_get_child_iterator */
2330 kern_return_t
is_io_registry_entry_get_child_iterator(
2331 io_object_t registry_entry
,
2333 io_object_t
*iterator
)
2335 CHECK( IORegistryEntry
, registry_entry
, entry
);
2337 *iterator
= entry
->getChildIterator(
2338 IORegistryEntry::getPlane( plane
));
2340 return( kIOReturnSuccess
);
2343 /* Routine io_registry_entry_get_parent_iterator */
2344 kern_return_t
is_io_registry_entry_get_parent_iterator(
2345 io_object_t registry_entry
,
2347 io_object_t
*iterator
)
2349 CHECK( IORegistryEntry
, registry_entry
, entry
);
2351 *iterator
= entry
->getParentIterator(
2352 IORegistryEntry::getPlane( plane
));
2354 return( kIOReturnSuccess
);
2357 /* Routine io_service_get_busy_state */
2358 kern_return_t
is_io_service_get_busy_state(
2359 io_object_t _service
,
2360 uint32_t *busyState
)
2362 CHECK( IOService
, _service
, service
);
2364 *busyState
= service
->getBusyState();
2366 return( kIOReturnSuccess
);
2369 /* Routine io_service_get_state */
2370 kern_return_t
is_io_service_get_state(
2371 io_object_t _service
,
2373 uint32_t *busy_state
,
2374 uint64_t *accumulated_busy_time
)
2376 CHECK( IOService
, _service
, service
);
2378 *state
= service
->getState();
2379 *busy_state
= service
->getBusyState();
2380 *accumulated_busy_time
= service
->getAccumulatedBusyTime();
2382 return( kIOReturnSuccess
);
2385 /* Routine io_service_wait_quiet */
2386 kern_return_t
is_io_service_wait_quiet(
2387 io_object_t _service
,
2388 mach_timespec_t wait_time
)
2392 CHECK( IOService
, _service
, service
);
2394 timeoutNS
= wait_time
.tv_sec
;
2395 timeoutNS
*= kSecondScale
;
2396 timeoutNS
+= wait_time
.tv_nsec
;
2398 return( service
->waitQuiet(timeoutNS
) );
2401 /* Routine io_service_request_probe */
2402 kern_return_t
is_io_service_request_probe(
2403 io_object_t _service
,
2406 CHECK( IOService
, _service
, service
);
2408 return( service
->requestProbe( options
));
2411 /* Routine io_service_open_ndr */
2412 kern_return_t
is_io_service_open_extended(
2413 io_object_t _service
,
2415 uint32_t connect_type
,
2417 io_buf_ptr_t properties
,
2418 mach_msg_type_number_t propertiesCnt
,
2419 kern_return_t
* result
,
2420 io_object_t
*connection
)
2422 IOUserClient
* client
= 0;
2423 kern_return_t err
= KERN_SUCCESS
;
2424 IOReturn res
= kIOReturnSuccess
;
2425 OSDictionary
* propertiesDict
= 0;
2427 bool disallowAccess
;
2429 CHECK( IOService
, _service
, service
);
2437 vm_map_offset_t map_data
;
2439 err
= vm_map_copyout( kernel_map
, &map_data
, (vm_map_copy_t
) properties
);
2441 data
= CAST_DOWN(vm_offset_t
, map_data
);
2442 if (KERN_SUCCESS
== err
)
2444 // must return success after vm_map_copyout() succeeds
2445 obj
= OSUnserializeXML( (const char *) data
);
2446 vm_deallocate( kernel_map
, data
, propertiesCnt
);
2447 propertiesDict
= OSDynamicCast(OSDictionary
, obj
);
2448 if (!propertiesDict
)
2450 res
= kIOReturnBadArgument
;
2455 if (kIOReturnSuccess
!= res
)
2459 crossEndian
= (ndr
.int_rep
!= NDR_record
.int_rep
);
2462 if (!propertiesDict
)
2463 propertiesDict
= OSDictionary::withCapacity(4);
2464 OSData
* data
= OSData::withBytes(&ndr
, sizeof(ndr
));
2468 propertiesDict
->setObject(kIOUserClientCrossEndianKey
, data
);
2473 res
= service
->newUserClient( owningTask
, (void *) owningTask
,
2474 connect_type
, propertiesDict
, &client
);
2477 propertiesDict
->release();
2479 if (res
== kIOReturnSuccess
)
2481 assert( OSDynamicCast(IOUserClient
, client
) );
2483 disallowAccess
= (crossEndian
2484 && (kOSBooleanTrue
!= service
->getProperty(kIOUserClientCrossEndianCompatibleKey
))
2485 && (kOSBooleanTrue
!= client
->getProperty(kIOUserClientCrossEndianCompatibleKey
)));
2486 if (disallowAccess
) res
= kIOReturnUnsupported
;
2488 else if (0 != mac_iokit_check_open(kauth_cred_get(), client
, connect_type
))
2489 res
= kIOReturnNotPermitted
;
2491 if (kIOReturnSuccess
!= res
)
2493 IOStatisticsClientCall();
2494 client
->clientClose();
2499 client
->sharedInstance
= (0 != client
->getProperty(kIOUserClientSharedInstanceKey
));
2500 OSString
* creatorName
= IOCopyLogNameForPID(proc_selfpid());
2503 client
->setProperty(kIOUserClientCreatorKey
, creatorName
);
2504 creatorName
->release();
2510 *connection
= client
;
2516 /* Routine io_service_close */
2517 kern_return_t
is_io_service_close(
2518 io_object_t connection
)
2521 if ((mappings
= OSDynamicCast(OSSet
, connection
)))
2522 return( kIOReturnSuccess
);
2524 CHECK( IOUserClient
, connection
, client
);
2526 IOStatisticsClientCall();
2527 client
->clientClose();
2529 return( kIOReturnSuccess
);
2532 /* Routine io_connect_get_service */
2533 kern_return_t
is_io_connect_get_service(
2534 io_object_t connection
,
2535 io_object_t
*service
)
2537 IOService
* theService
;
2539 CHECK( IOUserClient
, connection
, client
);
2541 theService
= client
->getService();
2543 theService
->retain();
2545 *service
= theService
;
2547 return( theService
? kIOReturnSuccess
: kIOReturnUnsupported
);
2550 /* Routine io_connect_set_notification_port */
2551 kern_return_t
is_io_connect_set_notification_port(
2552 io_object_t connection
,
2553 uint32_t notification_type
,
2557 CHECK( IOUserClient
, connection
, client
);
2559 IOStatisticsClientCall();
2560 return( client
->registerNotificationPort( port
, notification_type
,
2561 (io_user_reference_t
) reference
));
2564 /* Routine io_connect_set_notification_port */
2565 kern_return_t
is_io_connect_set_notification_port_64(
2566 io_object_t connection
,
2567 uint32_t notification_type
,
2569 io_user_reference_t reference
)
2571 CHECK( IOUserClient
, connection
, client
);
2573 IOStatisticsClientCall();
2574 return( client
->registerNotificationPort( port
, notification_type
,
2578 /* Routine io_connect_map_memory_into_task */
2579 kern_return_t is_io_connect_map_memory_into_task
2581 io_connect_t connection
,
2582 uint32_t memory_type
,
2584 mach_vm_address_t
*address
,
2585 mach_vm_size_t
*size
,
2592 CHECK( IOUserClient
, connection
, client
);
2594 IOStatisticsClientCall();
2595 map
= client
->mapClientMemory64( memory_type
, into_task
, flags
, *address
);
2598 *address
= map
->getAddress();
2600 *size
= map
->getSize();
2602 if( client
->sharedInstance
2603 || (into_task
!= current_task())) {
2604 // push a name out to the task owning the map,
2605 // so we can clean up maps
2606 mach_port_name_t name __unused
=
2607 IOMachPort::makeSendRightForTask(
2608 into_task
, map
, IKOT_IOKIT_OBJECT
);
2612 // keep it with the user client
2613 IOLockLock( gIOObjectPortLock
);
2614 if( 0 == client
->mappings
)
2615 client
->mappings
= OSSet::withCapacity(2);
2616 if( client
->mappings
)
2617 client
->mappings
->setObject( map
);
2618 IOLockUnlock( gIOObjectPortLock
);
2621 err
= kIOReturnSuccess
;
2624 err
= kIOReturnBadArgument
;
2629 /* Routine is_io_connect_map_memory */
2630 kern_return_t
is_io_connect_map_memory(
2631 io_object_t connect
,
2634 vm_address_t
* mapAddr
,
2635 vm_size_t
* mapSize
,
2639 mach_vm_address_t address
;
2640 mach_vm_size_t size
;
2642 address
= SCALAR64(*mapAddr
);
2643 size
= SCALAR64(*mapSize
);
2645 err
= is_io_connect_map_memory_into_task(connect
, type
, task
, &address
, &size
, flags
);
2647 *mapAddr
= SCALAR32(address
);
2648 *mapSize
= SCALAR32(size
);
2655 IOMemoryMap
* IOUserClient::removeMappingForDescriptor(IOMemoryDescriptor
* mem
)
2658 IOMemoryMap
* map
= 0;
2660 IOLockLock(gIOObjectPortLock
);
2662 iter
= OSCollectionIterator::withCollection(mappings
);
2665 while ((map
= OSDynamicCast(IOMemoryMap
, iter
->getNextObject())))
2667 if(mem
== map
->getMemoryDescriptor())
2670 mappings
->removeObject(map
);
2677 IOLockUnlock(gIOObjectPortLock
);
2684 /* Routine io_connect_unmap_memory_from_task */
2685 kern_return_t is_io_connect_unmap_memory_from_task
2687 io_connect_t connection
,
2688 uint32_t memory_type
,
2690 mach_vm_address_t address
)
2693 IOOptionBits options
= 0;
2694 IOMemoryDescriptor
* memory
;
2697 CHECK( IOUserClient
, connection
, client
);
2699 IOStatisticsClientCall();
2700 err
= client
->clientMemoryForType( (UInt32
) memory_type
, &options
, &memory
);
2702 if( memory
&& (kIOReturnSuccess
== err
)) {
2704 options
= (options
& ~kIOMapUserOptionsMask
)
2705 | kIOMapAnywhere
| kIOMapReference
;
2707 map
= memory
->createMappingInTask( from_task
, address
, options
);
2711 IOLockLock( gIOObjectPortLock
);
2712 if( client
->mappings
)
2713 client
->mappings
->removeObject( map
);
2714 IOLockUnlock( gIOObjectPortLock
);
2716 mach_port_name_t name
= 0;
2717 if (from_task
!= current_task())
2718 name
= IOMachPort::makeSendRightForTask( from_task
, map
, IKOT_IOKIT_OBJECT
);
2721 map
->userClientUnmap();
2722 err
= iokit_mod_send_right( from_task
, name
, -2 );
2723 err
= kIOReturnSuccess
;
2726 IOMachPort::releasePortForObject( map
, IKOT_IOKIT_OBJECT
);
2727 if (from_task
== current_task())
2731 err
= kIOReturnBadArgument
;
2737 kern_return_t
is_io_connect_unmap_memory(
2738 io_object_t connect
,
2741 vm_address_t mapAddr
)
2744 mach_vm_address_t address
;
2746 address
= SCALAR64(mapAddr
);
2748 err
= is_io_connect_unmap_memory_from_task(connect
, type
, task
, mapAddr
);
2754 /* Routine io_connect_add_client */
2755 kern_return_t
is_io_connect_add_client(
2756 io_object_t connection
,
2757 io_object_t connect_to
)
2759 CHECK( IOUserClient
, connection
, client
);
2760 CHECK( IOUserClient
, connect_to
, to
);
2762 IOStatisticsClientCall();
2763 return( client
->connectClient( to
) );
2767 /* Routine io_connect_set_properties */
2768 kern_return_t
is_io_connect_set_properties(
2769 io_object_t connection
,
2770 io_buf_ptr_t properties
,
2771 mach_msg_type_number_t propertiesCnt
,
2772 kern_return_t
* result
)
2774 return( is_io_registry_entry_set_properties( connection
, properties
, propertiesCnt
, result
));
2777 /* Routine io_user_client_method */
2778 kern_return_t is_io_connect_method_var_output
2780 io_connect_t connection
,
2782 io_scalar_inband64_t scalar_input
,
2783 mach_msg_type_number_t scalar_inputCnt
,
2784 io_struct_inband_t inband_input
,
2785 mach_msg_type_number_t inband_inputCnt
,
2786 mach_vm_address_t ool_input
,
2787 mach_vm_size_t ool_input_size
,
2788 io_struct_inband_t inband_output
,
2789 mach_msg_type_number_t
*inband_outputCnt
,
2790 io_scalar_inband64_t scalar_output
,
2791 mach_msg_type_number_t
*scalar_outputCnt
,
2792 io_buf_ptr_t
*var_output
,
2793 mach_msg_type_number_t
*var_outputCnt
2796 CHECK( IOUserClient
, connection
, client
);
2798 IOExternalMethodArguments args
;
2800 IOMemoryDescriptor
* inputMD
= 0;
2801 OSObject
* structureVariableOutputData
= 0;
2803 bzero(&args
.__reserved
[0], sizeof(args
.__reserved
));
2804 args
.version
= kIOExternalMethodArgumentsCurrentVersion
;
2806 args
.selector
= selector
;
2808 args
.asyncWakePort
= MACH_PORT_NULL
;
2809 args
.asyncReference
= 0;
2810 args
.asyncReferenceCount
= 0;
2811 args
.structureVariableOutputData
= &structureVariableOutputData
;
2813 args
.scalarInput
= scalar_input
;
2814 args
.scalarInputCount
= scalar_inputCnt
;
2815 args
.structureInput
= inband_input
;
2816 args
.structureInputSize
= inband_inputCnt
;
2819 inputMD
= IOMemoryDescriptor::withAddressRange(ool_input
, ool_input_size
,
2820 kIODirectionOut
, current_task());
2822 args
.structureInputDescriptor
= inputMD
;
2824 args
.scalarOutput
= scalar_output
;
2825 args
.scalarOutputCount
= *scalar_outputCnt
;
2826 args
.structureOutput
= inband_output
;
2827 args
.structureOutputSize
= *inband_outputCnt
;
2828 args
.structureOutputDescriptor
= NULL
;
2829 args
.structureOutputDescriptorSize
= 0;
2831 IOStatisticsClientCall();
2832 ret
= client
->externalMethod( selector
, &args
);
2834 *scalar_outputCnt
= args
.scalarOutputCount
;
2835 *inband_outputCnt
= args
.structureOutputSize
;
2837 if (var_outputCnt
&& var_output
&& (kIOReturnSuccess
== ret
))
2839 OSSerialize
* serialize
;
2843 if ((serialize
= OSDynamicCast(OSSerialize
, structureVariableOutputData
)))
2845 len
= serialize
->getLength();
2846 *var_outputCnt
= len
;
2847 ret
= copyoutkdata(serialize
->text(), len
, var_output
);
2849 else if ((data
= OSDynamicCast(OSData
, structureVariableOutputData
)))
2851 len
= data
->getLength();
2852 *var_outputCnt
= len
;
2853 ret
= copyoutkdata(data
->getBytesNoCopy(), len
, var_output
);
2857 ret
= kIOReturnUnderrun
;
2863 if (structureVariableOutputData
)
2864 structureVariableOutputData
->release();
2869 /* Routine io_user_client_method */
2870 kern_return_t is_io_connect_method
2872 io_connect_t connection
,
2874 io_scalar_inband64_t scalar_input
,
2875 mach_msg_type_number_t scalar_inputCnt
,
2876 io_struct_inband_t inband_input
,
2877 mach_msg_type_number_t inband_inputCnt
,
2878 mach_vm_address_t ool_input
,
2879 mach_vm_size_t ool_input_size
,
2880 io_struct_inband_t inband_output
,
2881 mach_msg_type_number_t
*inband_outputCnt
,
2882 io_scalar_inband64_t scalar_output
,
2883 mach_msg_type_number_t
*scalar_outputCnt
,
2884 mach_vm_address_t ool_output
,
2885 mach_vm_size_t
*ool_output_size
2888 CHECK( IOUserClient
, connection
, client
);
2890 IOExternalMethodArguments args
;
2892 IOMemoryDescriptor
* inputMD
= 0;
2893 IOMemoryDescriptor
* outputMD
= 0;
2895 bzero(&args
.__reserved
[0], sizeof(args
.__reserved
));
2896 args
.version
= kIOExternalMethodArgumentsCurrentVersion
;
2898 args
.selector
= selector
;
2900 args
.asyncWakePort
= MACH_PORT_NULL
;
2901 args
.asyncReference
= 0;
2902 args
.asyncReferenceCount
= 0;
2903 args
.structureVariableOutputData
= 0;
2905 args
.scalarInput
= scalar_input
;
2906 args
.scalarInputCount
= scalar_inputCnt
;
2907 args
.structureInput
= inband_input
;
2908 args
.structureInputSize
= inband_inputCnt
;
2911 inputMD
= IOMemoryDescriptor::withAddressRange(ool_input
, ool_input_size
,
2912 kIODirectionOut
, current_task());
2914 args
.structureInputDescriptor
= inputMD
;
2916 args
.scalarOutput
= scalar_output
;
2917 args
.scalarOutputCount
= *scalar_outputCnt
;
2918 args
.structureOutput
= inband_output
;
2919 args
.structureOutputSize
= *inband_outputCnt
;
2921 if (ool_output
&& ool_output_size
)
2923 outputMD
= IOMemoryDescriptor::withAddressRange(ool_output
, *ool_output_size
,
2924 kIODirectionIn
, current_task());
2927 args
.structureOutputDescriptor
= outputMD
;
2928 args
.structureOutputDescriptorSize
= ool_output_size
? *ool_output_size
: 0;
2930 IOStatisticsClientCall();
2931 ret
= client
->externalMethod( selector
, &args
);
2933 *scalar_outputCnt
= args
.scalarOutputCount
;
2934 *inband_outputCnt
= args
.structureOutputSize
;
2935 *ool_output_size
= args
.structureOutputDescriptorSize
;
2940 outputMD
->release();
2945 /* Routine io_async_user_client_method */
2946 kern_return_t is_io_connect_async_method
2948 io_connect_t connection
,
2949 mach_port_t wake_port
,
2950 io_async_ref64_t reference
,
2951 mach_msg_type_number_t referenceCnt
,
2953 io_scalar_inband64_t scalar_input
,
2954 mach_msg_type_number_t scalar_inputCnt
,
2955 io_struct_inband_t inband_input
,
2956 mach_msg_type_number_t inband_inputCnt
,
2957 mach_vm_address_t ool_input
,
2958 mach_vm_size_t ool_input_size
,
2959 io_struct_inband_t inband_output
,
2960 mach_msg_type_number_t
*inband_outputCnt
,
2961 io_scalar_inband64_t scalar_output
,
2962 mach_msg_type_number_t
*scalar_outputCnt
,
2963 mach_vm_address_t ool_output
,
2964 mach_vm_size_t
* ool_output_size
2967 CHECK( IOUserClient
, connection
, client
);
2969 IOExternalMethodArguments args
;
2971 IOMemoryDescriptor
* inputMD
= 0;
2972 IOMemoryDescriptor
* outputMD
= 0;
2974 bzero(&args
.__reserved
[0], sizeof(args
.__reserved
));
2975 args
.version
= kIOExternalMethodArgumentsCurrentVersion
;
2977 reference
[0] = (io_user_reference_t
) wake_port
;
2978 if (vm_map_is_64bit(get_task_map(current_task())))
2979 reference
[0] |= kIOUCAsync64Flag
;
2981 args
.selector
= selector
;
2983 args
.asyncWakePort
= wake_port
;
2984 args
.asyncReference
= reference
;
2985 args
.asyncReferenceCount
= referenceCnt
;
2987 args
.scalarInput
= scalar_input
;
2988 args
.scalarInputCount
= scalar_inputCnt
;
2989 args
.structureInput
= inband_input
;
2990 args
.structureInputSize
= inband_inputCnt
;
2993 inputMD
= IOMemoryDescriptor::withAddressRange(ool_input
, ool_input_size
,
2994 kIODirectionOut
, current_task());
2996 args
.structureInputDescriptor
= inputMD
;
2998 args
.scalarOutput
= scalar_output
;
2999 args
.scalarOutputCount
= *scalar_outputCnt
;
3000 args
.structureOutput
= inband_output
;
3001 args
.structureOutputSize
= *inband_outputCnt
;
3005 outputMD
= IOMemoryDescriptor::withAddressRange(ool_output
, *ool_output_size
,
3006 kIODirectionIn
, current_task());
3009 args
.structureOutputDescriptor
= outputMD
;
3010 args
.structureOutputDescriptorSize
= *ool_output_size
;
3012 IOStatisticsClientCall();
3013 ret
= client
->externalMethod( selector
, &args
);
3015 *inband_outputCnt
= args
.structureOutputSize
;
3016 *ool_output_size
= args
.structureOutputDescriptorSize
;
3021 outputMD
->release();
3026 /* Routine io_connect_method_scalarI_scalarO */
3027 kern_return_t
is_io_connect_method_scalarI_scalarO(
3028 io_object_t connect
,
3030 io_scalar_inband_t input
,
3031 mach_msg_type_number_t inputCount
,
3032 io_scalar_inband_t output
,
3033 mach_msg_type_number_t
* outputCount
)
3037 io_scalar_inband64_t _input
;
3038 io_scalar_inband64_t _output
;
3040 mach_msg_type_number_t struct_outputCnt
= 0;
3041 mach_vm_size_t ool_output_size
= 0;
3043 for (i
= 0; i
< inputCount
; i
++)
3044 _input
[i
] = SCALAR64(input
[i
]);
3046 err
= is_io_connect_method(connect
, index
,
3050 NULL
, &struct_outputCnt
,
3051 _output
, outputCount
,
3052 0, &ool_output_size
);
3054 for (i
= 0; i
< *outputCount
; i
++)
3055 output
[i
] = SCALAR32(_output
[i
]);
3060 kern_return_t
shim_io_connect_method_scalarI_scalarO(
3061 IOExternalMethod
* method
,
3063 const io_user_scalar_t
* input
,
3064 mach_msg_type_number_t inputCount
,
3065 io_user_scalar_t
* output
,
3066 mach_msg_type_number_t
* outputCount
)
3069 io_scalar_inband_t _output
;
3071 err
= kIOReturnBadArgument
;
3075 if( inputCount
!= method
->count0
)
3077 IOLog("%s: IOUserClient inputCount count mismatch\n", object
->getName());
3080 if( *outputCount
!= method
->count1
)
3082 IOLog("%s: IOUserClient outputCount count mismatch\n", object
->getName());
3086 func
= method
->func
;
3088 switch( inputCount
) {
3091 err
= (object
->*func
)( ARG32(input
[0]), ARG32(input
[1]), ARG32(input
[2]),
3092 ARG32(input
[3]), ARG32(input
[4]), ARG32(input
[5]) );
3095 err
= (object
->*func
)( ARG32(input
[0]), ARG32(input
[1]), ARG32(input
[2]),
3096 ARG32(input
[3]), ARG32(input
[4]),
3100 err
= (object
->*func
)( ARG32(input
[0]), ARG32(input
[1]), ARG32(input
[2]),
3102 &_output
[0], &_output
[1] );
3105 err
= (object
->*func
)( ARG32(input
[0]), ARG32(input
[1]), ARG32(input
[2]),
3106 &_output
[0], &_output
[1], &_output
[2] );
3109 err
= (object
->*func
)( ARG32(input
[0]), ARG32(input
[1]),
3110 &_output
[0], &_output
[1], &_output
[2],
3114 err
= (object
->*func
)( ARG32(input
[0]),
3115 &_output
[0], &_output
[1], &_output
[2],
3116 &_output
[3], &_output
[4] );
3119 err
= (object
->*func
)( &_output
[0], &_output
[1], &_output
[2],
3120 &_output
[3], &_output
[4], &_output
[5] );
3124 IOLog("%s: Bad method table\n", object
->getName());
3130 for (i
= 0; i
< *outputCount
; i
++)
3131 output
[i
] = SCALAR32(_output
[i
]);
3136 /* Routine io_async_method_scalarI_scalarO */
3137 kern_return_t
is_io_async_method_scalarI_scalarO(
3138 io_object_t connect
,
3139 mach_port_t wake_port
,
3140 io_async_ref_t reference
,
3141 mach_msg_type_number_t referenceCnt
,
3143 io_scalar_inband_t input
,
3144 mach_msg_type_number_t inputCount
,
3145 io_scalar_inband_t output
,
3146 mach_msg_type_number_t
* outputCount
)
3150 io_scalar_inband64_t _input
;
3151 io_scalar_inband64_t _output
;
3152 io_async_ref64_t _reference
;
3154 for (i
= 0; i
< referenceCnt
; i
++)
3155 _reference
[i
] = REF64(reference
[i
]);
3157 mach_msg_type_number_t struct_outputCnt
= 0;
3158 mach_vm_size_t ool_output_size
= 0;
3160 for (i
= 0; i
< inputCount
; i
++)
3161 _input
[i
] = SCALAR64(input
[i
]);
3163 err
= is_io_connect_async_method(connect
,
3164 wake_port
, _reference
, referenceCnt
,
3169 NULL
, &struct_outputCnt
,
3170 _output
, outputCount
,
3171 0, &ool_output_size
);
3173 for (i
= 0; i
< *outputCount
; i
++)
3174 output
[i
] = SCALAR32(_output
[i
]);
3178 /* Routine io_async_method_scalarI_structureO */
3179 kern_return_t
is_io_async_method_scalarI_structureO(
3180 io_object_t connect
,
3181 mach_port_t wake_port
,
3182 io_async_ref_t reference
,
3183 mach_msg_type_number_t referenceCnt
,
3185 io_scalar_inband_t input
,
3186 mach_msg_type_number_t inputCount
,
3187 io_struct_inband_t output
,
3188 mach_msg_type_number_t
* outputCount
)
3191 io_scalar_inband64_t _input
;
3192 io_async_ref64_t _reference
;
3194 for (i
= 0; i
< referenceCnt
; i
++)
3195 _reference
[i
] = REF64(reference
[i
]);
3197 mach_msg_type_number_t scalar_outputCnt
= 0;
3198 mach_vm_size_t ool_output_size
= 0;
3200 for (i
= 0; i
< inputCount
; i
++)
3201 _input
[i
] = SCALAR64(input
[i
]);
3203 return (is_io_connect_async_method(connect
,
3204 wake_port
, _reference
, referenceCnt
,
3209 output
, outputCount
,
3210 NULL
, &scalar_outputCnt
,
3211 0, &ool_output_size
));
3214 /* Routine io_async_method_scalarI_structureI */
3215 kern_return_t
is_io_async_method_scalarI_structureI(
3216 io_connect_t connect
,
3217 mach_port_t wake_port
,
3218 io_async_ref_t reference
,
3219 mach_msg_type_number_t referenceCnt
,
3221 io_scalar_inband_t input
,
3222 mach_msg_type_number_t inputCount
,
3223 io_struct_inband_t inputStruct
,
3224 mach_msg_type_number_t inputStructCount
)
3227 io_scalar_inband64_t _input
;
3228 io_async_ref64_t _reference
;
3230 for (i
= 0; i
< referenceCnt
; i
++)
3231 _reference
[i
] = REF64(reference
[i
]);
3233 mach_msg_type_number_t scalar_outputCnt
= 0;
3234 mach_msg_type_number_t inband_outputCnt
= 0;
3235 mach_vm_size_t ool_output_size
= 0;
3237 for (i
= 0; i
< inputCount
; i
++)
3238 _input
[i
] = SCALAR64(input
[i
]);
3240 return (is_io_connect_async_method(connect
,
3241 wake_port
, _reference
, referenceCnt
,
3244 inputStruct
, inputStructCount
,
3246 NULL
, &inband_outputCnt
,
3247 NULL
, &scalar_outputCnt
,
3248 0, &ool_output_size
));
3251 /* Routine io_async_method_structureI_structureO */
3252 kern_return_t
is_io_async_method_structureI_structureO(
3253 io_object_t connect
,
3254 mach_port_t wake_port
,
3255 io_async_ref_t reference
,
3256 mach_msg_type_number_t referenceCnt
,
3258 io_struct_inband_t input
,
3259 mach_msg_type_number_t inputCount
,
3260 io_struct_inband_t output
,
3261 mach_msg_type_number_t
* outputCount
)
3264 mach_msg_type_number_t scalar_outputCnt
= 0;
3265 mach_vm_size_t ool_output_size
= 0;
3266 io_async_ref64_t _reference
;
3268 for (i
= 0; i
< referenceCnt
; i
++)
3269 _reference
[i
] = REF64(reference
[i
]);
3271 return (is_io_connect_async_method(connect
,
3272 wake_port
, _reference
, referenceCnt
,
3277 output
, outputCount
,
3278 NULL
, &scalar_outputCnt
,
3279 0, &ool_output_size
));
3283 kern_return_t
shim_io_async_method_scalarI_scalarO(
3284 IOExternalAsyncMethod
* method
,
3286 mach_port_t asyncWakePort
,
3287 io_user_reference_t
* asyncReference
,
3288 uint32_t asyncReferenceCount
,
3289 const io_user_scalar_t
* input
,
3290 mach_msg_type_number_t inputCount
,
3291 io_user_scalar_t
* output
,
3292 mach_msg_type_number_t
* outputCount
)
3296 io_scalar_inband_t _output
;
3298 io_async_ref_t reference
;
3300 for (i
= 0; i
< asyncReferenceCount
; i
++)
3301 reference
[i
] = REF32(asyncReference
[i
]);
3303 err
= kIOReturnBadArgument
;
3307 if( inputCount
!= method
->count0
)
3309 IOLog("%s: IOUserClient inputCount count mismatch\n", object
->getName());
3312 if( *outputCount
!= method
->count1
)
3314 IOLog("%s: IOUserClient outputCount count mismatch\n", object
->getName());
3318 func
= method
->func
;
3320 switch( inputCount
) {
3323 err
= (object
->*func
)( reference
,
3324 ARG32(input
[0]), ARG32(input
[1]), ARG32(input
[2]),
3325 ARG32(input
[3]), ARG32(input
[4]), ARG32(input
[5]) );
3328 err
= (object
->*func
)( reference
,
3329 ARG32(input
[0]), ARG32(input
[1]), ARG32(input
[2]),
3330 ARG32(input
[3]), ARG32(input
[4]),
3334 err
= (object
->*func
)( reference
,
3335 ARG32(input
[0]), ARG32(input
[1]), ARG32(input
[2]),
3337 &_output
[0], &_output
[1] );
3340 err
= (object
->*func
)( reference
,
3341 ARG32(input
[0]), ARG32(input
[1]), ARG32(input
[2]),
3342 &_output
[0], &_output
[1], &_output
[2] );
3345 err
= (object
->*func
)( reference
,
3346 ARG32(input
[0]), ARG32(input
[1]),
3347 &_output
[0], &_output
[1], &_output
[2],
3351 err
= (object
->*func
)( reference
,
3353 &_output
[0], &_output
[1], &_output
[2],
3354 &_output
[3], &_output
[4] );
3357 err
= (object
->*func
)( reference
,
3358 &_output
[0], &_output
[1], &_output
[2],
3359 &_output
[3], &_output
[4], &_output
[5] );
3363 IOLog("%s: Bad method table\n", object
->getName());
3368 for (i
= 0; i
< *outputCount
; i
++)
3369 output
[i
] = SCALAR32(_output
[i
]);
3375 /* Routine io_connect_method_scalarI_structureO */
3376 kern_return_t
is_io_connect_method_scalarI_structureO(
3377 io_object_t connect
,
3379 io_scalar_inband_t input
,
3380 mach_msg_type_number_t inputCount
,
3381 io_struct_inband_t output
,
3382 mach_msg_type_number_t
* outputCount
)
3385 io_scalar_inband64_t _input
;
3387 mach_msg_type_number_t scalar_outputCnt
= 0;
3388 mach_vm_size_t ool_output_size
= 0;
3390 for (i
= 0; i
< inputCount
; i
++)
3391 _input
[i
] = SCALAR64(input
[i
]);
3393 return (is_io_connect_method(connect
, index
,
3397 output
, outputCount
,
3398 NULL
, &scalar_outputCnt
,
3399 0, &ool_output_size
));
3402 kern_return_t
shim_io_connect_method_scalarI_structureO(
3404 IOExternalMethod
* method
,
3406 const io_user_scalar_t
* input
,
3407 mach_msg_type_number_t inputCount
,
3408 io_struct_inband_t output
,
3409 IOByteCount
* outputCount
)
3414 err
= kIOReturnBadArgument
;
3417 if( inputCount
!= method
->count0
)
3419 IOLog("%s: IOUserClient inputCount count mismatch\n", object
->getName());
3422 if( (kIOUCVariableStructureSize
!= method
->count1
)
3423 && (*outputCount
!= method
->count1
))
3425 IOLog("%s: IOUserClient outputCount count mismatch\n", object
->getName());
3429 func
= method
->func
;
3431 switch( inputCount
) {
3434 err
= (object
->*func
)( ARG32(input
[0]), ARG32(input
[1]), ARG32(input
[2]),
3435 ARG32(input
[3]), ARG32(input
[4]),
3439 err
= (object
->*func
)( ARG32(input
[0]), ARG32(input
[1]), ARG32(input
[2]),
3441 output
, (void *)outputCount
);
3444 err
= (object
->*func
)( ARG32(input
[0]), ARG32(input
[1]), ARG32(input
[2]),
3445 output
, (void *)outputCount
, 0 );
3448 err
= (object
->*func
)( ARG32(input
[0]), ARG32(input
[1]),
3449 output
, (void *)outputCount
, 0, 0 );
3452 err
= (object
->*func
)( ARG32(input
[0]),
3453 output
, (void *)outputCount
, 0, 0, 0 );
3456 err
= (object
->*func
)( output
, (void *)outputCount
, 0, 0, 0, 0 );
3460 IOLog("%s: Bad method table\n", object
->getName());
3469 kern_return_t
shim_io_async_method_scalarI_structureO(
3470 IOExternalAsyncMethod
* method
,
3472 mach_port_t asyncWakePort
,
3473 io_user_reference_t
* asyncReference
,
3474 uint32_t asyncReferenceCount
,
3475 const io_user_scalar_t
* input
,
3476 mach_msg_type_number_t inputCount
,
3477 io_struct_inband_t output
,
3478 mach_msg_type_number_t
* outputCount
)
3483 io_async_ref_t reference
;
3485 for (i
= 0; i
< asyncReferenceCount
; i
++)
3486 reference
[i
] = REF32(asyncReference
[i
]);
3488 err
= kIOReturnBadArgument
;
3490 if( inputCount
!= method
->count0
)
3492 IOLog("%s: IOUserClient inputCount count mismatch\n", object
->getName());
3495 if( (kIOUCVariableStructureSize
!= method
->count1
)
3496 && (*outputCount
!= method
->count1
))
3498 IOLog("%s: IOUserClient outputCount count mismatch\n", object
->getName());
3502 func
= method
->func
;
3504 switch( inputCount
) {
3507 err
= (object
->*func
)( reference
,
3508 ARG32(input
[0]), ARG32(input
[1]), ARG32(input
[2]),
3509 ARG32(input
[3]), ARG32(input
[4]),
3513 err
= (object
->*func
)( reference
,
3514 ARG32(input
[0]), ARG32(input
[1]), ARG32(input
[2]),
3516 output
, (void *)outputCount
);
3519 err
= (object
->*func
)( reference
,
3520 ARG32(input
[0]), ARG32(input
[1]), ARG32(input
[2]),
3521 output
, (void *)outputCount
, 0 );
3524 err
= (object
->*func
)( reference
,
3525 ARG32(input
[0]), ARG32(input
[1]),
3526 output
, (void *)outputCount
, 0, 0 );
3529 err
= (object
->*func
)( reference
,
3531 output
, (void *)outputCount
, 0, 0, 0 );
3534 err
= (object
->*func
)( reference
,
3535 output
, (void *)outputCount
, 0, 0, 0, 0 );
3539 IOLog("%s: Bad method table\n", object
->getName());
3547 /* Routine io_connect_method_scalarI_structureI */
3548 kern_return_t
is_io_connect_method_scalarI_structureI(
3549 io_connect_t connect
,
3551 io_scalar_inband_t input
,
3552 mach_msg_type_number_t inputCount
,
3553 io_struct_inband_t inputStruct
,
3554 mach_msg_type_number_t inputStructCount
)
3557 io_scalar_inband64_t _input
;
3559 mach_msg_type_number_t scalar_outputCnt
= 0;
3560 mach_msg_type_number_t inband_outputCnt
= 0;
3561 mach_vm_size_t ool_output_size
= 0;
3563 for (i
= 0; i
< inputCount
; i
++)
3564 _input
[i
] = SCALAR64(input
[i
]);
3566 return (is_io_connect_method(connect
, index
,
3568 inputStruct
, inputStructCount
,
3570 NULL
, &inband_outputCnt
,
3571 NULL
, &scalar_outputCnt
,
3572 0, &ool_output_size
));
3575 kern_return_t
shim_io_connect_method_scalarI_structureI(
3576 IOExternalMethod
* method
,
3578 const io_user_scalar_t
* input
,
3579 mach_msg_type_number_t inputCount
,
3580 io_struct_inband_t inputStruct
,
3581 mach_msg_type_number_t inputStructCount
)
3584 IOReturn err
= kIOReturnBadArgument
;
3588 if( (kIOUCVariableStructureSize
!= method
->count0
)
3589 && (inputCount
!= method
->count0
))
3591 IOLog("%s: IOUserClient inputCount count mismatch\n", object
->getName());
3594 if( (kIOUCVariableStructureSize
!= method
->count1
)
3595 && (inputStructCount
!= method
->count1
))
3597 IOLog("%s: IOUserClient outputCount count mismatch\n", object
->getName());
3601 func
= method
->func
;
3603 switch( inputCount
) {
3606 err
= (object
->*func
)( ARG32(input
[0]), ARG32(input
[1]), ARG32(input
[2]),
3607 ARG32(input
[3]), ARG32(input
[4]),
3611 err
= (object
->*func
)( ARG32(input
[0]), ARG32(input
[1]), (void *) input
[2],
3613 inputStruct
, (void *)inputStructCount
);
3616 err
= (object
->*func
)( ARG32(input
[0]), ARG32(input
[1]), ARG32(input
[2]),
3617 inputStruct
, (void *)inputStructCount
,
3621 err
= (object
->*func
)( ARG32(input
[0]), ARG32(input
[1]),
3622 inputStruct
, (void *)inputStructCount
,
3626 err
= (object
->*func
)( ARG32(input
[0]),
3627 inputStruct
, (void *)inputStructCount
,
3631 err
= (object
->*func
)( inputStruct
, (void *)inputStructCount
,
3636 IOLog("%s: Bad method table\n", object
->getName());
3644 kern_return_t
shim_io_async_method_scalarI_structureI(
3645 IOExternalAsyncMethod
* method
,
3647 mach_port_t asyncWakePort
,
3648 io_user_reference_t
* asyncReference
,
3649 uint32_t asyncReferenceCount
,
3650 const io_user_scalar_t
* input
,
3651 mach_msg_type_number_t inputCount
,
3652 io_struct_inband_t inputStruct
,
3653 mach_msg_type_number_t inputStructCount
)
3657 IOReturn err
= kIOReturnBadArgument
;
3658 io_async_ref_t reference
;
3660 for (i
= 0; i
< asyncReferenceCount
; i
++)
3661 reference
[i
] = REF32(asyncReference
[i
]);
3665 if( (kIOUCVariableStructureSize
!= method
->count0
)
3666 && (inputCount
!= method
->count0
))
3668 IOLog("%s: IOUserClient inputCount count mismatch\n", object
->getName());
3671 if( (kIOUCVariableStructureSize
!= method
->count1
)
3672 && (inputStructCount
!= method
->count1
))
3674 IOLog("%s: IOUserClient outputCount count mismatch\n", object
->getName());
3678 func
= method
->func
;
3680 switch( inputCount
) {
3683 err
= (object
->*func
)( reference
,
3684 ARG32(input
[0]), ARG32(input
[1]), ARG32(input
[2]),
3685 ARG32(input
[3]), ARG32(input
[4]),
3689 err
= (object
->*func
)( reference
,
3690 ARG32(input
[0]), ARG32(input
[1]), ARG32(input
[2]),
3692 inputStruct
, (void *)inputStructCount
);
3695 err
= (object
->*func
)( reference
,
3696 ARG32(input
[0]), ARG32(input
[1]), ARG32(input
[2]),
3697 inputStruct
, (void *)inputStructCount
,
3701 err
= (object
->*func
)( reference
,
3702 ARG32(input
[0]), ARG32(input
[1]),
3703 inputStruct
, (void *)inputStructCount
,
3707 err
= (object
->*func
)( reference
,
3709 inputStruct
, (void *)inputStructCount
,
3713 err
= (object
->*func
)( reference
,
3714 inputStruct
, (void *)inputStructCount
,
3719 IOLog("%s: Bad method table\n", object
->getName());
3727 /* Routine io_connect_method_structureI_structureO */
3728 kern_return_t
is_io_connect_method_structureI_structureO(
3729 io_object_t connect
,
3731 io_struct_inband_t input
,
3732 mach_msg_type_number_t inputCount
,
3733 io_struct_inband_t output
,
3734 mach_msg_type_number_t
* outputCount
)
3736 mach_msg_type_number_t scalar_outputCnt
= 0;
3737 mach_vm_size_t ool_output_size
= 0;
3739 return (is_io_connect_method(connect
, index
,
3743 output
, outputCount
,
3744 NULL
, &scalar_outputCnt
,
3745 0, &ool_output_size
));
3748 kern_return_t
shim_io_connect_method_structureI_structureO(
3749 IOExternalMethod
* method
,
3751 io_struct_inband_t input
,
3752 mach_msg_type_number_t inputCount
,
3753 io_struct_inband_t output
,
3754 IOByteCount
* outputCount
)
3757 IOReturn err
= kIOReturnBadArgument
;
3761 if( (kIOUCVariableStructureSize
!= method
->count0
)
3762 && (inputCount
!= method
->count0
))
3764 IOLog("%s: IOUserClient inputCount count mismatch\n", object
->getName());
3767 if( (kIOUCVariableStructureSize
!= method
->count1
)
3768 && (*outputCount
!= method
->count1
))
3770 IOLog("%s: IOUserClient outputCount count mismatch\n", object
->getName());
3774 func
= method
->func
;
3776 if( method
->count1
) {
3777 if( method
->count0
) {
3778 err
= (object
->*func
)( input
, output
,
3779 (void *)inputCount
, outputCount
, 0, 0 );
3781 err
= (object
->*func
)( output
, outputCount
, 0, 0, 0, 0 );
3784 err
= (object
->*func
)( input
, (void *)inputCount
, 0, 0, 0, 0 );
3793 kern_return_t
shim_io_async_method_structureI_structureO(
3794 IOExternalAsyncMethod
* method
,
3796 mach_port_t asyncWakePort
,
3797 io_user_reference_t
* asyncReference
,
3798 uint32_t asyncReferenceCount
,
3799 io_struct_inband_t input
,
3800 mach_msg_type_number_t inputCount
,
3801 io_struct_inband_t output
,
3802 mach_msg_type_number_t
* outputCount
)
3807 io_async_ref_t reference
;
3809 for (i
= 0; i
< asyncReferenceCount
; i
++)
3810 reference
[i
] = REF32(asyncReference
[i
]);
3812 err
= kIOReturnBadArgument
;
3815 if( (kIOUCVariableStructureSize
!= method
->count0
)
3816 && (inputCount
!= method
->count0
))
3818 IOLog("%s: IOUserClient inputCount count mismatch\n", object
->getName());
3821 if( (kIOUCVariableStructureSize
!= method
->count1
)
3822 && (*outputCount
!= method
->count1
))
3824 IOLog("%s: IOUserClient outputCount count mismatch\n", object
->getName());
3828 func
= method
->func
;
3830 if( method
->count1
) {
3831 if( method
->count0
) {
3832 err
= (object
->*func
)( reference
,
3834 (void *)inputCount
, outputCount
, 0, 0 );
3836 err
= (object
->*func
)( reference
,
3837 output
, outputCount
, 0, 0, 0, 0 );
3840 err
= (object
->*func
)( reference
,
3841 input
, (void *)inputCount
, 0, 0, 0, 0 );
3849 /* Routine io_make_matching */
3850 kern_return_t
is_io_make_matching(
3851 mach_port_t master_port
,
3854 io_struct_inband_t input
,
3855 mach_msg_type_number_t inputCount
,
3856 io_string_t matching
)
3859 IOReturn err
= kIOReturnSuccess
;
3860 OSDictionary
* dict
;
3862 if( master_port
!= master_device_port
)
3863 return( kIOReturnNotPrivileged
);
3867 case kIOServiceMatching
:
3868 dict
= IOService::serviceMatching( gIOServiceKey
);
3871 case kIOBSDNameMatching
:
3872 dict
= IOBSDNameMatching( (const char *) input
);
3875 case kIOOFPathMatching
:
3876 dict
= IOOFPathMatching( (const char *) input
,
3877 matching
, sizeof( io_string_t
));
3885 return( kIOReturnUnsupported
);
3888 s
= OSSerialize::withCapacity(4096);
3890 err
= kIOReturnNoMemory
;
3894 if( !dict
->serialize( s
)) {
3895 err
= kIOReturnUnsupported
;
3899 if( s
->getLength() > sizeof( io_string_t
)) {
3900 err
= kIOReturnNoMemory
;
3903 strlcpy(matching
, s
->text(), sizeof(io_string_t
));
3915 /* Routine io_catalog_send_data */
3916 kern_return_t
is_io_catalog_send_data(
3917 mach_port_t master_port
,
3919 io_buf_ptr_t inData
,
3920 mach_msg_type_number_t inDataCount
,
3921 kern_return_t
* result
)
3925 kern_return_t kr
= kIOReturnError
;
3927 //printf("io_catalog_send_data called. flag: %d\n", flag);
3929 if( master_port
!= master_device_port
)
3930 return kIOReturnNotPrivileged
;
3932 if( (flag
!= kIOCatalogRemoveKernelLinker
&&
3933 flag
!= kIOCatalogKextdActive
&&
3934 flag
!= kIOCatalogKextdFinishedLaunching
) &&
3935 ( !inData
|| !inDataCount
) )
3937 return kIOReturnBadArgument
;
3941 vm_map_offset_t map_data
;
3943 kr
= vm_map_copyout( kernel_map
, &map_data
, (vm_map_copy_t
)inData
);
3944 data
= CAST_DOWN(vm_offset_t
, map_data
);
3946 if( kr
!= KERN_SUCCESS
)
3949 // must return success after vm_map_copyout() succeeds
3952 obj
= (OSObject
*)OSUnserializeXML((const char *)data
);
3953 vm_deallocate( kernel_map
, data
, inDataCount
);
3955 *result
= kIOReturnNoMemory
;
3956 return( KERN_SUCCESS
);
3962 case kIOCatalogResetDrivers
:
3963 case kIOCatalogResetDriversNoMatch
: {
3966 array
= OSDynamicCast(OSArray
, obj
);
3968 if ( !gIOCatalogue
->resetAndAddDrivers(array
,
3969 flag
== kIOCatalogResetDrivers
) ) {
3971 kr
= kIOReturnError
;
3974 kr
= kIOReturnBadArgument
;
3979 case kIOCatalogAddDrivers
:
3980 case kIOCatalogAddDriversNoMatch
: {
3983 array
= OSDynamicCast(OSArray
, obj
);
3985 if ( !gIOCatalogue
->addDrivers( array
,
3986 flag
== kIOCatalogAddDrivers
) ) {
3987 kr
= kIOReturnError
;
3991 kr
= kIOReturnBadArgument
;
3996 case kIOCatalogRemoveDrivers
:
3997 case kIOCatalogRemoveDriversNoMatch
: {
3998 OSDictionary
* dict
;
4000 dict
= OSDynamicCast(OSDictionary
, obj
);
4002 if ( !gIOCatalogue
->removeDrivers( dict
,
4003 flag
== kIOCatalogRemoveDrivers
) ) {
4004 kr
= kIOReturnError
;
4008 kr
= kIOReturnBadArgument
;
4013 case kIOCatalogStartMatching
: {
4014 OSDictionary
* dict
;
4016 dict
= OSDynamicCast(OSDictionary
, obj
);
4018 if ( !gIOCatalogue
->startMatching( dict
) ) {
4019 kr
= kIOReturnError
;
4023 kr
= kIOReturnBadArgument
;
4028 case kIOCatalogRemoveKernelLinker
:
4029 kr
= KERN_NOT_SUPPORTED
;
4032 case kIOCatalogKextdActive
:
4034 IOServiceTrace(IOSERVICE_KEXTD_ALIVE
, 0, 0, 0, 0);
4035 OSKext::setKextdActive();
4037 /* Dump all nonloaded startup extensions; kextd will now send them
4040 OSKext::flushNonloadedKexts( /* flushPrelinkedKexts */ false);
4042 kr
= kIOReturnSuccess
;
4045 case kIOCatalogKextdFinishedLaunching
: {
4047 static bool clearedBusy
= false;
4050 IOService
* serviceRoot
= IOService::getServiceRoot();
4052 IOServiceTrace(IOSERVICE_KEXTD_READY
, 0, 0, 0, 0);
4053 serviceRoot
->adjustBusy(-1);
4058 kr
= kIOReturnSuccess
;
4063 kr
= kIOReturnBadArgument
;
4067 if (obj
) obj
->release();
4070 return( KERN_SUCCESS
);
4073 /* Routine io_catalog_terminate */
4074 kern_return_t
is_io_catalog_terminate(
4075 mach_port_t master_port
,
4081 if( master_port
!= master_device_port
)
4082 return kIOReturnNotPrivileged
;
4084 kr
= IOUserClient::clientHasPrivilege( (void *) current_task(),
4085 kIOClientPrivilegeAdministrator
);
4086 if( kIOReturnSuccess
!= kr
)
4090 #if !defined(SECURE_KERNEL)
4091 case kIOCatalogServiceTerminate
:
4093 IOService
* service
;
4095 iter
= IORegistryIterator::iterateOver(gIOServicePlane
,
4096 kIORegistryIterateRecursively
);
4098 return kIOReturnNoMemory
;
4102 while( (service
= (IOService
*)iter
->getNextObject()) ) {
4103 if( service
->metaCast(name
)) {
4104 if ( !service
->terminate( kIOServiceRequired
4105 | kIOServiceSynchronous
) ) {
4106 kr
= kIOReturnUnsupported
;
4111 } while( !service
&& !iter
->isValid());
4115 case kIOCatalogModuleUnload
:
4116 case kIOCatalogModuleTerminate
:
4117 kr
= gIOCatalogue
->terminateDriversForModule(name
,
4118 flag
== kIOCatalogModuleUnload
);
4123 kr
= kIOReturnBadArgument
;
4130 /* Routine io_catalog_get_data */
4131 kern_return_t
is_io_catalog_get_data(
4132 mach_port_t master_port
,
4134 io_buf_ptr_t
*outData
,
4135 mach_msg_type_number_t
*outDataCount
)
4137 kern_return_t kr
= kIOReturnSuccess
;
4140 if( master_port
!= master_device_port
)
4141 return kIOReturnNotPrivileged
;
4143 //printf("io_catalog_get_data called. flag: %d\n", flag);
4145 s
= OSSerialize::withCapacity(4096);
4147 return kIOReturnNoMemory
;
4151 kr
= gIOCatalogue
->serializeData(flag
, s
);
4153 if ( kr
== kIOReturnSuccess
) {
4158 size
= s
->getLength();
4159 kr
= vm_allocate(kernel_map
, &data
, size
, VM_FLAGS_ANYWHERE
);
4160 if ( kr
== kIOReturnSuccess
) {
4161 bcopy(s
->text(), (void *)data
, size
);
4162 kr
= vm_map_copyin(kernel_map
, (vm_map_address_t
)data
,
4163 (vm_map_size_t
)size
, true, ©
);
4164 *outData
= (char *)copy
;
4165 *outDataCount
= size
;
4174 /* Routine io_catalog_get_gen_count */
4175 kern_return_t
is_io_catalog_get_gen_count(
4176 mach_port_t master_port
,
4179 if( master_port
!= master_device_port
)
4180 return kIOReturnNotPrivileged
;
4182 //printf("io_catalog_get_gen_count called.\n");
4185 return kIOReturnBadArgument
;
4187 *genCount
= gIOCatalogue
->getGenerationCount();
4189 return kIOReturnSuccess
;
4192 /* Routine io_catalog_module_loaded.
4193 * Is invoked from IOKitLib's IOCatalogueModuleLoaded(). Doesn't seem to be used.
4195 kern_return_t
is_io_catalog_module_loaded(
4196 mach_port_t master_port
,
4199 if( master_port
!= master_device_port
)
4200 return kIOReturnNotPrivileged
;
4202 //printf("io_catalog_module_loaded called. name %s\n", name);
4205 return kIOReturnBadArgument
;
4207 gIOCatalogue
->moduleHasLoaded(name
);
4209 return kIOReturnSuccess
;
4212 kern_return_t
is_io_catalog_reset(
4213 mach_port_t master_port
,
4216 if( master_port
!= master_device_port
)
4217 return kIOReturnNotPrivileged
;
4220 case kIOCatalogResetDefault
:
4221 gIOCatalogue
->reset();
4225 return kIOReturnBadArgument
;
4228 return kIOReturnSuccess
;
4231 kern_return_t
iokit_user_client_trap(struct iokit_user_client_trap_args
*args
)
4233 kern_return_t result
= kIOReturnBadArgument
;
4234 IOUserClient
*userClient
;
4236 if ((userClient
= OSDynamicCast(IOUserClient
,
4237 iokit_lookup_connect_ref_current_task((OSObject
*)(args
->userClientRef
))))) {
4238 IOExternalTrap
*trap
;
4239 IOService
*target
= NULL
;
4241 trap
= userClient
->getTargetAndTrapForIndex(&target
, args
->index
);
4243 if (trap
&& target
) {
4249 result
= (target
->*func
)(args
->p1
, args
->p2
, args
->p3
, args
->p4
, args
->p5
, args
->p6
);
4253 userClient
->release();
4261 IOReturn
IOUserClient::externalMethod( uint32_t selector
, IOExternalMethodArguments
* args
,
4262 IOExternalMethodDispatch
* dispatch
, OSObject
* target
, void * reference
)
4266 IOByteCount structureOutputSize
;
4271 count
= dispatch
->checkScalarInputCount
;
4272 if ((kIOUCVariableStructureSize
!= count
) && (count
!= args
->scalarInputCount
))
4274 return (kIOReturnBadArgument
);
4277 count
= dispatch
->checkStructureInputSize
;
4278 if ((kIOUCVariableStructureSize
!= count
)
4279 && (count
!= ((args
->structureInputDescriptor
)
4280 ? args
->structureInputDescriptor
->getLength() : args
->structureInputSize
)))
4282 return (kIOReturnBadArgument
);
4285 count
= dispatch
->checkScalarOutputCount
;
4286 if ((kIOUCVariableStructureSize
!= count
) && (count
!= args
->scalarOutputCount
))
4288 return (kIOReturnBadArgument
);
4291 count
= dispatch
->checkStructureOutputSize
;
4292 if ((kIOUCVariableStructureSize
!= count
)
4293 && (count
!= ((args
->structureOutputDescriptor
)
4294 ? args
->structureOutputDescriptor
->getLength() : args
->structureOutputSize
)))
4296 return (kIOReturnBadArgument
);
4299 if (dispatch
->function
)
4300 err
= (*dispatch
->function
)(target
, reference
, args
);
4302 err
= kIOReturnNoCompletion
; /* implementator can dispatch */
4308 // pre-Leopard API's don't do ool structs
4309 if (args
->structureInputDescriptor
|| args
->structureOutputDescriptor
)
4311 err
= kIOReturnIPCError
;
4315 structureOutputSize
= args
->structureOutputSize
;
4317 if (args
->asyncWakePort
)
4319 IOExternalAsyncMethod
* method
;
4321 if( !(method
= getAsyncTargetAndMethodForIndex(&object
, selector
)) )
4322 return (kIOReturnUnsupported
);
4324 if (kIOUCForegroundOnly
& method
->flags
)
4326 /* is graphics access denied for current task? */
4327 if (proc_get_task_selfgpuacc_deny() != 0)
4328 return (kIOReturnNotPermitted
);
4331 switch (method
->flags
& kIOUCTypeMask
)
4333 case kIOUCScalarIStructI
:
4334 err
= shim_io_async_method_scalarI_structureI( method
, object
,
4335 args
->asyncWakePort
, args
->asyncReference
, args
->asyncReferenceCount
,
4336 args
->scalarInput
, args
->scalarInputCount
,
4337 (char *)args
->structureInput
, args
->structureInputSize
);
4340 case kIOUCScalarIScalarO
:
4341 err
= shim_io_async_method_scalarI_scalarO( method
, object
,
4342 args
->asyncWakePort
, args
->asyncReference
, args
->asyncReferenceCount
,
4343 args
->scalarInput
, args
->scalarInputCount
,
4344 args
->scalarOutput
, &args
->scalarOutputCount
);
4347 case kIOUCScalarIStructO
:
4348 err
= shim_io_async_method_scalarI_structureO( method
, object
,
4349 args
->asyncWakePort
, args
->asyncReference
, args
->asyncReferenceCount
,
4350 args
->scalarInput
, args
->scalarInputCount
,
4351 (char *) args
->structureOutput
, &args
->structureOutputSize
);
4355 case kIOUCStructIStructO
:
4356 err
= shim_io_async_method_structureI_structureO( method
, object
,
4357 args
->asyncWakePort
, args
->asyncReference
, args
->asyncReferenceCount
,
4358 (char *)args
->structureInput
, args
->structureInputSize
,
4359 (char *) args
->structureOutput
, &args
->structureOutputSize
);
4363 err
= kIOReturnBadArgument
;
4369 IOExternalMethod
* method
;
4371 if( !(method
= getTargetAndMethodForIndex(&object
, selector
)) )
4372 return (kIOReturnUnsupported
);
4374 if (kIOUCForegroundOnly
& method
->flags
)
4376 /* is graphics access denied for current task? */
4377 if (proc_get_task_selfgpuacc_deny() != 0)
4378 return (kIOReturnNotPermitted
);
4382 switch (method
->flags
& kIOUCTypeMask
)
4384 case kIOUCScalarIStructI
:
4385 err
= shim_io_connect_method_scalarI_structureI( method
, object
,
4386 args
->scalarInput
, args
->scalarInputCount
,
4387 (char *) args
->structureInput
, args
->structureInputSize
);
4390 case kIOUCScalarIScalarO
:
4391 err
= shim_io_connect_method_scalarI_scalarO( method
, object
,
4392 args
->scalarInput
, args
->scalarInputCount
,
4393 args
->scalarOutput
, &args
->scalarOutputCount
);
4396 case kIOUCScalarIStructO
:
4397 err
= shim_io_connect_method_scalarI_structureO( method
, object
,
4398 args
->scalarInput
, args
->scalarInputCount
,
4399 (char *) args
->structureOutput
, &structureOutputSize
);
4403 case kIOUCStructIStructO
:
4404 err
= shim_io_connect_method_structureI_structureO( method
, object
,
4405 (char *) args
->structureInput
, args
->structureInputSize
,
4406 (char *) args
->structureOutput
, &structureOutputSize
);
4410 err
= kIOReturnBadArgument
;
4415 args
->structureOutputSize
= structureOutputSize
;
4422 OSMetaClassDefineReservedUnused(IOUserClient
, 0);
4423 OSMetaClassDefineReservedUnused(IOUserClient
, 1);
4425 OSMetaClassDefineReservedUsed(IOUserClient
, 0);
4426 OSMetaClassDefineReservedUsed(IOUserClient
, 1);
4428 OSMetaClassDefineReservedUnused(IOUserClient
, 2);
4429 OSMetaClassDefineReservedUnused(IOUserClient
, 3);
4430 OSMetaClassDefineReservedUnused(IOUserClient
, 4);
4431 OSMetaClassDefineReservedUnused(IOUserClient
, 5);
4432 OSMetaClassDefineReservedUnused(IOUserClient
, 6);
4433 OSMetaClassDefineReservedUnused(IOUserClient
, 7);
4434 OSMetaClassDefineReservedUnused(IOUserClient
, 8);
4435 OSMetaClassDefineReservedUnused(IOUserClient
, 9);
4436 OSMetaClassDefineReservedUnused(IOUserClient
, 10);
4437 OSMetaClassDefineReservedUnused(IOUserClient
, 11);
4438 OSMetaClassDefineReservedUnused(IOUserClient
, 12);
4439 OSMetaClassDefineReservedUnused(IOUserClient
, 13);
4440 OSMetaClassDefineReservedUnused(IOUserClient
, 14);
4441 OSMetaClassDefineReservedUnused(IOUserClient
, 15);