AppleDTUpdater.cpp [plain text]
#include <IOKit/IOLib.h>
#include <IOKit/IODeviceTreeSupport.h>
#include "AppleDTUpdater.h"
OSDefineMetaClassAndStructors(AudioDeviceTreeUpdater, IOService)
#define super IOService
void
AudioDeviceTreeUpdater::mergeProperties(OSObject* inDest, OSObject* inSrc)
{
OSDictionary* dest = OSDynamicCast(OSDictionary, inDest) ;
OSDictionary* src = OSDynamicCast(OSDictionary, inSrc) ;
if (!src || !dest)
return ;
OSCollectionIterator* srcIterator = OSCollectionIterator::withCollection(src) ;
OSSymbol* keyObject = NULL ;
OSObject* destObject = NULL ;
while (NULL != (keyObject = OSDynamicCast(OSSymbol, srcIterator->getNextObject())))
{
if (NULL != (destObject = dest->getObject(keyObject)) && (OSDynamicCast(OSDictionary, src->getObject(keyObject))))
mergeProperties(destObject, src->getObject(keyObject)) ;
else
dest->setObject(keyObject, src->getObject(keyObject)) ;
}
srcIterator->release();
}
bool AudioDeviceTreeUpdater::start(IOService * provider )
{
super::start(provider);
OSArray* arrayObj = OSDynamicCast(OSArray, getProperty("DeviceTreePatches"));
do {
if(!arrayObj)
break;
OSCollectionIterator* patchIterator = OSCollectionIterator::withCollection(arrayObj) ;
OSDictionary * patchDict;
while (NULL != (patchDict = OSDynamicCast(OSDictionary, patchIterator->getNextObject()))) {
OSString *parentPath;
OSString *nodeName;
char nodePath[128];
parentPath = OSDynamicCast(OSString, patchDict->getObject("Parent"));
if(!parentPath)
break;
nodeName = OSDynamicCast(OSString, patchDict->getObject("Node"));
if(!nodeName)
break;
if((parentPath->getLength() + nodeName->getLength() + 2) > sizeof(nodePath))
break;
strcpy(nodePath, parentPath->getCStringNoCopy());
strcat(nodePath, "/");
strcat(nodePath, nodeName->getCStringNoCopy());
IORegistryEntry *patchParent;
IORegistryEntry *patch;
patchParent = IORegistryEntry::fromPath(parentPath->getCStringNoCopy(), gIODTPlane);
if(!patchParent)
break;
patch = IORegistryEntry::fromPath(nodePath, gIODTPlane);
if(!patch) {
patch = new IORegistryEntry;
if(!patch)
break;
if(!patch->init(OSDynamicCast(OSDictionary, patchDict->getObject("NodeData")))) {
patch->release();
patch = NULL;
break;
}
if(!patch->attachToParent(patchParent, gIODTPlane)) {
patch->release();
patch = NULL;
break;
}
patch->setName(nodeName->getCStringNoCopy());
}
else
mergeProperties(patch->getPropertyTable(), patchDict->getObject("NodeData"));
}
} while (false);
return false;
}