IORegistryEntry * IORegistryEntry::fromPath( char * path, const IORegistryPlane * plane, char * opath, int * length, IORegistryEntry * fromEntry ) { IORegistryEntry * where = 0; IORegistryEntry * aliasEntry = 0; IORegistryEntry * next; char * alias; char * end; char * path; int len = 0; int len2; char c; char temp[ kIOMaxPlaneName + 1 ]; char * pathfinder; pathfinder = path; if( 0 == path) return( 0 ); if( 0 == plane) { // get plane name if( (path[13] == 0x2F) && (path[14] == 0x65) && (path[15] == 0x66) && (path[16] == 0x69) ) { pathfinder[14] = 0x72; pathfinder[15] = 0x6F; pathfinder[16] = 0x6D; } end = strchr( pathfinder, ':' ); if( end && ((end - pathfinder) < kIOMaxPlaneName)) { strncpy( temp, pathfinder, end - pathfinder ); temp[ end - pathfinder ] = 0; plane = getPlane( temp ); pathfinder = end + 1; } } if( 0 == plane) return( 0 ); // check for alias end = pathfinder; if( (alias = dealiasPath( &end, plane))) { if(length) len = *length; aliasEntry = IORegistryEntry::fromPath( alias, plane, opath, &len, fromEntry ); where = aliasEntry; if( where) pathfinder = end; else len = 0; } RLOCK; do { if( 0 == where) { if( (0 == fromEntry) && (*pathfinder++ == '/')) fromEntry = gRegistryRoot->getChildEntry( plane ); where = fromEntry; if( 0 == where) break; } else { c = *pathfinder++; if( c != '/') { if( c && (c != ':')) // check valid terminator where = 0; break; } } next = where->getChildFromComponent( &pathfinder, plane ); if( next) where = next; } while( next ); if( where) { // check residual path if( where != fromEntry) pathfinder--; if( opath && length) { // copy out residual path len2 = len + strlen( pathfinder ); if( len2 < *length) strcpy( opath + len, pathfinder ); *length = len2; } else if( pathfinder[0]) // no residual path => must be no tail for success where = 0; } if( where) where->retain(); if( aliasEntry) aliasEntry->release(); UNLOCK; return( where ); }