1 /* 2 * Copyright (c) 2019 Daniel Widdis 3 * 4 * The contents of this file is dual-licensed under 2 5 * alternative Open Source/Free licenses: LGPL 2.1 or later and 6 * Apache License 2.0. (starting with JNA version 4.0.0). 7 * 8 * You can freely decide which license you want to apply to 9 * the project. 10 * 11 * You may obtain a copy of the LGPL License at: 12 * 13 * http://www.gnu.org/licenses/licenses.html 14 * 15 * A copy is also included in the downloadable source code package 16 * containing JNA, in file "LGPL2.1". 17 * 18 * You may obtain a copy of the Apache License at: 19 * 20 * http://www.apache.org/licenses/ 21 * 22 * A copy is also included in the downloadable source code package 23 * containing JNA, in file "AL2.0". 24 */ 25 package com.sun.jna.platform.mac; 26 27 import com.sun.jna.Library; 28 import com.sun.jna.Memory; 29 import com.sun.jna.Native; 30 import com.sun.jna.Pointer; 31 import com.sun.jna.PointerType; 32 import com.sun.jna.platform.mac.CoreFoundation.CFAllocatorRef; 33 import com.sun.jna.platform.mac.CoreFoundation.CFArrayRef; 34 import com.sun.jna.platform.mac.CoreFoundation.CFBooleanRef; 35 import com.sun.jna.platform.mac.CoreFoundation.CFDataRef; 36 import com.sun.jna.platform.mac.CoreFoundation.CFDictionaryRef; 37 import com.sun.jna.platform.mac.CoreFoundation.CFMutableDictionaryRef; 38 import com.sun.jna.platform.mac.CoreFoundation.CFNumberRef; 39 import com.sun.jna.platform.mac.CoreFoundation.CFStringRef; 40 import com.sun.jna.platform.mac.CoreFoundation.CFTypeRef; 41 import com.sun.jna.ptr.IntByReference; 42 import com.sun.jna.ptr.LongByReference; 43 import com.sun.jna.ptr.PointerByReference; 44 45 /** 46 * The I/O Kit framework implements non-kernel access to I/O Kit objects 47 * (drivers and nubs) through the device-interface mechanism. 48 */ 49 public interface IOKit extends Library { 50 51 IOKit INSTANCE = Native.load("IOKit", IOKit.class); 52 53 int kIORegistryIterateRecursively = 0x00000001; 54 int kIORegistryIterateParents = 0x00000002; 55 56 /** 57 * Return value when attempting parent or child in registry and they do not 58 * exist 59 */ 60 int kIOReturnNoDevice = 0xe00002c0; 61 62 double kIOPSTimeRemainingUnlimited = -2.0; 63 double kIOPSTimeRemainingUnknown = -1.0; 64 65 /** 66 * IOKitLib implements non-kernel task access to common IOKit object types - 67 * IORegistryEntry, IOService, IOIterator etc. These functions are generic - 68 * families may provide API that is more specific. 69 * <p> 70 * IOKitLib represents IOKit objects outside the kernel with the types 71 * io_object_t, io_registry_entry_t, io_service_t, and io_connect_t. Function 72 * names usually begin with the type of object they are compatible with - e.g., 73 * IOObjectRelease can be used with any io_object_t. Inside the kernel, the c++ 74 * class hierarchy allows the subclasses of each object type to receive the same 75 * requests from user level clients, for example in the kernel, IOService is a 76 * subclass of IORegistryEntry, which means any of the IORegistryEntryXXX 77 * functions in IOKitLib may be used with io_service_t's as well as 78 * io_registry_t's. There are functions available to introspect the class of the 79 * kernel object which any io_object_t et al. represents. IOKit objects returned 80 * by all functions should be released with {@link IOKit#IOObjectRelease}. 81 */ 82 class IOObject extends PointerType { IOObject()83 public IOObject() { 84 super(); 85 } 86 IOObject(Pointer p)87 public IOObject(Pointer p) { 88 super(p); 89 } 90 91 /** 92 * Convenience method for {@link IOKit#IOObjectConformsTo} on this object. 93 * 94 * @param className 95 * The name of the class. 96 * @return If the object handle is valid, and represents an object in the kernel 97 * that dynamic casts to the class true is returned, otherwise false. 98 */ conformsTo(String className)99 public boolean conformsTo(String className) { 100 return INSTANCE.IOObjectConformsTo(this, className); 101 } 102 103 /** 104 * Convenience method for {@link IOKit#IOObjectRelease} on this object. 105 * 106 * @return 0 if successful, otherwise a {@code kern_return_t} error code. 107 */ release()108 public int release() { 109 return INSTANCE.IOObjectRelease(this); 110 } 111 } 112 113 /** 114 * An IOKit iterator handle. 115 */ 116 class IOIterator extends IOObject { IOIterator()117 public IOIterator() { 118 super(); 119 } 120 IOIterator(Pointer p)121 public IOIterator(Pointer p) { 122 super(p); 123 } 124 125 /** 126 * Convenience method for {@link IOKit#IOIteratorNext} on this object. 127 * 128 * @return If the iterator handle is valid, the next element in the iteration is 129 * returned, otherwise {@code null} is returned. The element should be 130 * released by the caller when it is finished. 131 */ next()132 public IORegistryEntry next() { 133 return INSTANCE.IOIteratorNext(this); 134 } 135 } 136 137 /** 138 * The base class for all objects in the registry. 139 */ 140 class IORegistryEntry extends IOObject { IORegistryEntry()141 public IORegistryEntry() { 142 super(); 143 } 144 IORegistryEntry(Pointer p)145 public IORegistryEntry(Pointer p) { 146 super(p); 147 } 148 149 /** 150 * Convenience method for {@link #IORegistryEntryGetRegistryEntryID} to 151 * return an ID for this registry entry that is global to all tasks. 152 * 153 * @return the ID. 154 * @throws IOReturnException 155 * if the ID could not be retrieved. 156 */ getRegistryEntryID()157 public long getRegistryEntryID() { 158 LongByReference id = new LongByReference(); 159 int kr = INSTANCE.IORegistryEntryGetRegistryEntryID(this, id); 160 if (kr != 0) { 161 throw new IOReturnException(kr); 162 } 163 return id.getValue(); 164 } 165 166 /** 167 * Convenience method for {@link #IORegistryEntryGetName} to return a 168 * name assigned to this registry entry. 169 * 170 * @return The name 171 * @throws IOReturnException 172 * if the name could not be retrieved. 173 */ getName()174 public String getName() { 175 Memory name = new Memory(128); 176 int kr = INSTANCE.IORegistryEntryGetName(this, name); 177 if (kr != 0) { 178 throw new IOReturnException(kr); 179 } 180 return name.getString(0); 181 } 182 183 /** 184 * Convenience method for {@link #IORegistryEntryGetChildIterator} to 185 * return an iterator over this registry entry’s child entries in a 186 * plane. 187 * 188 * @param plane 189 * The name of an existing registry plane. Plane names are 190 * defined in {@code IOKitKeys.h}, for example, 191 * {@code kIOServicePlane}. 192 * @return The iterator 193 * @throws IOReturnException 194 * if the iterator could not be retrieved. 195 */ getChildIterator(String plane)196 public IOIterator getChildIterator(String plane) { 197 PointerByReference iter = new PointerByReference(); 198 int kr = INSTANCE.IORegistryEntryGetChildIterator(this, plane, iter); 199 if (kr != 0) { 200 throw new IOReturnException(kr); 201 } 202 return new IOIterator(iter.getValue()); 203 } 204 205 /** 206 * Convenience method for {@link #IORegistryEntryGetChildEntry} to 207 * return the first child of this registry entry in a plane. 208 * 209 * @param plane 210 * The name of an existing registry plane. 211 * @return The child registry entry, if a child exists, null otherwise 212 * @throws IOReturnException 213 * if the entry exists but could not be retrieved. 214 */ getChildEntry(String plane)215 public IORegistryEntry getChildEntry(String plane) { 216 PointerByReference child = new PointerByReference(); 217 int kr = INSTANCE.IORegistryEntryGetChildEntry(this, plane, child); 218 if (kr == kIOReturnNoDevice) { 219 return null; 220 } else if (kr != 0) { 221 throw new IOReturnException(kr); 222 } 223 return new IORegistryEntry(child.getValue()); 224 } 225 226 /** 227 * Convenience method for {@link #IORegistryEntryGetParentEntry} to 228 * return the first parent of this registry entry in a plane. 229 * 230 * @param plane 231 * The name of an existing registry plane. 232 * @return The parent registry entry, if a parent exists, null otherwise 233 * @throws IOReturnException 234 * if the entry exists but could not be retrieved. 235 */ getParentEntry(String plane)236 public IORegistryEntry getParentEntry(String plane) { 237 PointerByReference parent = new PointerByReference(); 238 int kr = INSTANCE.IORegistryEntryGetParentEntry(this, plane, parent); 239 if (kr == kIOReturnNoDevice) { 240 return null; 241 } else if (kr != 0) { 242 throw new IOReturnException(kr); 243 } 244 return new IORegistryEntry(parent.getValue()); 245 } 246 247 /** 248 * Convenience method for {@link #IORegistryEntryCreateCFProperty} to create a 249 * CF representation of this registry entry's property. 250 * 251 * @param key 252 * A {@code CFString} specifying the property name. 253 * @return A CF container is created and returned the caller on success. 254 * <p> 255 * The caller should release with {@link CoreFoundation#CFRelease}. 256 */ createCFProperty(CFStringRef key)257 public CFTypeRef createCFProperty(CFStringRef key) { 258 return INSTANCE.IORegistryEntryCreateCFProperty(this, key, CoreFoundation.INSTANCE.CFAllocatorGetDefault(), 259 0); 260 } 261 262 /** 263 * Convenience method for {@link #IORegistryEntryCreateCFProperties} to 264 * create a CF dictionary representation of this registry entry's 265 * property table. 266 * 267 * @return The property table. 268 * <p> 269 * The caller should release with 270 * {@link CoreFoundation#CFRelease}. 271 * @throws IOReturnException 272 * if the entry could not be retrieved. 273 */ createCFProperties()274 public CFMutableDictionaryRef createCFProperties() { 275 PointerByReference properties = new PointerByReference(); 276 int kr = INSTANCE.IORegistryEntryCreateCFProperties(this, properties, 277 CoreFoundation.INSTANCE.CFAllocatorGetDefault(), 0); 278 if (kr != 0) { 279 throw new IOReturnException(kr); 280 } 281 return new CFMutableDictionaryRef(properties.getValue()); 282 } 283 284 /** 285 * Convenience method for {@link #IORegistryEntrySearchCFProperty} to create a 286 * CF representation of a registry entry's property searched from this object. 287 * 288 * @param plane 289 * The name of an existing registry plane. Plane names are defined in 290 * {@code IOKitKeys.h}, for example, {@code kIOServicePlane}. 291 * @param key 292 * A {@code CFString} specifying the property name. 293 * @param options 294 * {@link #kIORegistryIterateRecursively} may be set to recurse 295 * automatically into the registry hierarchy. Without this option, 296 * this method degenerates into the standard 297 * {@link #IORegistryEntryCreateCFProperty} call. 298 * {@link #kIORegistryIterateParents} may be set to iterate the 299 * parents of the entry, in place of the children. 300 * @return A CF container is created and returned the caller on success. The 301 * caller should release with CFRelease. 302 */ searchCFProperty(String plane, CFStringRef key, int options)303 CFTypeRef searchCFProperty(String plane, CFStringRef key, int options) { 304 return INSTANCE.IORegistryEntrySearchCFProperty(this, plane, key, 305 CoreFoundation.INSTANCE.CFAllocatorGetDefault(), options); 306 } 307 308 /** 309 * Convenience method to get a {@link java.lang.String} value from this IO 310 * Registry Entry. 311 * 312 * @param key 313 * The string name of the key to retrieve 314 * @return The value of the registry entry if it exists; {@code null} otherwise 315 */ getStringProperty(String key)316 public String getStringProperty(String key) { 317 String value = null; 318 CFStringRef keyAsCFString = CFStringRef.createCFString(key); 319 CFTypeRef valueAsCFType = this.createCFProperty(keyAsCFString); 320 keyAsCFString.release(); 321 if (valueAsCFType != null) { 322 CFStringRef valueAsCFString = new CFStringRef(valueAsCFType.getPointer()); 323 value = valueAsCFString.stringValue(); 324 valueAsCFType.release(); 325 } 326 return value; 327 } 328 329 /** 330 * Convenience method to get a {@link java.lang.Long} value from this IO 331 * Registry Entry. 332 * 333 * @param key 334 * The string name of the key to retrieve 335 * @return The value of the registry entry if it exists; {@code null} otherwise 336 * <p> 337 * This method assumes a 64-bit integer is stored and does not do type 338 * checking. If this object's type differs from the return type, and the 339 * conversion is lossy or the return value is out of range, then this 340 * method returns an approximate value. 341 */ getLongProperty(String key)342 public Long getLongProperty(String key) { 343 Long value = null; 344 CFStringRef keyAsCFString = CFStringRef.createCFString(key); 345 CFTypeRef valueAsCFType = this.createCFProperty(keyAsCFString); 346 keyAsCFString.release(); 347 if (valueAsCFType != null) { 348 CFNumberRef valueAsCFNumber = new CFNumberRef(valueAsCFType.getPointer()); 349 value = valueAsCFNumber.longValue(); 350 valueAsCFType.release(); 351 } 352 return value; 353 } 354 355 /** 356 * Convenience method to get an {@link java.lang.Integer} value from this IO 357 * Registry Entry. 358 * 359 * @param key 360 * The string name of the key to retrieve 361 * @return The value of the registry entry if it exists; {@code null} otherwise 362 * <p> 363 * This method assumes a 32-bit integer is stored and does not do type 364 * checking. If this object's type differs from the return type, and the 365 * conversion is lossy or the return value is out of range, then this 366 * method returns an approximate value. 367 */ getIntegerProperty(String key)368 public Integer getIntegerProperty(String key) { 369 Integer value = null; 370 CFStringRef keyAsCFString = CFStringRef.createCFString(key); 371 CFTypeRef valueAsCFType = this.createCFProperty(keyAsCFString); 372 keyAsCFString.release(); 373 if (valueAsCFType != null) { 374 CFNumberRef valueAsCFNumber = new CFNumberRef(valueAsCFType.getPointer()); 375 value = valueAsCFNumber.intValue(); 376 valueAsCFType.release(); 377 } 378 return value; 379 } 380 381 /** 382 * Convenience method to get a {@link java.lang.Double} value from this IO 383 * Registry Entry. 384 * 385 * @param key 386 * The string name of the key to retrieve 387 * @return The value of the registry entry if it exists; {@code null} otherwise 388 * <p> 389 * This method assumes a floating point value is stored and does not do 390 * type checking. If this object's type differs from the return type, 391 * and the conversion is lossy or the return value is out of range, then 392 * this method returns an approximate value. 393 */ getDoubleProperty(String key)394 public Double getDoubleProperty(String key) { 395 Double value = null; 396 CFStringRef keyAsCFString = CFStringRef.createCFString(key); 397 CFTypeRef valueAsCFType = this.createCFProperty(keyAsCFString); 398 keyAsCFString.release(); 399 if (valueAsCFType != null) { 400 CFNumberRef valueAsCFNumber = new CFNumberRef(valueAsCFType.getPointer()); 401 value = valueAsCFNumber.doubleValue(); 402 valueAsCFType.release(); 403 } 404 return value; 405 } 406 407 /** 408 * Convenience method to get a {@link java.lang.Boolean} value from this IO 409 * Registry Entry. 410 * 411 * @param key 412 * The string name of the key to retrieve 413 * @return The value of the registry entry if it exists; {@code null} otherwise 414 */ getBooleanProperty(String key)415 public Boolean getBooleanProperty(String key) { 416 Boolean value = null; 417 CFStringRef keyAsCFString = CFStringRef.createCFString(key); 418 CFTypeRef valueAsCFType = this.createCFProperty(keyAsCFString); 419 keyAsCFString.release(); 420 if (valueAsCFType != null) { 421 CFBooleanRef valueAsCFBoolean = new CFBooleanRef(valueAsCFType.getPointer()); 422 value = valueAsCFBoolean.booleanValue(); 423 valueAsCFType.release(); 424 } 425 return value; 426 } 427 428 /** 429 * Convenience method to get a {@code byte} array value from this IO Registry 430 * Entry. 431 * 432 * @param key 433 * The string name of the key to retrieve 434 * @return The value of the registry entry if it exists; {@code null} otherwise 435 */ getByteArrayProperty(String key)436 public byte[] getByteArrayProperty(String key) { 437 byte[] value = null; 438 CFStringRef keyAsCFString = CFStringRef.createCFString(key); 439 CFTypeRef valueAsCFType = this.createCFProperty(keyAsCFString); 440 keyAsCFString.release(); 441 if (valueAsCFType != null) { 442 CFDataRef valueAsCFData = new CFDataRef(valueAsCFType.getPointer()); 443 int length = valueAsCFData.getLength(); 444 Pointer p = valueAsCFData.getBytePtr(); 445 value = p.getByteArray(0, length); 446 valueAsCFType.release(); 447 } 448 return value; 449 } 450 } 451 452 /** 453 * The base class for most I/O Kit families, devices, and drivers. 454 */ 455 class IOService extends IORegistryEntry { IOService()456 public IOService() { 457 super(); 458 } 459 IOService(Pointer p)460 public IOService(Pointer p) { 461 super(p); 462 } 463 } 464 465 /** 466 * For an application to communicate with a device, the first thing it must do 467 * is create a connection between itself and the in-kernel object representing 468 * the device. To do this, it creates a user client object. 469 */ 470 class IOConnect extends IOService { IOConnect()471 public IOConnect() { 472 super(); 473 } 474 IOConnect(Pointer p)475 public IOConnect(Pointer p) { 476 super(p); 477 } 478 } 479 480 /** 481 * Returns the mach port used to initiate communication with IOKit. 482 * 483 * @param bootstrapPort 484 * Pass 0 for the default. 485 * @param port 486 * A pointer to the master port is returned. Multiple calls to 487 * IOMasterPort will not result in leaking ports (each call to 488 * IOMasterPort adds another send right to the port) but it is 489 * considered good programming practice to deallocate the port when 490 * you are finished with it using 491 * {@link SystemB#mach_port_deallocate}. 492 * @return 0 if successful, otherwise a {@code kern_return_t} error code. 493 */ IOMasterPort(int bootstrapPort, IntByReference port)494 int IOMasterPort(int bootstrapPort, IntByReference port); 495 496 /** 497 * Create a matching dictionary that specifies an {@code IOService} class match. 498 * 499 * @param name 500 * The class name. Class matching is successful on {@code IOService}s 501 * of this class or any subclass. 502 * @return The matching dictionary created, is returned on success, or 503 * {@code null} on failure. 504 * <p> 505 * The dictionary is commonly passed to 506 * {@link #IOServiceGetMatchingServices} which will consume a reference, 507 * otherwise it should be released with {@link CoreFoundation#CFRelease} 508 * by the caller. 509 */ IOServiceMatching(String name)510 CFMutableDictionaryRef IOServiceMatching(String name); 511 512 /** 513 * Create a matching dictionary that specifies an {@code IOService} name match. 514 * 515 * @param name 516 * The {@code IOService} name. 517 * @return The matching dictionary created, is returned on success, or 518 * {@code null} on failure. 519 * <p> 520 * The dictionary is commonly passed to 521 * {@link #IOServiceGetMatchingServices} which will consume a reference, 522 * otherwise it should be released with {@link CoreFoundation#CFRelease} 523 * by the caller. 524 */ IOServiceNameMatching(String name)525 CFMutableDictionaryRef IOServiceNameMatching(String name); 526 527 /** 528 * Create a matching dictionary that specifies an {@code IOService} match based 529 * on BSD device name. 530 * 531 * @param masterPort 532 * The master port obtained from {@link #IOMasterPort}. 533 * @param options 534 * No options are currently defined. 535 * @param bsdName 536 * The BSD name. 537 * @return The matching dictionary created, is returned on success, or 538 * {@code null} on failure. 539 * <p> 540 * The dictionary is commonly passed to 541 * {@link #IOServiceGetMatchingServices} which will consume a reference, 542 * otherwise it should be released with {@link CoreFoundation#CFRelease} 543 * by the caller. 544 */ IOBSDNameMatching(int masterPort, int options, String bsdName)545 CFMutableDictionaryRef IOBSDNameMatching(int masterPort, int options, String bsdName); 546 547 /** 548 * Look up a registered IOService object that matches a matching dictionary. 549 * 550 * @param masterPort 551 * The master port obtained from {@link #IOMasterPort}. 552 * @param matchingDictionary 553 * A CF dictionary containing matching information, of which one 554 * reference is always consumed by this function. IOKitLib can 555 * construct matching dictionaries for common criteria with helper 556 * functions such as {@link #IOServiceMatching}, 557 * {@link #IOServiceNameMatching}, and {@link #IOBSDNameMatching}. 558 * @return The first service matched is returned on success. 559 * <p> 560 * The service must be released by the caller. 561 */ IOServiceGetMatchingService(int masterPort, CFDictionaryRef matchingDictionary)562 IOService IOServiceGetMatchingService(int masterPort, CFDictionaryRef matchingDictionary); 563 564 /** 565 * Look up registered IOService objects that match a matching dictionary. 566 * 567 * @param masterPort 568 * The master port obtained from {@link #IOMasterPort}. 569 * @param matchingDictionary 570 * A CF dictionary containing matching information, of which one 571 * reference is always consumed by this function. IOKitLib can 572 * construct matching dictionaries for common criteria with helper 573 * functions such as {@link #IOServiceMatching}, 574 * {@link #IOServiceNameMatching}, and {@link #IOBSDNameMatching}. 575 * @param iterator 576 * An iterator handle is returned on success, and should be released 577 * by the caller when the iteration is finished. 578 * @return 0 if successful, otherwise a {@code kern_return_t} error code. 579 */ IOServiceGetMatchingServices(int masterPort, CFDictionaryRef matchingDictionary, PointerByReference iterator)580 int IOServiceGetMatchingServices(int masterPort, CFDictionaryRef matchingDictionary, PointerByReference iterator); 581 582 /** 583 * Returns the next object in an iteration. 584 * 585 * @param iterator 586 * An IOKit iterator handle. 587 * @return If the iterator handle is valid, the next element in the iteration is 588 * returned, otherwise zero is returned. The element should be released 589 * by the caller when it is finished. 590 */ IOIteratorNext(IOIterator iterator)591 IORegistryEntry IOIteratorNext(IOIterator iterator); 592 593 /** 594 * Create a CF representation of a registry entry's property. 595 * 596 * @param entry 597 * The registry entry handle whose property to copy. 598 * @param key 599 * A {@code CFString} specifying the property name. 600 * @param allocator 601 * The CF allocator to use when creating the CF container. 602 * @param options 603 * No options are currently defined. 604 * @return A CF container is created and returned the caller on success. 605 * <p> 606 * The caller should release with {@link CoreFoundation#CFRelease}. 607 */ IORegistryEntryCreateCFProperty(IORegistryEntry entry, CFStringRef key, CFAllocatorRef allocator, int options)608 CFTypeRef IORegistryEntryCreateCFProperty(IORegistryEntry entry, CFStringRef key, CFAllocatorRef allocator, 609 int options); 610 611 /** 612 * Create a CF dictionary representation of a registry entry's property table. 613 * 614 * @param entry 615 * The registry entry handle whose property table to copy. 616 * @param properties 617 * A CFDictionary is created and returned the caller on success. The 618 * caller should release with CFRelease. 619 * @param allocator 620 * The CF allocator to use when creating the CF containers. 621 * @param options 622 * No options are currently defined. 623 * @return 0 if successful, otherwise a {@code kern_return_t} error code. 624 */ IORegistryEntryCreateCFProperties(IORegistryEntry entry, PointerByReference properties, CFAllocatorRef allocator, int options)625 int IORegistryEntryCreateCFProperties(IORegistryEntry entry, PointerByReference properties, 626 CFAllocatorRef allocator, int options); 627 628 /** 629 * Create a CF representation of a registry entry's property. 630 * 631 * @param entry 632 * The registry entry at which to start the search. 633 * @param plane 634 * The name of an existing registry plane. Plane names are defined in 635 * {@code IOKitKeys.h}, for example, {@code kIOServicePlane}. 636 * @param key 637 * A {@code CFString} specifying the property name. 638 * @param allocator 639 * The CF allocator to use when creating the CF container. 640 * @param options 641 * {@link #kIORegistryIterateRecursively} may be set to recurse 642 * automatically into the registry hierarchy. Without this option, 643 * this method degenerates into the standard 644 * {@link #IORegistryEntryCreateCFProperty} call. 645 * {@link #kIORegistryIterateParents} may be set to iterate the 646 * parents of the entry, in place of the children. 647 * @return A CF container is created and returned the caller on success. The 648 * caller should release with CFRelease. 649 */ IORegistryEntrySearchCFProperty(IORegistryEntry entry, String plane, CFStringRef key, CFAllocatorRef allocator, int options)650 CFTypeRef IORegistryEntrySearchCFProperty(IORegistryEntry entry, String plane, CFStringRef key, 651 CFAllocatorRef allocator, int options); 652 653 /** 654 * Returns an ID for the registry entry that is global to all tasks. 655 * 656 * @param entry 657 * The registry entry handle whose ID to look up. 658 * @param id 659 * The resulting ID. 660 * @return 0 if successful, otherwise a {@code kern_return_t} error code. 661 */ IORegistryEntryGetRegistryEntryID(IORegistryEntry entry, LongByReference id)662 int IORegistryEntryGetRegistryEntryID(IORegistryEntry entry, LongByReference id); 663 664 /** 665 * Returns a name assigned to a registry entry. 666 * 667 * @param entry 668 * The registry entry handle whose name to look up. 669 * @param name 670 * The caller's buffer to receive the name. This must be a 128-byte 671 * buffer. 672 * @return 0 if successful, otherwise a {@code kern_return_t} error code. 673 */ IORegistryEntryGetName(IORegistryEntry entry, Pointer name)674 int IORegistryEntryGetName(IORegistryEntry entry, Pointer name); 675 676 /** 677 * Returns an iterator over a registry entry’s child entries in a plane. 678 * 679 * @param entry 680 * The registry entry whose children to iterate over. 681 * @param plane 682 * The name of an existing registry plane. Plane names are defined in 683 * {@code IOKitKeys.h}, for example, {@code kIOServicePlane}. 684 * @param iter 685 * The created iterator over the children of the entry, on success. 686 * The iterator must be released when the iteration is finished. 687 * @return 0 if successful, otherwise a {@code kern_return_t} error code. 688 */ IORegistryEntryGetChildIterator(IORegistryEntry entry, String plane, PointerByReference iter)689 int IORegistryEntryGetChildIterator(IORegistryEntry entry, String plane, PointerByReference iter); 690 691 /** 692 * Returns the first child of a registry entry in a plane. 693 * 694 * @param entry 695 * The registry entry whose child to look up. 696 * @param plane 697 * The name of an existing registry plane. Plane names are defined in 698 * {@code IOKitKeys.h}, for example, {@code kIOServicePlane}. 699 * @param child 700 * The first child of the registry entry, on success. The child must 701 * be released by the caller. 702 * @return 0 if successful, otherwise a {@code kern_return_t} error code. 703 */ IORegistryEntryGetChildEntry(IORegistryEntry entry, String plane, PointerByReference child)704 int IORegistryEntryGetChildEntry(IORegistryEntry entry, String plane, PointerByReference child); 705 706 /** 707 * Returns the first parent of a registry entry in a plane. 708 * 709 * @param entry 710 * The registry entry whose parent to look up. 711 * @param plane 712 * The name of an existing registry plane. Plane names are defined in 713 * {@code IOKitKeys.h}, for example, {@code kIOServicePlane}. 714 * @param parent 715 * The first parent of the registry entry, on success. The parent 716 * must be released by the caller. 717 * @return 0 if successful, otherwise a {@code kern_return_t} error code. 718 */ IORegistryEntryGetParentEntry(IORegistryEntry entry, String plane, PointerByReference parent)719 int IORegistryEntryGetParentEntry(IORegistryEntry entry, String plane, PointerByReference parent); 720 721 /** 722 * Return a handle to the registry root. 723 * 724 * @param masterPort 725 * The master port obtained from {@link #IOMasterPort}. 726 * @return A handle to the IORegistryEntry root instance, to be released with 727 * {@link #IOObjectRelease} by the caller, or 0 on failure. 728 */ IORegistryGetRootEntry(int masterPort)729 IORegistryEntry IORegistryGetRootEntry(int masterPort); 730 731 /** 732 * Performs an OSDynamicCast operation on an IOKit object. 733 * 734 * @param object 735 * An IOKit object. 736 * @param className 737 * The name of the class. 738 * @return If the object handle is valid, and represents an object in the kernel 739 * that dynamic casts to the class true is returned, otherwise false. 740 */ IOObjectConformsTo(IOObject object, String className)741 boolean IOObjectConformsTo(IOObject object, String className); 742 743 /** 744 * Releases an object handle previously returned by {@code IOKitLib}. 745 * 746 * @param object 747 * The IOKit object to release. 748 * @return 0 if successful, otherwise a {@code kern_return_t} error code. 749 */ IOObjectRelease(IOObject object)750 int IOObjectRelease(IOObject object); 751 752 /** 753 * A request to create a connection to an IOService. 754 * 755 * @param service 756 * The IOService object to open a connection to, usually obtained via 757 * the {@link #IOServiceGetMatchingServices} API. 758 * @param owningTask 759 * The mach task requesting the connection. 760 * @param type 761 * A constant specifying the type of connection to be created, 762 * interpreted only by the IOService's family. 763 * @param connect 764 * An {@code io_connect_t} handle is returned on success, to be used 765 * with the IOConnectXXX APIs. It should be destroyed with 766 * {@link IOServiceClose}. 767 * @return A return code generated by {@code IOService::newUserClient}. 768 */ IOServiceOpen(IOService service, int owningTask, int type, PointerByReference connect)769 int IOServiceOpen(IOService service, int owningTask, int type, PointerByReference connect); 770 771 /** 772 * Returns the busyState of an IOService. 773 * 774 * @param service 775 * The IOService whose busyState to return. 776 * @param busyState 777 * The busyState count is returned. 778 * @return 0 if successful, otherwise a {@code kern_return_t} error code. 779 */ IOServiceGetBusyState(IOService service, IntByReference busyState)780 int IOServiceGetBusyState(IOService service, IntByReference busyState); 781 782 /** 783 * Close a connection to an IOService and destroy the connect handle. 784 * 785 * @param connect 786 * The connect handle created by IOServiceOpen. It will be destroyed 787 * by this function, and should not be released with IOObjectRelease. 788 * @return 0 if successful, otherwise a {@code kern_return_t} error code. 789 */ IOServiceClose(IOConnect connect)790 int IOServiceClose(IOConnect connect); 791 792 /** 793 * Returns a blob of Power Source information in an opaque CFTypeRef. 794 * 795 * @return {@code null} if errors were encountered, a {@link CFTypeRef} 796 * otherwise. 797 * <p> 798 * Caller must {@link CoreFoundation#CFRelease} the return value when 799 * done accessing it. 800 */ IOPSCopyPowerSourcesInfo()801 CFTypeRef IOPSCopyPowerSourcesInfo(); 802 803 /** 804 * Returns a CFArray of Power Source handles, each of type CFTypeRef. 805 * 806 * @param blob 807 * Takes the {@link CFTypeRef} returned by 808 * {@link #IOPSCopyPowerSourcesInfo} 809 * @return {@code null} if errors were encountered, otherwise a CFArray of 810 * {@link CFTypeRef}s. 811 * <p> 812 * Caller must {@link CoreFoundation#CFRelease} the returned 813 * {@link CFArrayRef}. 814 */ IOPSCopyPowerSourcesList(CFTypeRef blob)815 CFArrayRef IOPSCopyPowerSourcesList(CFTypeRef blob); 816 817 /** 818 * Returns a CFDictionary with readable information about the specific power 819 * source. 820 * 821 * @param blob 822 * the {@link CFTypeRef} returned by 823 * {@link #IOPSCopyPowerSourcesInfo} 824 * @param ps 825 * One of the {@link CFTypeRef}s in the CFArray returned by 826 * {@link #IOPSCopyPowerSourcesList}. 827 * @return {@code null} if an error was encountered, otherwise a CFDictionary. 828 * <p> 829 * Caller should NOT release the returned CFDictionary - it will be 830 * released as part of the {@link CFTypeRef} returned by 831 * {@link IOPSCopyPowerSourcesInfo}. 832 */ IOPSGetPowerSourceDescription(CFTypeRef blob, CFTypeRef ps)833 CFDictionaryRef IOPSGetPowerSourceDescription(CFTypeRef blob, CFTypeRef ps); 834 835 /** 836 * Returns the estimated seconds remaining until all power sources (battery 837 * and/or UPS's) are empty. 838 * 839 * @return Returns {@link #kIOPSTimeRemainingUnknown} if the OS cannot determine 840 * the time remaining. 841 * <p> 842 * Returns {@link #kIOPSTimeRemainingUnlimited} if the system has an 843 * unlimited power source. 844 * <p> 845 * Otherwise returns a positive number indicating the time remaining in 846 * seconds until all power sources are depleted. 847 */ IOPSGetTimeRemainingEstimate()848 double IOPSGetTimeRemainingEstimate(); 849 } 850