/*
- * Copyright (c) 1998-2000 Apple Computer, Inc. All rights reserved.
+ * Copyright (c) 1998-2019 Apple Inc. All rights reserved.
*
- * @APPLE_LICENSE_HEADER_START@
- *
- * The contents of this file constitute Original Code as defined in and
- * are subject to the Apple Public Source License Version 1.1 (the
- * "License"). You may not use this file except in compliance with the
- * License. Please obtain a copy of the License at
- * http://www.apple.com/publicsource and read it before using this file.
- *
- * This Original Code and all software distributed under the License are
- * distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY KIND, EITHER
+ * @APPLE_OSREFERENCE_LICENSE_HEADER_START@
+ *
+ * This file contains Original Code and/or Modifications of Original Code
+ * as defined in and that are subject to the Apple Public Source License
+ * Version 2.0 (the 'License'). You may not use this file except in
+ * compliance with the License. The rights granted to you under the License
+ * may not be used to create, or enable the creation or redistribution of,
+ * unlawful or unlicensed copies of an Apple operating system, or to
+ * circumvent, violate, or enable the circumvention or violation of, any
+ * terms of an Apple operating system software license agreement.
+ *
+ * Please obtain a copy of the License at
+ * http://www.opensource.apple.com/apsl/ and read it before using this file.
+ *
+ * The Original Code and all software distributed under the License are
+ * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
* EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
* INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT. Please see the
- * License for the specific language governing rights and limitations
- * under the License.
- *
- * @APPLE_LICENSE_HEADER_END@
- */
-/*
- * Copyright (c) 1998 Apple Computer, Inc. All rights reserved.
- *
- * HISTORY
- * 12 Nov 98 sdouglas created.
+ * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
+ * Please see the License for the specific language governing rights and
+ * limitations under the License.
*
+ * @APPLE_OSREFERENCE_LICENSE_HEADER_END@
*/
#include <IOKit/IORegistryEntry.h>
#include <libkern/c++/OSContainers.h>
#include <IOKit/IOService.h>
#include <IOKit/IOKitKeys.h>
+#include <IOKit/IOTimeStamp.h>
#include <IOKit/IOLib.h>
-
+#include <stdatomic.h>
#include <IOKit/assert.h>
+#include "IOKitKernelInternal.h"
+
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
#define super OSObject
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
+#define kIORegPlaneParentSuffix "ParentLinks"
+#define kIORegPlaneChildSuffix "ChildLinks"
+#define kIORegPlaneNameSuffix "Name"
+#define kIORegPlaneLocationSuffix "Location"
+
+#define kIORegPlaneParentSuffixLen (sizeof(kIORegPlaneParentSuffix) - 1)
+#define kIORegPlaneChildSuffixLen (sizeof(kIORegPlaneChildSuffix) - 1)
+#define kIORegPlaneNameSuffixLen (sizeof(kIORegPlaneNameSuffix) - 1)
+#define kIORegPlaneLocationSuffixLen (sizeof(kIORegPlaneLocationSuffix) - 1)
+
+#define KASLR_IOREG_DEBUG 0
+
+struct IORegistryEntry::ExpansionData {
+ IORecursiveLock * fLock;
+ uint64_t fRegistryEntryID;
+ SInt32 fRegistryEntryGenerationCount;
+ OSObject **_Atomic fIndexedProperties;
+};
+
+
static IORegistryEntry * gRegistryRoot;
-static OSDictionary * gIORegistryPlanes;
+static OSDictionary * gIORegistryPlanes;
-const OSSymbol * gIONameKey;
-const OSSymbol * gIOLocationKey;
+const OSSymbol * gIONameKey;
+const OSSymbol * gIOLocationKey;
+const OSSymbol * gIORegistryEntryIDKey;
+const OSSymbol * gIORegistryEntryPropertyKeysKey;
enum {
- kParentSetIndex = 0,
- kChildSetIndex = 1,
- kNumSetIndex
+ kParentSetIndex = 0,
+ kChildSetIndex = 1,
+ kNumSetIndex
};
enum {
- kIOMaxPlaneName = 32
+ kIOMaxPlaneName = 32
};
-class IORegistryPlane : public OSObject {
+enum { kIORegistryIDReserved = (1ULL << 32) + 255 };
- friend class IORegistryEntry;
+static uint64_t gIORegistryLastID = kIORegistryIDReserved;
- OSDeclareAbstractStructors(IORegistryPlane)
+class IORegistryPlane : public OSObject {
+ friend class IORegistryEntry;
+
+ OSDeclareAbstractStructors(IORegistryPlane);
- const OSSymbol * nameKey;
- const OSSymbol * keys[ kNumSetIndex ];
- const OSSymbol * pathNameKey;
- const OSSymbol * pathLocationKey;
- int reserved[2];
+ const OSSymbol * nameKey;
+ const OSSymbol * keys[kNumSetIndex];
+ const OSSymbol * pathNameKey;
+ const OSSymbol * pathLocationKey;
+ int reserved[2];
public:
- virtual bool serialize(OSSerialize *s) const;
+ virtual bool serialize(OSSerialize *s) const APPLE_KEXT_OVERRIDE;
};
OSDefineMetaClassAndStructors(IORegistryPlane, OSObject)
-static IORecursiveLock * gPropertiesLock;
-static SInt32 gIORegistryGenerationCount;
+static IORecursiveLock * gPropertiesLock;
+static SInt32 gIORegistryGenerationCount;
-#define UNLOCK s_lock_done( &gIORegistryLock )
-#define RLOCK s_lock_read( &gIORegistryLock )
-#define WLOCK s_lock_write( &gIORegistryLock ); \
- gIORegistryGenerationCount++
- // make atomic
+#define UNLOCK lck_rw_done( &gIORegistryLock )
+#define RLOCK lck_rw_lock_shared( &gIORegistryLock )
+#define WLOCK lck_rw_lock_exclusive( &gIORegistryLock ); \
+ gIORegistryGenerationCount++
+// make atomic
-#define PUNLOCK IORecursiveLockUnlock( gPropertiesLock )
-#define PLOCK IORecursiveLockLock( gPropertiesLock )
+#define PUNLOCK IORecursiveLockUnlock( reserved->fLock )
+#define PLOCK IORecursiveLockLock( reserved->fLock )
#define IOREGSPLITTABLES
#ifdef IOREGSPLITTABLES
-#define registryTable() fRegistryTable
+#define registryTable() fRegistryTable
#else
-#define registryTable() fPropertyTable
+#define registryTable() fPropertyTable
#endif
-#define DEBUG_FREE 1
+#define DEBUG_FREE 1
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
-struct s_lock_t {
- decl_simple_lock_data(,interlock) /* "hardware" interlock field */
- volatile unsigned int
- read_count:16, /* No. of accepted readers */
- want_upgrade:1, /* Read-to-write upgrade waiting */
- want_write:1, /* Writer is waiting, or
- locked for write */
- waiting:1, /* Someone is sleeping on lock */
- can_sleep:1; /* Can attempts to lock go to sleep? */
-};
+lck_rw_t gIORegistryLock;
+lck_grp_t *gIORegistryLockGrp;
+lck_grp_attr_t *gIORegistryLockGrpAttr;
+lck_attr_t *gIORegistryLockAttr;
-static struct s_lock_t gIORegistryLock;
-
-/* Time we loop without holding the interlock.
- * The former is for when we cannot sleep, the latter
- * for when our thread can go to sleep (loop less)
- * we shouldn't retake the interlock at all frequently
- * if we cannot go to sleep, since it interferes with
- * any other processors. In particular, 100 is too small
- * a number for powerpc MP systems because of cache
- * coherency issues and differing lock fetch times between
- * the processors
- */
-static unsigned int lock_wait_time[2] = { (unsigned int)-1, 100 } ;
-
-static void
-s_lock_init(
- s_lock_t *l,
- boolean_t can_sleep)
-{
- (void) memset((void *) l, 0, sizeof(s_lock_t));
- simple_lock_init(&l->interlock, 0);
- l->want_write = FALSE;
- l->want_upgrade = FALSE;
- l->read_count = 0;
- l->can_sleep = can_sleep;
-}
+/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
-static void
-s_lock_write(
- register s_lock_t * l)
+IORegistryEntry *
+IORegistryEntry::initialize( void )
{
- register int i;
-
- simple_lock(&l->interlock);
-
- /*
- * Try to acquire the want_write bit.
- */
- while (l->want_write) {
-
- i = lock_wait_time[l->can_sleep ? 1 : 0];
- if (i != 0) {
- simple_unlock(&l->interlock);
- while (--i != 0 && l->want_write)
- continue;
- simple_lock(&l->interlock);
- }
-
- if (l->can_sleep && l->want_write) {
- l->waiting = TRUE;
- thread_sleep_simple_lock((event_t) l,
- simple_lock_addr(l->interlock),
- THREAD_UNINT);
- /* interlock relocked */
- }
- }
- l->want_write = TRUE;
-
- /* Wait for readers (and upgrades) to finish */
+ bool ok;
- while ((l->read_count != 0) || l->want_upgrade) {
+ if (!gRegistryRoot) {
+ gIORegistryLockGrpAttr = lck_grp_attr_alloc_init();
+ gIORegistryLockGrp = lck_grp_alloc_init("IORegistryLock", gIORegistryLockGrpAttr);
+ gIORegistryLockAttr = lck_attr_alloc_init();
+ lck_attr_rw_shared_priority(gIORegistryLockAttr);
+ lck_rw_init( &gIORegistryLock, gIORegistryLockGrp, gIORegistryLockAttr);
- i = lock_wait_time[l->can_sleep ? 1 : 0];
- if (i != 0) {
- simple_unlock(&l->interlock);
- while (--i != 0 && (l->read_count != 0 ||
- l->want_upgrade))
- continue;
- simple_lock(&l->interlock);
- }
-
- if (l->can_sleep && (l->read_count != 0 || l->want_upgrade)) {
- l->waiting = TRUE;
- thread_sleep_simple_lock((event_t) l,
- simple_lock_addr(l->interlock),
- THREAD_UNINT);
- /* interlock relocked */
- }
- }
-
- simple_unlock(&l->interlock);
-}
-
-static void
-s_lock_done(
- register s_lock_t * l)
-{
- boolean_t do_wakeup = FALSE;
+ gRegistryRoot = new IORegistryEntry;
+ gPropertiesLock = IORecursiveLockAlloc();
+ gIORegistryPlanes = OSDictionary::withCapacity( 1 );
- simple_lock(&l->interlock);
+ assert( gRegistryRoot && gPropertiesLock
+ && gIORegistryPlanes );
+ ok = gRegistryRoot->init();
- if (l->read_count != 0) {
- l->read_count -= 1;
- }
- else {
- if (l->want_upgrade) {
- l->want_upgrade = FALSE;
+ if (ok) {
+ gRegistryRoot->reserved->fRegistryEntryID = ++gIORegistryLastID;
}
- else {
- l->want_write = FALSE;
- }
- }
-
- /*
- * There is no reason to wakeup a waiting thread
- * if the read-count is non-zero. Consider:
- * we must be dropping a read lock
- * threads are waiting only if one wants a write lock
- * if there are still readers, they can't proceed
- */
- if (l->waiting && (l->read_count == 0)) {
- l->waiting = FALSE;
- do_wakeup = TRUE;
- }
-
- simple_unlock(&l->interlock);
-
- if (do_wakeup)
- thread_wakeup((event_t) l);
-}
-
-static void
-s_lock_read(
- register s_lock_t * l)
-{
- register int i;
-
- simple_lock(&l->interlock);
- while ( l->want_upgrade || ((0 == l->read_count) && l->want_write )) {
+ gIONameKey = OSSymbol::withCStringNoCopy( "IOName" );
+ gIOLocationKey = OSSymbol::withCStringNoCopy( "IOLocation" );
+ gIORegistryEntryIDKey = OSSymbol::withCStringNoCopy( kIORegistryEntryIDKey );
+ gIORegistryEntryPropertyKeysKey = OSSymbol::withCStringNoCopy( kIORegistryEntryPropertyKeysKey );
- i = lock_wait_time[l->can_sleep ? 1 : 0];
-
- if (i != 0) {
- simple_unlock(&l->interlock);
- while (--i != 0 &&
- (l->want_upgrade || ((0 == l->read_count) && l->want_write )))
- continue;
- simple_lock(&l->interlock);
- }
+ assert( ok && gIONameKey && gIOLocationKey );
- if (l->can_sleep &&
- (l->want_upgrade || ((0 == l->read_count) && l->want_write ))) {
- l->waiting = TRUE;
- thread_sleep_simple_lock((event_t) l,
- simple_lock_addr(l->interlock),
- THREAD_UNINT);
- /* interlock relocked */
- }
+ gRegistryRoot->setName( "Root" );
+ gRegistryRoot->setProperty( kIORegistryPlanesKey, gIORegistryPlanes );
}
- l->read_count += 1;
- simple_unlock(&l->interlock);
-
+ return gRegistryRoot;
}
-/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
-
-IORegistryEntry * IORegistryEntry::initialize( void )
+IORegistryEntry *
+IORegistryEntry::getRegistryRoot( void )
{
- bool ok;
-
- if( !gRegistryRoot) {
-
- s_lock_init( &gIORegistryLock, true );
- gRegistryRoot = new IORegistryEntry;
- gPropertiesLock = IORecursiveLockAlloc();
- gIORegistryPlanes = OSDictionary::withCapacity( 1 );
-
- assert( gRegistryRoot && gPropertiesLock
- && gIORegistryPlanes );
- ok = gRegistryRoot->init();
-
- gIONameKey = OSSymbol::withCStringNoCopy( "IOName" );
- gIOLocationKey = OSSymbol::withCStringNoCopy( "IOLocation" );
-
- assert( ok && gIONameKey && gIOLocationKey );
-
- gRegistryRoot->setName( "Root" );
- gRegistryRoot->setProperty( kIORegistryPlanesKey, gIORegistryPlanes );
- }
-
- return( gRegistryRoot );
+ return gRegistryRoot;
}
-IORegistryEntry * IORegistryEntry::getRegistryRoot( void )
+SInt32
+IORegistryEntry::getGenerationCount( void )
{
- return( gRegistryRoot );
+ return gIORegistryGenerationCount;
}
-SInt32 IORegistryEntry::getGenerationCount( void )
+SInt32
+IORegistryEntry::getRegistryEntryGenerationCount(void) const
{
- return( gIORegistryGenerationCount );
+ return reserved->fRegistryEntryGenerationCount;
}
-
-const IORegistryPlane * IORegistryEntry::makePlane( const char * name )
+const IORegistryPlane *
+IORegistryEntry::makePlane( const char * name )
{
- IORegistryPlane * plane;
- const OSSymbol * nameKey;
- const OSSymbol * parentKey;
- const OSSymbol * childKey;
- const OSSymbol * pathNameKey;
- const OSSymbol * pathLocationKey;
- char key[ kIOMaxPlaneName + 16 ];
- char * end;
+ IORegistryPlane * plane;
+ const OSSymbol * nameKey;
+ const OSSymbol * parentKey;
+ const OSSymbol * childKey;
+ const OSSymbol * pathNameKey;
+ const OSSymbol * pathLocationKey;
+ char key[kIOMaxPlaneName + 16];
+ char * end;
- strncpy( key, name, kIOMaxPlaneName );
- key[ kIOMaxPlaneName ] = 0;
- end = key + strlen( name );
+ strlcpy( key, name, kIOMaxPlaneName + 1 );
+ end = key + strlen( key );
- nameKey = OSSymbol::withCString( key);
+ nameKey = OSSymbol::withCString( key);
- strcpy( end, "ParentLinks" );
- parentKey = OSSymbol::withCString( key);
+ strlcpy( end, kIORegPlaneParentSuffix, kIORegPlaneParentSuffixLen + 1 );
+ parentKey = OSSymbol::withCString( key);
- strcpy( end, "ChildLinks" );
- childKey = OSSymbol::withCString( key);
+ strlcpy( end, kIORegPlaneChildSuffix, kIORegPlaneChildSuffixLen + 1 );
+ childKey = OSSymbol::withCString( key);
- strcpy( end, "Name" );
- pathNameKey = OSSymbol::withCString( key);
+ strlcpy( end, kIORegPlaneNameSuffix, kIORegPlaneNameSuffixLen + 1 );
+ pathNameKey = OSSymbol::withCString( key);
- strcpy( end, "Location" );
- pathLocationKey = OSSymbol::withCString( key);
+ strlcpy( end, kIORegPlaneLocationSuffix, kIORegPlaneLocationSuffixLen + 1 );
+ pathLocationKey = OSSymbol::withCString( key);
- plane = new IORegistryPlane;
+ plane = new IORegistryPlane;
- if( plane && plane->init()
- && nameKey && parentKey && childKey
- && pathNameKey && pathLocationKey ) {
+ if (plane && plane->init()
+ && nameKey && parentKey && childKey
+ && pathNameKey && pathLocationKey) {
+ plane->nameKey = nameKey;
+ plane->keys[kParentSetIndex] = parentKey;
+ plane->keys[kChildSetIndex] = childKey;
+ plane->pathNameKey = pathNameKey;
+ plane->pathLocationKey = pathLocationKey;
- plane->nameKey = nameKey;
- plane->keys[ kParentSetIndex ] = parentKey;
- plane->keys[ kChildSetIndex ] = childKey;
- plane->pathNameKey = pathNameKey;
- plane->pathLocationKey = pathLocationKey;
-
- WLOCK;
- gIORegistryPlanes->setObject( nameKey, plane );
- UNLOCK;
-
- } else {
-
- if( plane)
- plane->release();
- if( pathLocationKey)
- pathLocationKey->release();
- if( pathNameKey)
- pathNameKey->release();
- if( parentKey)
- parentKey->release();
- if( childKey)
- childKey->release();
- if( nameKey)
- nameKey->release();
- plane = 0;
- }
+ WLOCK;
+ gIORegistryPlanes->setObject( nameKey, plane );
+ UNLOCK;
+ } else {
+ if (plane) {
+ plane->release();
+ }
+ if (pathLocationKey) {
+ pathLocationKey->release();
+ }
+ if (pathNameKey) {
+ pathNameKey->release();
+ }
+ if (parentKey) {
+ parentKey->release();
+ }
+ if (childKey) {
+ childKey->release();
+ }
+ if (nameKey) {
+ nameKey->release();
+ }
+ plane = NULL;
+ }
- return( plane);
+ return plane;
}
-const IORegistryPlane * IORegistryEntry::getPlane( const char * name )
+const IORegistryPlane *
+IORegistryEntry::getPlane( const char * name )
{
- const IORegistryPlane * plane;
+ const IORegistryPlane * plane;
- RLOCK;
- plane = (const IORegistryPlane *) gIORegistryPlanes->getObject( name );
- UNLOCK;
+ RLOCK;
+ plane = (const IORegistryPlane *) gIORegistryPlanes->getObject( name );
+ UNLOCK;
- return( plane );
+ return plane;
}
-bool IORegistryPlane::serialize(OSSerialize *s) const
+bool
+IORegistryPlane::serialize(OSSerialize *s) const
{
- return( nameKey->serialize(s) );
+ return nameKey->serialize(s);
}
enum { kIORegCapacityIncrement = 4 };
-bool IORegistryEntry::init( OSDictionary * dict )
+bool
+IORegistryEntry::init( OSDictionary * dict )
{
- OSString * prop;
-
- if( !super::init())
- return( false);
+ OSString * prop;
- if( dict) {
- dict->retain();
- if( fPropertyTable)
- fPropertyTable->release();
- fPropertyTable = dict;
+ if (!super::init()) {
+ return false;
+ }
- } else if( !fPropertyTable) {
- fPropertyTable = OSDictionary::withCapacity( kIORegCapacityIncrement );
- if( fPropertyTable)
- fPropertyTable->setCapacityIncrement( kIORegCapacityIncrement );
- }
+ if (!reserved) {
+ reserved = IONew(ExpansionData, 1);
+ if (!reserved) {
+ return false;
+ }
+ bzero(reserved, sizeof(ExpansionData));
+ reserved->fLock = IORecursiveLockAlloc();
+ if (!reserved->fLock) {
+ return false;
+ }
+ }
+ if (dict) {
+ if (OSCollection::kImmutable & dict->setOptions(0, 0)) {
+ dict = (OSDictionary *) dict->copyCollection();
+ if (!dict) {
+ return false;
+ }
+ } else {
+ dict->retain();
+ }
+ if (fPropertyTable) {
+ fPropertyTable->release();
+ }
+ fPropertyTable = dict;
+ } else if (!fPropertyTable) {
+ fPropertyTable = OSDictionary::withCapacity( kIORegCapacityIncrement );
+ if (fPropertyTable) {
+ fPropertyTable->setCapacityIncrement( kIORegCapacityIncrement );
+ }
+ }
- if( !fPropertyTable)
- return( false);
+ if (!fPropertyTable) {
+ return false;
+ }
#ifdef IOREGSPLITTABLES
- if( !fRegistryTable) {
- fRegistryTable = OSDictionary::withCapacity( kIORegCapacityIncrement );
- if( fRegistryTable)
- fRegistryTable->setCapacityIncrement( kIORegCapacityIncrement );
- }
-
- if( (prop = OSDynamicCast( OSString, getProperty( gIONameKey)))) {
- OSSymbol * sym = (OSSymbol *)OSSymbol::withString( prop);
- // ok for OSSymbol too
- setName( sym);
- sym->release();
- }
+ if (!fRegistryTable) {
+ fRegistryTable = OSDictionary::withCapacity( kIORegCapacityIncrement );
+ if (fRegistryTable) {
+ fRegistryTable->setCapacityIncrement( kIORegCapacityIncrement );
+ }
+ }
+
+ if ((prop = OSDynamicCast( OSString, getProperty( gIONameKey)))) {
+ OSSymbol * sym = (OSSymbol *)OSSymbol::withString( prop);
+ // ok for OSSymbol too
+ setName( sym);
+ sym->release();
+ }
#endif /* IOREGSPLITTABLES */
- return( true);
+ return true;
}
-bool IORegistryEntry::init( IORegistryEntry * old,
- const IORegistryPlane * plane )
+bool
+IORegistryEntry::init( IORegistryEntry * old,
+ const IORegistryPlane * plane )
{
- OSArray * all;
- IORegistryEntry * next;
- unsigned int index;
+ OSArray * all;
+ IORegistryEntry * next;
+ unsigned int index;
+
+ if (!super::init()) {
+ return false;
+ }
- if( !super::init())
- return( false);
+ if (!reserved) {
+ reserved = IONew(ExpansionData, 1);
+ if (!reserved) {
+ return false;
+ }
+ bzero(reserved, sizeof(ExpansionData));
+ reserved->fLock = IORecursiveLockAlloc();
+ if (!reserved->fLock) {
+ return false;
+ }
+ }
- WLOCK;
+ WLOCK;
- fPropertyTable = old->getPropertyTable();
- fPropertyTable->retain();
+ reserved->fRegistryEntryID = old->reserved->fRegistryEntryID;
+
+ fPropertyTable = old->dictionaryWithProperties();
#ifdef IOREGSPLITTABLES
- fRegistryTable = old->fRegistryTable;
- old->fRegistryTable = OSDictionary::withDictionary( fRegistryTable );
+ fRegistryTable = old->fRegistryTable;
+ old->fRegistryTable = (OSDictionary *) fRegistryTable->copyCollection();
#endif /* IOREGSPLITTABLES */
- old->registryTable()->removeObject( plane->keys[ kParentSetIndex ] );
- old->registryTable()->removeObject( plane->keys[ kChildSetIndex ] );
+ old->registryTable()->removeObject( plane->keys[kParentSetIndex] );
+ old->registryTable()->removeObject( plane->keys[kChildSetIndex] );
- all = getParentSetReference( plane );
- if( all) for( index = 0;
- (next = (IORegistryEntry *) all->getObject(index));
- index++ ) {
- next->makeLink( this, kChildSetIndex, plane );
- next->breakLink( old, kChildSetIndex, plane );
- }
+ all = getParentSetReference( plane );
+ if (all) {
+ for (index = 0;
+ (next = (IORegistryEntry *) all->getObject(index));
+ index++) {
+ next->makeLink( this, kChildSetIndex, plane );
+ next->breakLink( old, kChildSetIndex, plane );
+ }
+ }
- all = getChildSetReference( plane );
- if( all) for( index = 0;
- (next = (IORegistryEntry *) all->getObject(index));
- index++ ) {
- next->makeLink( this, kParentSetIndex, plane );
- next->breakLink( old, kParentSetIndex, plane );
- }
+ all = getChildSetReference( plane );
+ if (all) {
+ for (index = 0;
+ (next = (IORegistryEntry *) all->getObject(index));
+ index++) {
+ next->makeLink( this, kParentSetIndex, plane );
+ next->breakLink( old, kParentSetIndex, plane );
+ }
+ }
- UNLOCK;
+ UNLOCK;
- return( true );
+ return true;
}
-void IORegistryEntry::free( void )
+void
+IORegistryEntry::free( void )
{
-
#if DEBUG_FREE
-#define msg ": attached at free()"
- char buf[ strlen(msg) + 40 ];
-
- if( registryTable() && gIOServicePlane) {
- if( getParentSetReference( gIOServicePlane )
- || getChildSetReference( gIOServicePlane )) {
-
- strncpy( buf, getName(), 32);
- buf[32] = 0;
- strcat( buf, msg );
- IOPanic( buf );
- }
- }
+ if (registryTable() && gIOServicePlane) {
+ if (getParentSetReference( gIOServicePlane )
+ || getChildSetReference( gIOServicePlane )) {
+ panic("%s: attached at free()", getName());
+ }
+ }
#endif
- if( getPropertyTable())
- getPropertyTable()->release();
+ if (getPropertyTable()) {
+ getPropertyTable()->release();
+ }
#ifdef IOREGSPLITTABLES
- if( registryTable())
- registryTable()->release();
+ if (registryTable()) {
+ registryTable()->release();
+ }
#endif /* IOREGSPLITTABLES */
- super::free();
+ if (reserved) {
+ if (reserved->fIndexedProperties) {
+ for (int idx = 0; idx < kIORegistryEntryIndexedPropertyCount; idx++) {
+ if (reserved->fIndexedProperties[idx]) {
+ reserved->fIndexedProperties[idx]->release();
+ }
+ }
+ IODelete(reserved->fIndexedProperties, OSObject *, kIORegistryEntryIndexedPropertyCount);
+ }
+ if (reserved->fLock) {
+ IORecursiveLockFree(reserved->fLock);
+ }
+ IODelete(reserved, ExpansionData, 1);
+ }
+
+ super::free();
}
-void IORegistryEntry::setPropertyTable( OSDictionary * dict )
+void
+IORegistryEntry::setPropertyTable( OSDictionary * dict )
{
- if( fPropertyTable)
- fPropertyTable->release();
- if( dict)
- dict->retain();
- fPropertyTable = dict;
+ PLOCK;
+ if (dict) {
+ dict->retain();
+ }
+ if (fPropertyTable) {
+ fPropertyTable->release();
+ }
+
+ fPropertyTable = dict;
+ PUNLOCK;
}
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
/* Wrappers to synchronize property table */
-#define wrap2(type, constant) \
-OSObject * \
-IORegistryEntry::copyProperty( type * aKey) constant \
-{ \
- OSObject * obj; \
- \
- PLOCK; \
- obj = getProperty( aKey ); \
- if( obj) \
- obj->retain(); \
- PUNLOCK; \
- \
- return( obj ); \
-}
-
-#define wrap4(type,constant) \
+#define wrap2(type, constant) \
+OSObject * \
+IORegistryEntry::copyProperty( type * aKey) constant \
+{ \
+ OSObject * obj; \
+ \
+ PLOCK; \
+ obj = getProperty( aKey ); \
+ if( obj) \
+ obj->retain(); \
+ PUNLOCK; \
+ \
+ return( obj ); \
+}
+
+#define wrap4(type, constant) \
OSObject * \
IORegistryEntry::getProperty( type * aKey, \
- const IORegistryPlane * plane, \
- IOOptionBits options ) constant \
+ const IORegistryPlane * plane, \
+ IOOptionBits options ) constant \
{ \
OSObject * obj = getProperty( aKey ); \
\
- if ( (0 == obj) && plane && (options & kIORegistryIterateRecursively) ) { \
- IORegistryEntry * entry = (IORegistryEntry *) this; \
- IORegistryIterator * iter; \
- iter = IORegistryIterator::iterateOver( entry, plane, options ); \
+ if ( (NULL == obj) && plane && (options & kIORegistryIterateRecursively) ) { \
+ IORegistryEntry * entry = (IORegistryEntry *) this; \
+ IORegistryIterator * iter; \
+ iter = IORegistryIterator::iterateOver( entry, plane, options ); \
\
- if(iter) { \
- while ( (0 == obj) && (entry = iter->getNextObject()) ) { \
- obj = entry->getProperty( aKey ); \
- } \
- iter->release(); \
- } \
+ if(iter) { \
+ while ( (NULL == obj) && (entry = iter->getNextObject()) ) { \
+ obj = entry->getProperty( aKey ); \
+ } \
+ iter->release(); \
+ } \
} \
\
return( obj ); \
}
-#define wrap5(type,constant) \
+#define wrap5(type, constant) \
OSObject * \
IORegistryEntry::copyProperty( type * aKey, \
- const IORegistryPlane * plane, \
- IOOptionBits options ) constant \
+ const IORegistryPlane * plane, \
+ IOOptionBits options ) constant \
{ \
OSObject * obj = copyProperty( aKey ); \
\
- if ( (0 == obj) && plane && (options & kIORegistryIterateRecursively) ) { \
- IORegistryEntry * entry = (IORegistryEntry *) this; \
- IORegistryIterator * iter; \
- iter = IORegistryIterator::iterateOver( entry, plane, options ); \
+ if ( (NULL == obj) && plane && (options & kIORegistryIterateRecursively) ) { \
+ IORegistryEntry * entry = (IORegistryEntry *) this; \
+ IORegistryIterator * iter; \
+ iter = IORegistryIterator::iterateOver( entry, plane, options ); \
\
- if(iter) { \
- while ( (0 == obj) && (entry = iter->getNextObject()) ) { \
- obj = entry->copyProperty( aKey ); \
- } \
- iter->release(); \
- } \
+ if(iter) { \
+ while ( (NULL == obj) && (entry = iter->getNextObject()) ) { \
+ obj = entry->copyProperty( aKey ); \
+ } \
+ iter->release(); \
+ } \
} \
\
return( obj ); \
}
-bool IORegistryEntry::serializeProperties( OSSerialize * s ) const
+bool
+IORegistryEntry::serializeProperties( OSSerialize * s ) const
{
- bool ok;
-
// setProperty( getRetainCount(), 32, "__retain" );
- PLOCK;
- ok = getPropertyTable()->serialize( s );
- PUNLOCK;
+ PLOCK;
+ OSCollection *snapshotProperties = getPropertyTable()->copyCollection();
+ PUNLOCK;
+
+ if (!snapshotProperties) {
+ return false;
+ }
+
+ bool ok = snapshotProperties->serialize( s );
+ snapshotProperties->release();
+ return ok;
+}
+
+OSArray *
+IORegistryEntry::copyPropertyKeys(void) const
+{
+ PLOCK;
+ OSArray * keys = getPropertyTable()->copyKeys();
+ PUNLOCK;
- return( ok );
+ return keys;
}
-OSDictionary * IORegistryEntry::dictionaryWithProperties( void ) const
+OSDictionary *
+IORegistryEntry::dictionaryWithProperties( void ) const
{
- OSDictionary * dict;
+ OSDictionary * dict;
- PLOCK;
- dict = OSDictionary::withDictionary( getPropertyTable(),
- getPropertyTable()->getCapacity() );
- PUNLOCK;
+ PLOCK;
+ dict = OSDictionary::withDictionary( getPropertyTable(),
+ getPropertyTable()->getCapacity());
+ PUNLOCK;
- return( dict );
+ return dict;
}
-IOReturn IORegistryEntry::setProperties( OSObject * properties )
+IOReturn
+IORegistryEntry::setProperties( OSObject * properties )
{
- return( kIOReturnUnsupported );
+ return kIOReturnUnsupported;
}
wrap2(const OSSymbol, const) // copyProperty() definition
wrap2(const OSString, const) // copyProperty() definition
-wrap2(const char, const) // copyProperty() definition
+wrap2(const char, const) // copyProperty() definition
wrap4(const OSSymbol, const) // getProperty() w/plane definition
wrap4(const OSString, const) // getProperty() w/plane definition
OSObject *
IORegistryEntry::getProperty( const OSSymbol * aKey) const
{
- OSObject * obj;
+ OSObject * obj;
+
+ PLOCK;
+ obj = getPropertyTable()->getObject( aKey );
+ PUNLOCK;
+
+ return obj;
+}
+
+void
+IORegistryEntry::removeProperty( const OSSymbol * aKey)
+{
+ PLOCK;
+ getPropertyTable()->removeObject( aKey );
+ PUNLOCK;
+}
+
+#if KASLR_IOREG_DEBUG
+extern "C" {
+bool ScanForAddrInObject(OSObject * theObject,
+ int indent);
+}; /* extern "C" */
+#endif
+
+bool
+IORegistryEntry::setProperty( const OSSymbol * aKey, OSObject * anObject)
+{
+ bool ret = false;
+
+ // If we are inserting a collection class and the current entry
+ // is attached into the registry (inPlane()) then mark the collection
+ // as immutable.
+ OSCollection *coll = OSDynamicCast(OSCollection, anObject);
+ bool makeImmutable = (coll && inPlane());
+
+ PLOCK;
+ if (makeImmutable) {
+ coll->setOptions( OSCollection::kMASK, OSCollection::kImmutable );
+ }
+
+ ret = getPropertyTable()->setObject( aKey, anObject );
+ PUNLOCK;
+
+#if KASLR_IOREG_DEBUG
+ if (anObject && strcmp(kIOKitDiagnosticsKey, aKey->getCStringNoCopy()) != 0) {
+ if (ScanForAddrInObject(anObject, 0)) {
+ IOLog("%s: IORegistryEntry name %s with key \"%s\" \n",
+ __FUNCTION__,
+ getName(0),
+ aKey->getCStringNoCopy());
+ }
+ }
+#endif
+
+ return ret;
+}
+
+IOReturn
+IORegistryEntry::
+runPropertyAction(Action inAction, OSObject *target,
+ void *arg0, void *arg1, void *arg2, void *arg3)
+{
+ IOReturn res;
- PLOCK;
- obj = getPropertyTable()->getObject( aKey );
- PUNLOCK;
+ // closeGate is recursive so don't worry if we already hold the lock.
+ PLOCK;
+ res = (*inAction)(target, arg0, arg1, arg2, arg3);
+ PUNLOCK;
- return( obj );
+ return res;
+}
+
+static IOReturn
+IORegistryEntryActionToBlock(OSObject *target,
+ void *arg0, void *arg1,
+ void *arg2, void *arg3)
+{
+ IORegistryEntry::ActionBlock block = (typeof(block))arg0;
+ return block();
+}
+
+IOReturn
+IORegistryEntry::runPropertyActionBlock(ActionBlock block)
+{
+ IOReturn res;
+
+ res = runPropertyAction(&IORegistryEntryActionToBlock, this, block);
+
+ return res;
}
OSObject *
IORegistryEntry::getProperty( const OSString * aKey) const
{
- const OSSymbol * tmpKey = OSSymbol::withString( aKey );
- OSObject * obj = getProperty( tmpKey );
+ const OSSymbol * tmpKey = OSSymbol::withString( aKey );
+ OSObject * obj = getProperty( tmpKey );
- tmpKey->release();
- return( obj );
+ tmpKey->release();
+ return obj;
}
OSObject *
IORegistryEntry::getProperty( const char * aKey) const
{
- const OSSymbol * tmpKey = OSSymbol::withCString( aKey );
- OSObject * obj = getProperty( tmpKey );
+ const OSSymbol * tmpKey = OSSymbol::withCString( aKey );
+ OSObject * obj = getProperty( tmpKey );
- tmpKey->release();
- return( obj );
+ tmpKey->release();
+ return obj;
}
-void
-IORegistryEntry::removeProperty( const OSSymbol * aKey)
-{
- PLOCK;
- getPropertyTable()->removeObject( aKey );
- PUNLOCK;
-}
void
IORegistryEntry::removeProperty( const OSString * aKey)
{
- const OSSymbol * tmpKey = OSSymbol::withString( aKey );
- removeProperty( tmpKey );
- tmpKey->release();
+ const OSSymbol * tmpKey = OSSymbol::withString( aKey );
+ removeProperty( tmpKey );
+ tmpKey->release();
}
void
IORegistryEntry::removeProperty( const char * aKey)
{
- const OSSymbol * tmpKey = OSSymbol::withCString( aKey );
- removeProperty( tmpKey );
- tmpKey->release();
-}
-
-bool
-IORegistryEntry::setProperty( const OSSymbol * aKey, OSObject * anObject)
-{
- bool ret = false;
- PLOCK;
- ret = getPropertyTable()->setObject( aKey, anObject );
- PUNLOCK;
-
- return ret;
+ const OSSymbol * tmpKey = OSSymbol::withCString( aKey );
+ removeProperty( tmpKey );
+ tmpKey->release();
}
bool
IORegistryEntry::setProperty( const OSString * aKey, OSObject * anObject)
{
- const OSSymbol * tmpKey = OSSymbol::withString( aKey );
- bool ret = setProperty( tmpKey, anObject );
+ const OSSymbol * tmpKey = OSSymbol::withString( aKey );
+ bool ret = setProperty( tmpKey, anObject );
- tmpKey->release();
- return ret;
+ tmpKey->release();
+ return ret;
}
bool
-IORegistryEntry::setProperty( const char * aKey, OSObject * anObject)
+IORegistryEntry::setProperty( const char * aKey, OSObject * anObject)
{
- const OSSymbol * tmpKey = OSSymbol::withCString( aKey );
- bool ret = setProperty( tmpKey, anObject );
+ const OSSymbol * tmpKey = OSSymbol::withCString( aKey );
+ bool ret = setProperty( tmpKey, anObject );
- tmpKey->release();
- return ret;
+ tmpKey->release();
+ return ret;
}
bool
IORegistryEntry::setProperty(const char * aKey, const char * aString)
{
- bool ret = false;
- OSSymbol * aSymbol = (OSSymbol *) OSSymbol::withCString( aString );
+ bool ret = false;
+ OSSymbol * aSymbol = (OSSymbol *) OSSymbol::withCString( aString );
- if( aSymbol) {
- const OSSymbol * tmpKey = OSSymbol::withCString( aKey );
- ret = setProperty( tmpKey, aSymbol );
+ if (aSymbol) {
+ const OSSymbol * tmpKey = OSSymbol::withCString( aKey );
+ ret = setProperty( tmpKey, aSymbol );
- tmpKey->release();
- aSymbol->release();
- }
- return( ret );
+ tmpKey->release();
+ aSymbol->release();
+ }
+ return ret;
}
bool
IORegistryEntry::setProperty(const char * aKey, bool aBoolean)
{
- bool ret = false;
- OSBoolean * aBooleanObj = OSBoolean::withBoolean( aBoolean );
+ bool ret = false;
+ OSBoolean * aBooleanObj = OSBoolean::withBoolean( aBoolean );
- if( aBooleanObj) {
- const OSSymbol * tmpKey = OSSymbol::withCString( aKey );
- ret = setProperty( tmpKey, aBooleanObj );
+ if (aBooleanObj) {
+ const OSSymbol * tmpKey = OSSymbol::withCString( aKey );
+ ret = setProperty( tmpKey, aBooleanObj );
- tmpKey->release();
- aBooleanObj->release();
- }
- return( ret );
+ tmpKey->release();
+ aBooleanObj->release();
+ }
+ return ret;
}
bool
IORegistryEntry::setProperty( const char * aKey,
- unsigned long long aValue,
- unsigned int aNumberOfBits)
+ unsigned long long aValue,
+ unsigned int aNumberOfBits)
{
- bool ret = false;
- OSNumber * anOffset = OSNumber::withNumber( aValue, aNumberOfBits );
+ bool ret = false;
+ OSNumber * anOffset = OSNumber::withNumber( aValue, aNumberOfBits );
- if( anOffset) {
- const OSSymbol * tmpKey = OSSymbol::withCString( aKey );
- ret = setProperty( tmpKey, anOffset );
+ if (anOffset) {
+ const OSSymbol * tmpKey = OSSymbol::withCString( aKey );
+ ret = setProperty( tmpKey, anOffset );
- tmpKey->release();
- anOffset->release();
- }
- return( ret );
+ tmpKey->release();
+ anOffset->release();
+ }
+ return ret;
}
bool
IORegistryEntry::setProperty( const char * aKey,
- void * bytes,
- unsigned int length)
+ void * bytes,
+ unsigned int length)
{
- bool ret = false;
- OSData * data = OSData::withBytes( bytes, length );
+ bool ret = false;
+ OSData * data = OSData::withBytes( bytes, length );
- if( data) {
- const OSSymbol * tmpKey = OSSymbol::withCString( aKey );
- ret = setProperty( tmpKey, data );
+ if (data) {
+ const OSSymbol * tmpKey = OSSymbol::withCString( aKey );
+ ret = setProperty( tmpKey, data );
- tmpKey->release();
- data->release();
- }
- return( ret );
+ tmpKey->release();
+ data->release();
+ }
+ return ret;
+}
+
+/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
+
+OSObject *
+IORegistryEntry::setIndexedProperty(uint32_t index, OSObject * anObject)
+{
+ OSObject ** array;
+ OSObject * prior;
+
+ if (index >= kIORegistryEntryIndexedPropertyCount) {
+ return NULL;
+ }
+
+ array = atomic_load_explicit(&reserved->fIndexedProperties, memory_order_acquire);
+ if (!array) {
+ array = IONew(OSObject *, kIORegistryEntryIndexedPropertyCount);
+ if (!array) {
+ return NULL;
+ }
+ bzero(array, kIORegistryEntryIndexedPropertyCount * sizeof(array[0]));
+ if (!OSCompareAndSwapPtr(NULL, array, &reserved->fIndexedProperties)) {
+ IODelete(array, OSObject *, kIORegistryEntryIndexedPropertyCount);
+ }
+ }
+ if (!reserved->fIndexedProperties) {
+ return NULL;
+ }
+
+ prior = reserved->fIndexedProperties[index];
+ if (anObject) {
+ anObject->retain();
+ }
+ reserved->fIndexedProperties[index] = anObject;
+
+ return prior;
+}
+
+OSObject *
+IORegistryEntry::getIndexedProperty(uint32_t index) const
+{
+ if (index >= kIORegistryEntryIndexedPropertyCount) {
+ return NULL;
+ }
+ if (!reserved->fIndexedProperties) {
+ return NULL;
+ }
+
+ return reserved->fIndexedProperties[index];
}
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
/* Name, location, paths */
-const char * IORegistryEntry::getName( const IORegistryPlane * plane ) const
+const char *
+IORegistryEntry::getName( const IORegistryPlane * plane ) const
{
- OSSymbol * sym = 0;
+ OSSymbol * sym = NULL;
- RLOCK;
- if( plane)
- sym = (OSSymbol *) registryTable()->getObject( plane->pathNameKey );
- if( !sym)
- sym = (OSSymbol *) registryTable()->getObject( gIONameKey );
- UNLOCK;
+ RLOCK;
+ if (plane) {
+ sym = (OSSymbol *) registryTable()->getObject( plane->pathNameKey );
+ }
+ if (!sym) {
+ sym = (OSSymbol *) registryTable()->getObject( gIONameKey );
+ }
+ UNLOCK;
- if( sym)
- return( sym->getCStringNoCopy());
- else
- return( (getMetaClass())->getClassName());
+ if (sym) {
+ return sym->getCStringNoCopy();
+ } else {
+ return (getMetaClass())->getClassName();
+ }
}
-const OSSymbol * IORegistryEntry::copyName(
- const IORegistryPlane * plane ) const
+const OSSymbol *
+IORegistryEntry::copyName(
+ const IORegistryPlane * plane ) const
{
- OSSymbol * sym = 0;
+ OSSymbol * sym = NULL;
- RLOCK;
- if( plane)
- sym = (OSSymbol *) registryTable()->getObject( plane->pathNameKey );
- if( !sym)
- sym = (OSSymbol *) registryTable()->getObject( gIONameKey );
- if( sym)
- sym->retain();
- UNLOCK;
+ RLOCK;
+ if (plane) {
+ sym = (OSSymbol *) registryTable()->getObject( plane->pathNameKey );
+ }
+ if (!sym) {
+ sym = (OSSymbol *) registryTable()->getObject( gIONameKey );
+ }
+ if (sym) {
+ sym->retain();
+ }
+ UNLOCK;
- if( sym)
- return( sym );
- else
- return( OSSymbol::withCString((getMetaClass())->getClassName()) );
+ if (sym) {
+ return sym;
+ } else {
+ return OSSymbol::withCString((getMetaClass())->getClassName());
+ }
}
-const OSSymbol * IORegistryEntry::copyLocation(
- const IORegistryPlane * plane ) const
+const OSSymbol *
+IORegistryEntry::copyLocation(
+ const IORegistryPlane * plane ) const
{
- OSSymbol * sym = 0;
+ OSSymbol * sym = NULL;
- RLOCK;
- if( plane)
- sym = (OSSymbol *) registryTable()->getObject( plane->pathLocationKey );
- if( !sym)
- sym = (OSSymbol *) registryTable()->getObject( gIOLocationKey );
- if( sym)
- sym->retain();
- UNLOCK;
+ RLOCK;
+ if (plane) {
+ sym = (OSSymbol *) registryTable()->getObject( plane->pathLocationKey );
+ }
+ if (!sym) {
+ sym = (OSSymbol *) registryTable()->getObject( gIOLocationKey );
+ }
+ if (sym) {
+ sym->retain();
+ }
+ UNLOCK;
- return( sym );
+ return sym;
}
-const char * IORegistryEntry::getLocation( const IORegistryPlane * plane ) const
+const char *
+IORegistryEntry::getLocation( const IORegistryPlane * plane ) const
{
- const OSSymbol * sym = copyLocation( plane );
- const char * result = 0;
+ const OSSymbol * sym = copyLocation( plane );
+ const char * result = NULL;
- if( sym) {
- result = sym->getCStringNoCopy();
- sym->release();
- }
+ if (sym) {
+ result = sym->getCStringNoCopy();
+ sym->release();
+ }
- return( result );
+ return result;
}
-void IORegistryEntry::setName( const OSSymbol * name,
- const IORegistryPlane * plane )
+void
+IORegistryEntry::setName( const OSSymbol * name,
+ const IORegistryPlane * plane )
{
- const OSSymbol * key;
+ const OSSymbol * key;
- if( name) {
- if( plane)
- key = plane->pathNameKey;
- else
- key = gIONameKey;
+ if (name) {
+ if (plane) {
+ key = plane->pathNameKey;
+ } else {
+ key = gIONameKey;
+ }
- WLOCK;
- registryTable()->setObject( key, (OSObject *) name);
- UNLOCK;
- }
+ if (gIOKitTrace && reserved && reserved->fRegistryEntryID) {
+ uint64_t str_id = 0;
+ uint64_t __unused regID = getRegistryEntryID();
+ kernel_debug_string(IODBG_IOREGISTRY(IOREGISTRYENTRY_NAME_STRING), &str_id, name->getCStringNoCopy());
+ KERNEL_DEBUG_CONSTANT(IODBG_IOREGISTRY(IOREGISTRYENTRY_NAME),
+ (uintptr_t) regID,
+ (uintptr_t) (regID >> 32),
+ (uintptr_t) str_id,
+ (uintptr_t) (str_id >> 32),
+ 0);
+ }
+
+ WLOCK;
+ registryTable()->setObject( key, (OSObject *) name);
+ UNLOCK;
+ }
}
-void IORegistryEntry::setName( const char * name,
- const IORegistryPlane * plane )
+void
+IORegistryEntry::setName( const char * name,
+ const IORegistryPlane * plane )
{
- OSSymbol * sym = (OSSymbol *)OSSymbol::withCString( name );
- if ( sym ) {
- setName( sym, plane );
- sym->release();
- }
+ OSSymbol * sym = (OSSymbol *)OSSymbol::withCString( name );
+ if (sym) {
+ setName( sym, plane );
+ sym->release();
+ }
}
-void IORegistryEntry::setLocation( const OSSymbol * location,
- const IORegistryPlane * plane )
+void
+IORegistryEntry::setName( const OSString * name,
+ const IORegistryPlane * plane )
{
- const OSSymbol * key;
+ const OSSymbol * sym = OSSymbol::withString( name );
+ if (sym) {
+ setName( sym, plane );
+ sym->release();
+ }
+}
- if( location) {
- if( plane)
- key = plane->pathLocationKey;
- else
- key = gIOLocationKey;
+void
+IORegistryEntry::setLocation( const OSSymbol * location,
+ const IORegistryPlane * plane )
+{
+ const OSSymbol * key;
- WLOCK;
- registryTable()->setObject( key, (OSObject *) location);
- UNLOCK;
- }
+ if (location) {
+ if (plane) {
+ key = plane->pathLocationKey;
+ } else {
+ key = gIOLocationKey;
+ }
+
+ WLOCK;
+ registryTable()->setObject( key, (OSObject *) location);
+ UNLOCK;
+ }
}
-void IORegistryEntry::setLocation( const char * location,
- const IORegistryPlane * plane )
+void
+IORegistryEntry::setLocation( const char * location,
+ const IORegistryPlane * plane )
{
- OSSymbol * sym = (OSSymbol *)OSSymbol::withCString( location );
- if ( sym ) {
- setLocation( sym, plane );
- sym->release();
- }
+ OSSymbol * sym = (OSSymbol *)OSSymbol::withCString( location );
+ if (sym) {
+ setLocation( sym, plane );
+ sym->release();
+ }
}
bool
IORegistryEntry::compareName( OSString * name, OSString ** matched ) const
{
- const OSSymbol * sym = copyName();
- bool isEqual;
+ const OSSymbol * sym = copyName();
+ bool isEqual;
- isEqual = sym->isEqualTo( name );
+ isEqual = (sym && sym->isEqualTo(name));
- if( isEqual && matched) {
- name->retain();
- *matched = name;
- }
+ if (isEqual && matched) {
+ name->retain();
+ *matched = name;
+ }
- if( sym)
- sym->release();
+ if (sym) {
+ sym->release();
+ }
- return( isEqual );
+ return isEqual;
}
bool
IORegistryEntry::compareNames( OSObject * names, OSString ** matched ) const
{
- OSString * string;
- OSCollection * collection;
- OSIterator * iter = 0;
- bool result = false;
-
- if( (collection = OSDynamicCast( OSCollection, names))) {
- iter = OSCollectionIterator::withCollection( collection );
- string = 0;
- } else
- string = OSDynamicCast( OSString, names);
-
- do {
- if( string)
- result = compareName( string, matched );
-
- } while( (false == result)
- && iter && (string = OSDynamicCast( OSString, iter->getNextObject())));
-
- if( iter)
- iter->release();
-
- return( result);
-}
-
-
-bool IORegistryEntry::getPath( char * path, int * length,
- const IORegistryPlane * plane ) const
+ OSString * string;
+ OSCollection * collection;
+ OSIterator * iter = NULL;
+ bool result = false;
+
+ if ((collection = OSDynamicCast( OSCollection, names))) {
+ iter = OSCollectionIterator::withCollection( collection );
+ string = NULL;
+ } else {
+ string = OSDynamicCast( OSString, names);
+ }
+
+ do {
+ if (string) {
+ result = compareName( string, matched );
+ }
+ } while ((false == result)
+ && iter && (string = OSDynamicCast( OSString, iter->getNextObject())));
+
+ if (iter) {
+ iter->release();
+ }
+
+ return result;
+}
+
+
+bool
+IORegistryEntry::getPath( char * path, int * length,
+ const IORegistryPlane * plane ) const
+{
+ OSArray * stack;
+ IORegistryEntry * root;
+ const IORegistryEntry * entry;
+ const IORegistryEntry * parent;
+ const OSSymbol * alias;
+ int index;
+ int len, maxLength, compLen, aliasLen;
+ char * nextComp;
+ bool ok;
+
+ if (!path || !length || !plane) {
+ return false;
+ }
+
+ len = 0;
+ maxLength = *length - 2;
+ nextComp = path;
+
+ len = plane->nameKey->getLength();
+ if (len >= maxLength) {
+ return false;
+ }
+ strlcpy( nextComp, plane->nameKey->getCStringNoCopy(), len + 1);
+ nextComp[len++] = ':';
+ nextComp += len;
+
+ if ((alias = hasAlias( plane ))) {
+ aliasLen = alias->getLength();
+ len += aliasLen;
+ ok = (maxLength > len);
+ *length = len;
+ if (ok) {
+ strlcpy( nextComp, alias->getCStringNoCopy(), aliasLen + 1);
+ }
+ return ok;
+ }
+
+ stack = OSArray::withCapacity( getDepth( plane ));
+ if (!stack) {
+ return false;
+ }
+
+ RLOCK;
+
+ parent = entry = this;
+ root = gRegistryRoot->getChildEntry( plane );
+ while (parent && (parent != root)) {
+ // stop below root
+ entry = parent;
+ parent = entry->getParentEntry( plane );
+ stack->setObject((OSObject *) entry );
+ }
+
+ ok = (NULL != parent);
+ if (ok) {
+ index = stack->getCount();
+ if (0 == index) {
+ *nextComp++ = '/';
+ *nextComp = 0;
+ len++;
+ } else {
+ while (ok && ((--index) >= 0)) {
+ entry = (IORegistryEntry *) stack->getObject((unsigned int) index );
+ assert( entry );
+
+ if ((alias = entry->hasAlias( plane ))) {
+ len = plane->nameKey->getLength() + 1;
+ nextComp = path + len;
+
+ compLen = alias->getLength();
+ ok = (maxLength > (len + compLen));
+ if (ok) {
+ strlcpy( nextComp, alias->getCStringNoCopy(), compLen + 1);
+ }
+ } else {
+ compLen = maxLength - len;
+ ok = entry->getPathComponent( nextComp + 1, &compLen, plane );
+
+ if (ok && compLen) {
+ compLen++;
+ *nextComp = '/';
+ }
+ }
+
+ if (ok) {
+ len += compLen;
+ nextComp += compLen;
+ }
+ }
+ }
+ *length = len;
+ }
+ UNLOCK;
+ stack->release();
+
+ return ok;
+}
+
+bool
+IORegistryEntry::getPathComponent( char * path, int * length,
+ const IORegistryPlane * plane ) const
{
- OSArray * stack;
- IORegistryEntry * root;
- const IORegistryEntry * entry;
- IORegistryEntry * parent;
- const OSSymbol * alias;
- int index;
- int len, maxLength, compLen;
- char * nextComp;
- bool ok;
+ int len, locLen, maxLength;
+ const char * compName;
+ const char * loc;
+ bool ok;
- if( !path || !length || !plane)
- return( false);
+ maxLength = *length;
- len = 0;
- maxLength = *length - 2;
- nextComp = path;
+ compName = getName( plane );
+ len = strlen( compName );
+ if ((loc = getLocation( plane ))) {
+ locLen = 1 + strlen( loc );
+ } else {
+ locLen = 0;
+ }
- len = plane->nameKey->getLength();
- if( len >= maxLength)
- return( false);
- strcpy( nextComp, plane->nameKey->getCStringNoCopy());
- nextComp[ len++ ] = ':';
- nextComp += len;
-
- if( (alias = hasAlias( plane ))) {
- len += alias->getLength();
- ok = (maxLength > len);
- *length = len;
- if( ok)
- strcpy( nextComp, alias->getCStringNoCopy());
- return( ok );
- }
+ ok = ((len + locLen + 1) < maxLength);
+ if (ok) {
+ strlcpy( path, compName, len + 1 );
+ if (loc) {
+ path += len;
+ len += locLen;
+ *path++ = '@';
+ strlcpy( path, loc, locLen );
+ }
+ *length = len;
+ }
- entry = this;
- parent = entry->getParentEntry( plane );
- if( !parent)
- // Error if not attached in plane
- return( false);
+ return ok;
+}
+
+const char *
+IORegistryEntry::matchPathLocation( const char * cmp,
+ const IORegistryPlane * plane )
+{
+ const char * str;
+ const char * result = NULL;
+ u_quad_t num1, num2;
+ char lastPathChar, lastLocationChar;
+
+ str = getLocation( plane );
+ if (str) {
+ lastPathChar = cmp[0];
+ lastLocationChar = str[0];
+ do {
+ if (lastPathChar) {
+ num1 = strtouq( cmp, (char **) &cmp, 16 );
+ lastPathChar = *cmp++;
+ } else {
+ num1 = 0;
+ }
+
+ if (lastLocationChar) {
+ num2 = strtouq( str, (char **) &str, 16 );
+ lastLocationChar = *str++;
+ } else {
+ num2 = 0;
+ }
+
+ if (num1 != num2) {
+ break;
+ }
+
+ if (!lastPathChar && !lastLocationChar) {
+ result = cmp - 1;
+ break;
+ }
+
+ if ((',' != lastPathChar) && (':' != lastPathChar)) {
+ lastPathChar = 0;
+ }
+
+ if (lastPathChar && lastLocationChar && (lastPathChar != lastLocationChar)) {
+ break;
+ }
+ } while (true);
+ }
- stack = OSArray::withCapacity( getDepth( plane ));
- if( !stack)
- return( false);
-
- RLOCK;
-
- root = gRegistryRoot->getChildEntry( plane );
- while( parent && (entry != root)) {
- // stop below root
- stack->setObject( (OSObject *) entry );
- entry = parent;
- parent = entry->getParentEntry( plane );
- }
-
- index = stack->getCount();
- ok = true;
-
- if( 0 == index) {
-
- *nextComp++ = '/';
- *nextComp = 0;
- len++;
-
- } else while( ok && ((--index) >= 0)) {
-
- entry = (IORegistryEntry *) stack->getObject((unsigned int) index );
- assert( entry );
-
- if( (alias = entry->hasAlias( plane ))) {
- len = plane->nameKey->getLength() + 1;
- nextComp = path + len;
-
- compLen = alias->getLength();
- ok = (maxLength > len + compLen);
- if( ok)
- strcpy( nextComp, alias->getCStringNoCopy());
- } else {
- compLen = maxLength - len;
- ok = entry->getPathComponent( nextComp + 1, &compLen, plane );
-
- if( ok && compLen) {
- compLen++;
- *nextComp = '/';
- }
- }
+ return result;
+}
+
+IORegistryEntry *
+IORegistryEntry::getChildFromComponent( const char ** opath,
+ const IORegistryPlane * plane )
+{
+ IORegistryEntry * entry = NULL;
+ OSArray * set;
+ unsigned int index;
+ const char * path;
+ const char * cmp = NULL;
+ char c;
+ size_t len;
+ const char * str;
+
+ set = getChildSetReference( plane );
+ if (set) {
+ path = *opath;
+
+ for (index = 0;
+ (entry = (IORegistryEntry *) set->getObject(index));
+ index++) {
+ cmp = path;
+
+ if (*cmp != '@') {
+ str = entry->getName( plane );
+ len = strlen( str );
+ if (strncmp( str, cmp, len )) {
+ continue;
+ }
+ cmp += len;
+
+ c = *cmp;
+ if ((c == 0) || (c == '/') || (c == ':')) {
+ break;
+ }
+ if (c != '@') {
+ continue;
+ }
+ }
+ cmp++;
+ if ((cmp = entry->matchPathLocation( cmp, plane ))) {
+ break;
+ }
+ }
+ if (entry) {
+ *opath = cmp;
+ }
+ }
- if( ok) {
- len += compLen;
- nextComp += compLen;
- }
- }
- *length = len;
-
- UNLOCK;
-
- stack->release();
-
- return( ok );
-}
-
-bool IORegistryEntry::getPathComponent( char * path, int * length,
- const IORegistryPlane * plane ) const
-{
- int len, locLen, maxLength;
- const char * compName;
- const char * loc;
- bool ok;
-
- maxLength = *length;
-
- compName = getName( plane );
- len = strlen( compName );
- if( (loc = getLocation( plane )))
- locLen = 1 + strlen( loc );
- else
- locLen = 0;
-
- ok = ((len + locLen) < maxLength);
- if( ok) {
- strcpy( path, compName );
- if( loc) {
- path += len;
- len += locLen;
- *path++ = '@';
- strcpy( path, loc );
- }
- *length = len;
- }
-
- return( ok );
+ return entry;
+}
+
+const OSSymbol *
+IORegistryEntry::hasAlias( const IORegistryPlane * plane,
+ char * opath, int * length ) const
+{
+ IORegistryEntry * entry;
+ IORegistryEntry * entry2;
+ const OSSymbol * key;
+ const OSSymbol * bestKey = NULL;
+ OSIterator * iter;
+ OSData * data;
+ const char * path = "/aliases";
+
+ entry = IORegistryEntry::fromPath( path, plane );
+ if (entry) {
+ RLOCK;
+ if ((iter = OSCollectionIterator::withCollection(
+ entry->getPropertyTable()))) {
+ while ((key = (OSSymbol *) iter->getNextObject())) {
+ data = (OSData *) entry->getProperty( key );
+ path = (const char *) data->getBytesNoCopy();
+ if ((entry2 = IORegistryEntry::fromPath( path, plane,
+ opath, length ))) {
+ if (this == entry2) {
+ if (!bestKey
+ || (bestKey->getLength() > key->getLength())) {
+ // pick the smallest alias
+ bestKey = key;
+ }
+ }
+ entry2->release();
+ }
+ }
+ iter->release();
+ }
+ entry->release();
+ UNLOCK;
+ }
+ return bestKey;
}
-const char * IORegistryEntry::matchPathLocation( const char * cmp,
- const IORegistryPlane * plane )
+const char *
+IORegistryEntry::dealiasPath(
+ const char ** opath,
+ const IORegistryPlane * plane )
{
- const char * str;
- const char * result = 0;
- u_quad_t num1, num2;
- char lastPathChar, lastLocationChar;
+ IORegistryEntry * entry;
+ OSData * data;
+ const char * path = *opath;
+ const char * rpath = NULL;
+ const char * end;
+ char c;
+ char temp[kIOMaxPlaneName + 1];
+
+ if (path[0] == '/') {
+ return rpath;
+ }
+
+ // check for alias
+ end = path;
+ while ((c = *end++) && (c != '/') && (c != ':')) {
+ }
+ end--;
+ if ((end - path) < kIOMaxPlaneName) {
+ strlcpy( temp, path, end - path + 1 );
+
+ RLOCK;
+ entry = IORegistryEntry::fromPath( "/aliases", plane );
+ if (entry) {
+ data = (OSData *) entry->getProperty( temp );
+ if (data) {
+ rpath = (const char *) data->getBytesNoCopy();
+ if (rpath) {
+ *opath = end;
+ }
+ }
+ entry->release();
+ }
+ UNLOCK;
+ }
+
+ return rpath;
+}
+
+IORegistryEntry *
+IORegistryEntry::fromPath(
+ const char * path,
+ const IORegistryPlane * plane,
+ char * opath,
+ int * length,
+ IORegistryEntry * fromEntry )
+{
+ IORegistryEntry * where = NULL;
+ IORegistryEntry * aliasEntry = NULL;
+ IORegistryEntry * next;
+ const char * alias;
+ const char * end;
+ int len = 0;
+ int len2;
+ char c;
+ char temp[kIOMaxPlaneName + 1];
+
+ if (NULL == path) {
+ return NULL;
+ }
+
+ if (NULL == plane) {
+ // get plane name
+ end = strchr( path, ':' );
+ if (end && ((end - path) < kIOMaxPlaneName)) {
+ strlcpy( temp, path, end - path + 1 );
+ plane = getPlane( temp );
+ path = end + 1;
+ }
+ }
+ if (NULL == plane) {
+ return NULL;
+ }
+
+ // check for alias
+ end = path;
+ if ((alias = dealiasPath( &end, plane))) {
+ if (length) {
+ len = *length;
+ }
+ aliasEntry = IORegistryEntry::fromPath( alias, plane,
+ opath, &len, fromEntry );
+ where = aliasEntry;
+ if (where) {
+ path = end;
+ } else {
+ len = 0;
+ }
+ }
+
+ RLOCK;
- str = getLocation( plane );
- if( str) {
- lastPathChar = cmp[0];
- lastLocationChar = str[0];
do {
- if( lastPathChar) {
- num1 = strtouq( cmp, (char **) &cmp, 16 );
- lastPathChar = *cmp++;
- } else
- num1 = 0;
-
- if( lastLocationChar) {
- num2 = strtouq( str, (char **) &str, 16 );
- lastLocationChar = *str++;
- } else
- num2 = 0;
-
- if( num1 != num2)
- break;
-
- if (!lastPathChar && !lastLocationChar) {
- result = cmp - 1;
- break;
- }
-
- if( (',' != lastPathChar) && (':' != lastPathChar))
- lastPathChar = 0;
-
- if (lastPathChar && lastLocationChar && (lastPathChar != lastLocationChar))
- break;
-
- } while( true);
- }
-
- return( result );
-}
-
-IORegistryEntry * IORegistryEntry::getChildFromComponent( const char ** opath,
- const IORegistryPlane * plane )
-{
- IORegistryEntry * entry = 0;
- OSArray * set;
- unsigned int index;
- const char * path;
- const char * cmp = 0;
- char c;
- size_t len;
- const char * str;
-
- set = getChildSetReference( plane );
- if( set) {
-
- path = *opath;
-
- for( index = 0;
- (entry = (IORegistryEntry *) set->getObject(index));
- index++ ) {
-
- cmp = path;
-
- if( *cmp != '@') {
- str = entry->getName( plane );
- len = strlen( str );
- if( strncmp( str, cmp, len ))
- continue;
- cmp += len;
-
- c = *cmp;
- if( (c == 0) || (c == '/') || (c == ':'))
- break;
- if( c != '@')
- continue;
- }
- cmp++;
- if( (cmp = entry->matchPathLocation( cmp, plane )))
- break;
- }
- if( entry)
- *opath = cmp;
- }
-
- return( entry );
-}
-
-const OSSymbol * IORegistryEntry::hasAlias( const IORegistryPlane * plane,
- char * opath, int * length ) const
-{
- IORegistryEntry * entry;
- IORegistryEntry * entry2;
- const OSSymbol * key;
- const OSSymbol * bestKey = 0;
- OSIterator * iter;
- OSData * data;
- const char * path = "/aliases";
-
- entry = IORegistryEntry::fromPath( path, plane );
- if( entry) {
- RLOCK;
- if( (iter = OSCollectionIterator::withCollection(
- entry->getPropertyTable() ))) {
-
- while( (key = (OSSymbol *) iter->getNextObject())) {
-
- data = (OSData *) entry->getProperty( key );
- path = (const char *) data->getBytesNoCopy();
- if( (entry2 = IORegistryEntry::fromPath( path, plane,
- opath, length ))) {
- if( this == entry2) {
- if( !bestKey
- || (bestKey->getLength() > key->getLength()))
- // pick the smallest alias
- bestKey = key;
- }
- entry2->release();
+ if (NULL == where) {
+ if ((NULL == fromEntry) && (*path++ == '/')) {
+ fromEntry = gRegistryRoot->getChildEntry( plane );
+ }
+ where = fromEntry;
+ if (NULL == where) {
+ break;
+ }
+ } else {
+ c = *path++;
+ if (c != '/') {
+ if (c && (c != ':')) { // check valid terminator
+ where = NULL;
+ }
+ break;
+ }
+ }
+ next = where->getChildFromComponent( &path, plane );
+ if (next) {
+ where = next;
+ }
+ } while (next);
+
+ if (where) {
+ // check residual path
+ if (where != fromEntry) {
+ path--;
}
- }
- iter->release();
- }
- entry->release();
+
+ if (opath && length) {
+ // copy out residual path
+ len2 = strlen( path );
+ if ((len + len2) < *length) {
+ strlcpy( opath + len, path, len2 + 1 );
+ }
+ *length = (len + len2);
+ } else if (path[0]) {
+ // no residual path => must be no tail for success
+ where = NULL;
+ }
+ }
+
+ if (where) {
+ where->retain();
+ }
+ if (aliasEntry) {
+ aliasEntry->release();
+ }
+
UNLOCK;
- }
- return( bestKey );
-}
-
-const char * IORegistryEntry::dealiasPath(
- const char ** opath,
- const IORegistryPlane * plane )
-{
- IORegistryEntry * entry;
- OSData * data;
- const char * path = *opath;
- const char * rpath = 0;
- const char * end;
- char c;
- char temp[ kIOMaxPlaneName + 1 ];
-
- if( path[0] == '/')
- return( rpath );
-
- // check for alias
- end = path;
- while( (c = *end++) && (c != '/') && (c != ':'))
- {}
- end--;
- if( (end - path) < kIOMaxPlaneName) {
- strncpy( temp, path, end - path );
- temp[ end - path ] = 0;
-
- RLOCK;
- entry = IORegistryEntry::fromPath( "/aliases", plane );
- if( entry) {
- data = (OSData *) entry->getProperty( temp );
- if( data ) {
- rpath = (const char *) data->getBytesNoCopy();
- if( rpath)
- *opath = end;
- }
- entry->release();
- }
- UNLOCK;
- }
-
- return( rpath );
-}
-
-IORegistryEntry * IORegistryEntry::fromPath(
- const char * path,
- const IORegistryPlane * plane,
- char * opath,
- int * length,
- IORegistryEntry * fromEntry )
-{
- IORegistryEntry * where = 0;
- IORegistryEntry * aliasEntry = 0;
- IORegistryEntry * next;
- const char * alias;
- const char * end;
- int len = 0;
- int len2;
- char c;
- char temp[ kIOMaxPlaneName + 1 ];
-
- if( 0 == path)
- return( 0 );
-
- if( 0 == plane) {
- // get plane name
- end = strchr( path, ':' );
- if( end && ((end - path) < kIOMaxPlaneName)) {
- strncpy( temp, path, end - path );
- temp[ end - path ] = 0;
- plane = getPlane( temp );
- path = end + 1;
- }
- }
- if( 0 == plane)
- return( 0 );
-
- // check for alias
- end = path;
- if( (alias = dealiasPath( &end, plane))) {
- if( length)
- len = *length;
- aliasEntry = IORegistryEntry::fromPath( alias, plane,
- opath, &len, fromEntry );
- where = aliasEntry;
- if( where)
- path = end;
- else
- len = 0;
- }
-
- RLOCK;
-
- do {
- if( 0 == where) {
- if( (0 == fromEntry) && (*path++ == '/'))
- fromEntry = gRegistryRoot->getChildEntry( plane );
- where = fromEntry;
- if( 0 == where)
- break;
- } else {
- c = *path++;
- if( c != '/') {
- if( c && (c != ':')) // check valid terminator
- where = 0;
- break;
- }
- }
- next = where->getChildFromComponent( &path, plane );
- if( next)
- where = next;
- } while( next );
-
- if( where) {
- // check residual path
- if( where != fromEntry)
- path--;
-
- if( opath && length) {
- // copy out residual path
- len2 = len + strlen( path );
- if( len2 < *length)
- strcpy( opath + len, path );
- *length = len2;
-
- } else if( path[0])
- // no residual path => must be no tail for success
- where = 0;
- }
-
- if( where)
- where->retain();
- if( aliasEntry)
- aliasEntry->release();
-
- UNLOCK;
-
- return( where );
-}
-
-IORegistryEntry * IORegistryEntry::childFromPath(
- const char * path,
- const IORegistryPlane * plane,
- char * opath,
- int * len )
-{
- return( IORegistryEntry::fromPath( path, plane, opath, len, this ));
+
+ return where;
+}
+
+IORegistryEntry *
+IORegistryEntry::childFromPath(
+ const char * path,
+ const IORegistryPlane * plane,
+ char * opath,
+ int * len )
+{
+ return IORegistryEntry::fromPath( path, plane, opath, len, this );
}
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
#undef super
#define super OSObject
-inline bool IORegistryEntry::arrayMember( OSArray * set,
- const IORegistryEntry * member,
- unsigned int * index ) const
+inline bool
+IORegistryEntry::arrayMember( OSArray * set,
+ const IORegistryEntry * member,
+ unsigned int * index ) const
{
- int i;
- OSObject * probeObject;
+ int i;
+ OSObject * probeObject;
- for( i = 0; (probeObject = set->getObject(i)); i++) {
- if (probeObject == (OSObject *) member) {
- if( index)
- *index = i;
- return( true );
+ for (i = 0; (probeObject = set->getObject(i)); i++) {
+ if (probeObject == (OSObject *) member) {
+ if (index) {
+ *index = i;
+ }
+ return true;
+ }
}
- }
- return( false );
+ return false;
}
-bool IORegistryEntry::makeLink( IORegistryEntry * to,
- unsigned int relation,
- const IORegistryPlane * plane ) const
-{
- OSArray * links;
- bool result = false;
-
- if( (links = (OSArray *)
- registryTable()->getObject( plane->keys[ relation ] ))) {
-
- result = arrayMember( links, to );
- if( !result)
- result = links->setObject( to );
-
- } else {
-
- links = OSArray::withObjects( (const OSObject **) &to, 1, 1 );
- result = (links != 0);
- if( result) {
- result = registryTable()->setObject( plane->keys[ relation ],
- links );
- links->release();
+bool
+IORegistryEntry::makeLink( IORegistryEntry * to,
+ unsigned int relation,
+ const IORegistryPlane * plane ) const
+{
+ OSArray * links;
+ bool result = false;
+
+ if ((links = (OSArray *)
+ registryTable()->getObject( plane->keys[relation] ))) {
+ result = arrayMember( links, to );
+ if (!result) {
+ result = links->setObject( to );
+ }
+ } else {
+ links = OSArray::withObjects((const OSObject **) &to, 1, 1 );
+ result = (links != NULL);
+ if (result) {
+ result = registryTable()->setObject( plane->keys[relation],
+ links );
+ links->release();
+ }
}
- }
+ reserved->fRegistryEntryGenerationCount++;
- return( result);
+ return result;
}
-void IORegistryEntry::breakLink( IORegistryEntry * to,
- unsigned int relation,
- const IORegistryPlane * plane ) const
-{
- OSArray * links;
- unsigned int index;
-
- if( (links = (OSArray *)
- registryTable()->getObject( plane->keys[ relation ]))) {
-
- if( arrayMember( links, to, &index )) {
- links->removeObject( index );
- if( 0 == links->getCount())
- registryTable()->removeObject( plane->keys[ relation ]);
- }
- }
+void
+IORegistryEntry::breakLink( IORegistryEntry * to,
+ unsigned int relation,
+ const IORegistryPlane * plane ) const
+{
+ OSArray * links;
+ unsigned int index;
+
+ if ((links = (OSArray *)
+ registryTable()->getObject( plane->keys[relation]))) {
+ if (arrayMember( links, to, &index )) {
+ links->removeObject( index );
+ if (0 == links->getCount()) {
+ registryTable()->removeObject( plane->keys[relation]);
+ }
+ }
+ }
+ reserved->fRegistryEntryGenerationCount++;
}
-OSArray * IORegistryEntry::getParentSetReference(
- const IORegistryPlane * plane ) const
+OSArray *
+IORegistryEntry::getParentSetReference(
+ const IORegistryPlane * plane ) const
{
- if( plane)
- return( (OSArray *) registryTable()->getObject(
- plane->keys[ kParentSetIndex ]));
- else
- return( 0 );
+ if (plane) {
+ return (OSArray *) registryTable()->getObject(
+ plane->keys[kParentSetIndex]);
+ } else {
+ return NULL;
+ }
}
-OSIterator * IORegistryEntry::getParentIterator(
- const IORegistryPlane * plane ) const
+OSIterator *
+IORegistryEntry::getParentIterator(
+ const IORegistryPlane * plane ) const
{
- OSArray * links;
- OSIterator * iter;
+ OSArray * links;
+ OSIterator * iter;
- if( !plane)
- return( 0 );
+ if (!plane) {
+ return NULL;
+ }
- RLOCK;
- links = getParentSetReference( plane );
- if( 0 == links)
- links = OSArray::withCapacity( 1 );
- else
- links = OSArray::withArray( links, links->getCount() );
- UNLOCK;
+ RLOCK;
+ links = getParentSetReference( plane );
+ if (NULL == links) {
+ links = OSArray::withCapacity( 1 );
+ } else {
+ links = OSArray::withArray( links, links->getCount());
+ }
+ UNLOCK;
- iter = IOLinkIterator::withCollection( links );
+ iter = IOLinkIterator::withCollection( links );
- if( links)
- links->release();
+ if (links) {
+ links->release();
+ }
- return( iter );
+ return iter;
}
-IORegistryEntry * IORegistryEntry::copyParentEntry( const IORegistryPlane * plane ) const
+IORegistryEntry *
+IORegistryEntry::copyParentEntry( const IORegistryPlane * plane ) const
{
- IORegistryEntry * entry = 0;
- OSArray * links;
+ IORegistryEntry * entry = NULL;
+ OSArray * links;
- RLOCK;
+ RLOCK;
- if( (links = getParentSetReference( plane ))) {
- entry = (IORegistryEntry *) links->getObject( 0 );
- entry->retain();
- }
+ if ((links = getParentSetReference( plane ))) {
+ entry = (IORegistryEntry *) links->getObject( 0 );
+ entry->retain();
+ }
- UNLOCK;
+ UNLOCK;
- return( entry);
+ return entry;
}
-IORegistryEntry * IORegistryEntry::getParentEntry( const IORegistryPlane * plane ) const
+IORegistryEntry *
+IORegistryEntry::getParentEntry( const IORegistryPlane * plane ) const
{
- IORegistryEntry * entry;
+ IORegistryEntry * entry;
- entry = copyParentEntry( plane );
- if( entry)
- entry->release();
+ entry = copyParentEntry( plane );
+ if (entry) {
+ entry->release();
+ }
- return( entry );
+ return entry;
}
-OSArray * IORegistryEntry::getChildSetReference( const IORegistryPlane * plane ) const
+OSArray *
+IORegistryEntry::getChildSetReference( const IORegistryPlane * plane ) const
{
- if( plane)
- return( (OSArray *) registryTable()->getObject(
- plane->keys[ kChildSetIndex ]));
- else
- return( 0 );
+ if (plane) {
+ return (OSArray *) registryTable()->getObject(
+ plane->keys[kChildSetIndex]);
+ } else {
+ return NULL;
+ }
}
-OSIterator * IORegistryEntry::getChildIterator( const IORegistryPlane * plane ) const
+OSIterator *
+IORegistryEntry::getChildIterator( const IORegistryPlane * plane ) const
{
- OSArray * links;
- OSIterator * iter;
+ OSArray * links;
+ OSIterator * iter;
- if( !plane)
- return( 0 );
+ if (!plane) {
+ return NULL;
+ }
- RLOCK;
- links = getChildSetReference( plane );
- if( 0 == links)
- links = OSArray::withCapacity( 1 );
- else
- links = OSArray::withArray( links, links->getCount() );
- UNLOCK;
+ RLOCK;
+ links = getChildSetReference( plane );
+ if (NULL == links) {
+ links = OSArray::withCapacity( 1 );
+ } else {
+ links = OSArray::withArray( links, links->getCount());
+ }
+ UNLOCK;
- iter = IOLinkIterator::withCollection( links );
+ iter = IOLinkIterator::withCollection( links );
- if( links)
- links->release();
+ if (links) {
+ links->release();
+ }
- return( iter );
+ return iter;
}
+uint32_t
+IORegistryEntry::getChildCount( const IORegistryPlane * plane ) const
+{
+ OSArray * links;
+ uint32_t count = 0;
-IORegistryEntry * IORegistryEntry::copyChildEntry(
- const IORegistryPlane * plane ) const
+ RLOCK;
+ links = getChildSetReference( plane );
+ if (links) {
+ count = links->getCount();
+ }
+ UNLOCK;
+
+ return count;
+}
+
+IORegistryEntry *
+IORegistryEntry::copyChildEntry(
+ const IORegistryPlane * plane ) const
{
- IORegistryEntry * entry = 0;
- OSArray * links;
+ IORegistryEntry * entry = NULL;
+ OSArray * links;
- RLOCK;
+ RLOCK;
- if( (links = getChildSetReference( plane ))) {
- entry = (IORegistryEntry *) links->getObject( 0 );
- entry->retain();
- }
+ if ((links = getChildSetReference( plane ))) {
+ entry = (IORegistryEntry *) links->getObject( 0 );
+ entry->retain();
+ }
- UNLOCK;
+ UNLOCK;
- return( entry);
+ return entry;
}
-IORegistryEntry * IORegistryEntry::getChildEntry(
- const IORegistryPlane * plane ) const
+IORegistryEntry *
+IORegistryEntry::getChildEntry(
+ const IORegistryPlane * plane ) const
{
- IORegistryEntry * entry;
+ IORegistryEntry * entry;
- entry = copyChildEntry( plane );
- if( entry)
- entry->release();
-
- return( entry );
+ entry = copyChildEntry( plane );
+ if (entry) {
+ entry->release();
+ }
+
+ return entry;
}
-void IORegistryEntry::applyToChildren( IORegistryEntryApplierFunction applier,
- void * context,
- const IORegistryPlane * plane ) const
+void
+IORegistryEntry::applyToChildren( IORegistryEntryApplierFunction applier,
+ void * context,
+ const IORegistryPlane * plane ) const
{
- OSArray * array;
- unsigned int index;
- IORegistryEntry * next;
+ OSArray * array;
+ unsigned int index;
+ IORegistryEntry * next;
- if( !plane)
- return;
+ if (!plane) {
+ return;
+ }
- RLOCK;
- array = OSArray::withArray( getChildSetReference( plane ));
- UNLOCK;
- if( array) {
- for( index = 0;
- (next = (IORegistryEntry *) array->getObject( index ));
- index++)
- (*applier)(next, context);
- array->release();
- }
+ RLOCK;
+ array = OSArray::withArray( getChildSetReference( plane ));
+ UNLOCK;
+ if (array) {
+ for (index = 0;
+ (next = (IORegistryEntry *) array->getObject( index ));
+ index++) {
+ (*applier)(next, context);
+ }
+ array->release();
+ }
}
-void IORegistryEntry::applyToParents( IORegistryEntryApplierFunction applier,
- void * context,
- const IORegistryPlane * plane ) const
+void
+IORegistryEntry::applyToParents( IORegistryEntryApplierFunction applier,
+ void * context,
+ const IORegistryPlane * plane ) const
{
- OSArray * array;
- unsigned int index;
- IORegistryEntry * next;
+ OSArray * array;
+ unsigned int index;
+ IORegistryEntry * next;
- if( !plane)
- return;
+ if (!plane) {
+ return;
+ }
- RLOCK;
- array = OSArray::withArray( getParentSetReference( plane ));
- UNLOCK;
- if( array) {
- for( index = 0;
- (next = (IORegistryEntry *) array->getObject( index ));
- index++)
- (*applier)(next, context);
- array->release();
- }
+ RLOCK;
+ array = OSArray::withArray( getParentSetReference( plane ));
+ UNLOCK;
+ if (array) {
+ for (index = 0;
+ (next = (IORegistryEntry *) array->getObject( index ));
+ index++) {
+ (*applier)(next, context);
+ }
+ array->release();
+ }
}
-bool IORegistryEntry::isChild( IORegistryEntry * child,
- const IORegistryPlane * plane,
- bool onlyChild ) const
+bool
+IORegistryEntry::isChild( IORegistryEntry * child,
+ const IORegistryPlane * plane,
+ bool onlyChild ) const
{
- OSArray * links;
- bool ret = false;
+ OSArray * links;
+ bool ret = false;
- RLOCK;
+ RLOCK;
- if( (links = getChildSetReference( plane ))) {
- if( (!onlyChild) || (1 == links->getCount()))
- ret = arrayMember( links, child );
- }
- if( ret && (links = child->getParentSetReference( plane )))
- ret = arrayMember( links, this );
+ if ((links = getChildSetReference( plane ))) {
+ if ((!onlyChild) || (1 == links->getCount())) {
+ ret = arrayMember( links, child );
+ }
+ }
+ if (ret && (links = child->getParentSetReference( plane ))) {
+ ret = arrayMember( links, this );
+ }
- UNLOCK;
+ UNLOCK;
- return( ret);
+ return ret;
}
-bool IORegistryEntry::isParent( IORegistryEntry * parent,
- const IORegistryPlane * plane,
- bool onlyParent ) const
-
+bool
+IORegistryEntry::isParent( IORegistryEntry * parent,
+ const IORegistryPlane * plane,
+ bool onlyParent ) const
{
- OSArray * links;
- bool ret = false;
+ OSArray * links;
+ bool ret = false;
- RLOCK;
+ RLOCK;
- if( (links = getParentSetReference( plane ))) {
- if( (!onlyParent) || (1 == links->getCount()))
- ret = arrayMember( links, parent );
- }
- if( ret && (links = parent->getChildSetReference( plane )))
- ret = arrayMember( links, this );
+ if ((links = getParentSetReference( plane ))) {
+ if ((!onlyParent) || (1 == links->getCount())) {
+ ret = arrayMember( links, parent );
+ }
+ }
+ if (ret && (links = parent->getChildSetReference( plane ))) {
+ ret = arrayMember( links, this );
+ }
- UNLOCK;
+ UNLOCK;
- return( ret);
+ return ret;
}
-bool IORegistryEntry::inPlane( const IORegistryPlane * plane ) const
+bool
+IORegistryEntry::inPlane( const IORegistryPlane * plane ) const
{
- bool ret;
+ bool ret;
- RLOCK;
+ RLOCK;
- ret = (0 != getParentSetReference( plane ));
+ if (plane) {
+ ret = (NULL != getParentSetReference( plane ));
+ } else {
+ // Check to see if this is in any plane. If it is in a plane
+ // then the registryTable will contain a key with the ParentLinks
+ // suffix. When we iterate over the keys looking for that suffix
+ ret = false;
+
+ OSCollectionIterator *iter =
+ OSCollectionIterator::withCollection( registryTable());
+ if (iter) {
+ const OSSymbol *key;
+
+ while ((key = (OSSymbol *) iter->getNextObject())) {
+ size_t keysuffix;
+
+ // Get a pointer to this keys suffix
+ keysuffix = key->getLength();
+ if (keysuffix <= kIORegPlaneParentSuffixLen) {
+ continue;
+ }
+ keysuffix -= kIORegPlaneParentSuffixLen;
+ if (!strncmp(key->getCStringNoCopy() + keysuffix,
+ kIORegPlaneParentSuffix,
+ kIORegPlaneParentSuffixLen + 1)) {
+ ret = true;
+ break;
+ }
+ }
+ iter->release();
+ }
+ }
- UNLOCK;
+ UNLOCK;
- return( ret );
+ return ret;
}
-bool IORegistryEntry::attachToParent( IORegistryEntry * parent,
- const IORegistryPlane * plane )
+bool
+IORegistryEntry::attachToParent( IORegistryEntry * parent,
+ const IORegistryPlane * plane )
{
- OSArray * links;
- bool ret;
- bool needParent;
+ OSArray * links;
+ bool ret;
+ bool needParent;
+ bool traceName = false;
- if( this == parent)
- return( false );
+ if (this == parent) {
+ return false;
+ }
- WLOCK;
+ WLOCK;
- ret = makeLink( parent, kParentSetIndex, plane );
+ if (!reserved->fRegistryEntryID) {
+ reserved->fRegistryEntryID = ++gIORegistryLastID;
+ traceName = (0 != gIOKitTrace);
+ }
- if( (links = parent->getChildSetReference( plane )))
- needParent = (false == arrayMember( links, this ));
- else
- needParent = true;
+ ret = makeLink( parent, kParentSetIndex, plane );
-// ret &= parent->makeLink( this, kChildSetIndex, plane );
+ if ((links = parent->getChildSetReference( plane ))) {
+ needParent = (false == arrayMember( links, this ));
+ } else {
+ needParent = true;
+ }
- UNLOCK;
+ UNLOCK;
- if( needParent)
- ret &= parent->attachToChild( this, plane );
+ if (traceName) {
+ uint64_t str_id = 0;
+ uint64_t __unused regID = getRegistryEntryID();
+ kernel_debug_string(IODBG_IOREGISTRY(IOREGISTRYENTRY_NAME_STRING), &str_id, getName());
+ KERNEL_DEBUG_CONSTANT(IODBG_IOREGISTRY(IOREGISTRYENTRY_NAME),
+ (uintptr_t) regID,
+ (uintptr_t) (regID >> 32),
+ (uintptr_t) str_id,
+ (uintptr_t) (str_id >> 32),
+ 0);
+ }
- return( ret );
+ PLOCK;
+
+ // Mark any collections in the property list as immutable
+ OSDictionary *ptable = getPropertyTable();
+ OSCollectionIterator *iter =
+ OSCollectionIterator::withCollection( ptable );
+ if (iter) {
+ const OSSymbol *key;
+
+ while ((key = (OSSymbol *) iter->getNextObject())) {
+ // Is object for key a collection?
+ OSCollection *coll =
+ OSDynamicCast( OSCollection, ptable->getObject( key ));
+
+ if (coll) {
+ // Yup so mark it as immutable
+ coll->setOptions( OSCollection::kMASK,
+ OSCollection::kImmutable );
+ }
+ }
+ iter->release();
+ }
+
+ PUNLOCK;
+
+ if (needParent) {
+ ret &= parent->attachToChild( this, plane );
+ }
+
+ return ret;
}
-bool IORegistryEntry::attachToChild( IORegistryEntry * child,
- const IORegistryPlane * plane )
+uint64_t
+IORegistryEntry::getRegistryEntryID( void )
{
- OSArray * links;
- bool ret;
- bool needChild;
+ if (reserved) {
+ return reserved->fRegistryEntryID;
+ } else {
+ return 0;
+ }
+}
- if( this == child)
- return( false );
+bool
+IORegistryEntry::attachToChild( IORegistryEntry * child,
+ const IORegistryPlane * plane )
+{
+ OSArray * links;
+ bool ret;
+ bool needChild;
- WLOCK;
+ if (this == child) {
+ return false;
+ }
- ret = makeLink( child, kChildSetIndex, plane );
+ WLOCK;
- if( (links = child->getParentSetReference( plane )))
- needChild = (false == arrayMember( links, this ));
- else
- needChild = true;
+ ret = makeLink( child, kChildSetIndex, plane );
- UNLOCK;
+ if ((links = child->getParentSetReference( plane ))) {
+ needChild = (false == arrayMember( links, this ));
+ } else {
+ needChild = true;
+ }
- if( needChild)
- ret &= child->attachToParent( this, plane );
+ UNLOCK;
- return( ret );
+ if (needChild) {
+ ret &= child->attachToParent( this, plane );
+ }
+
+ return ret;
}
-void IORegistryEntry::detachFromParent( IORegistryEntry * parent,
- const IORegistryPlane * plane )
+void
+IORegistryEntry::detachFromParent( IORegistryEntry * parent,
+ const IORegistryPlane * plane )
{
- OSArray * links;
- bool needParent;
+ OSArray * links;
+ bool needParent;
- WLOCK;
+ WLOCK;
- parent->retain();
+ parent->retain();
- breakLink( parent, kParentSetIndex, plane );
+ breakLink( parent, kParentSetIndex, plane );
- if( (links = parent->getChildSetReference( plane )))
- needParent = arrayMember( links, this );
- else
- needParent = false;
+ if ((links = parent->getChildSetReference( plane ))) {
+ needParent = arrayMember( links, this );
+ } else {
+ needParent = false;
+ }
// parent->breakLink( this, kChildSetIndex, plane );
- UNLOCK;
+ UNLOCK;
- if( needParent)
- parent->detachFromChild( this, plane );
+ if (needParent) {
+ parent->detachFromChild( this, plane );
+ }
- parent->release();
+ parent->release();
}
-void IORegistryEntry::detachFromChild( IORegistryEntry * child,
- const IORegistryPlane * plane )
+void
+IORegistryEntry::detachFromChild( IORegistryEntry * child,
+ const IORegistryPlane * plane )
{
- OSArray * links;
- bool needChild;
+ OSArray * links;
+ bool needChild;
- WLOCK;
+ WLOCK;
- child->retain();
+ child->retain();
- breakLink( child, kChildSetIndex, plane );
+ breakLink( child, kChildSetIndex, plane );
- if( (links = child->getParentSetReference( plane )))
- needChild = arrayMember( links, this );
- else
- needChild = false;
+ if ((links = child->getParentSetReference( plane ))) {
+ needChild = arrayMember( links, this );
+ } else {
+ needChild = false;
+ }
- UNLOCK;
+ UNLOCK;
- if( needChild)
- child->detachFromParent( this, plane );
+ if (needChild) {
+ child->detachFromParent( this, plane );
+ }
- child->release();
+ child->release();
}
-void IORegistryEntry::detachAbove( const IORegistryPlane * plane )
+void
+IORegistryEntry::detachAbove( const IORegistryPlane * plane )
{
- IORegistryEntry * parent;
+ IORegistryEntry * parent;
- retain();
- while( (parent = getParentEntry( plane )))
- detachFromParent( parent, plane );
- release();
+ retain();
+ while ((parent = copyParentEntry( plane ))) {
+ detachFromParent( parent, plane );
+ parent->release();
+ }
+ release();
}
-void IORegistryEntry::detachAll( const IORegistryPlane * plane )
+void
+IORegistryEntry::detachAll( const IORegistryPlane * plane )
{
- OSOrderedSet * all;
- IORegistryEntry * next;
- IORegistryIterator * regIter;
-
- regIter = IORegistryIterator::iterateOver( this, plane, true );
- if( 0 == regIter)
- return;
- all = regIter->iterateAll();
- regIter->release();
+ OSOrderedSet * all;
+ IORegistryEntry * next;
+ IORegistryIterator * regIter;
- detachAbove( plane );
- if( all) {
- while( (next = (IORegistryEntry *) all->getLastObject())) {
+ regIter = IORegistryIterator::iterateOver( this, plane, true );
+ if (NULL == regIter) {
+ return;
+ }
+ all = regIter->iterateAll();
+ regIter->release();
- next->retain();
- all->removeObject(next);
+ detachAbove( plane );
+ if (all) {
+ while ((next = (IORegistryEntry *) all->getLastObject())) {
+ next->retain();
+ all->removeObject(next);
- next->detachAbove( plane );
- next->release();
- }
- all->release();
- }
+ next->detachAbove( plane );
+ next->release();
+ }
+ all->release();
+ }
}
-unsigned int IORegistryEntry::getDepth( const IORegistryPlane * plane ) const
+unsigned int
+IORegistryEntry::getDepth( const IORegistryPlane * plane ) const
{
- unsigned int depth = 1;
- OSArray * parents;
- unsigned int oneDepth, maxParentDepth, count;
- IORegistryEntry * one;
- const IORegistryEntry * next;
- unsigned int index;
-
- RLOCK;
+ unsigned int depth = 1;
+ OSArray * parents;
+ unsigned int oneDepth, maxParentDepth, count;
+ IORegistryEntry * one;
+ const IORegistryEntry * next;
+ unsigned int index;
- next = this;
- while( (parents = next->getParentSetReference( plane ))) {
+ RLOCK;
- count = parents->getCount();
- if( 0 == count)
- break;
- if( 1 == count) {
- depth++;
- next = (IORegistryEntry *) parents->getObject( 0 );
- } else {
- // painful
- maxParentDepth = 0;
- for( index = 0;
- (one = (IORegistryEntry *) parents->getObject( index ));
- index++ ) {
- oneDepth = one->getDepth( plane );
- if( oneDepth > maxParentDepth)
- maxParentDepth = oneDepth;
- }
- depth += maxParentDepth;
- break;
+ next = this;
+ while ((parents = next->getParentSetReference( plane ))) {
+ count = parents->getCount();
+ if (0 == count) {
+ break;
+ }
+ if (1 == count) {
+ depth++;
+ next = (IORegistryEntry *) parents->getObject( 0 );
+ } else {
+ // painful
+ maxParentDepth = 0;
+ for (index = 0;
+ (one = (IORegistryEntry *) parents->getObject( index ));
+ index++) {
+ oneDepth = one->getDepth( plane );
+ if (oneDepth > maxParentDepth) {
+ maxParentDepth = oneDepth;
+ }
+ }
+ depth += maxParentDepth;
+ break;
+ }
}
- }
- UNLOCK;
+ UNLOCK;
- return( depth);
+ return depth;
}
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
IORegistryIterator *
IORegistryIterator::iterateOver( IORegistryEntry * root,
- const IORegistryPlane * plane,
- IOOptionBits options )
+ const IORegistryPlane * plane,
+ IOOptionBits options )
{
- IORegistryIterator * create;
+ IORegistryIterator * create;
- if( 0 == root)
- return( 0);
- if( 0 == plane)
- return( 0);
-
- create = new IORegistryIterator;
- if( create) {
- if( create->init()) {
-
- root->retain();
- create->root = root;
- create->where = &create->start;
- create->start.current = root;
- create->plane = plane;
- create->options = options & ~kIORegistryIteratorInvalidFlag;
+ if (NULL == root) {
+ return NULL;
+ }
+ if (NULL == plane) {
+ return NULL;
+ }
- } else {
- create->release();
- create = 0;
+ create = new IORegistryIterator;
+ if (create) {
+ if (create->init()) {
+ root->retain();
+ create->root = root;
+ create->where = &create->start;
+ create->start.current = root;
+ create->plane = plane;
+ create->options = options & ~kIORegistryIteratorInvalidFlag;
+ } else {
+ create->release();
+ create = NULL;
+ }
}
- }
- return( create);
+ return create;
}
IORegistryIterator *
IORegistryIterator::iterateOver( const IORegistryPlane * plane,
- IOOptionBits options )
+ IOOptionBits options )
{
- return( iterateOver( gRegistryRoot, plane, options ));
+ return iterateOver( gRegistryRoot, plane, options );
}
-bool IORegistryIterator::isValid( void )
+bool
+IORegistryIterator::isValid( void )
{
- bool ok;
- IORegCursor * next;
+ bool ok;
+ IORegCursor * next;
- next = where;
+ next = where;
- RLOCK;
+ RLOCK;
- ok = (0 == (kIORegistryIteratorInvalidFlag & options));
+ ok = (0 == (kIORegistryIteratorInvalidFlag & options));
- while( ok && next) {
- if( where->iter)
- ok = where->iter->isValid();
- next = next->next;
- }
- UNLOCK;
+ while (ok && next) {
+ if (where->iter) {
+ ok = where->iter->isValid();
+ }
+ next = next->next;
+ }
+ UNLOCK;
- return( ok);
+ return ok;
}
-void IORegistryIterator::enterEntry( const IORegistryPlane * enterPlane )
+void
+IORegistryIterator::enterEntry( const IORegistryPlane * enterPlane )
{
- IORegCursor * prev;
+ IORegCursor * prev;
- prev = where;
- where = (IORegCursor *) IOMalloc( sizeof( IORegCursor));
- assert( where);
+ prev = where;
+ where = (IORegCursor *) IOMalloc( sizeof(IORegCursor));
+ assert( where);
- if( where) {
- where->iter = 0;
- where->next = prev;
- where->current = prev->current;
- plane = enterPlane;
- }
+ if (where) {
+ where->iter = NULL;
+ where->next = prev;
+ where->current = prev->current;
+ plane = enterPlane;
+ }
}
-void IORegistryIterator::enterEntry( void )
+void
+IORegistryIterator::enterEntry( void )
{
- enterEntry( plane );
+ enterEntry( plane );
}
-bool IORegistryIterator::exitEntry( void )
+bool
+IORegistryIterator::exitEntry( void )
{
- IORegCursor * gone;
-
- if( where->iter) {
- where->iter->release();
- where->iter = 0;
- if( where->current)// && (where != &start))
- where->current->release();
- }
+ IORegCursor * gone;
- if( where != &start) {
- gone = where;
- where = gone->next;
- IOFree( gone, sizeof( IORegCursor));
- return( true);
+ if (where->iter) {
+ where->iter->release();
+ where->iter = NULL;
+ if (where->current) {// && (where != &start))
+ where->current->release();
+ }
+ }
- } else
- return( false);
+ if (where != &start) {
+ gone = where;
+ where = gone->next;
+ IOFree( gone, sizeof(IORegCursor));
+ return true;
+ } else {
+ return false;
+ }
}
-void IORegistryIterator::reset( void )
+void
+IORegistryIterator::reset( void )
{
- while( exitEntry())
- {}
+ while (exitEntry()) {
+ }
- if( done) {
- done->release();
- done = 0;
- }
+ if (done) {
+ done->release();
+ done = NULL;
+ }
- where->current = root;
- options &= ~kIORegistryIteratorInvalidFlag;
+ where->current = root;
+ options &= ~kIORegistryIteratorInvalidFlag;
}
-void IORegistryIterator::free( void )
+void
+IORegistryIterator::free( void )
{
- reset();
+ reset();
- if( root)
- root->release();
+ if (root) {
+ root->release();
+ }
- super::free();
+ super::free();
}
-IORegistryEntry * IORegistryIterator::getNextObjectFlat( void )
+IORegistryEntry *
+IORegistryIterator::getNextObjectFlat( void )
{
- IORegistryEntry * next = 0;
- OSArray * links = 0;
-
- RLOCK;
-
- if( (0 == where->iter)) {
- // just entered - create new iter
- if( isValid()
- && where->current
- && (links = ( (options & kIORegistryIterateParents) ?
- where->current->getParentSetReference( plane ) :
- where->current->getChildSetReference( plane ) )) )
+ IORegistryEntry * next = NULL;
+ OSArray * links = NULL;
- where->iter = OSCollectionIterator::withCollection( links );
+ RLOCK;
- } else
+ if ((NULL == where->iter)) {
+ // just entered - create new iter
+ if (isValid()
+ && where->current
+ && (links = ((options & kIORegistryIterateParents) ?
+ where->current->getParentSetReference( plane ) :
+ where->current->getChildSetReference( plane )))) {
+ where->iter = OSCollectionIterator::withCollection( links );
+ }
+ } else
// next sibling - release current
- if( where->current)
- where->current->release();
-
- if( where->iter) {
+ if (where->current) {
+ where->current->release();
+ }
- next = (IORegistryEntry *) where->iter->getNextObject();
+ if (where->iter) {
+ next = (IORegistryEntry *) where->iter->getNextObject();
- if( next)
- next->retain();
- else if( !where->iter->isValid())
- options |= kIORegistryIteratorInvalidFlag;
- }
+ if (next) {
+ next->retain();
+ } else if (!where->iter->isValid()) {
+ options |= kIORegistryIteratorInvalidFlag;
+ }
+ }
- where->current = next;
+ where->current = next;
- UNLOCK;
+ UNLOCK;
- return( next);
+ return next;
}
-IORegistryEntry * IORegistryIterator::getNextObjectRecursive( void )
+IORegistryEntry *
+IORegistryIterator::getNextObjectRecursive( void )
{
- IORegistryEntry * next;
+ IORegistryEntry * next;
- do
- next = getNextObjectFlat();
- while( (0 == next) && exitEntry());
+ do{
+ next = getNextObjectFlat();
+ } while ((NULL == next) && exitEntry());
- if( next) {
- if( 0 == done)
- done = OSOrderedSet::withCapacity( 10 );
- if( done->setObject((OSObject *) next)) {
- // done set didn't contain this one, so recurse
- enterEntry();
+ if (next) {
+ if (NULL == done) {
+ done = OSOrderedSet::withCapacity( 10 );
+ }
+ if (done->setObject((OSObject *) next)) {
+ // done set didn't contain this one, so recurse
+ enterEntry();
+ }
}
- }
- return( next);
+ return next;
}
-IORegistryEntry * IORegistryIterator::getNextObject( void )
+IORegistryEntry *
+IORegistryIterator::getNextObject( void )
{
- if( options & kIORegistryIterateRecursively)
- return( getNextObjectRecursive());
- else
- return( getNextObjectFlat());
+ if (options & kIORegistryIterateRecursively) {
+ return getNextObjectRecursive();
+ } else {
+ return getNextObjectFlat();
+ }
}
-IORegistryEntry * IORegistryIterator::getCurrentEntry( void )
+IORegistryEntry *
+IORegistryIterator::getCurrentEntry( void )
{
- if( isValid())
- return( where->current);
- else
- return( 0);
+ if (isValid()) {
+ return where->current;
+ } else {
+ return NULL;
+ }
}
-OSOrderedSet * IORegistryIterator::iterateAll( void )
+OSOrderedSet *
+IORegistryIterator::iterateAll( void )
{
- reset();
- while( getNextObjectRecursive())
- {}
- if( done)
- done->retain();
- return( done);
+ reset();
+ while (getNextObjectRecursive()) {
+ }
+ if (done) {
+ done->retain();
+ }
+ return done;
}
+#if __LP64__
+OSMetaClassDefineReservedUnused(IORegistryEntry, 0);
+OSMetaClassDefineReservedUnused(IORegistryEntry, 1);
+OSMetaClassDefineReservedUnused(IORegistryEntry, 2);
+OSMetaClassDefineReservedUnused(IORegistryEntry, 3);
+OSMetaClassDefineReservedUnused(IORegistryEntry, 4);
+OSMetaClassDefineReservedUnused(IORegistryEntry, 5);
+#else
OSMetaClassDefineReservedUsed(IORegistryEntry, 0);
OSMetaClassDefineReservedUsed(IORegistryEntry, 1);
OSMetaClassDefineReservedUsed(IORegistryEntry, 2);
OSMetaClassDefineReservedUsed(IORegistryEntry, 3);
OSMetaClassDefineReservedUsed(IORegistryEntry, 4);
-
-OSMetaClassDefineReservedUnused(IORegistryEntry, 5);
+OSMetaClassDefineReservedUsed(IORegistryEntry, 5);
+#endif
OSMetaClassDefineReservedUnused(IORegistryEntry, 6);
OSMetaClassDefineReservedUnused(IORegistryEntry, 7);
OSMetaClassDefineReservedUnused(IORegistryEntry, 8);
OSMetaClassDefineReservedUnused(IORegistryEntry, 31);
/* inline function implementation */
-OSDictionary * IORegistryEntry::getPropertyTable( void ) const
-{ return(fPropertyTable); }
+OSDictionary *
+IORegistryEntry::getPropertyTable( void ) const
+{
+ return fPropertyTable;
+}