]> git.saurik.com Git - apple/xnu.git/blobdiff - iokit/Kernel/IORegistryEntry.cpp
xnu-1504.9.17.tar.gz
[apple/xnu.git] / iokit / Kernel / IORegistryEntry.cpp
index 4be7e3aa5bb823cfbd3329494f6dc0f38fbf7e7a..e41a94bdcf185984707a2b48f51f4ec0858f244a 100644 (file)
@@ -1,23 +1,29 @@
 /*
- * 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. 
@@ -48,13 +54,18 @@ OSDefineMetaClassAndStructors(IORegistryEntry, OSObject)
 #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)
 
 static IORegistryEntry * gRegistryRoot;
 static OSDictionary *   gIORegistryPlanes;
 
 const OSSymbol *       gIONameKey;
 const OSSymbol *       gIOLocationKey;
+const OSSymbol *       gIORegistryEntryIDKey;
 
 enum {
     kParentSetIndex    = 0,
@@ -65,6 +76,10 @@ enum {
     kIOMaxPlaneName    = 32
 };
 
+enum { kIORegistryIDReserved = (1ULL << 32) + 255 };
+
+static uint64_t gIORegistryLastID = kIORegistryIDReserved;
+
 class IORegistryPlane : public OSObject {
 
     friend class IORegistryEntry;
@@ -139,8 +154,12 @@ IORegistryEntry * IORegistryEntry::initialize( void )
                && 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 );
 
@@ -173,22 +192,21 @@ const IORegistryPlane * IORegistryEntry::makePlane( const char * name )
     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, kIORegPlaneParentSuffix );
+    strlcpy( end, kIORegPlaneParentSuffix, kIORegPlaneParentSuffixLen + 1 );
     parentKey = OSSymbol::withCString( key);
 
-    strcpy( end, kIORegPlaneChildSuffix );
+    strlcpy( end, kIORegPlaneChildSuffix, kIORegPlaneChildSuffixLen + 1 );
     childKey = OSSymbol::withCString( key);
 
-    strcpy( end, kIORegPlaneNameSuffix );
+    strlcpy( end, kIORegPlaneNameSuffix, kIORegPlaneNameSuffixLen + 1 );
     pathNameKey = OSSymbol::withCString( key);
 
-    strcpy( end, kIORegPlaneLocationSuffix );
+    strlcpy( end, kIORegPlaneLocationSuffix, kIORegPlaneLocationSuffixLen + 1 );
     pathLocationKey = OSSymbol::withCString( key);
 
     plane = new IORegistryPlane;
@@ -252,6 +270,13 @@ bool IORegistryEntry::init( OSDictionary * dict )
     if( !super::init())
        return( false);
 
+    if (!reserved)
+    {
+       reserved = IONew(ExpansionData, 1);
+       if (!reserved)
+           return (false);
+       bzero(reserved, sizeof(ExpansionData));
+    }
     if( dict) {
        dict->retain();
        if( fPropertyTable)
@@ -298,6 +323,9 @@ bool IORegistryEntry::init( IORegistryEntry * old,
 
     WLOCK;
 
+    reserved = old->reserved;
+    old->reserved = NULL;
+
     fPropertyTable = old->getPropertyTable();
     fPropertyTable->retain();
 #ifdef IOREGSPLITTABLES
@@ -331,19 +359,11 @@ bool IORegistryEntry::init( IORegistryEntry * old,
 
 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
@@ -356,6 +376,9 @@ void IORegistryEntry::free( void )
         registryTable()->release();
 #endif /* IOREGSPLITTABLES */
 
+    if (reserved)
+       IODelete(reserved, ExpansionData, 1);
+
     super::free();
 }
 
@@ -839,7 +862,7 @@ bool IORegistryEntry::getPath(      char * path, int * length,
     IORegistryEntry *  parent;
     const OSSymbol *   alias;
     int                        index;
-    int                        len, maxLength, compLen;
+    int                        len, maxLength, compLen, aliasLen;
     char *             nextComp;
     bool               ok;
 
@@ -853,16 +876,17 @@ bool IORegistryEntry::getPath(    char * path, int * length,
     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 );
     }
 
@@ -905,9 +929,9 @@ bool IORegistryEntry::getPath(      char * path, int * length,
             nextComp = path + len;
 
             compLen = alias->getLength();
-            ok = (maxLength > len + compLen);
+            ok = (maxLength > (len + compLen));
             if( ok)
-                strcpy( nextComp, alias->getCStringNoCopy());
+                strlcpy( nextComp, alias->getCStringNoCopy(), compLen + 1);
         } else {
             compLen = maxLength - len;
             ok = entry->getPathComponent( nextComp + 1, &compLen, plane );
@@ -949,14 +973,14 @@ bool IORegistryEntry::getPathComponent( char * path, int * length,
     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;
     }
@@ -1117,8 +1141,7 @@ const char * IORegistryEntry::dealiasPath(
         {}
     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 );
@@ -1161,8 +1184,7 @@ IORegistryEntry * IORegistryEntry::fromPath(
        // 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;
        }
@@ -1213,10 +1235,10 @@ IORegistryEntry * IORegistryEntry::fromPath(
 
        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
@@ -1550,12 +1572,16 @@ bool IORegistryEntry::inPlane( const IORegistryPlane * plane ) const
            const OSSymbol *key;
 
             while( (key = (OSSymbol *) iter->getNextObject()) ) {
-               const char *keysuffix;
+               size_t keysuffix;
 
                // Get a pointer to this keys suffix
-               keysuffix = key->getCStringNoCopy()
-                         + key->getLength() - kIORegPlaneParentSuffixLen;
-               if( !strcmp(keysuffix, kIORegPlaneParentSuffix) ) {
+               keysuffix = key->getLength();
+               if (keysuffix <= kIORegPlaneParentSuffixLen)
+                   continue;
+               keysuffix -= kIORegPlaneParentSuffixLen;
+               if( !strncmp(key->getCStringNoCopy() + keysuffix, 
+                               kIORegPlaneParentSuffix, 
+                               kIORegPlaneParentSuffixLen + 1) ) {
                    ret = true;
                    break;
                }
@@ -1581,6 +1607,9 @@ bool IORegistryEntry::attachToParent( IORegistryEntry * parent,
 
     WLOCK;
 
+    if (!reserved->fRegistryEntryID)
+       reserved->fRegistryEntryID = ++gIORegistryLastID;
+
     ret = makeLink( parent, kParentSetIndex, plane );
 
     if( (links = parent->getChildSetReference( plane )))
@@ -1621,6 +1650,14 @@ bool IORegistryEntry::attachToParent( IORegistryEntry * parent,
     return( ret );
 }
 
+uint64_t IORegistryEntry::getRegistryEntryID( void )
+{
+    if (reserved)
+       return (reserved->fRegistryEntryID);
+    else
+       return (0);
+}
+
 bool IORegistryEntry::attachToChild( IORegistryEntry * child,
                                         const IORegistryPlane * plane )
 {
@@ -1851,7 +1888,7 @@ void IORegistryIterator::enterEntry( const IORegistryPlane * enterPlane )
     IORegCursor *      prev;
 
     prev = where;
-    where = (IORegCursor *) IOMalloc( sizeof( IORegCursor));
+    where = (IORegCursor *) IOMalloc( sizeof(IORegCursor));
     assert( where);
 
     if( where) {
@@ -1881,7 +1918,7 @@ bool IORegistryIterator::exitEntry( void )
     if( where != &start) {
        gone = where;
         where = gone->next;
-        IOFree( gone, sizeof( IORegCursor));
+        IOFree( gone, sizeof(IORegCursor));
        return( true);
 
     } else
@@ -1997,13 +2034,21 @@ OSOrderedSet * IORegistryIterator::iterateAll( void )
     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);
 OSMetaClassDefineReservedUsed(IORegistryEntry, 5);
-
+#endif
 OSMetaClassDefineReservedUnused(IORegistryEntry, 6);
 OSMetaClassDefineReservedUnused(IORegistryEntry, 7);
 OSMetaClassDefineReservedUnused(IORegistryEntry, 8);