/*
- * Copyright (c) 1998-2000 Apple Computer, Inc. All rights reserved.
+ * Copyright (c) 1998-2006 Apple Computer, Inc. All rights reserved.
*
- * @APPLE_LICENSE_HEADER_START@
+ * @APPLE_OSREFERENCE_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 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.
*
- * This Original Code and all software distributed under the License are
- * distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY KIND, EITHER
+ * 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.
+ * 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_LICENSE_HEADER_END@
+ * @APPLE_OSREFERENCE_LICENSE_HEADER_END@
*/
/*
* Copyright (c) 1998 Apple Computer, Inc. All rights reserved.
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
+#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
+
static IORegistryEntry * gRegistryRoot;
static OSDictionary * gIORegistryPlanes;
const OSSymbol * gIONameKey;
const OSSymbol * gIOLocationKey;
+const OSSymbol * gIORegistryEntryIDKey;
enum {
kParentSetIndex = 0,
kIOMaxPlaneName = 32
};
+enum { kIORegistryIDReserved = (1ULL << 32) + 255 };
+
+static uint64_t gIORegistryLastID = kIORegistryIDReserved;
+
class IORegistryPlane : public OSObject {
friend class IORegistryEntry;
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;
-#define UNLOCK s_lock_done( &gIORegistryLock )
-#define RLOCK s_lock_read( &gIORegistryLock )
-#define WLOCK s_lock_write( &gIORegistryLock ); \
+#define UNLOCK lck_rw_done( &gIORegistryLock )
+#define RLOCK lck_rw_lock_shared( &gIORegistryLock )
+#define WLOCK lck_rw_lock_exclusive( &gIORegistryLock ); \
gIORegistryGenerationCount++
// make atomic
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
-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? */
-};
-
-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)
-{
- 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 */
-
- while ((l->read_count != 0) || l->want_upgrade) {
-
- 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);
- }
+lck_rw_t gIORegistryLock;
+lck_grp_t *gIORegistryLockGrp;
+lck_grp_attr_t *gIORegistryLockGrpAttr;
+lck_attr_t *gIORegistryLockAttr;
- 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;
-
- simple_lock(&l->interlock);
-
- if (l->read_count != 0) {
- l->read_count -= 1;
- }
- else {
- if (l->want_upgrade) {
- l->want_upgrade = FALSE;
- }
- 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 )) {
-
- 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);
- }
-
- 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 */
- }
- }
-
- l->read_count += 1;
- simple_unlock(&l->interlock);
-
-}
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
if( !gRegistryRoot) {
- s_lock_init( &gIORegistryLock, true );
+
+ gIORegistryLockGrpAttr = lck_grp_attr_alloc_init();
+ //lck_grp_attr_setstat(gIORegistryLockGrpAttr);
+ gIORegistryLockGrp = lck_grp_alloc_init("IORegistryLock", gIORegistryLockGrpAttr);
+ gIORegistryLockAttr = lck_attr_alloc_init();
+ lck_attr_rw_shared_priority(gIORegistryLockAttr);
+ //lck_attr_setdebug(gIORegistryLockAttr);
+ lck_rw_init( &gIORegistryLock, gIORegistryLockGrp, gIORegistryLockAttr);
+
gRegistryRoot = new IORegistryEntry;
gPropertiesLock = IORecursiveLockAlloc();
gIORegistryPlanes = OSDictionary::withCapacity( 1 );
&& gIORegistryPlanes );
ok = gRegistryRoot->init();
+ if (ok)
+ gRegistryRoot->reserved->fRegistryEntryID = ++gIORegistryLastID;
+
gIONameKey = OSSymbol::withCStringNoCopy( "IOName" );
gIOLocationKey = OSSymbol::withCStringNoCopy( "IOLocation" );
+ gIORegistryEntryIDKey = OSSymbol::withCStringNoCopy( kIORegistryEntryIDKey );
assert( ok && gIONameKey && gIOLocationKey );
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);
- strcpy( end, "ParentLinks" );
+ strlcpy( end, kIORegPlaneParentSuffix, kIORegPlaneParentSuffixLen + 1 );
parentKey = OSSymbol::withCString( key);
- strcpy( end, "ChildLinks" );
+ strlcpy( end, kIORegPlaneChildSuffix, kIORegPlaneChildSuffixLen + 1 );
childKey = OSSymbol::withCString( key);
- strcpy( end, "Name" );
+ strlcpy( end, kIORegPlaneNameSuffix, kIORegPlaneNameSuffixLen + 1 );
pathNameKey = OSSymbol::withCString( key);
- strcpy( end, "Location" );
+ strlcpy( end, kIORegPlaneLocationSuffix, kIORegPlaneLocationSuffixLen + 1 );
pathLocationKey = OSSymbol::withCString( key);
plane = new IORegistryPlane;
enum { kIORegCapacityIncrement = 4 };
-bool IORegistryEntry::init( OSDictionary * dict = 0 )
+bool IORegistryEntry::init( OSDictionary * dict )
{
OSString * prop;
if( !super::init())
return( false);
+ if (!reserved)
+ {
+ reserved = IONew(ExpansionData, 1);
+ if (!reserved)
+ return (false);
+ bzero(reserved, sizeof(ExpansionData));
+ }
if( dict) {
- dict->retain();
+ if (OSCollection::kImmutable & dict->setOptions(0, 0)) {
+ dict = (OSDictionary *) dict->copyCollection();
+ if (!dict)
+ return (false);
+ } else
+ dict->retain();
if( fPropertyTable)
fPropertyTable->release();
fPropertyTable = dict;
WLOCK;
+ reserved = old->reserved;
+ old->reserved = NULL;
+
fPropertyTable = old->getPropertyTable();
fPropertyTable->retain();
#ifdef IOREGSPLITTABLES
fRegistryTable = old->fRegistryTable;
- old->fRegistryTable = OSDictionary::withDictionary( fRegistryTable );
+ old->fRegistryTable = (OSDictionary *) fRegistryTable->copyCollection();
#endif /* IOREGSPLITTABLES */
old->registryTable()->removeObject( plane->keys[ kParentSetIndex ] );
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 );
+ panic("%s: attached at free()", getName());
}
}
#endif
registryTable()->release();
#endif /* IOREGSPLITTABLES */
+ if (reserved)
+ IODelete(reserved, ExpansionData, 1);
+
super::free();
}
/* Wrappers to synchronize property table */
-#define wrap1(func, type, constant) \
-OSObject * \
-IORegistryEntry::func ## Property( type * aKey) constant \
-{ \
- OSObject * obj; \
- \
- PLOCK; \
- obj = getPropertyTable()->func ## Object( aKey ); \
- PUNLOCK; \
- \
- return( obj ); \
-}
-
#define wrap2(type, constant) \
OSObject * \
IORegistryEntry::copyProperty( type * aKey) constant \
return( obj ); \
}
-#define wrap3(func,type,constant) \
-void \
-IORegistryEntry::func ## Property( type * aKey) constant \
-{ \
- PLOCK; \
- getPropertyTable()->func ## Object( aKey ); \
- PUNLOCK; \
-}
-
#define wrap4(type,constant) \
OSObject * \
IORegistryEntry::getProperty( type * aKey, \
bool IORegistryEntry::serializeProperties( OSSerialize * s ) const
{
- bool ok;
-
// setProperty( getRetainCount(), 32, "__retain" );
PLOCK;
- ok = getPropertyTable()->serialize( s );
+ OSCollection *snapshotProperties = getPropertyTable()->copyCollection();
PUNLOCK;
+ bool ok = snapshotProperties->serialize( s );
+ snapshotProperties->release();
return( ok );
}
return( kIOReturnUnsupported );
}
-wrap1(get, const OSSymbol, const) // getProperty() definition
-wrap1(get, const OSString, const) // getProperty() definition
-wrap1(get, const char, const) // getProperty() definition
-
wrap2(const OSSymbol, const) // copyProperty() definition
wrap2(const OSString, const) // copyProperty() definition
wrap2(const char, const) // copyProperty() definition
-wrap3(remove, const OSSymbol,) // removeProperty() definition
-wrap3(remove, const OSString,) // removeProperty() definition
-wrap3(remove, const char,) // removeProperty() definition
-
wrap4(const OSSymbol, const) // getProperty() w/plane definition
wrap4(const OSString, const) // getProperty() w/plane definition
wrap4(const char, const) // getProperty() w/plane definition
wrap5(const char, const) // copyProperty() w/plane definition
+OSObject *
+IORegistryEntry::getProperty( const OSSymbol * aKey) const
+{
+ 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;
}
-bool
-IORegistryEntry::setProperty( const OSString * aKey, OSObject * anObject)
+IOReturn IORegistryEntry::
+runPropertyAction(Action inAction, OSObject *target,
+ void *arg0, void *arg1, void *arg2, void *arg3)
{
- bool ret = false;
+ IOReturn res;
+
+ // closeGate is recursive so don't worry if we already hold the lock.
PLOCK;
- ret = getPropertyTable()->setObject( aKey, anObject );
+ res = (*inAction)(target, arg0, arg1, arg2, arg3);
PUNLOCK;
+ return res;
+}
+
+OSObject *
+IORegistryEntry::getProperty( const OSString * aKey) const
+{
+ const OSSymbol * tmpKey = OSSymbol::withString( aKey );
+ OSObject * obj = getProperty( tmpKey );
+
+ tmpKey->release();
+ return( obj );
+}
+
+OSObject *
+IORegistryEntry::getProperty( const char * aKey) const
+{
+ const OSSymbol * tmpKey = OSSymbol::withCString( aKey );
+ OSObject * obj = getProperty( tmpKey );
+
+ tmpKey->release();
+ return( obj );
+}
+
+
+void
+IORegistryEntry::removeProperty( const OSString * aKey)
+{
+ 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 OSString * aKey, OSObject * anObject)
+{
+ const OSSymbol * tmpKey = OSSymbol::withString( aKey );
+ bool ret = setProperty( tmpKey, anObject );
+
+ tmpKey->release();
return ret;
}
bool
IORegistryEntry::setProperty( const char * aKey, OSObject * anObject)
{
- bool ret = false;
- PLOCK;
- ret = getPropertyTable()->setObject( aKey, anObject );
- PUNLOCK;
-
+ const OSSymbol * tmpKey = OSSymbol::withCString( aKey );
+ bool ret = setProperty( tmpKey, anObject );
+
+ tmpKey->release();
return ret;
}
OSSymbol * aSymbol = (OSSymbol *) OSSymbol::withCString( aString );
if( aSymbol) {
- PLOCK;
- ret = getPropertyTable()->setObject( aKey, aSymbol );
- PUNLOCK;
+ const OSSymbol * tmpKey = OSSymbol::withCString( aKey );
+ ret = setProperty( tmpKey, aSymbol );
+
+ tmpKey->release();
aSymbol->release();
}
return( ret );
OSBoolean * aBooleanObj = OSBoolean::withBoolean( aBoolean );
if( aBooleanObj) {
- PLOCK;
- ret = getPropertyTable()->setObject( aKey, aBooleanObj );
- PUNLOCK;
+ const OSSymbol * tmpKey = OSSymbol::withCString( aKey );
+ ret = setProperty( tmpKey, aBooleanObj );
+
+ tmpKey->release();
aBooleanObj->release();
}
return( ret );
OSNumber * anOffset = OSNumber::withNumber( aValue, aNumberOfBits );
if( anOffset) {
- PLOCK;
- ret = getPropertyTable()->setObject( aKey, anOffset );
- PUNLOCK;
+ const OSSymbol * tmpKey = OSSymbol::withCString( aKey );
+ ret = setProperty( tmpKey, anOffset );
+
+ tmpKey->release();
anOffset->release();
}
return( ret );
OSData * data = OSData::withBytes( bytes, length );
if( data) {
- PLOCK;
- ret = getPropertyTable()->setObject( aKey, data );
- PUNLOCK;
+ const OSSymbol * tmpKey = OSSymbol::withCString( aKey );
+ ret = setProperty( tmpKey, data );
+
+ tmpKey->release();
data->release();
}
return( ret );
/* Name, location, paths */
-const char * IORegistryEntry::getName( const IORegistryPlane * plane = 0 ) const
+const char * IORegistryEntry::getName( const IORegistryPlane * plane ) const
{
OSSymbol * sym = 0;
}
const OSSymbol * IORegistryEntry::copyName(
- const IORegistryPlane * plane = 0 ) const
+ const IORegistryPlane * plane ) const
{
OSSymbol * sym = 0;
}
const OSSymbol * IORegistryEntry::copyLocation(
- const IORegistryPlane * plane = 0 ) const
+ const IORegistryPlane * plane ) const
{
OSSymbol * sym = 0;
return( sym );
}
-const char * IORegistryEntry::getLocation( const IORegistryPlane * plane = 0 ) const
+const char * IORegistryEntry::getLocation( const IORegistryPlane * plane ) const
{
const OSSymbol * sym = copyLocation( plane );
const char * result = 0;
}
void IORegistryEntry::setName( const OSSymbol * name,
- const IORegistryPlane * plane = 0 )
+ const IORegistryPlane * plane )
{
const OSSymbol * key;
}
void IORegistryEntry::setName( const char * name,
- const IORegistryPlane * plane = 0 )
+ const IORegistryPlane * plane )
{
OSSymbol * sym = (OSSymbol *)OSSymbol::withCString( name );
if ( sym ) {
}
void IORegistryEntry::setLocation( const OSSymbol * location,
- const IORegistryPlane * plane = 0 )
+ const IORegistryPlane * plane )
{
const OSSymbol * key;
}
void IORegistryEntry::setLocation( const char * location,
- const IORegistryPlane * plane = 0 )
+ const IORegistryPlane * plane )
{
OSSymbol * sym = (OSSymbol *)OSSymbol::withCString( location );
if ( sym ) {
}
bool
-IORegistryEntry::compareName( OSString * name, OSString ** matched = 0 ) const
+IORegistryEntry::compareName( OSString * name, OSString ** matched ) const
{
const OSSymbol * sym = copyName();
bool isEqual;
}
bool
-IORegistryEntry::compareNames( OSObject * names, OSString ** matched = 0 ) const
+IORegistryEntry::compareNames( OSObject * names, OSString ** matched ) const
{
OSString * string;
OSCollection * collection;
OSArray * stack;
IORegistryEntry * root;
const IORegistryEntry * entry;
- IORegistryEntry * parent;
+ const IORegistryEntry * parent;
const OSSymbol * alias;
int index;
- int len, maxLength, compLen;
+ int len, maxLength, compLen, aliasLen;
char * nextComp;
bool ok;
len = plane->nameKey->getLength();
if( len >= maxLength)
return( false);
- strcpy( nextComp, plane->nameKey->getCStringNoCopy());
+ strlcpy( nextComp, plane->nameKey->getCStringNoCopy(), len + 1);
nextComp[ len++ ] = ':';
nextComp += len;
if( (alias = hasAlias( plane ))) {
- len += alias->getLength();
+ aliasLen = alias->getLength();
+ len += aliasLen;
ok = (maxLength > len);
*length = len;
if( ok)
- strcpy( nextComp, alias->getCStringNoCopy());
+ strlcpy( nextComp, alias->getCStringNoCopy(), aliasLen + 1);
return( ok );
}
- entry = this;
- parent = entry->getParentEntry( plane );
- if( !parent)
- // Error if not attached in plane
- return( false);
-
stack = OSArray::withCapacity( getDepth( plane ));
- if( !stack)
- return( false);
+ if (!stack) return( false);
RLOCK;
+ parent = entry = this;
root = gRegistryRoot->getChildEntry( plane );
- while( parent && (entry != root)) {
+ while (parent && (parent != root))
+ {
// stop below root
- stack->setObject( (OSObject *) entry );
entry = parent;
parent = entry->getParentEntry( plane );
+ stack->setObject( (OSObject *) entry );
}
- index = stack->getCount();
- ok = true;
-
- if( 0 == index) {
+ ok = (0 != parent);
+ if (ok)
+ {
+ index = stack->getCount();
+ if( 0 == index) {
- *nextComp++ = '/';
- *nextComp = 0;
- len++;
+ *nextComp++ = '/';
+ *nextComp = 0;
+ len++;
- } else while( ok && ((--index) >= 0)) {
+ } else while( ok && ((--index) >= 0)) {
- entry = (IORegistryEntry *) stack->getObject((unsigned int) index );
- assert( entry );
+ entry = (IORegistryEntry *) stack->getObject((unsigned int) index );
+ assert( entry );
- if( (alias = entry->hasAlias( plane ))) {
- len = plane->nameKey->getLength() + 1;
- nextComp = path + len;
+ 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 );
+ 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 && compLen) {
+ compLen++;
+ *nextComp = '/';
+ }
}
- }
- if( ok) {
- len += compLen;
- nextComp += compLen;
+ if( ok) {
+ len += compLen;
+ nextComp += compLen;
+ }
}
+ *length = len;
}
- *length = len;
-
UNLOCK;
-
stack->release();
return( ok );
else
locLen = 0;
- ok = ((len + locLen) < maxLength);
+ ok = ((len + locLen + 1) < maxLength);
if( ok) {
- strcpy( path, compName );
+ strlcpy( path, compName, len + 1 );
if( loc) {
path += len;
len += locLen;
*path++ = '@';
- strcpy( path, loc );
+ strlcpy( path, loc, locLen );
}
*length = len;
}
const char * str;
const char * result = 0;
u_quad_t num1, num2;
- char c1, c2;
+ char lastPathChar, lastLocationChar;
str = getLocation( plane );
if( str) {
- c2 = str[0];
+ lastPathChar = cmp[0];
+ lastLocationChar = str[0];
do {
- num1 = strtouq( cmp, (char **) &cmp, 16 );
- if( c2) {
+ if( lastPathChar) {
+ num1 = strtouq( cmp, (char **) &cmp, 16 );
+ lastPathChar = *cmp++;
+ } else
+ num1 = 0;
+
+ if( lastLocationChar) {
num2 = strtouq( str, (char **) &str, 16 );
- c2 = str[0];
+ lastLocationChar = *str++;
} else
num2 = 0;
if( num1 != num2)
break;
- c1 = *cmp++;
-
- if( (c2 == ':') && (c2 == c1)) {
- str++;
- continue;
- }
-
- if( ',' != c1) {
+ if (!lastPathChar && !lastLocationChar) {
result = cmp - 1;
break;
}
- if( c2) {
- if( c2 != ',')
- break;
- str++;
- }
+ if( (',' != lastPathChar) && (':' != lastPathChar))
+ lastPathChar = 0;
+
+ if (lastPathChar && lastLocationChar && (lastPathChar != lastLocationChar))
+ break;
} while( true);
}
}
const OSSymbol * IORegistryEntry::hasAlias( const IORegistryPlane * plane,
- char * opath = 0, int * length = 0 ) const
+ char * opath, int * length ) const
{
IORegistryEntry * entry;
IORegistryEntry * entry2;
{}
end--;
if( (end - path) < kIOMaxPlaneName) {
- strncpy( temp, path, end - path );
- temp[ end - path ] = 0;
+ strlcpy( temp, path, end - path + 1 );
RLOCK;
entry = IORegistryEntry::fromPath( "/aliases", plane );
IORegistryEntry * IORegistryEntry::fromPath(
const char * path,
- const IORegistryPlane * plane = 0,
- char * opath = 0,
- int * length = 0,
- IORegistryEntry * fromEntry = 0 )
+ const IORegistryPlane * plane,
+ char * opath,
+ int * length,
+ IORegistryEntry * fromEntry )
{
IORegistryEntry * where = 0;
IORegistryEntry * aliasEntry = 0;
// get plane name
end = strchr( path, ':' );
if( end && ((end - path) < kIOMaxPlaneName)) {
- strncpy( temp, path, end - path );
- temp[ end - path ] = 0;
+ strlcpy( temp, path, end - path + 1 );
plane = getPlane( temp );
path = end + 1;
}
if( opath && length) {
// copy out residual path
- len2 = len + strlen( path );
- if( len2 < *length)
- strcpy( opath + len, path );
- *length = len2;
+ 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
IORegistryEntry * IORegistryEntry::childFromPath(
const char * path,
- const IORegistryPlane * plane = 0,
- char * opath = 0,
- int * len = 0 )
+ const IORegistryPlane * plane,
+ char * opath,
+ int * len )
{
return( IORegistryEntry::fromPath( path, plane, opath, len, this ));
}
inline bool IORegistryEntry::arrayMember( OSArray * set,
const IORegistryEntry * member,
- unsigned int * index = 0 ) const
+ unsigned int * index ) const
{
int i;
OSObject * probeObject;
} else {
- links = OSArray::withObjects( & (const OSObject *) to, 1, 1 );
+ links = OSArray::withObjects( (const OSObject **) &to, 1, 1 );
result = (links != 0);
if( result) {
result = registryTable()->setObject( plane->keys[ relation ],
bool IORegistryEntry::isChild( IORegistryEntry * child,
const IORegistryPlane * plane,
- bool onlyChild = false ) const
+ bool onlyChild ) const
{
OSArray * links;
bool ret = false;
bool IORegistryEntry::isParent( IORegistryEntry * parent,
const IORegistryPlane * plane,
- bool onlyParent = false ) const
+ bool onlyParent ) const
{
OSArray * links;
RLOCK;
- ret = (0 != getParentSetReference( plane ));
+ if( plane)
+ ret = (0 != 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;
WLOCK;
+ if (!reserved->fRegistryEntryID)
+ reserved->fRegistryEntryID = ++gIORegistryLastID;
+
ret = makeLink( parent, kParentSetIndex, plane );
if( (links = parent->getChildSetReference( plane )))
else
needParent = true;
-// ret &= parent->makeLink( this, kChildSetIndex, plane );
-
UNLOCK;
+ 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 );
}
+uint64_t IORegistryEntry::getRegistryEntryID( void )
+{
+ if (reserved)
+ return (reserved->fRegistryEntryID);
+ else
+ return (0);
+}
+
bool IORegistryEntry::attachToChild( IORegistryEntry * child,
const IORegistryPlane * plane )
{
IORegistryEntry * parent;
retain();
- while( (parent = getParentEntry( plane )))
+ while( (parent = copyParentEntry( plane )))
+ {
detachFromParent( parent, plane );
+ parent->release();
+ }
release();
}
IORegistryIterator *
IORegistryIterator::iterateOver( IORegistryEntry * root,
const IORegistryPlane * plane,
- IOOptionBits options = 0 )
+ IOOptionBits options )
{
IORegistryIterator * create;
IORegistryIterator *
IORegistryIterator::iterateOver( const IORegistryPlane * plane,
- IOOptionBits options = 0 )
+ IOOptionBits options )
{
return( iterateOver( gRegistryRoot, plane, options ));
}
IORegCursor * prev;
prev = where;
- where = (IORegCursor *) IOMalloc( sizeof( IORegCursor));
+ where = (IORegCursor *) IOMalloc( sizeof(IORegCursor));
assert( where);
if( where) {
if( where != &start) {
gone = where;
where = gone->next;
- IOFree( gone, sizeof( IORegCursor));
+ IOFree( gone, sizeof(IORegCursor));
return( true);
} else
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);