1/* 2 * Copyright (c) 1998-2014 Apple Computer, Inc. All rights reserved. 3 * 4 * @APPLE_LICENSE_HEADER_START@ 5 * 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. Please obtain a copy of the License at 10 * http://www.opensource.apple.com/apsl/ and read it before using this 11 * file. 12 * 13 * The Original Code and all software distributed under the License are 14 * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER 15 * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, 16 * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, 17 * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. 18 * Please see the License for the specific language governing rights and 19 * limitations under the License. 20 * 21 * @APPLE_LICENSE_HEADER_END@ 22 */ 23 24#ifndef IOCONNECT_MAPMEMORY_10_6 25#define IOCONNECT_MAPMEMORY_10_6 1 26#endif 27 28#include <IOKit/IOTypes.h> 29#include <device/device_types.h> 30 31#include <mach/mach.h> 32#include <mach/mach_port.h> 33 34#if TARGET_IPHONE_SIMULATOR 35#include <servers/bootstrap.h> 36#endif 37 38#include <stdlib.h> 39#include <stdarg.h> 40#include <sys/file.h> 41#include <sys/stat.h> 42#include <sys/mman.h> 43#include <unistd.h> 44#include <asl.h> 45#include <dispatch/dispatch.h> 46#include <dispatch/private.h> 47#include <xpc/xpc.h> 48 49#include <CoreFoundation/CoreFoundation.h> 50#include <CoreFoundation/CFMachPort.h> 51 52 53#include <IOKit/IOBSD.h> 54#include <IOKit/IOKitLib.h> 55#include <IOKit/IOKitServer.h> 56 57#include <IOKit/IOCFSerialize.h> 58#include <IOKit/IOCFUnserialize.h> 59 60#include <IOKit/IOKitLibPrivate.h> 61 62#if __LP64__ 63typedef struct OSNotificationHeader64 NotificationHeader; 64 65// XXX gvdl: Need to conditionalise this for LP64 66#define mig_external __private_extern__ 67#include <iokitmig64.h> 68#undef mig_external 69 70#else 71 72// To stage the IOKitUser map the 64 bit aware APIs locally 73# if EMULATE_IOCONNECT 74# define EMULATE_IOCONNECT_64 1 75# define EMULATE_IOCONNECT_ASYNC_64 1 76# endif 77 78# if EMULATE_IOCONNECT_64 79# define io_connect_method em_connect_method 80# endif 81 82# if EMULATE_IOCONNECT_ASYNC_64 83# define io_connect_async_method em_connect_async_method 84# endif 85 86typedef struct OSNotificationHeader NotificationHeader; 87#include <iokitmig32.h> 88 89#endif 90 91uint64_t 92gIOKitLibServerVersion; 93CFOptionFlags 94gIOKitLibSerializeOptions = kIOCFSerializeToBinary; 95 96/* 97 * Ports 98 */ 99 100extern mach_port_t mach_task_self(); 101const mach_port_t kIOMasterPortDefault = MACH_PORT_NULL; 102 103static mach_port_t 104__IOGetDefaultMasterPort() 105{ 106 mach_port_t masterPort; 107 108 kern_return_t result = IOMasterPort(MACH_PORT_NULL, &masterPort); 109 if( KERN_SUCCESS != result) 110 masterPort = MACH_PORT_NULL; 111 112 return( masterPort ); 113} 114 115kern_return_t 116#if TARGET_IPHONE_SIMULATOR 117IOMasterPort( mach_port_t bootstrapPort, mach_port_t * masterPort ) 118#else 119IOMasterPort( mach_port_t bootstrapPort __unused, mach_port_t * masterPort ) 120#endif 121{ 122 kern_return_t result = KERN_SUCCESS; 123 mach_port_t host_port = 0; 124 125#if TARGET_IPHONE_SIMULATOR 126 /* Defaulting to bypass until <rdar://problem/13141176> is addressed */ 127 static boolean_t use_iokitsimd = 0; 128 static dispatch_once_t once; 129 130 dispatch_once(&once, ^{ 131 const char *value = getenv("IOS_SIMULATOR_IOKITSIMD"); 132 133 if (value) { 134 use_iokitsimd = (*value == '1'); 135 } 136 137/* Don't log about it until <rdar://problem/13141176> is addressed */ 138#if 0 139 if (!use_iokitsimd) 140 asl_log(NULL, NULL, ASL_LEVEL_NOTICE, 141 "IOKit.framework:IOMasterPort bypassing iokitsimd"); 142#endif 143 }); 144 145 if (use_iokitsimd) { 146 if (bootstrapPort == MACH_PORT_NULL) 147 bootstrapPort = bootstrap_port; 148 return bootstrap_look_up(bootstrapPort, "com.apple.iokitsimd", masterPort); 149 } 150#endif 151 152 host_port = mach_host_self(); 153 result = host_get_io_master(host_port, masterPort); 154 155 static dispatch_once_t versionOnce; 156 dispatch_once(&versionOnce, ^{ 157#if IOKIT_SERVER_VERSION >= 20140421 158 kern_return_t kr; 159 kr = io_server_version(*masterPort, &gIOKitLibServerVersion); 160 if (KERN_SUCCESS != kr) gIOKitLibServerVersion = 0; 161#endif /* IOKIT_SERVER_VERSION >= 20140421 */ 162 if (gIOKitLibServerVersion < 20140421) gIOKitLibSerializeOptions &= ~kIOCFSerializeToBinary; 163 }); 164 165 /* Dispose of the host port to prevent security breaches and port 166 * leaks. We don't care about the kern_return_t value of this 167 * call for now as there's nothing we can do if it fails. 168 */ 169 if (host_port) mach_port_deallocate(mach_task_self(), host_port); 170 return result; 171} 172 173kern_return_t 174IOCreateReceivePort( uint32_t msgType, mach_port_t * recvPort ) 175{ 176 kern_return_t res; 177 switch (msgType) { 178 case kOSNotificationMessageID: 179 case kOSAsyncCompleteMessageID: 180 res = mach_port_allocate(mach_task_self(), 181 MACH_PORT_RIGHT_RECEIVE, recvPort); 182 183 break; 184 185 default: 186 res = kIOReturnBadArgument; 187 } 188 return res; 189} 190 191/* 192 * IOObject 193 */ 194 195kern_return_t 196IOObjectRelease( 197 io_object_t object ) 198{ 199 return( mach_port_deallocate( mach_task_self(), object )); 200} 201 202kern_return_t 203IOObjectRetain( 204 io_object_t object ) 205{ 206 return( mach_port_mod_refs(mach_task_self(), 207 object, 208 MACH_PORT_RIGHT_SEND, 209 1 )); 210} 211 212kern_return_t 213IOObjectGetClass( 214 io_object_t object, 215 io_name_t className ) 216{ 217 return( io_object_get_class( object, className )); 218} 219 220 221CFStringRef 222IOObjectCopyClass(io_object_t object) 223{ 224 io_name_t my_name; 225 CFStringRef my_str = NULL; 226 227 // if there's no argument, no point going on. Return NULL. 228 if (!object) 229 return my_str; 230 231 io_object_get_class( object, my_name ); 232 my_str = CFStringCreateWithCString (kCFAllocatorDefault, my_name, kCFStringEncodingUTF8); 233 234 return my_str; 235} 236 237CFStringRef 238IOObjectCopySuperclassForClass(CFStringRef classname) 239{ 240 io_name_t my_name, orig_name; 241 CFStringRef my_str = NULL; 242 char * my_cstr; 243 kern_return_t kr; 244 245 // if there's no argument, no point going on. Return NULL. 246 if (classname == NULL) { 247 return my_str; 248 } 249 250 my_cstr = malloc(sizeof(char) * 128); 251 CFStringGetCString (classname, my_cstr, 128, kCFStringEncodingUTF8); 252 253 strncpy(orig_name, my_cstr, sizeof(io_name_t)); 254 255 mach_port_t masterPort = __IOGetDefaultMasterPort(); 256 257 kr = io_object_get_superclass(masterPort, orig_name, my_name); 258 259 if (masterPort != MACH_PORT_NULL) 260 mach_port_deallocate(mach_task_self(), masterPort); 261 262 if (kr == kIOReturnSuccess) { 263 my_str = CFStringCreateWithCString (kCFAllocatorDefault, my_name, kCFStringEncodingUTF8); 264 } 265 free(my_cstr); 266 267 return my_str; 268} 269 270CFStringRef 271IOObjectCopyBundleIdentifierForClass(CFStringRef classname) 272{ 273 io_name_t my_name, orig_name; 274 CFStringRef my_str = NULL; 275 char * my_cstr; 276 kern_return_t kr; 277 278 // if there's no argument, no point going on. Return NULL. 279 if (classname == NULL) { 280 return my_str; 281 } 282 283 my_cstr = malloc(sizeof(char) * 128); 284 CFStringGetCString (classname, my_cstr, 128, kCFStringEncodingUTF8); 285 286 strncpy(orig_name, my_cstr, sizeof(io_name_t)); 287 288 mach_port_t masterPort = __IOGetDefaultMasterPort(); 289 290 kr = io_object_get_bundle_identifier(masterPort, orig_name, my_name); 291 292 if (masterPort != MACH_PORT_NULL) 293 mach_port_deallocate(mach_task_self(), masterPort); 294 295 if (kr == kIOReturnSuccess) { 296 my_str = CFStringCreateWithCString (kCFAllocatorDefault, my_name, kCFStringEncodingUTF8); 297 } 298 free(my_cstr); 299 300 return my_str; 301} 302 303boolean_t 304IOObjectConformsTo( 305 io_object_t object, 306 const io_name_t className ) 307{ 308 boolean_t conforms; 309 310 if( kIOReturnSuccess != io_object_conforms_to( 311 object, (char *) className, &conforms )) 312 conforms = 0; 313 314 return( conforms ); 315} 316 317boolean_t 318IOObjectIsEqualTo( 319 io_object_t object, 320 io_object_t anObject ) 321{ 322 return( object == anObject ); 323} 324 325uint32_t 326IOObjectGetKernelRetainCount( 327 io_object_t object ) 328{ 329 uint32_t count; 330 331 if( kIOReturnSuccess != io_object_get_retain_count( object, &count)) 332 count = 0; 333 334 return( count ); 335} 336 337uint32_t 338IOObjectGetRetainCount( 339 io_object_t object ) 340{ 341 return( IOObjectGetKernelRetainCount(object) ); 342} 343 344uint32_t 345IOObjectGetUserRetainCount( 346 io_object_t object ) 347{ 348 mach_port_urefs_t urefs; 349 350 if( kIOReturnSuccess != mach_port_get_refs( mach_task_self(), object, MACH_PORT_RIGHT_SEND, &urefs)) 351 urefs = 0; 352 353 return( urefs ); 354} 355 356/* 357 * IOIterator 358 */ 359 360io_object_t 361IOIteratorNext( 362 io_iterator_t iterator ) 363{ 364 io_object_t next; 365 366 if( kIOReturnSuccess != io_iterator_next( iterator, &next)) 367 next = 0; 368 369 return( next ); 370} 371 372void 373IOIteratorReset( 374 io_iterator_t iterator ) 375{ 376 io_iterator_reset( iterator ); 377} 378 379boolean_t 380IOIteratorIsValid( 381 io_iterator_t iterator ) 382{ 383 boolean_t valid; 384 385 if( kIOReturnSuccess != io_iterator_is_valid( iterator, &valid )) 386 valid = FALSE; 387 388 return( valid ); 389} 390 391/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ 392 393/* 394 * IOService 395 */ 396 397io_service_t 398IOServiceGetMatchingService( 399 mach_port_t _masterPort, 400 CFDictionaryRef matching ) 401{ 402 kern_return_t kr; 403 CFDataRef data; 404 CFIndex dataLen; 405 mach_port_t masterPort; 406 io_service_t service = MACH_PORT_NULL; 407 bool ool; 408 409 if( !matching) 410 return( MACH_PORT_NULL); 411 412 if (MACH_PORT_NULL == _masterPort) 413 masterPort = __IOGetDefaultMasterPort(); 414 else 415 masterPort = _masterPort; 416 417 data = IOCFSerialize( matching, gIOKitLibSerializeOptions ); 418 CFRelease( matching ); 419 if( !data) 420 return( MACH_PORT_NULL ); 421 422 dataLen = CFDataGetLength(data); 423 424 ool = true; 425#if IOKIT_SERVER_VERSION >= 20140421 426 if (kIOCFSerializeToBinary & gIOKitLibSerializeOptions) 427 { 428 if ((size_t) dataLen < sizeof(io_struct_inband_t)) 429 { 430 kr = io_service_get_matching_service_bin(masterPort, 431 (char *) CFDataGetBytePtr(data), dataLen, &service ); 432 ool = false; 433 } 434 } 435 else 436#endif /* IOKIT_SERVER_VERSION >= 20140421 */ 437 { 438 if ((size_t) dataLen < sizeof(io_string_t)) 439 { 440 kr = io_service_get_matching_service( masterPort, 441 (char *) CFDataGetBytePtr(data), &service ); 442 ool = false; 443 } 444 } 445 446 if (ool) 447 { 448 kern_return_t result; 449 kr = io_service_get_matching_service_ool( masterPort, 450 (char *) CFDataGetBytePtr(data), dataLen, &result, &service ); 451 if (KERN_SUCCESS == kr) 452 kr = result; 453 } 454 455 CFRelease( data ); 456 if ((masterPort != MACH_PORT_NULL) && (masterPort != _masterPort)) 457 mach_port_deallocate(mach_task_self(), masterPort); 458 459 if (KERN_SUCCESS != kr) 460 service = MACH_PORT_NULL; 461 462 return( service ); 463} 464 465kern_return_t 466IOServiceGetMatchingServices( 467 mach_port_t _masterPort, 468 CFDictionaryRef matching, 469 io_iterator_t * existing ) 470{ 471 kern_return_t kr; 472 CFDataRef data; 473 CFIndex dataLen; 474 mach_port_t masterPort; 475 bool ool; 476 477 if( !matching) 478 return( kIOReturnBadArgument); 479 480 if (MACH_PORT_NULL == _masterPort) 481 masterPort = __IOGetDefaultMasterPort(); 482 else 483 masterPort = _masterPort; 484 485 data = IOCFSerialize(matching, gIOKitLibSerializeOptions); 486 CFRelease( matching ); 487 if( !data) 488 return( kIOReturnUnsupported ); 489 490 dataLen = CFDataGetLength(data); 491 492 ool = true; 493#if IOKIT_SERVER_VERSION >= 20140421 494 if (kIOCFSerializeToBinary & gIOKitLibSerializeOptions) 495 { 496 if ((size_t) dataLen < sizeof(io_struct_inband_t)) 497 { 498 kr = io_service_get_matching_services_bin(masterPort, 499 (char *) CFDataGetBytePtr(data), dataLen, existing); 500 ool = false; 501 } 502 } 503 else 504#endif /* IOKIT_SERVER_VERSION >= 20140421 */ 505 { 506 if ((size_t) dataLen < sizeof(io_string_t)) 507 { 508 kr = io_service_get_matching_services(masterPort, 509 (char *) CFDataGetBytePtr(data), existing); 510 ool = false; 511 } 512 } 513 if (ool) 514 { 515 kern_return_t result; 516 kr = io_service_get_matching_services_ool( masterPort, 517 (char *) CFDataGetBytePtr(data), dataLen, &result, existing ); 518 if (KERN_SUCCESS == kr) 519 kr = result; 520 } 521 522 CFRelease( data ); 523 if ((masterPort != MACH_PORT_NULL) && (masterPort != _masterPort)) 524 mach_port_deallocate(mach_task_self(), masterPort); 525 526 return( kr ); 527} 528 529kern_return_t 530IOServiceMatchPropertyTable( io_service_t service, CFDictionaryRef matching, 531 boolean_t * matches ) 532{ 533 kern_return_t kr; 534 CFDataRef data; 535 CFIndex dataLen; 536 bool ool; 537 538 if( !matching) 539 return( kIOReturnBadArgument); 540 541 data = IOCFSerialize( matching, gIOKitLibSerializeOptions ); 542 if( !data) 543 return( kIOReturnUnsupported ); 544 545 dataLen = CFDataGetLength(data); 546 547 548 ool = true; 549#if IOKIT_SERVER_VERSION >= 20140421 550 if (kIOCFSerializeToBinary & gIOKitLibSerializeOptions) 551 { 552 if ((size_t) dataLen < sizeof(io_struct_inband_t)) 553 { 554 kr = io_service_match_property_table_bin(service, 555 (char *) CFDataGetBytePtr(data), dataLen, matches); 556 ool = false; 557 } 558 } 559 else 560#endif /* IOKIT_SERVER_VERSION >= 20140421 */ 561 { 562 if ((size_t) dataLen < sizeof(io_string_t)) 563 { 564 kr = io_service_match_property_table(service, 565 (char *) CFDataGetBytePtr(data), matches); 566 ool = false; 567 } 568 } 569 if (ool) 570 { 571 kern_return_t result; 572 kr = io_service_match_property_table_ool( service, 573 (char *) CFDataGetBytePtr(data), dataLen, &result, matches ); 574 if (KERN_SUCCESS == kr) 575 kr = result; 576 } 577 578 CFRelease( data ); 579 580 return( kr ); 581} 582 583static kern_return_t 584InternalIOServiceAddNotification( 585 mach_port_t _masterPort, 586 const io_name_t notificationType, 587 CFDictionaryRef matching, 588 mach_port_t wakePort, 589 io_async_ref_t asyncRef, 590 mach_msg_type_number_t referenceCnt, 591 io_iterator_t * notification ) 592{ 593 kern_return_t kr; 594 CFDataRef data; 595 CFIndex dataLen; 596 mach_port_t masterPort; 597 bool ool; 598 599 if( !matching) 600 return( kIOReturnBadArgument); 601 602 if (MACH_PORT_NULL == _masterPort) 603 masterPort = __IOGetDefaultMasterPort(); 604 else 605 masterPort = _masterPort; 606 607 data = IOCFSerialize( matching, gIOKitLibSerializeOptions ); 608 CFRelease( matching ); 609 if( !data) 610 return( kIOReturnUnsupported ); 611 612 dataLen = CFDataGetLength(data); 613 614 ool = true; 615#if IOKIT_SERVER_VERSION >= 20140421 616 if (kIOCFSerializeToBinary & gIOKitLibSerializeOptions) 617 { 618 if ((size_t) dataLen < sizeof(io_struct_inband_t)) 619 { 620 kr = io_service_add_notification_bin( masterPort, (char *) notificationType, 621 (char *) CFDataGetBytePtr(data), dataLen, 622 wakePort, asyncRef, referenceCnt, 623 notification ); 624 ool = false; 625 } 626 } 627 else 628#endif /* IOKIT_SERVER_VERSION >= 20140421 */ 629 { 630 if ((size_t) dataLen < sizeof(io_string_t)) 631 { 632 kr = io_service_add_notification( masterPort, (char *) notificationType, 633 (char *) CFDataGetBytePtr(data), 634 wakePort, asyncRef, referenceCnt, 635 notification ); 636 ool = false; 637 } 638 } 639 if (ool) 640 { 641 kern_return_t result; 642 643 kr = io_service_add_notification_ool( masterPort, (char *) notificationType, 644 (char *) CFDataGetBytePtr(data), dataLen, 645 wakePort, asyncRef, referenceCnt, 646 &result, notification ); 647 if (KERN_SUCCESS == kr) kr = result; 648 } 649 650 CFRelease( data ); 651 if ((masterPort != MACH_PORT_NULL) && (masterPort != _masterPort)) 652 mach_port_deallocate(mach_task_self(), masterPort); 653 654 return( kr ); 655} 656 657kern_return_t 658IOServiceAddNotification( 659 mach_port_t _masterPort, 660 const io_name_t notificationType, 661 CFDictionaryRef matching, 662 mach_port_t wakePort, 663 uintptr_t reference, 664 io_iterator_t *notification ) 665{ 666 return (InternalIOServiceAddNotification(_masterPort, notificationType, 667 matching, wakePort, 668 (io_user_reference_t *) &reference, 1, 669 notification)); 670} 671 672kern_return_t 673IOServiceAddMatchingNotification( 674 IONotificationPortRef notifyPort, 675 const io_name_t notificationType, 676 CFDictionaryRef matching, 677 IOServiceMatchingCallback callback, 678 void * refcon, 679 io_iterator_t * notification ) 680{ 681 io_user_reference_t asyncRef[kIOMatchingCalloutCount]; 682 683 asyncRef[kIOMatchingCalloutFuncIndex] = (io_user_reference_t) callback; 684 asyncRef[kIOMatchingCalloutRefconIndex] = (io_user_reference_t) refcon; 685 686 return (InternalIOServiceAddNotification(notifyPort->masterPort, notificationType, 687 matching, notifyPort->wakePort, 688 &asyncRef[0], kIOMatchingCalloutCount, 689 notification)); 690} 691 692kern_return_t 693IOServiceAddInterestNotification( 694 IONotificationPortRef notifyPort, 695 io_service_t service, 696 const io_name_t interestType, 697 IOServiceInterestCallback callback, 698 void * refcon, 699 io_object_t * notification ) 700{ 701 io_user_reference_t asyncRef[kIOInterestCalloutCount]; 702 kern_return_t kr; 703 704 asyncRef[kIOInterestCalloutFuncIndex] = (io_user_reference_t) callback; 705 asyncRef[kIOInterestCalloutRefconIndex] = (io_user_reference_t) refcon; 706 asyncRef[kIOInterestCalloutServiceIndex] = (io_user_reference_t) service; 707 708 kr = io_service_add_interest_notification( service, (char *) interestType, 709 notifyPort->wakePort, 710 asyncRef, kIOInterestCalloutCount, 711 notification ); 712 713 return( kr ); 714} 715 716IONotificationPortRef 717IONotificationPortCreate( 718 mach_port_t masterPort ) 719{ 720 kern_return_t kr; 721 IONotificationPort *notify; 722 723 if (MACH_PORT_NULL == masterPort) { 724 masterPort = __IOGetDefaultMasterPort(); 725 } else { 726 IOObjectRetain(masterPort); 727 } 728 729 notify = calloc( 1, sizeof( IONotificationPort)); 730 if (!notify) { 731 return( 0 ); 732 } 733 notify->masterPort = masterPort; 734 735 kr = IOCreateReceivePort(kOSNotificationMessageID, ¬ify->wakePort); 736 if( kr != kIOReturnSuccess) { 737 free( notify ); 738 return( 0 ); 739 } 740 741 return notify; 742} 743 744void 745IONotificationPortDestroy( 746 IONotificationPortRef notify ) 747{ 748 749 if (notify->cfmachPort) { 750 CFMachPortInvalidate(notify->cfmachPort); 751 CFRelease(notify->cfmachPort); 752 } 753 754 if( notify->source) { 755 CFRelease(notify->source); 756 } 757 758 if (notify->dispatchSource) { 759 dispatch_source_cancel(notify->dispatchSource); 760 dispatch_release(notify->dispatchSource); 761 } 762 763 mach_port_mod_refs(mach_task_self(), notify->wakePort, 764 MACH_PORT_RIGHT_RECEIVE, -1); 765 766 mach_port_deallocate(mach_task_self(), notify->masterPort); 767 768 free( notify ); 769} 770 771CFRunLoopSourceRef 772IONotificationPortGetRunLoopSource( 773 IONotificationPortRef notify ) 774{ 775 CFMachPortContext context; 776 Boolean cfReusedPort = false; 777 778 if (notify->source) 779 return (notify->source); 780 781 context.version = 1; 782 context.info = (void *) notify; 783 context.retain = NULL; 784 context.release = NULL; 785 context.copyDescription = NULL; 786 787 notify->cfmachPort = CFMachPortCreateWithPort(NULL, notify->wakePort, 788 IODispatchCalloutFromCFMessage, &context, &cfReusedPort); 789 if (!notify->cfmachPort) 790 return NULL; 791 792 if (cfReusedPort) 793 { 794 // We got a CFMachPortRef that CF re-used from its pool. 795 // This is probably a race condition, and this belongs 796 // to a recently dead port. 797 // We expect a new CFMachPortRef - we treat it as an error. 798 799 CFStringRef description = NULL; 800 char str[255]; 801 if (notify->cfmachPort) { 802 description = CFCopyDescription(notify->cfmachPort); 803 if (description) { 804 CFStringGetCString(description, str, sizeof(str), kCFStringEncodingUTF8); 805 CFRelease(description); 806 } 807 } 808 809 asl_log(NULL, NULL, ASL_LEVEL_ERR, 810 "IOKit.framework:IONotificationPortGetRunLoopSource bad CFMachPort, %s\n", 811 description ? str : "No Description"); 812 813 CFRelease(notify->cfmachPort); 814 notify->cfmachPort = NULL; 815 goto exit; 816 } 817 818 notify->source = CFMachPortCreateRunLoopSource(NULL, notify->cfmachPort, 0); 819 820exit: 821 return (notify->source); 822} 823 824mach_port_t 825IONotificationPortGetMachPort( 826 IONotificationPortRef notify ) 827{ 828 return( notify->wakePort ); 829} 830 831boolean_t _IODispatchCalloutWithDispatch(mach_msg_header_t *msg, mach_msg_header_t *reply) 832{ 833 mig_reply_setup(msg, reply); 834 ((mig_reply_error_t*)reply)->RetCode = MIG_NO_REPLY; 835 836 IODispatchCalloutFromCFMessage(NULL, msg, msg->msgh_size, dispatch_mach_msg_get_context(msg)); 837 return TRUE; 838} 839 840#define MAX_MSG_SIZE (8ul * 1024ul - MAX_TRAILER_SIZE) 841 842void 843IONotificationPortSetDispatchQueue(IONotificationPortRef notify, dispatch_queue_t queue) 844{ 845 dispatch_source_t dispatchSource; 846 847 if (notify->dispatchSource) 848 { 849 dispatch_source_cancel(notify->dispatchSource); 850 dispatch_release(notify->dispatchSource); 851 notify->dispatchSource = NULL; 852 } 853 854 if (!queue) return; 855 856 dispatchSource = dispatch_source_create(DISPATCH_SOURCE_TYPE_MACH_RECV, notify->wakePort, 0, queue); 857 dispatch_source_set_event_handler(dispatchSource, ^{ 858 dispatch_mig_server(dispatchSource, MAX_MSG_SIZE, _IODispatchCalloutWithDispatch); 859 }); 860 notify->dispatchSource = dispatchSource; 861 862 /* Note: normally, dispatch sources for mach ports should destroy the underlying 863 * mach port in their cancellation handler. We take care to destroy the port 864 * after we destroy the source in IONotificationPortDestroy(), which gives us the 865 * flexibility of changing the queue used for the dispatch source. 866 */ 867 868 dispatch_resume(notify->dispatchSource); 869} 870 871/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ 872 873/* 874 * Matching creation helpers 875 */ 876 877static CFMutableDictionaryRef 878MakeOneStringProp( 879 CFStringRef key, 880 const char * name ) 881{ 882 CFMutableDictionaryRef dict; 883 CFStringRef string; 884 885 dict = CFDictionaryCreateMutable( kCFAllocatorDefault, 0, 886 &kCFTypeDictionaryKeyCallBacks, 887 &kCFTypeDictionaryValueCallBacks); 888 889 if( !dict) 890 return( dict); 891 892 string = CFStringCreateWithCString( kCFAllocatorDefault, name, 893 kCFStringEncodingMacRoman ); 894 895 if( string) { 896 CFDictionarySetValue( dict, key, string ); 897 CFRelease( string ); 898 } else { 899 CFRelease( dict ); 900 dict = 0; 901 } 902 903 return( dict ); 904} 905 906static CFMutableDictionaryRef 907MakeOneNumProp( 908 CFStringRef key, 909 uint64_t value ) 910{ 911 CFMutableDictionaryRef dict; 912 CFNumberRef num; 913 914 dict = CFDictionaryCreateMutable( kCFAllocatorDefault, 0, 915 &kCFTypeDictionaryKeyCallBacks, 916 &kCFTypeDictionaryValueCallBacks); 917 918 if( !dict) 919 return( dict); 920 921 num = CFNumberCreate( kCFAllocatorDefault, kCFNumberSInt64Type, &value ); 922 if( num) { 923 CFDictionarySetValue( dict, key, num ); 924 CFRelease( num ); 925 } else { 926 CFRelease( dict ); 927 dict = 0; 928 } 929 930 return( dict ); 931} 932 933 934CFMutableDictionaryRef 935IOServiceMatching( 936 const char * name ) 937{ 938 return( MakeOneStringProp( CFSTR(kIOProviderClassKey), name ) ); 939} 940 941CFMutableDictionaryRef 942IOServiceNameMatching( 943 const char * name ) 944{ 945 return( MakeOneStringProp( CFSTR(kIONameMatchKey), name )); 946} 947 948CFMutableDictionaryRef 949IORegistryEntryIDMatching( 950 uint64_t entryID ) 951{ 952 return( MakeOneNumProp( CFSTR(kIORegistryEntryIDKey), entryID )); 953} 954 955CFMutableDictionaryRef 956IOBSDNameMatching( 957 mach_port_t masterPort __unused, 958 uint32_t options __unused, 959 const char * name ) 960{ 961 if( !name) 962 return( 0 ); 963 964 return( MakeOneStringProp( CFSTR(kIOBSDNameKey), name )); 965} 966 967CFMutableDictionaryRef 968IOOpenFirmwarePathMatching( 969 mach_port_t masterPort __unused, 970 uint32_t options __unused, 971 const char * path ) 972{ 973 io_string_t buf; 974 int maxLen; 975 char * comp; 976 int len; 977 978 maxLen = sizeof( io_string_t); 979 980 do { 981 982 len = strlen( kIODeviceTreePlane ":" ); 983 maxLen -= len; 984 if( maxLen <= 0) 985 continue; 986 987 strlcpy( buf, kIODeviceTreePlane ":", len + 1 ); 988 comp = buf + len; 989 990 len = strlen( path ); 991 maxLen -= len; 992 if( maxLen <= 0) 993 continue; 994 strlcpy( comp, path, len + 1 ); 995 996 return( MakeOneStringProp( CFSTR(kIOPathMatchKey), buf )); 997 998 } while( false ); 999 1000 return( 0 ); 1001} 1002 1003/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ 1004 1005kern_return_t 1006OSGetNotificationFromMessage( 1007 mach_msg_header_t *msg, 1008 uint32_t index, 1009 uint32_t *type, 1010 uintptr_t *reference, 1011 void **content, 1012 vm_size_t *size ) 1013{ 1014 // The kernel handles the downcast of the reference vector for 32bit tasks 1015 NotificationHeader * header; 1016 1017 if( msg->msgh_id != kOSNotificationMessageID) 1018 return( kIOReturnBadMessageID ); 1019 1020 if( msg->msgh_size < (sizeof( mach_msg_header_t) 1021 + sizeof( NotificationHeader))) 1022 return( kIOReturnNoResources ); 1023 1024 if( index) 1025 return( kIOReturnNoResources ); 1026 1027 header = (NotificationHeader *) (msg + 1); 1028 if( type) 1029 *type = (kIOKitNoticationTypeMask & header->type); 1030 if( reference) 1031 *reference = (uintptr_t) header->reference[0]; 1032 if( size) 1033 *size = header->size; 1034 if( content) { 1035 if( header->size) 1036 *content = &header->content[0]; 1037 else 1038 *content = 0; 1039 } 1040 1041 return( kIOReturnSuccess ); 1042} 1043 1044/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ 1045 1046void 1047IODispatchCalloutFromMessage(void *cfPort, mach_msg_header_t *msg, void *info) 1048{ 1049 return( IODispatchCalloutFromCFMessage( cfPort, msg, -1, info )); 1050} 1051 1052void 1053IODispatchCalloutFromCFMessage(CFMachPortRef port __unused, 1054 void *_msg, CFIndex size __unused, void *info __unused) 1055{ 1056 struct ComplexMsg { 1057 mach_msg_header_t msgHdr; 1058 mach_msg_body_t msgBody; 1059 mach_msg_port_descriptor_t ports[1]; 1060 } * complexMsg = NULL; 1061 mach_msg_header_t * msg = (mach_msg_header_t *)_msg; 1062 NotificationHeader * header; 1063 io_iterator_t notifier = MACH_PORT_NULL; 1064 io_service_t service = MACH_PORT_NULL; 1065 uint32_t leftOver; 1066 boolean_t deliver = TRUE; 1067 1068 if( msg->msgh_id != kOSNotificationMessageID) 1069 return; 1070 1071 if( MACH_MSGH_BITS_COMPLEX & msg->msgh_bits) { 1072 1073 complexMsg = (struct ComplexMsg *)_msg; 1074 1075 if( complexMsg->msgBody.msgh_descriptor_count) 1076 service = complexMsg->ports[0].name; 1077 header = (NotificationHeader *) &complexMsg->ports[complexMsg->msgBody.msgh_descriptor_count]; 1078 1079 } else 1080 header = (NotificationHeader *) (msg + 1); 1081 1082 leftOver = msg->msgh_size - (((vm_address_t) (header + 1)) - ((vm_address_t) msg)); 1083 1084 // remote port is the notification (an iterator_t) that fired 1085 notifier = msg->msgh_remote_port; 1086 1087 if( MACH_PORT_NULL != notifier) { 1088 kern_return_t kr; 1089 mach_port_urefs_t urefs; 1090 1091 kr = mach_port_get_refs( mach_task_self(), msg->msgh_remote_port, MACH_PORT_RIGHT_SEND, &urefs); 1092 if( (KERN_SUCCESS != kr) || (urefs < 2)) { 1093 // one ref carried by the message - < 2 means owner has released the notifier 1094 deliver = false; 1095 } 1096 } 1097 1098 if(deliver) 1099 { 1100 leftOver -= (kIOKitNoticationMsgSizeMask & (header->type >> kIOKitNoticationTypeSizeAdjShift)); 1101 1102 switch( kIOKitNoticationTypeMask & header->type ) 1103 { 1104 case kIOAsyncCompletionNotificationType: 1105 { 1106 IOAsyncCompletionContent *asyncHdr; 1107 1108 asyncHdr = (IOAsyncCompletionContent *)(header + 1); 1109 leftOver = (leftOver - sizeof(*asyncHdr)) / sizeof(void *); 1110 void *func = (void *) header->reference[kIOAsyncCalloutFuncIndex]; 1111 void *refCon = (void *) header->reference[kIOAsyncCalloutRefconIndex]; 1112 switch (leftOver) { 1113 case 0: 1114 ((IOAsyncCallback0) func)(refCon, asyncHdr->result); 1115 break; 1116 case 1: 1117 ((IOAsyncCallback1) func)(refCon, asyncHdr->result, 1118 asyncHdr->args[0]); 1119 break; 1120 case 2: 1121 ((IOAsyncCallback2) func)(refCon, asyncHdr->result, 1122 asyncHdr->args[0], asyncHdr->args[1]); 1123 break; 1124 default: 1125 ((IOAsyncCallback) func)(refCon, asyncHdr->result, 1126 asyncHdr->args, leftOver); 1127 break; 1128 } 1129 break; 1130 } 1131 case kIOServiceMessageNotificationType: 1132 { 1133 IOServiceInterestContent * interestHdr; 1134 void * arg; 1135 1136 interestHdr = (IOServiceInterestContent *)(header + 1); 1137 leftOver = (leftOver - sizeof(*interestHdr) + sizeof(interestHdr->messageArgument)) / sizeof(void *); 1138 if (leftOver <= 1) 1139 arg = interestHdr->messageArgument[0]; 1140 else 1141 arg = &interestHdr->messageArgument[0]; 1142 1143 ((IOServiceInterestCallback)header->reference[kIOInterestCalloutFuncIndex])( 1144 (void *) header->reference[kIOInterestCalloutRefconIndex], 1145 service ? service : (io_service_t) header->reference[kIOInterestCalloutServiceIndex], 1146 interestHdr->messageType, arg ); 1147 break; 1148 } 1149 case kIOServicePublishNotificationType: 1150 case kIOServiceMatchedNotificationType: 1151 case kIOServiceTerminatedNotificationType: 1152 1153 ((IOServiceMatchingCallback)header->reference[kIOMatchingCalloutFuncIndex])( 1154 (void *) header->reference[kIOMatchingCalloutRefconIndex], 1155 notifier); 1156 break; 1157 } 1158 } 1159 1160 if( MACH_PORT_NULL != notifier) 1161 mach_port_deallocate( mach_task_self(), notifier ); 1162 if( complexMsg) 1163 { 1164 uint32_t i; 1165 for( i = 0; i < complexMsg->msgBody.msgh_descriptor_count; i++) 1166 mach_port_deallocate( mach_task_self(), complexMsg->ports[i].name ); 1167 } 1168} 1169 1170/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ 1171 1172kern_return_t 1173IOServiceGetBusyStateAndTime( 1174 io_service_t service, 1175 uint64_t * state, 1176 uint32_t * busy_state, 1177 uint64_t * accumulated_busy_time) 1178{ 1179 kern_return_t kr; 1180 1181 kr = io_service_get_state( service, state, busy_state, accumulated_busy_time ); 1182 1183 if (kr != KERN_SUCCESS) 1184 { 1185 *state = 0; 1186 *busy_state = 0; 1187 *accumulated_busy_time = 0; 1188 } 1189 1190 return( kr ); 1191} 1192 1193kern_return_t 1194IOServiceGetBusyState( 1195 io_service_t service, 1196 uint32_t * busyState ) 1197{ 1198 uint64_t state; 1199 uint64_t accumulated_busy_time; 1200 1201 return (IOServiceGetBusyStateAndTime(service, &state, busyState, &accumulated_busy_time)); 1202} 1203 1204kern_return_t 1205IOServiceGetState( 1206 io_service_t service, 1207 uint64_t * state ) 1208{ 1209 uint32_t busy_state; 1210 uint64_t accumulated_busy_time; 1211 1212 return (IOServiceGetBusyStateAndTime(service, state, &busy_state, &accumulated_busy_time)); 1213} 1214 1215kern_return_t 1216IOKitGetBusyState( 1217 mach_port_t _masterPort, 1218 uint32_t * busyState ) 1219{ 1220 io_service_t root; 1221 kern_return_t kr; 1222 mach_port_t masterPort; 1223 1224 if (MACH_PORT_NULL == _masterPort) 1225 masterPort = __IOGetDefaultMasterPort(); 1226 else 1227 masterPort = _masterPort; 1228 1229 kr = io_registry_entry_from_path( masterPort, 1230 kIOServicePlane ":/", &root ); 1231 1232 if( kr == KERN_SUCCESS) { 1233 kr = IOServiceGetBusyState( root, busyState ); 1234 IOObjectRelease( root ); 1235 } else 1236 *busyState = 0; 1237 1238 if ((masterPort != MACH_PORT_NULL) && (masterPort != _masterPort)) 1239 mach_port_deallocate(mach_task_self(), masterPort); 1240 1241 return( kr ); 1242} 1243 1244kern_return_t 1245IOServiceWaitQuiet( 1246 io_service_t service, 1247 mach_timespec_t * waitTime ) 1248{ 1249 kern_return_t kr; 1250 mach_timespec_t defaultWait = { 0, -1 }; 1251 1252 if( 0 == waitTime) 1253 waitTime = &defaultWait; 1254 1255 kr = io_service_wait_quiet( service, *waitTime ); 1256 1257 return( kr ); 1258} 1259 1260 1261kern_return_t 1262IOKitWaitQuiet( 1263 mach_port_t _masterPort, 1264 mach_timespec_t * waitTime ) 1265{ 1266 io_service_t root; 1267 kern_return_t kr; 1268 mach_timespec_t defaultWait = { 0, -1 }; 1269 mach_port_t masterPort; 1270 1271 if (MACH_PORT_NULL == _masterPort) 1272 masterPort = __IOGetDefaultMasterPort(); 1273 else 1274 masterPort = _masterPort; 1275 1276 kr = io_registry_entry_from_path( masterPort, 1277 kIOServicePlane ":/", &root ); 1278 1279 if( kr == KERN_SUCCESS) { 1280 if( 0 == waitTime) 1281 waitTime = &defaultWait; 1282 kr = io_service_wait_quiet( root, *waitTime ); 1283 IOObjectRelease( root ); 1284 } 1285 1286 if ((masterPort != MACH_PORT_NULL) && (masterPort != _masterPort)) 1287 mach_port_deallocate(mach_task_self(), masterPort); 1288 1289 return( kr ); 1290} 1291 1292kern_return_t 1293IOServiceOpen( 1294 io_service_t service, 1295 task_port_t owningTask, 1296 uint32_t type, 1297 io_connect_t * connect ) 1298{ 1299 kern_return_t kr; 1300 kern_return_t result; 1301 1302 kr = io_service_open_extended( service, 1303 owningTask, type, NDR_record, NULL, 0, &result, connect ); 1304 1305 if (KERN_SUCCESS == kr) 1306 kr = result; 1307 1308 return (kr); 1309} 1310 1311kern_return_t 1312IOServiceClose( 1313 io_connect_t connect ) 1314{ 1315 kern_return_t kr; 1316 1317 kr = io_service_close( connect); 1318 IOObjectRelease( connect ); 1319 1320 return( kr ); 1321} 1322 1323kern_return_t 1324IOServiceRequestProbe( 1325 io_service_t service, 1326 uint32_t options ) 1327{ 1328 return( io_service_request_probe( service, options )); 1329} 1330 1331kern_return_t 1332IOServiceAuthorize( 1333 io_service_t service, 1334 uint32_t options ) 1335{ 1336 kern_return_t status; 1337 uint64_t serviceID; 1338 1339 status = IORegistryEntryGetRegistryEntryID( service, &serviceID ); 1340 1341 if ( status == kIOReturnSuccess ) 1342 { 1343 xpc_object_t message; 1344 1345 message = xpc_dictionary_create( NULL, NULL, 0 ); 1346 1347 if ( message ) 1348 { 1349 xpc_connection_t connection; 1350 1351 xpc_dictionary_set_uint64( message, "options", options ); 1352 xpc_dictionary_set_uint64( message, "service", serviceID ); 1353 1354 connection = xpc_connection_create( "com.apple.iokit.IOServiceAuthorizeAgent", NULL ); 1355 1356 if ( connection ) 1357 { 1358 xpc_object_t reply; 1359 1360 xpc_connection_set_event_handler( connection, ^( xpc_object_t object __unused ) { } ); 1361 1362 xpc_connection_resume( connection ); 1363 1364 reply = xpc_connection_send_message_with_reply_sync( connection, message ); 1365 1366 if ( reply ) 1367 { 1368 xpc_type_t type; 1369 1370 type = xpc_get_type( reply ); 1371 1372 if ( type == XPC_TYPE_DICTIONARY ) 1373 { 1374 status = xpc_dictionary_get_uint64( reply, "status" ); 1375 } 1376 else 1377 { 1378 status = kIOReturnBadMessageID; 1379 } 1380 1381 xpc_release( reply ); 1382 } 1383 else 1384 { 1385 status = kIOReturnNotPrivileged; 1386 } 1387 1388 xpc_release( connection ); 1389 } 1390 else 1391 { 1392 status = kIOReturnUnsupported; 1393 } 1394 1395 xpc_release( message ); 1396 } 1397 else 1398 { 1399 status = kIOReturnNoMemory; 1400 } 1401 } 1402 else 1403 { 1404 status = kIOReturnBadArgument; 1405 } 1406 1407 return status; 1408} 1409 1410int 1411IOServiceOpenAsFileDescriptor( 1412 io_service_t service, 1413 int oflag ) 1414{ 1415 kern_return_t status; 1416 uint64_t serviceID; 1417 int fd = -1; 1418 1419 status = IORegistryEntryGetRegistryEntryID( service, &serviceID ); 1420 1421 if ( status == kIOReturnSuccess ) 1422 { 1423 xpc_object_t message; 1424 1425 message = xpc_dictionary_create( NULL, NULL, 0 ); 1426 1427 if ( message ) 1428 { 1429 xpc_connection_t connection; 1430 1431 xpc_dictionary_set_int64( message, "oflag", oflag ); 1432 xpc_dictionary_set_uint64( message, "service", serviceID ); 1433 1434 connection = xpc_connection_create( "com.apple.iokit.ioserviceauthorized", NULL ); 1435 1436 if ( connection ) 1437 { 1438 xpc_object_t reply; 1439 1440 xpc_connection_set_event_handler( connection, ^( xpc_object_t object __unused ) { } ); 1441 1442 xpc_connection_resume( connection ); 1443 1444 reply = xpc_connection_send_message_with_reply_sync( connection, message ); 1445 1446 if ( reply ) 1447 { 1448 xpc_type_t type; 1449 1450 type = xpc_get_type( reply ); 1451 1452 if ( type == XPC_TYPE_DICTIONARY ) 1453 { 1454 status = xpc_dictionary_get_uint64( reply, "status" ); 1455 1456 if ( status == kIOReturnSuccess ) 1457 { 1458 fd = xpc_dictionary_dup_fd( reply, "fd" ); 1459 } 1460 } 1461 else 1462 { 1463 status = unix_err( EBADMSG ); 1464 } 1465 1466 xpc_release( reply ); 1467 } 1468 else 1469 { 1470 status = unix_err( EACCES ); 1471 } 1472 1473 xpc_release( connection ); 1474 } 1475 else 1476 { 1477 status = unix_err( ENOTSUP ); 1478 } 1479 1480 xpc_release( message ); 1481 } 1482 else 1483 { 1484 status = unix_err( ENOMEM ); 1485 } 1486 } 1487 else 1488 { 1489 status = unix_err( EINVAL ); 1490 } 1491 1492 if ( status ) 1493 { 1494 if ( unix_err( err_get_code( status ) ) == status ) 1495 { 1496 errno = err_get_code( status ); 1497 } 1498 } 1499 1500 return fd; 1501} 1502 1503kern_return_t 1504_IOServiceGetAuthorizationID( 1505 io_service_t service, 1506 uint64_t * authorizationID ) 1507{ 1508 return( io_service_get_authorization_id( service, authorizationID ) ); 1509} 1510 1511kern_return_t 1512_IOServiceSetAuthorizationID( 1513 io_service_t service, 1514 uint64_t authorizationID ) 1515{ 1516 return( io_service_set_authorization_id( service, authorizationID ) ); 1517} 1518 1519/* 1520 * IOService connection 1521 */ 1522kern_return_t 1523IOConnectAddRef( 1524 io_connect_t connect ) 1525{ 1526 return mach_port_mod_refs(mach_task_self(), 1527 connect, 1528 MACH_PORT_RIGHT_SEND, 1529 1); 1530} 1531 1532kern_return_t 1533IOConnectRelease( 1534 io_connect_t connect ) 1535{ 1536 // XXX gvdl: Check with Simon about last reference removal 1537 return mach_port_mod_refs(mach_task_self(), 1538 connect, 1539 MACH_PORT_RIGHT_SEND, 1540 -1); 1541} 1542 1543kern_return_t 1544IOConnectGetService( 1545 io_connect_t connect, 1546 io_service_t * service ) 1547{ 1548 return( io_connect_get_service( connect, service )); 1549} 1550 1551kern_return_t 1552IOConnectSetNotificationPort( 1553 io_connect_t connect, 1554 uint32_t type, 1555 mach_port_t port, 1556 uintptr_t reference ) 1557{ 1558 return( io_connect_set_notification_port( connect, 1559 type, port, reference)); 1560} 1561 1562kern_return_t IOConnectMapMemory( 1563 io_connect_t connect, 1564 uint32_t memoryType, 1565 task_port_t intoTask, 1566 vm_address_t *atAddress, 1567 vm_size_t *ofSize, 1568 IOOptionBits options ) 1569{ 1570#if __LP64__ 1571 return io_connect_map_memory_into_task 1572 (connect, memoryType, intoTask, (mach_vm_address_t *) atAddress, (mach_vm_size_t *) ofSize, options); 1573 1574#else 1575 return io_connect_map_memory 1576 (connect, memoryType, intoTask, atAddress, ofSize, options); 1577#endif 1578} 1579 1580kern_return_t IOConnectMapMemory64( 1581 io_connect_t connect, 1582 uint32_t memoryType, 1583 task_port_t intoTask, 1584 mach_vm_address_t *atAddress, 1585 mach_vm_size_t *ofSize, 1586 IOOptionBits options ) 1587{ 1588 return io_connect_map_memory_into_task 1589 (connect, memoryType, intoTask, atAddress, ofSize, options); 1590} 1591 1592kern_return_t 1593IOConnectUnmapMemory( 1594 io_connect_t connect, 1595 uint32_t memoryType, 1596 task_port_t fromTask, 1597 vm_address_t atAddress ) 1598{ 1599#if __LP64__ 1600 return io_connect_unmap_memory_from_task 1601 (connect, memoryType, fromTask, atAddress); 1602#else 1603 return io_connect_unmap_memory 1604 (connect, memoryType, fromTask, atAddress); 1605#endif 1606} 1607 1608kern_return_t IOConnectUnmapMemory64( 1609 io_connect_t connect, 1610 uint32_t memoryType, 1611 task_port_t fromTask, 1612 mach_vm_address_t atAddress) 1613{ 1614 return io_connect_unmap_memory_from_task 1615 (connect, memoryType, fromTask, atAddress); 1616} 1617 1618kern_return_t 1619IOConnectAddClient( 1620 io_connect_t connect, 1621 io_connect_t client ) 1622{ 1623 return( io_connect_add_client( connect, client)); 1624} 1625 1626/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ 1627 1628#if USE_TRAP_TRANSPORT 1629 1630#define kUseTrapTransport 1 1631__private_extern__ char checkBegin = 0, checkEnd = 0; 1632static __inline__ void checkPtrRange(void *ptr, IOByteCount cnt) 1633{ 1634 checkBegin = ((uint8_t *) ptr)[0]; 1635 checkEnd = ((uint8_t *) ptr)[cnt]; 1636} 1637 1638#else 1639 1640#define kUseTrapTransport 0 1641 1642#endif /* USE_TRAP_TRANSPORT */ 1643 1644#define reinterpret_cast_mach_vm_address_t(p) \ 1645 ((mach_vm_address_t) (uintptr_t) p) 1646 1647kern_return_t 1648IOConnectCallMethod( 1649 mach_port_t connection, // In 1650 uint32_t selector, // In 1651 const uint64_t *input, // In 1652 uint32_t inputCnt, // In 1653 const void *inputStruct, // In 1654 size_t inputStructCnt, // In 1655 uint64_t *output, // Out 1656 uint32_t *outputCnt, // In/Out 1657 void *outputStruct, // Out 1658 size_t *outputStructCntP) // In/Out 1659{ 1660 kern_return_t rtn; 1661 1662 void *inb_input = 0; 1663 mach_msg_type_number_t inb_input_size = 0; 1664 void *inb_output = 0; 1665 mach_msg_type_number_t inb_output_size = 0; 1666 1667 mach_vm_address_t ool_input = 0; 1668 mach_vm_size_t ool_input_size = 0; 1669 mach_vm_address_t ool_output = 0; 1670 mach_vm_size_t ool_output_size = 0; 1671 io_buf_ptr_t var_output = NULL; 1672 mach_msg_type_number_t var_output_size = 0; 1673 1674 if (inputStructCnt <= sizeof(io_struct_inband_t)) { 1675 inb_input = (void *) inputStruct; 1676 inb_input_size = (mach_msg_type_number_t) inputStructCnt; 1677 } 1678 else { 1679 ool_input = reinterpret_cast_mach_vm_address_t(inputStruct); 1680 ool_input_size = inputStructCnt; 1681 } 1682 1683 if (!outputCnt) { 1684 static uint32_t zero = 0; 1685 outputCnt = &zero; 1686 } 1687 1688 if (outputStructCntP) { 1689 size_t size = *outputStructCntP; 1690 1691 if (size == (size_t) kIOConnectMethodVarOutputSize) { 1692 1693 rtn = io_connect_method_var_output( 1694 connection, selector, 1695 (uint64_t *) input, inputCnt, 1696 inb_input, inb_input_size, 1697 ool_input, ool_input_size, 1698 inb_output, &inb_output_size, 1699 output, outputCnt, 1700 &var_output, &var_output_size); 1701 1702 *(void **)outputStruct = var_output; 1703 *outputStructCntP = var_output_size; 1704 1705 return (rtn); 1706 1707 } 1708 else if (size <= sizeof(io_struct_inband_t)) { 1709 inb_output = outputStruct; 1710 inb_output_size = (mach_msg_type_number_t) size; 1711 } 1712 else { 1713 ool_output = reinterpret_cast_mach_vm_address_t(outputStruct); 1714 ool_output_size = (mach_vm_size_t) size; 1715 } 1716 } 1717 1718 rtn = io_connect_method(connection, selector, 1719 (uint64_t *) input, inputCnt, 1720 inb_input, inb_input_size, 1721 ool_input, ool_input_size, 1722 inb_output, &inb_output_size, 1723 output, outputCnt, 1724 ool_output, &ool_output_size); 1725 1726 if (outputStructCntP) { 1727 if (*outputStructCntP <= sizeof(io_struct_inband_t)) 1728 *outputStructCntP = (size_t) inb_output_size; 1729 else 1730 *outputStructCntP = (size_t) ool_output_size; 1731 } 1732 1733 return rtn; 1734} 1735 1736kern_return_t 1737IOConnectCallAsyncMethod( 1738 mach_port_t connection, // In 1739 uint32_t selector, // In 1740 mach_port_t wakePort, // In 1741 uint64_t *reference, // In 1742 uint32_t referenceCnt, // In 1743 const uint64_t *input, // In 1744 uint32_t inputCnt, // In 1745 const void *inputStruct, // In 1746 size_t inputStructCnt, // In 1747 uint64_t *output, // Out 1748 uint32_t *outputCnt, // In/Out 1749 void *outputStruct, // Out 1750 size_t *outputStructCntP) // In/Out 1751{ 1752 kern_return_t rtn; 1753 1754 void *inb_input = 0; 1755 mach_msg_type_number_t inb_input_size = 0; 1756 void *inb_output = 0; 1757 mach_msg_type_number_t inb_output_size = 0; 1758 1759 mach_vm_address_t ool_input = 0; 1760 mach_vm_size_t ool_input_size = 0; 1761 mach_vm_address_t ool_output = 0; 1762 mach_vm_size_t ool_output_size = 0; 1763 1764 if (inputStructCnt <= sizeof(io_struct_inband_t)) { 1765 inb_input = (void *) inputStruct; 1766 inb_input_size = (mach_msg_type_number_t) inputStructCnt; 1767 } 1768 else { 1769 ool_input = reinterpret_cast_mach_vm_address_t(inputStruct); 1770 ool_input_size = inputStructCnt; 1771 } 1772 1773 if (!outputCnt) { 1774 static uint32_t zero = 0; 1775 outputCnt = &zero; 1776 } 1777 1778 if (outputStructCntP) { 1779 size_t size = *outputStructCntP; 1780 1781 if (size <= sizeof(io_struct_inband_t)) { 1782 inb_output = outputStruct; 1783 inb_output_size = (mach_msg_type_number_t) size; 1784 } 1785 else { 1786 ool_output = reinterpret_cast_mach_vm_address_t(outputStruct); 1787 ool_output_size = (mach_vm_size_t) size; 1788 } 1789 } 1790 1791 rtn = io_connect_async_method(connection, wakePort, 1792 reference, referenceCnt, 1793 selector, 1794 (uint64_t *) input, inputCnt, 1795 inb_input, inb_input_size, 1796 ool_input, ool_input_size, 1797 inb_output, &inb_output_size, 1798 output, outputCnt, 1799 ool_output, &ool_output_size); 1800 1801 if (outputStructCntP) { 1802 if (*outputStructCntP <= sizeof(io_struct_inband_t)) 1803 *outputStructCntP = (size_t) inb_output_size; 1804 else 1805 *outputStructCntP = (size_t) ool_output_size; 1806 } 1807 1808 return rtn; 1809} 1810 1811kern_return_t 1812IOConnectCallStructMethod( 1813 mach_port_t connection, // In 1814 uint32_t selector, // In 1815 const void *inputStruct, // In 1816 size_t inputStructCnt, // In 1817 void *outputStruct, // Out 1818 size_t *outputStructCnt) // In/Out 1819{ 1820 return IOConnectCallMethod(connection, selector, 1821 NULL, 0, 1822 inputStruct, inputStructCnt, 1823 NULL, NULL, 1824 outputStruct, outputStructCnt); 1825} 1826 1827kern_return_t 1828IOConnectCallAsyncStructMethod( 1829 mach_port_t connection, // In 1830 uint32_t selector, // In 1831 mach_port_t wakePort, // In 1832 uint64_t *reference, // In 1833 uint32_t referenceCnt, // In 1834 const void *inputStruct, // In 1835 size_t inputStructCnt, // In 1836 void *outputStruct, // Out 1837 size_t *outputStructCnt) // In/Out 1838{ 1839 return IOConnectCallAsyncMethod(connection, selector, wakePort, 1840 reference, referenceCnt, 1841 NULL, 0, 1842 inputStruct, inputStructCnt, 1843 NULL, NULL, 1844 outputStruct, outputStructCnt); 1845} 1846 1847kern_return_t 1848IOConnectCallScalarMethod( 1849 mach_port_t connection, // In 1850 uint32_t selector, // In 1851 const uint64_t *input, // In 1852 uint32_t inputCnt, // In 1853 uint64_t *output, // Out 1854 uint32_t *outputCnt) // In/Out 1855{ 1856 return IOConnectCallMethod(connection, selector, 1857 input, inputCnt, 1858 NULL, 0, 1859 output, outputCnt, 1860 NULL, NULL); 1861} 1862 1863kern_return_t 1864IOConnectCallAsyncScalarMethod( 1865 mach_port_t connection, // In 1866 uint32_t selector, // In 1867 mach_port_t wakePort, // In 1868 uint64_t *reference, // In 1869 uint32_t referenceCnt, // In 1870 const uint64_t *input, // In 1871 uint32_t inputCnt, // In 1872 uint64_t *output, // Out 1873 uint32_t *outputCnt) // In/Out 1874{ 1875 return IOConnectCallAsyncMethod(connection, selector, wakePort, 1876 reference, referenceCnt, 1877 input, inputCnt, 1878 NULL, 0, 1879 output, outputCnt, 1880 NULL, NULL); 1881} 1882 1883/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ 1884 1885kern_return_t 1886IOConnectTrap0(io_connect_t connect, 1887 uint32_t index) 1888{ 1889 return iokit_user_client_trap(connect, index, 0, 0, 0, 0, 0, 0); 1890} 1891 1892kern_return_t 1893IOConnectTrap1(io_connect_t connect, 1894 uint32_t index, 1895 uintptr_t p1 ) 1896{ 1897 return iokit_user_client_trap(connect, index, p1, 0, 0, 0, 0, 0); 1898} 1899 1900kern_return_t 1901IOConnectTrap2(io_connect_t connect, 1902 uint32_t index, 1903 uintptr_t p1, 1904 uintptr_t p2 ) 1905{ 1906 return iokit_user_client_trap(connect, index, p1, p2, 0, 0, 0, 0); 1907} 1908 1909kern_return_t 1910IOConnectTrap3(io_connect_t connect, 1911 uint32_t index, 1912 uintptr_t p1, 1913 uintptr_t p2, 1914 uintptr_t p3 ) 1915{ 1916 return iokit_user_client_trap(connect, index, p1, p2, p3, 0, 0, 0); 1917} 1918 1919kern_return_t 1920IOConnectTrap4(io_connect_t connect, 1921 uint32_t index, 1922 uintptr_t p1, 1923 uintptr_t p2, 1924 uintptr_t p3, 1925 uintptr_t p4 ) 1926{ 1927 return iokit_user_client_trap(connect, index, p1, p2, p3, p4, 0, 0); 1928} 1929 1930kern_return_t 1931IOConnectTrap5(io_connect_t connect, 1932 uint32_t index, 1933 uintptr_t p1, 1934 uintptr_t p2, 1935 uintptr_t p3, 1936 uintptr_t p4, 1937 uintptr_t p5 ) 1938{ 1939 return iokit_user_client_trap(connect, index, p1, p2, p3, p4, p5, 0); 1940} 1941 1942kern_return_t 1943IOConnectTrap6(io_connect_t connect, 1944 uint32_t index, 1945 uintptr_t p1, 1946 uintptr_t p2, 1947 uintptr_t p3, 1948 uintptr_t p4, 1949 uintptr_t p5, 1950 uintptr_t p6 ) 1951{ 1952 return iokit_user_client_trap(connect, index, p1, p2, p3, p4, p5, p6); 1953} 1954 1955/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ 1956 1957kern_return_t 1958IOConnectSetCFProperties( 1959 io_connect_t connect, 1960 CFTypeRef properties ) 1961{ 1962 CFDataRef data; 1963 kern_return_t kr; 1964 kern_return_t result; 1965 1966 data = IOCFSerialize( properties, gIOKitLibSerializeOptions ); 1967 if( !data) 1968 return( kIOReturnUnsupported ); 1969 1970 kr = io_connect_set_properties( connect, 1971 (char *) CFDataGetBytePtr(data), CFDataGetLength(data), 1972 &result ); 1973 1974 CFRelease(data); 1975 1976 if( KERN_SUCCESS == kr) 1977 kr = result; 1978 1979 return( kr ); 1980} 1981 1982kern_return_t 1983IOConnectSetCFProperty( 1984 io_connect_t connect, 1985 CFStringRef propertyName, 1986 CFTypeRef property ) 1987{ 1988 CFDictionaryRef dict; 1989 kern_return_t kr; 1990 1991 CFTypeRef name = propertyName; 1992 dict = CFDictionaryCreate( kCFAllocatorDefault, 1993 &name, &property, 1, 1994 &kCFTypeDictionaryKeyCallBacks, 1995 &kCFTypeDictionaryValueCallBacks ); 1996 if( !dict) 1997 return( kIOReturnNoMemory ); 1998 1999 kr = IOConnectSetCFProperties( connect, dict ); 2000 CFRelease( dict ); 2001 2002 return( kr ); 2003} 2004 2005 2006/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ 2007 2008/* 2009 * IORegistry accessors 2010 */ 2011 2012kern_return_t 2013IORegistryCreateIterator( 2014 mach_port_t _masterPort, 2015 const io_name_t plane, 2016 IOOptionBits options, 2017 io_iterator_t * iterator ) 2018{ 2019 kern_return_t kr; 2020 mach_port_t masterPort; 2021 2022 if (MACH_PORT_NULL == _masterPort) 2023 masterPort = __IOGetDefaultMasterPort(); 2024 else 2025 masterPort = _masterPort; 2026 2027 kr = io_registry_create_iterator( masterPort, (char *) plane, 2028 options, iterator); 2029 2030 if ((masterPort != MACH_PORT_NULL) && (masterPort != _masterPort)) 2031 mach_port_deallocate(mach_task_self(), masterPort); 2032 2033 return( kr ); 2034} 2035 2036kern_return_t 2037IORegistryEntryCreateIterator( 2038 io_registry_entry_t entry, 2039 const io_name_t plane, 2040 IOOptionBits options, 2041 io_iterator_t * iterator ) 2042{ 2043 return( io_registry_entry_create_iterator( entry, (char *) plane, 2044 options, iterator)); 2045} 2046 2047kern_return_t 2048IORegistryIteratorEnterEntry( 2049 io_iterator_t iterator ) 2050{ 2051 return( io_registry_iterator_enter_entry( iterator)); 2052} 2053 2054 2055kern_return_t 2056IORegistryIteratorExitEntry( 2057 io_iterator_t iterator ) 2058{ 2059 return( io_registry_iterator_exit_entry( iterator)); 2060} 2061 2062io_registry_entry_t 2063IORegistryEntryFromPath( 2064 mach_port_t _masterPort, 2065 const io_string_t path ) 2066{ 2067 kern_return_t kr; 2068 io_registry_entry_t entry; 2069 mach_port_t masterPort; 2070 2071 if (MACH_PORT_NULL == _masterPort) 2072 masterPort = __IOGetDefaultMasterPort(); 2073 else 2074 masterPort = _masterPort; 2075 2076 kr = io_registry_entry_from_path( masterPort, (char *) path, &entry ); 2077 if( kIOReturnSuccess != kr) 2078 entry = 0; 2079 2080 if ((masterPort != MACH_PORT_NULL) && (masterPort != _masterPort)) 2081 mach_port_deallocate(mach_task_self(), masterPort); 2082 2083 return( entry ); 2084} 2085 2086io_registry_entry_t 2087IORegistryGetRootEntry( 2088 mach_port_t _masterPort ) 2089{ 2090 kern_return_t kr; 2091 mach_port_t masterPort; 2092 io_registry_entry_t entry; 2093 2094 if (MACH_PORT_NULL == _masterPort) 2095 masterPort = __IOGetDefaultMasterPort(); 2096 else 2097 masterPort = _masterPort; 2098 2099 kr = io_registry_get_root_entry( masterPort, &entry ); 2100 if( kIOReturnSuccess != kr) 2101 entry = 0; 2102 2103 if ((masterPort != MACH_PORT_NULL) && (masterPort != _masterPort)) 2104 mach_port_deallocate(mach_task_self(), masterPort); 2105 2106 return( entry ); 2107} 2108 2109kern_return_t 2110IORegistryEntryGetPath( 2111 io_registry_entry_t entry, 2112 const io_name_t plane, 2113 io_string_t path ) 2114{ 2115 return( io_registry_entry_get_path( entry, (char *) plane, path )); 2116} 2117 2118boolean_t 2119IORegistryEntryInPlane( 2120 io_registry_entry_t entry, 2121 const io_name_t plane ) 2122{ 2123 boolean_t inPlane; 2124 2125 if( kIOReturnSuccess != io_registry_entry_in_plane( 2126 entry, (char *) plane, &inPlane )) 2127 inPlane = false; 2128 2129 return( inPlane ); 2130} 2131 2132kern_return_t 2133IORegistryEntryGetName( 2134 io_registry_entry_t entry, 2135 io_name_t name ) 2136{ 2137 return( io_registry_entry_get_name( entry, name )); 2138} 2139 2140kern_return_t 2141IORegistryEntryGetNameInPlane( 2142 io_registry_entry_t entry, 2143 const io_name_t plane, 2144 io_name_t name ) 2145{ 2146 if( NULL == plane) 2147 plane = ""; 2148 return( io_registry_entry_get_name_in_plane( entry, 2149 (char *) plane, name )); 2150} 2151 2152kern_return_t 2153IORegistryEntryGetLocationInPlane( 2154 io_registry_entry_t entry, 2155 const io_name_t plane, 2156 io_name_t location ) 2157{ 2158 if( NULL == plane) 2159 plane = ""; 2160 return( io_registry_entry_get_location_in_plane( entry, 2161 (char *) plane, location )); 2162} 2163 2164kern_return_t 2165IORegistryEntryGetRegistryEntryID( 2166 io_registry_entry_t entry, 2167 uint64_t * entryID ) 2168{ 2169 kern_return_t kr; 2170 2171 kr = io_registry_entry_get_registry_entry_id(entry, entryID); 2172 if (KERN_SUCCESS != kr) 2173 *entryID = 0; 2174 2175 return (kr); 2176} 2177 2178kern_return_t 2179IORegistryEntryCreateCFProperties( 2180 io_registry_entry_t entry, 2181 CFMutableDictionaryRef * properties, 2182 CFAllocatorRef allocator, 2183 IOOptionBits options __unused ) 2184{ 2185 kern_return_t kr; 2186 uint32_t size; 2187 char * propertiesBuffer; 2188 CFStringRef errorString; 2189 const char * cstr; 2190 2191#if IOKIT_SERVER_VERSION >= 20140421 2192 if (kIOCFSerializeToBinary & gIOKitLibSerializeOptions) 2193 { 2194 kr = io_registry_entry_get_properties_bin(entry, &propertiesBuffer, &size); 2195 } 2196 else 2197#endif /* IOKIT_SERVER_VERSION >= 20140421 */ 2198 { 2199 kr = io_registry_entry_get_properties(entry, &propertiesBuffer, &size); 2200 } 2201 2202 if (kr != kIOReturnSuccess) return (kr); 2203 2204 *properties = (CFMutableDictionaryRef) IOCFUnserializeWithSize(propertiesBuffer, size, allocator, 2205 0, &errorString); 2206 if (!(*properties) && errorString) 2207 { 2208 if ((cstr = CFStringGetCStringPtr(errorString, kCFStringEncodingMacRoman))) printf("%s\n", cstr); 2209 CFRelease(errorString); 2210 } 2211 2212 // free propertiesBuffer ! 2213 vm_deallocate(mach_task_self(), (vm_address_t)propertiesBuffer, size); 2214 2215 return( *properties ? kIOReturnSuccess : kIOReturnInternalError ); 2216} 2217 2218CFTypeRef 2219IORegistryEntryCreateCFProperty( 2220 io_registry_entry_t entry, 2221 CFStringRef key, 2222 CFAllocatorRef allocator, 2223 IOOptionBits options __unused ) 2224{ 2225 return (IORegistryEntrySearchCFProperty(entry, NULL, key, allocator, kNilOptions)); 2226} 2227 2228CFTypeRef 2229IORegistryEntrySearchCFProperty( 2230 io_registry_entry_t entry, 2231 const io_name_t plane, 2232 CFStringRef key, 2233 CFAllocatorRef allocator, 2234 IOOptionBits options ) 2235{ 2236 IOReturn kr; 2237 CFTypeRef type; 2238 uint32_t size; 2239 char * propertiesBuffer; 2240 CFStringRef errorString; 2241 const char * cStr; 2242 char * buffer = NULL; 2243 2244 cStr = CFStringGetCStringPtr( key, kCFStringEncodingMacRoman); 2245 if( !cStr) 2246 { 2247 CFIndex bufferSize = CFStringGetMaximumSizeForEncoding( CFStringGetLength(key), 2248 kCFStringEncodingMacRoman) + sizeof('\0'); 2249 buffer = malloc( bufferSize); 2250 if( buffer && CFStringGetCString( key, buffer, bufferSize, kCFStringEncodingMacRoman)) 2251 cStr = buffer; 2252 } 2253 2254 if (!cStr) kr = kIOReturnError; 2255#if IOKIT_SERVER_VERSION >= 20140421 2256 else if (kIOCFSerializeToBinary & gIOKitLibSerializeOptions) 2257 { 2258 if (!(kIORegistryIterateRecursively & options)) plane = "\0"; 2259 kr = io_registry_entry_get_property_bin(entry, (char *) plane, (char *) cStr, 2260 options, &propertiesBuffer, &size); 2261 } 2262#endif /* IOKIT_SERVER_VERSION >= 20140421 */ 2263 else if (kIORegistryIterateRecursively & options) 2264 { 2265 kr = io_registry_entry_get_property_recursively(entry, (char *) plane, (char *) cStr, 2266 options, &propertiesBuffer, &size); 2267 } 2268 else 2269 { 2270 kr = io_registry_entry_get_property(entry, (char *) cStr, &propertiesBuffer, &size); 2271 } 2272 2273 if (buffer) free(buffer); 2274 if (kr != kIOReturnSuccess) return (NULL); 2275 2276 type = (CFMutableDictionaryRef) IOCFUnserializeWithSize(propertiesBuffer, size, allocator, 2277 0, &errorString); 2278 if (!type && errorString) 2279 { 2280 if ((cStr = CFStringGetCStringPtr(errorString, kCFStringEncodingMacRoman))) printf("%s\n", cStr); 2281 CFRelease(errorString); 2282 } 2283 2284 // free propertiesBuffer ! 2285 vm_deallocate(mach_task_self(), (vm_address_t)propertiesBuffer, size); 2286 2287 return( type ); 2288} 2289 2290kern_return_t 2291IORegistryEntryGetProperty( 2292 io_registry_entry_t entry, 2293 const io_name_t name, 2294 io_struct_inband_t buffer, 2295 uint32_t * size ) 2296{ 2297 return( io_registry_entry_get_property_bytes( entry, (char *) name, 2298 buffer, size )); 2299} 2300 2301kern_return_t 2302IORegistryEntrySetCFProperties( 2303 io_registry_entry_t entry, 2304 CFTypeRef properties ) 2305{ 2306 CFDataRef data; 2307 kern_return_t kr; 2308 kern_return_t result; 2309 2310 data = IOCFSerialize( properties, gIOKitLibSerializeOptions ); 2311 if( !data) 2312 return( kIOReturnUnsupported ); 2313 2314 kr = io_registry_entry_set_properties( entry, 2315 (char *) CFDataGetBytePtr(data), CFDataGetLength(data), 2316 &result ); 2317 2318 CFRelease(data); 2319 2320 if( KERN_SUCCESS == kr) 2321 kr = result; 2322 2323 return( kr ); 2324} 2325 2326kern_return_t 2327IORegistryEntrySetCFProperty( 2328 io_registry_entry_t entry, 2329 CFStringRef propertyName, 2330 CFTypeRef property ) 2331{ 2332 CFDictionaryRef dict; 2333 kern_return_t kr; 2334 2335 dict = CFDictionaryCreate( kCFAllocatorDefault, 2336 (const void **) &propertyName, (const void **) &property, 1, 2337 &kCFTypeDictionaryKeyCallBacks, 2338 &kCFTypeDictionaryValueCallBacks ); 2339 if( !dict) 2340 return( kIOReturnNoMemory ); 2341 2342 kr = IORegistryEntrySetCFProperties( entry, dict ); 2343 CFRelease( dict ); 2344 2345 return( kr ); 2346} 2347 2348kern_return_t 2349IORegistryEntryGetChildIterator( 2350 io_registry_entry_t entry, 2351 const io_name_t plane, 2352 io_iterator_t * iterator ) 2353{ 2354 return( io_registry_entry_get_child_iterator( entry, 2355 (char *) plane, iterator)); 2356} 2357 2358kern_return_t 2359IORegistryEntryGetParentIterator( 2360 io_registry_entry_t entry, 2361 const io_name_t plane, 2362 io_iterator_t * iterator ) 2363{ 2364 return( io_registry_entry_get_parent_iterator( entry, 2365 (char *) plane, iterator)); 2366} 2367 2368kern_return_t 2369IORegistryEntryGetChildEntry( 2370 io_registry_entry_t entry, 2371 const io_name_t plane, 2372 io_registry_entry_t * child ) 2373{ 2374 kern_return_t kr; 2375 io_iterator_t iter; 2376 2377 kr = IORegistryEntryGetChildIterator( entry, plane, &iter ); 2378 2379 if( KERN_SUCCESS == kr) { 2380 2381 *child = IOIteratorNext( iter ); 2382 IOObjectRelease( iter ); 2383 if( MACH_PORT_NULL == *child) 2384 kr = kIOReturnNoDevice; 2385 } 2386 2387 return( kr ); 2388} 2389 2390kern_return_t 2391IORegistryEntryGetParentEntry( 2392 io_registry_entry_t entry, 2393 const io_name_t plane, 2394 io_registry_entry_t * parent ) 2395{ 2396 kern_return_t kr; 2397 io_iterator_t iter; 2398 2399 kr = IORegistryEntryGetParentIterator( entry, plane, &iter ); 2400 2401 if( KERN_SUCCESS == kr) { 2402 2403 *parent = IOIteratorNext( iter ); 2404 IOObjectRelease( iter ); 2405 if( MACH_PORT_NULL == *parent) 2406 kr = kIOReturnNoDevice; 2407 } 2408 2409 return( kr ); 2410} 2411/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ 2412 2413kern_return_t 2414IOServiceOFPathToBSDName(mach_port_t masterPort, 2415 const io_name_t openFirmwarePath, 2416 io_name_t bsdName) 2417{ 2418 kern_return_t kr; 2419 io_registry_entry_t service; 2420 io_iterator_t services; 2421 2422 // Initialize return values. 2423 2424 bsdName[0] = 0; 2425 2426 // Find objects matching the given open firmware name. 2427 2428 kr = IOServiceGetMatchingServices( 2429 /* mach_port_t */ masterPort, 2430 /* void * */ IOOpenFirmwarePathMatching( 2431 /* mach_port_t */ masterPort, 2432 /* uint32_t */ 0, 2433 /* const char * */ openFirmwarePath ), 2434 /* io_iterator * */ &services ); 2435 2436 if( KERN_SUCCESS != kr ) return( kr ); 2437 2438 // Obtain the first (and presumably the only) match. 2439 2440 service = IOIteratorNext( services ); 2441 2442 if( service ) { 2443 2444 // Obtain the BSD name property from this object. 2445 2446 uint32_t bsdNameSize = sizeof(io_name_t); 2447 2448 kr = IORegistryEntryGetProperty( 2449 /* mach_port_t */ service, 2450 /* io_name_t */ kIOBSDNameKey, 2451 /* io_struct_inband_t */ bsdName, 2452 /* uint32_t * */ &bsdNameSize); 2453 2454 if( KERN_SUCCESS != kr ) bsdName[0] = 0; 2455 2456 IOObjectRelease( service ); 2457 } 2458 else { 2459 kr = KERN_FAILURE; 2460 } 2461 2462 IOObjectRelease( services ); 2463 2464 return kr; 2465} 2466 2467/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ 2468 2469kern_return_t 2470IOCatalogueSendData( 2471 mach_port_t _masterPort, 2472 uint32_t flag, 2473 const char *buffer, 2474 uint32_t size ) 2475{ 2476 kern_return_t kr; 2477 kern_return_t result; 2478 mach_port_t masterPort; 2479 2480 if (MACH_PORT_NULL == _masterPort) 2481 masterPort = __IOGetDefaultMasterPort(); 2482 else 2483 masterPort = _masterPort; 2484 2485 kr = io_catalog_send_data( masterPort, flag, 2486 (char *) buffer, size, &result ); 2487 if( KERN_SUCCESS == kr) 2488 kr = result; 2489 2490 if ((masterPort != MACH_PORT_NULL) && (masterPort != _masterPort)) 2491 mach_port_deallocate(mach_task_self(), masterPort); 2492 2493 return( kr ); 2494} 2495 2496kern_return_t 2497IOCatalogueTerminate( 2498 mach_port_t _masterPort, 2499 uint32_t flag, 2500 io_name_t description ) 2501{ 2502 kern_return_t kr; 2503 mach_port_t masterPort; 2504 2505 if (MACH_PORT_NULL == _masterPort) 2506 masterPort = __IOGetDefaultMasterPort(); 2507 else 2508 masterPort = _masterPort; 2509 2510 kr = io_catalog_terminate( masterPort, flag, description ); 2511 2512 if ((masterPort != MACH_PORT_NULL) && (masterPort != _masterPort)) 2513 mach_port_deallocate(mach_task_self(), masterPort); 2514 2515 return( kr ); 2516} 2517 2518kern_return_t 2519IOCatalogueGetData( 2520 mach_port_t _masterPort, 2521 uint32_t flag, 2522 char **buffer, 2523 uint32_t *size ) 2524{ 2525 kern_return_t kr; 2526 mach_port_t masterPort; 2527 2528 if (MACH_PORT_NULL == _masterPort) 2529 masterPort = __IOGetDefaultMasterPort(); 2530 else 2531 masterPort = _masterPort; 2532 2533 kr = io_catalog_get_data( masterPort, flag, (char **)buffer, (unsigned *)size ); 2534 2535 if ((masterPort != MACH_PORT_NULL) && (masterPort != _masterPort)) 2536 mach_port_deallocate(mach_task_self(), masterPort); 2537 2538 return( kr ); 2539} 2540 2541kern_return_t 2542IOCatlogueGetGenCount( 2543 mach_port_t _masterPort, 2544 uint32_t *genCount ) 2545{ 2546 kern_return_t kr; 2547 mach_port_t masterPort; 2548 2549 if (MACH_PORT_NULL == _masterPort) 2550 masterPort = __IOGetDefaultMasterPort(); 2551 else 2552 masterPort = _masterPort; 2553 2554 kr = io_catalog_get_gen_count( masterPort, genCount ); 2555 2556 if ((masterPort != MACH_PORT_NULL) && (masterPort != _masterPort)) 2557 mach_port_deallocate(mach_task_self(), masterPort); 2558 2559 return( kr ); 2560} 2561 2562kern_return_t 2563IOCatalogueModuleLoaded( 2564 mach_port_t _masterPort, 2565 io_name_t name ) 2566{ 2567 kern_return_t kr; 2568 mach_port_t masterPort; 2569 2570 if (MACH_PORT_NULL == _masterPort) 2571 masterPort = __IOGetDefaultMasterPort(); 2572 else 2573 masterPort = _masterPort; 2574 2575 kr = io_catalog_module_loaded( masterPort, name ); 2576 2577 if ((masterPort != MACH_PORT_NULL) && (masterPort != _masterPort)) 2578 mach_port_deallocate(mach_task_self(), masterPort); 2579 2580 return( kr ); 2581} 2582 2583kern_return_t 2584IOCatalogueReset( 2585 mach_port_t _masterPort, 2586 uint32_t flag ) 2587{ 2588 kern_return_t kr; 2589 mach_port_t masterPort; 2590 2591 if (MACH_PORT_NULL == _masterPort) 2592 masterPort = __IOGetDefaultMasterPort(); 2593 else 2594 masterPort = _masterPort; 2595 2596 kr = io_catalog_reset(masterPort, flag); 2597 2598 if ((masterPort != MACH_PORT_NULL) && (masterPort != _masterPort)) 2599 mach_port_deallocate(mach_task_self(), masterPort); 2600 2601 return( kr ); 2602} 2603 2604/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ 2605 2606// obsolete API 2607 2608kern_return_t 2609IORegistryCreateEnumerator( 2610 mach_port_t _masterPort, 2611 mach_port_t * enumerator ) 2612{ 2613 kern_return_t kr; 2614 mach_port_t masterPort; 2615 2616 if (MACH_PORT_NULL == _masterPort) 2617 masterPort = __IOGetDefaultMasterPort(); 2618 else 2619 masterPort = _masterPort; 2620 2621 kr = io_registry_create_iterator( masterPort, 2622 "IOService", true, enumerator ); 2623 2624 if ((masterPort != MACH_PORT_NULL) && (masterPort != _masterPort)) 2625 mach_port_deallocate(mach_task_self(), masterPort); 2626 2627 return( kr ); 2628} 2629 2630kern_return_t 2631IORegistryEnumeratorReset( 2632 mach_port_t enumerator ) 2633{ 2634 return( io_iterator_reset( enumerator)); 2635} 2636 2637 2638static io_object_t lastRegIter; 2639 2640kern_return_t 2641IORegistryEnumeratorNextConforming( 2642 mach_port_t enumerator, 2643 const char * name, 2644 boolean_t recursive __unused ) 2645{ 2646 io_object_t next = 0; 2647 2648 while( (next = IOIteratorNext( enumerator ))) { 2649 2650 if( IOObjectConformsTo( next, (char *) name )) 2651 break; 2652 2653 IOObjectRelease( next ); 2654 } 2655 2656 lastRegIter = next; 2657 2658 return( next ? kIOReturnSuccess : kIOReturnNoDevice ); 2659} 2660 2661 2662#if 0 2663kern_return_t 2664IORegistryGetProperties( 2665 mach_port_t enumerator , 2666 void ** properties ) 2667{ 2668 return( IORegistryEntryGetProperties( lastRegIter, 2669 (struct IOObject **)properties)); 2670} 2671#endif 2672 2673kern_return_t 2674IOOpenConnection( 2675 mach_port_t enumerator __unused, 2676 task_port_t owningTask, 2677 uint32_t type, 2678 mach_port_t * connect ) 2679{ 2680 kern_return_t kr; 2681 2682 kr = IOServiceOpen( lastRegIter, 2683 owningTask, type, connect ); 2684 2685 IOObjectRelease( lastRegIter ); 2686 2687 return( kr ); 2688} 2689 2690 2691kern_return_t 2692IOCloseConnection( 2693 mach_port_t connect ) 2694{ 2695 return( io_service_close( connect)); 2696} 2697 2698 2699kern_return_t 2700IOSetNotificationPort( 2701 mach_port_t connect, 2702 uint32_t type, 2703 mach_port_t port ) 2704{ 2705 return( io_connect_set_notification_port( connect, type, port, 0)); 2706} 2707kern_return_t 2708IORegisterClient( 2709 mach_port_t connect, 2710 mach_port_t client ) 2711{ 2712 return( io_connect_add_client( connect, client)); 2713} 2714 2715kern_return_t 2716IORegistryDisposeEnumerator( 2717 io_enumerator_t enumerator ) 2718{ 2719 return( IOObjectRelease( enumerator )); 2720} 2721 2722/* -------------------------- */ 2723 2724kern_return_t 2725IOCompatibiltyNumber( 2726 mach_port_t connect __unused, 2727 uint32_t * objectNumber ) 2728{ 2729 *objectNumber = 1; 2730 return( kIOReturnSuccess); 2731} 2732 2733 2734void 2735IOInitContainerClasses() 2736{ 2737} 2738 2739/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ 2740 2741/* 32bit binary compatibility routines for deprecated APIs */ 2742#if !defined(__LP64__) 2743 2744// Compatability routines with 32bit IOKitLib 2745kern_return_t 2746IOConnectMethodScalarIScalarO( 2747 io_connect_t connect, 2748 uint32_t index, 2749 IOItemCount inCount, 2750 IOItemCount scalarOutputCount, 2751 ... ) 2752{ 2753 uint64_t inData[6], outData[6]; 2754 kern_return_t err; 2755 uint32_t i, outCount; 2756 va_list val; 2757 2758 if (inCount + scalarOutputCount > 6) 2759 return MIG_ARRAY_TOO_LARGE; 2760 2761 va_start(val, scalarOutputCount); 2762 for (i = 0; i < inCount; i++) 2763 inData[i] = va_arg(val, uint32_t); 2764 2765 outCount = scalarOutputCount; 2766 err = IOConnectCallScalarMethod(connect, index, 2767 inData, inCount, outData, &outCount); 2768 2769 if( kIOReturnSuccess == err) { 2770 for (i = 0; i < outCount; i++) { 2771 uint32_t *out = va_arg(val, uint32_t *); 2772 *out = (uint32_t) outData[i]; 2773 } 2774 } 2775 va_end(val); 2776 2777 return err; 2778} 2779 2780kern_return_t 2781IOConnectMethodScalarIStructureO( 2782 io_connect_t connect, 2783 uint32_t index, 2784 IOItemCount inCount, 2785 IOByteCount * outSizeP, 2786 ... ) 2787{ 2788 uint64_t inData[6]; 2789 void *out = NULL; 2790 IOItemCount i; 2791 va_list val; 2792 2793 if (inCount > 6) 2794 return MIG_ARRAY_TOO_LARGE; 2795 2796 va_start(val, outSizeP); 2797 for (i = 0; i < inCount; i++) 2798 inData[i] = va_arg(val, uint32_t); 2799 if (outSizeP && *outSizeP) 2800 out = va_arg(val, void *); 2801 2802 kern_return_t err = IOConnectCallMethod(connect, index, 2803 inData, inCount, NULL, 0, 2804 NULL, 0, out, outSizeP); 2805 2806 va_end(val); 2807 2808 return err; 2809} 2810 2811kern_return_t 2812IOConnectMethodScalarIStructureI( 2813 io_connect_t connect, 2814 uint32_t index, 2815 IOItemCount inCount, 2816 IOByteCount inSize, 2817 ... ) 2818{ 2819 uint64_t inData[6]; 2820 uint8_t *in = NULL; 2821 va_list val; 2822 2823 if (inCount > 6) 2824 return MIG_ARRAY_TOO_LARGE; 2825 2826 va_start(val, inSize); 2827 for (IOItemCount i = 0; i < inCount; i++) 2828 inData[i] = va_arg(val, uint32_t); 2829 if (inSize) 2830 in = va_arg(val, void *); 2831 2832 kern_return_t err = IOConnectCallMethod(connect, index, 2833 inData, inCount, in, inSize, 2834 NULL, NULL, NULL, NULL); 2835 2836 va_end(val); 2837 2838 return err; 2839} 2840 2841kern_return_t 2842IOConnectMethodStructureIStructureO( 2843 io_connect_t connect, 2844 uint32_t index, 2845 IOItemCount inSize, 2846 IOByteCount * outSizeP, 2847 void * in, 2848 void * out ) 2849{ 2850 return IOConnectCallStructMethod(connect, index, in, inSize, out, outSizeP); 2851} 2852 2853kern_return_t 2854IOMapMemory( 2855 io_connect_t connect, 2856 uint32_t memoryType, 2857 task_port_t intoTask, 2858 vm_address_t * atAddress, 2859 vm_size_t * ofSize, 2860 uint32_t flags ) 2861{ 2862 return( io_connect_map_memory( connect, memoryType, intoTask, 2863 atAddress, ofSize, flags)); 2864} 2865 2866#if EMULATE_IOCONNECT_64 || EMULATE_IOCONNECT_ASYNC_64 2867 2868// ILP32 - need to remap up to 64 bit scalars these are helpers 2869#define arrayCnt(type) (sizeof(type)/sizeof(type[0])) 2870static void inflate_vec(uint64_t *dp, int d, int *sp, int s) 2871{ 2872 if (d > s) 2873 d = s; 2874 2875 for (int i = 0; i < d; i++) 2876 dp[i] = (uint32_t) sp[i]; 2877} 2878 2879static void deflate_vec(int *dp, int d, uint64_t *sp, int s) 2880{ 2881 if (d > s) 2882 d = s; 2883 2884 for (int i = 0; i < d; i++) 2885 dp[i] = (int) sp[i]; 2886} 2887#endif // EMULATE_IOCONNECT_64 || EMULATE_IOCONNECT_ASYNC_64 2888 2889#if EMULATE_IOCONNECT_64 2890kern_return_t io_connect_method 2891( 2892 mach_port_t connection, 2893 uint32_t selector, 2894 io_scalar_inband64_t input, 2895 mach_msg_type_number_t inputCnt, 2896 io_struct_inband_t inband_input, 2897 mach_msg_type_number_t inband_inputCnt, 2898 mach_vm_address_t ool_input, 2899 mach_vm_size_t ool_input_size __unused, 2900 io_scalar_inband64_t output, 2901 mach_msg_type_number_t *outputCnt, 2902 io_struct_inband_t inband_output, 2903 mach_msg_type_number_t *inband_outputCnt, 2904 mach_vm_address_t ool_output, 2905 mach_vm_size_t * ool_output_size __unused 2906) 2907{ 2908 if (ool_input || ool_output) 2909 return MIG_ARRAY_TOO_LARGE; 2910 2911 if (inband_input && inband_output) { 2912 // io_connect_method_structureI_structureO 2913 return io_connect_method_structureI_structureO(connection, selector, 2914 inband_input, inband_inputCnt, inband_output, inband_outputCnt); 2915 } 2916 2917 io_scalar_inband_t inData; 2918 deflate_vec(inData, arrayCnt(inData), input, inputCnt); 2919 2920 if (inband_input) { 2921 // io_connect_method_scalarI_structureI 2922 return io_connect_method_scalarI_structureI(connection, selector, 2923 inData, inputCnt, inband_input, inband_inputCnt); 2924 } 2925 else if (inband_output) { 2926 // io_connect_method_scalarI_structureO 2927 return io_connect_method_scalarI_structureO(connection, selector, 2928 inData, inputCnt, inband_output, inband_outputCnt); 2929 } 2930 2931 // io_connect_method_scalarI_scalarO 2932 kern_return_t rtn = io_connect_method_scalarI_scalarO(connection, selector, 2933 inData, inputCnt, inData, outputCnt); 2934 inputCnt = (rtn == KERN_SUCCESS && outputCnt)? *outputCnt : 0; 2935 inflate_vec(output, inputCnt, inData, arrayCnt(inData)); 2936 return rtn; 2937} 2938#endif // EMULATE_IOCONNECT_64 2939 2940#if EMULATE_IOCONNECT_ASYNC_64 2941kern_return_t io_connect_async_method 2942( 2943 mach_port_t connection, 2944 mach_port_t wake_port, 2945 io_async_ref64_t reference, 2946 mach_msg_type_number_t referenceCnt, 2947 uint32_t selector, 2948 io_scalar_inband64_t input, 2949 mach_msg_type_number_t inputCnt, 2950 io_struct_inband_t inband_input, 2951 mach_msg_type_number_t inband_inputCnt, 2952 mach_vm_address_t ool_input, 2953 mach_vm_size_t ool_input_size __unused, 2954 io_scalar_inband64_t output, 2955 mach_msg_type_number_t *outputCnt, 2956 io_struct_inband_t inband_output, 2957 mach_msg_type_number_t *inband_outputCnt, 2958 mach_vm_address_t ool_output, 2959 mach_vm_size_t * ool_output_size __unused 2960) 2961{ 2962 if (ool_input || ool_output) 2963 return MIG_ARRAY_TOO_LARGE; 2964 2965 io_async_ref_t refData; 2966 deflate_vec((int*)refData, arrayCnt(refData), reference, referenceCnt); 2967 2968 if (inband_input && inband_output) { 2969 // io_async_method_structureI_structureO 2970 return io_async_method_structureI_structureO( 2971 connection, wake_port, refData, referenceCnt, selector, 2972 inband_input, inband_inputCnt, inband_output, inband_outputCnt); 2973 } 2974 2975 io_scalar_inband_t inData; 2976 deflate_vec(inData, arrayCnt(inData), input, inputCnt); 2977 2978 if (inband_input) { 2979 // io_async_method_scalarI_structureI 2980 return io_async_method_scalarI_structureI( 2981 connection, wake_port, refData, referenceCnt, selector, 2982 inData, inputCnt, inband_input, inband_inputCnt); 2983 } 2984 else if (inband_output) { 2985 // io_async_method_scalarI_structureO 2986 return io_async_method_scalarI_structureO( 2987 connection, wake_port, refData, referenceCnt, selector, 2988 inData, inputCnt, inband_output, inband_outputCnt); 2989 } 2990 2991 // io_async_method_scalarI_scalarO 2992 kern_return_t rtn = io_async_method_scalarI_scalarO( 2993 connection, wake_port, refData, referenceCnt, selector, 2994 inData, inputCnt, inData, outputCnt); 2995 inputCnt = (rtn == KERN_SUCCESS && outputCnt)? *outputCnt : 0; 2996 inflate_vec(output, inputCnt, inData, arrayCnt(inData)); 2997 return rtn; 2998} 2999#endif // EMULATE_IOCONNECT_ASYNC_64 3000 3001 3002#endif /* !__LP64__ */ 3003 3004/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ 3005 3006__private_extern__ IOReturn 3007readFile(const char *path, vm_address_t * objAddr, vm_size_t * objSize) 3008{ 3009 int fd; 3010 int err; 3011 struct stat stat_buf; 3012 3013 *objAddr = 0; 3014 *objSize = 0; 3015 3016 if((fd = open(path, O_RDONLY)) == -1) 3017 return errno; 3018 3019 do { 3020 if(fstat(fd, &stat_buf) == -1) { 3021 err = errno; 3022 continue; 3023 } 3024 if (0 == (stat_buf.st_mode & S_IFREG)) 3025 { 3026 *objAddr = 0; 3027 *objSize = 0; 3028 err = kIOReturnNotReadable; 3029 continue; 3030 } 3031 *objSize = stat_buf.st_size; 3032 3033 *objAddr = (vm_address_t) mmap(NULL, round_page(stat_buf.st_size), PROT_READ, MAP_FILE|MAP_PRIVATE, fd, 0); 3034 if(!*objAddr) { 3035 *objSize = 0; 3036 err = errno; 3037 continue; 3038 } 3039 3040 err = kIOReturnSuccess; 3041 3042 } while( false ); 3043 3044 close(fd); 3045 3046 return( err ); 3047} 3048 3049__private_extern__ CFMutableDictionaryRef 3050readPlist( const char * path, UInt32 key __unused ) 3051{ 3052 IOReturn err; 3053 vm_offset_t bytes; 3054 vm_size_t byteLen; 3055 CFDataRef data; 3056 CFMutableDictionaryRef obj = 0; 3057 3058 err = readFile( path, &bytes, &byteLen ); 3059 3060 if( kIOReturnSuccess != err) 3061 return (0); 3062 3063 data = CFDataCreateWithBytesNoCopy( kCFAllocatorDefault, 3064 (const UInt8 *) bytes, byteLen, kCFAllocatorNull ); 3065 if( data) { 3066 obj = (CFMutableDictionaryRef) CFPropertyListCreateFromXMLData( kCFAllocatorDefault, data, 3067 kCFPropertyListMutableContainers, 3068 (CFStringRef *) NULL ); 3069 CFRelease( data ); 3070 } 3071 vm_deallocate( mach_task_self(), bytes, byteLen ); 3072 3073 return (obj); 3074} 3075 3076__private_extern__ Boolean 3077writePlist( const char * path, CFMutableDictionaryRef dict, UInt32 key __unused ) 3078{ 3079 Boolean result = false; 3080 CFDataRef data; 3081 CFIndex length; 3082 int fd = -1; 3083 3084 data = CFPropertyListCreateXMLData(kCFAllocatorDefault, dict); 3085 3086 if (data) 3087 { 3088 fd = open(path, O_WRONLY|O_CREAT|O_TRUNC, (S_IRUSR|S_IWUSR|S_IRGRP|S_IROTH)); 3089 result = (fd >= 0); 3090 if (result) 3091 { 3092 if ((length = CFDataGetLength(data))) 3093 result = (length == write(fd, CFDataGetBytePtr(data), length)); 3094 close(fd); 3095 } 3096 CFRelease(data); 3097 } 3098 3099 return (result); 3100} 3101 3102/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ 3103 3104#include <IOKit/IOSharedLock.h> 3105 3106boolean_t ev_try_lock(OSSpinLock * l) 3107{ 3108 return OSSpinLockTry(l); 3109} 3110 3111void ev_unlock(OSSpinLock * l) 3112{ 3113 OSSpinLockUnlock(l); 3114} 3115