예제 #1
0
파일: OSMetaClass.cpp 프로젝트: Prajna/xnu
/* static */
void
OSMetaClass::printInstanceCounts()
{
    OSCollectionIterator * classes;
    OSSymbol             * className;
    OSMetaClass          * meta;

    IOLockLock(sAllClassesLock);
    classes = OSCollectionIterator::withCollection(sAllClassesDict);
    assert(classes);

    while( (className = (OSSymbol *)classes->getNextObject())) {
        meta = (OSMetaClass *)sAllClassesDict->getObject(className);
        assert(meta);

        printf("%24s count: %03d x 0x%03x = 0x%06x\n",
            className->getCStringNoCopy(),
            meta->getInstanceCount(),
            meta->getClassSize(),
            meta->getInstanceCount() * meta->getClassSize() );
    }
    printf("\n");
    classes->release();
    IOLockUnlock(sAllClassesLock);
    return;
}
예제 #2
0
파일: OSSymbol.cpp 프로젝트: SbIm/xnu-env
const OSSymbol *OSSymbol::withCStringNoCopy(const char *cString)
{
    pool->closeGate();

    OSSymbol *oldSymb = pool->findSymbol(cString);
    if (!oldSymb) {
        OSSymbol *newSymb = new OSSymbol;
        if (!newSymb) {
            pool->openGate();
            return newSymb;
        }

	if (newSymb->OSString::initWithCStringNoCopy(cString))
	    oldSymb = pool->insertSymbol(newSymb);
        
        if (newSymb == oldSymb) {
            pool->openGate();
            return newSymb;	// return the newly created & inserted symbol.
        }
        else
            // Somebody else inserted the new symbol so free our copy
	    newSymb->OSString::free();
    }
    
    oldSymb->retain();	// Retain the old symbol before releasing the lock.

    pool->openGate();
    return oldSymb;
}
예제 #3
0
void
IOCatalogue::ping(thread_call_param_t arg, thread_call_param_t)
{
    IOCatalogue 	 * self = (IOCatalogue *) arg;
    OSOrderedSet         * set;
    OSDictionary         * table;
    int	                   newLimit;

    set = OSOrderedSet::withCapacity( 1 );

    IOLockLock( &self->lock );

    for( newLimit = 0; newLimit < kDriversPerIter; newLimit++) {
        table = (OSDictionary *) self->array->getObject(
                    hackLimit + newLimit );
        if( table) {
            set->setLastObject( table );

            OSSymbol * sym = (OSSymbol *) table->getObject(gIOClassKey);
            kprintf("enabling %s\n", sym->getCStringNoCopy());

        } else {
            newLimit--;
            break;
        }
    }

    IOService::catalogNewDrivers( set );

    hackLimit += newLimit;
    self->generation++;

    IOLockUnlock( &self->lock );

    if( kDriversPerIter == newLimit) {
        AbsoluteTime deadline;
        clock_interval_to_deadline(500, kMillisecondScale);
        thread_call_func_delayed(ping, this, deadline);
    }
}
예제 #4
0
OSObject *
OSUnserializeBinary(const char *buffer, size_t bufferSize, OSString **errorString)
{
	OSObject ** objsArray;
	uint32_t    objsCapacity;
	enum      { objsCapacityMax = 16*1024*1024 };
	uint32_t    objsIdx;

	OSObject ** stackArray;
	uint32_t    stackCapacity;
	enum      { stackCapacityMax = 64 };
	uint32_t    stackIdx;

    OSObject     * result;
    OSObject     * parent;
    OSDictionary * dict;
    OSArray      * array;
    OSSet        * set;
    OSDictionary * newDict;
    OSArray      * newArray;
    OSSet        * newSet;
    OSObject     * o;
    OSSymbol     * sym;
    OSString     * str;

    size_t           bufferPos;
    const uint32_t * next;
    uint32_t         key, len, wordLen;
    bool             end, newCollect, isRef;
    unsigned long long value;
    bool ok;

	if (errorString) *errorString = 0;
	if (bufferSize < sizeof(kOSSerializeBinarySignature)) return (NULL);
	if (0 != strcmp(kOSSerializeBinarySignature, buffer)) return (NULL);
	if (3 & ((uintptr_t) buffer)) return (NULL);
	bufferPos = sizeof(kOSSerializeBinarySignature);
	next = (typeof(next)) (((uintptr_t) buffer) + bufferPos);

	DEBG("---------OSUnserializeBinary(%p)\n", buffer);

	objsArray = stackArray    = NULL;
	objsIdx   = objsCapacity  = 0;
	stackIdx  = stackCapacity = 0;

    result   = 0;
    parent   = 0;
	dict     = 0;
	array    = 0;
	set      = 0;
	sym      = 0;

	ok = true;
	while (ok)
	{
		bufferPos += sizeof(*next);
		if (!(ok = (bufferPos <= bufferSize))) break;
		key = *next++;

        len = (key & kOSSerializeDataMask);
        wordLen = (len + 3) >> 2;
		end = (0 != (kOSSerializeEndCollecton & key));
        DEBG("key 0x%08x: 0x%04x, %d\n", key, len, end);

        newCollect = isRef = false;
		o = 0; newDict = 0; newArray = 0; newSet = 0;
		
		switch (kOSSerializeTypeMask & key)
		{
		    case kOSSerializeDictionary:
				o = newDict = OSDictionary::withCapacity(len);
				newCollect = (len != 0);
		        break;
		    case kOSSerializeArray:
				o = newArray = OSArray::withCapacity(len);
				newCollect = (len != 0);
		        break;
		    case kOSSerializeSet:
				o = newSet = OSSet::withCapacity(len);
				newCollect = (len != 0);
		        break;

		    case kOSSerializeObject:
				if (len >= objsIdx) break;
				o = objsArray[len];
				isRef = true;
				break;

		    case kOSSerializeNumber:
				bufferPos += sizeof(long long);
				if (bufferPos > bufferSize) break;
		        if ((len != 32) && (len != 64) && (len != 16) && (len != 8)) break;
		    	value = next[1];
		    	value <<= 32;
		    	value |= next[0];
		    	o = OSNumber::withNumber(value, len);
		    	next += 2;
		        break;

		    case kOSSerializeSymbol:
				bufferPos += (wordLen * sizeof(uint32_t));
				if (bufferPos > bufferSize)           break;
				if (len < 2)                          break;
				if (0 != ((const char *)next)[len-1]) break;
		        o = (OSObject *) OSSymbol::withCString((const char *) next);
		        next += wordLen;
		        break;

		    case kOSSerializeString:
				bufferPos += (wordLen * sizeof(uint32_t));
				if (bufferPos > bufferSize) break;
		        o = OSString::withStringOfLength((const char *) next, len);
		        next += wordLen;
		        break;

    	    case kOSSerializeData:
				bufferPos += (wordLen * sizeof(uint32_t));
				if (bufferPos > bufferSize) break;
		        o = OSData::withBytes(next, len);
		        next += wordLen;
		        break;

    	    case kOSSerializeBoolean:
				o = (len ? kOSBooleanTrue : kOSBooleanFalse);
		        break;

		    default:
		        break;
		}

		if (!(ok = (o != 0))) break;

		if (!isRef)
		{
			setAtIndex(objs, objsIdx, o);
			if (!ok)
			{
			    o->release();
                break;
            }
			objsIdx++;
		}

		if (dict)
		{
			if (!sym) sym = (OSSymbol *) o;
			else
			{
                str = sym;
				sym = OSDynamicCast(OSSymbol, sym);
				if (!sym && (str = OSDynamicCast(OSString, str)))
				{
				    sym = const_cast<OSSymbol *>(OSSymbol::withString(str));
                    ok = (sym != 0);
                    if (!ok) break;
				}
				DEBG("%s = %s\n", sym->getCStringNoCopy(), o->getMetaClass()->getClassName());
				if (o != dict) ok = dict->setObject(sym, o);
                if (sym && (sym != str)) sym->release();
				sym = 0;
			}
		}
		else if (array)  ok = array->setObject(o);
		else if (set)    ok = set->setObject(o);
		else if (result) ok = false;
		else
		{
		    assert(!parent);
		    result = o;
		}

		if (!ok) break;

        if (end) parent = 0;
		if (newCollect)
		{
            stackIdx++;
            setAtIndex(stack, stackIdx, parent);
            if (!ok) break;
			DEBG("++stack[%d] %p\n", stackIdx, parent);
			parent = o;
			dict   = newDict;
			array  = newArray;
			set    = newSet;
			end    = false;
		}

		if (end)
		{
            while (stackIdx)
            {
                parent = stackArray[stackIdx];
                DEBG("--stack[%d] %p\n", stackIdx, parent);
                stackIdx--;
                if (parent) break;
            }
            if (!parent) break;
			set   = 0;
			dict  = 0; 
			array = 0;
			if (!(dict = OSDynamicCast(OSDictionary, parent)))
			{
				if (!(array = OSDynamicCast(OSArray, parent))) ok = (0 != (set = OSDynamicCast(OSSet, parent)));
			}
		}
	}
	DEBG("ret %p\n", result);

	if (!ok) result = 0;

	if (objsCapacity)
	{
        for (len = (result != 0); len < objsIdx; len++) objsArray[len]->release();
	    kfree(objsArray,  objsCapacity  * sizeof(*objsArray));
    }
	if (stackCapacity) kfree(stackArray, stackCapacity * sizeof(*stackArray));

	return (result);
}
예제 #5
0
bool OSSerialize::binarySerialize(const OSMetaClassBase *o)
{
    OSDictionary * dict;
    OSArray      * array;
    OSSet        * set;
    OSNumber     * num;
    OSSymbol     * sym;
    OSString     * str;
    OSData       * ldata;
    OSBoolean    * boo;

	unsigned int  tagIdx;
    uint32_t   i, key;
    size_t     len;
    bool       ok;

	tagIdx = tags->getNextIndexOfObject(o, 0);
	// does it exist?
	if (-1U != tagIdx)
	{
		key = (kOSSerializeObject | tagIdx);
		if (endCollection)
		{
			 endCollection = false;
			 key |= kOSSerializeEndCollecton;
		}
		ok = addBinary(&key, sizeof(key));
		return (ok);
	}

	if ((dict = OSDynamicCast(OSDictionary, o)))
	{
		key = (kOSSerializeDictionary | dict->count);
		ok = addBinaryObject(o, key, NULL, 0);
		for (i = 0; ok && (i < dict->count);)
		{
			const OSSymbol        * dictKey;
			const OSMetaClassBase * dictValue;
			const OSMetaClassBase * nvalue = 0;

			dictKey = dict->dictionary[i].key;
			dictValue = dict->dictionary[i].value;
			i++;
			if (editor)
			{
				dictValue = nvalue = (*editor)(editRef, this, dict, dictKey, dictValue);
				if (!dictValue) dictValue = dict;
			}
			ok = binarySerialize(dictKey);
			if (!ok) break;
			endCollection = (i == dict->count);
			ok = binarySerialize(dictValue);
			if (!ok) ok = dictValue->serialize(this);
			if (nvalue) nvalue->release();
//			if (!ok) ok = binarySerialize(kOSBooleanFalse);
		}			
	}
	else if ((array = OSDynamicCast(OSArray, o)))
	{
		key = (kOSSerializeArray | array->count);
		ok = addBinaryObject(o, key, NULL, 0);
		for (i = 0; ok && (i < array->count);)
		{
			i++;
			endCollection = (i == array->count);
			ok = binarySerialize(array->array[i-1]);
			if (!ok) ok = array->array[i-1]->serialize(this);
//			if (!ok) ok = binarySerialize(kOSBooleanFalse);
		}			
	}
	else if ((set = OSDynamicCast(OSSet, o)))
	{
		key = (kOSSerializeSet | set->members->count);
		ok = addBinaryObject(o, key, NULL, 0);
		for (i = 0; ok && (i < set->members->count);)
		{
			i++;
			endCollection = (i == set->members->count);
			ok = binarySerialize(set->members->array[i-1]);
			if (!ok) ok = set->members->array[i-1]->serialize(this);
//			if (!ok) ok = binarySerialize(kOSBooleanFalse);
		}			
	}
	else if ((num = OSDynamicCast(OSNumber, o)))
	{
		key = (kOSSerializeNumber | num->size);
		ok = addBinaryObject(o, key, &num->value, sizeof(num->value));
	}
	else if ((boo = OSDynamicCast(OSBoolean, o)))
	{
		key = (kOSSerializeBoolean | (kOSBooleanTrue == boo));
		ok = addBinaryObject(o, key, NULL, 0);
	}
	else if ((sym = OSDynamicCast(OSSymbol, o)))
	{
		len = (sym->getLength() + 1);
		key = (kOSSerializeSymbol | len);
		ok = addBinaryObject(o, key, sym->getCStringNoCopy(), len);
	}
	else if ((str = OSDynamicCast(OSString, o)))
	{
		len = (str->getLength() + 0);
		key = (kOSSerializeString | len);
		ok = addBinaryObject(o, key, str->getCStringNoCopy(), len);
	}
	else if ((ldata = OSDynamicCast(OSData, o)))
	{
		len = ldata->getLength();
		if (ldata->reserved && ldata->reserved->disableSerialization) len = 0;
		key = (kOSSerializeData | len);
		ok = addBinaryObject(o, key, ldata->getBytesNoCopy(), len);
	}
	else return (false);

    return (ok);
}
예제 #6
0
//================================================================================================
//
//  MergeDictionaryIntoDictionary( parentSourceDictionary, parentTargetDictionary)
//
//  This routine will merge the contents of parentSourceDictionary into the parentTargetDictionary, recursively.
//  Note that we are only modifying copies of the parentTargetDictionary, so we don't expect anybody
//  else to be accessing them at the same time.
//
//================================================================================================
//
bool
IOUSBUserClientInit::MergeDictionaryIntoDictionary(OSDictionary * parentSourceDictionary,  OSDictionary * parentTargetDictionary)
{
    OSCollectionIterator*	srcIterator = NULL;
    OSSymbol*			keyObject = NULL ;
    OSObject*			targetObject = NULL ;
    bool			result = false;

    USBLog(6,"+%s[%p]::MergeDictionaryIntoDictionary(%p => %p)", getName(), this, parentSourceDictionary, parentTargetDictionary);

    if (!parentSourceDictionary || !parentTargetDictionary)
        return false ;

    // Get our source dictionary
    //
    srcIterator = OSCollectionIterator::withCollection(parentSourceDictionary) ;

    while (NULL != (keyObject = OSDynamicCast(OSSymbol, srcIterator->getNextObject())))
    {
        const char *	str;
        OSDictionary *	childSourceDictionary = NULL;
        OSDictionary *	childTargetDictionary = NULL;
        OSObject *	childTargetObject = NULL;

        // Get the symbol name for debugging
        //
        str = keyObject->getCStringNoCopy();
        USBLog(6,"%s[%p]::MergeDictionaryIntoDictionary  merging \"%s\"", getName(), this, str);

        // Check to see if our destination already has the same entry.
        //
        childTargetObject = parentTargetDictionary->getObject(keyObject);
        if ( childTargetObject )
        {
            childTargetDictionary = OSDynamicCast(OSDictionary, childTargetObject);
            if ( childTargetDictionary )
			{
                USBLog(6,"%s[%p]::MergeDictionaryIntoDictionary  target object %s is a dictionary (%p)", getName(), this, str, childTargetDictionary);
			}
        }

        // See if our source entry is also a dictionary
        //
        childSourceDictionary = OSDynamicCast(OSDictionary, parentSourceDictionary->getObject(keyObject));
        if ( childSourceDictionary )
        {
            USBLog(6,"%s[%p]::MergeDictionaryIntoDictionary  source dictionary had %s as a dictionary (%p)", getName(), this, str, childSourceDictionary);
        }

        if ( childTargetDictionary && childSourceDictionary)
        {
            // Our destination dictionary already has the entry for this same object AND our
            // source is also a dcitionary, so we need to recursively add it.
            //
            USBLog(6,"%s[%p]::MergeDictionaryIntoDictionary  recursing(%p,%p)", getName(), this, childSourceDictionary, childTargetDictionary);
            result = MergeDictionaryIntoDictionary(childSourceDictionary, childTargetDictionary) ;
            if ( !result )
            {
                USBLog(6,"%s[%p]::MergeDictionaryIntoDictionary  recursing (%p,%p) failed", getName(), this, childSourceDictionary, childTargetDictionary);
                break;
            }
        }
        else
        {
            // We have a property that we need to merge into our parent dictionary.
            //
            USBLog(6,"%s[%p]::MergeDictionaryIntoDictionary  setting object %s into dictionary %p", getName(), this, str, parentTargetDictionary);
            result = parentTargetDictionary->setObject(keyObject, parentSourceDictionary->getObject(keyObject)) ;
            if ( !result )
            {
                USBLog(6,"%s[%p]::MergeDictionaryIntoDictionary  setObject %s, returned false", getName(), this, str);
                break;
            }
        }

    }

    srcIterator->release();

    USBLog(6,"-%s[%p]::MergeDictionaryIntoDictionary(%p=>(%p)  result %d", getName(), this, parentSourceDictionary, parentTargetDictionary, result);
    return result;
}
예제 #7
0
void FileNVRAM::doSync(void)
{
	LOG(NOTICE, "doSync() called\n");

	/* if (!mFilePath)
	{
		return;
	} */

	if (!mSafeToSync)
	{
		return;
	}
	
	LOG(NOTICE, "doSync() running\n");

	//create the output Dictionary
	OSDictionary * outputDict = OSDictionary::withCapacity(1);

	//going to have to spin over ourselves..
	OSDictionary * inputDict = dictionaryWithProperties();
	OSCollectionIterator *iter = OSCollectionIterator::withCollection(inputDict);

	if (iter == 0)
	{
		LOG(ERROR, "FAILURE!. No iterator on input dictionary (myself)\n");
		return;
	}

	OSSymbol * key = NULL;
	OSObject * value = NULL;

	while ((key = OSDynamicCast(OSSymbol,iter->getNextObject())))
	{
		//just get the value now anyway
		value = inputDict->getObject(key);

		//if the key conmektains :, look to see if it's in the map already, cause we'll add a child pair to it
		//otherwise we just slam the key/val pair in

		const char * keyChar = key->getCStringNoCopy();
		const char * guidValueStr = NULL;

		if (( guidValueStr = strstr(keyChar , NVRAM_SEPERATOR)) != NULL)
		{
			//we have a GUID child to deal with
			//now substring out the GUID cause thats going to be a DICT itself on the new outputDict
			//guidValueStr points to the :
			size_t guidCutOff = guidValueStr - keyChar;

			//allocate buffer
			//we ar ereally accounting for + sizeof('\0')
			//thats always 1. so 1.
			char guidStr[guidCutOff+1];
			strlcpy(guidStr, keyChar, guidCutOff+1);

			//in theory we have a guid and a value
			//LOG("sync() -> Located GUIDStr as %s\n",guidStr);

			//check for ?OSDictionary? from the dictionary
			OSDictionary * guidDict = OSDynamicCast(OSDictionary, outputDict->getObject(guidStr));

			if (!guidDict)
			{
				guidDict = OSDictionary::withCapacity(1);
				outputDict->setObject(guidStr,guidDict);
			}

			//now we have a dict for the guid no matter what (mapping GUID | DICT)
			guidDict->setObject(OSString::withCString(guidValueStr+strlen(NVRAM_SEPERATOR)), value);
		}
		else
		{
			//we are boring.
			outputDict->setObject(key,value);
		}
	}//end while

	//serialize and write this out
	OSSerialize *s = OSSerialize::withCapacity(10000);
	s->addString(NVRAM_FILE_HEADER);
	outputDict->serialize(s);
	s->addString(NVRAM_FILE_FOOTER);

	int error = write_buffer(s->text(), mCtx);

	if (error)
	{
		LOG(ERROR, "Unable to write to %s, errno %d\n", mFilePath->getCStringNoCopy(), error);
	}

	//now free the dictionaries && iter
	iter->release();
	outputDict->release();
	s->release();

}
예제 #8
0
bool
ZFSDatasetProxy::start(IOService *provider)
{
	OSObject *property = NULL, *size = NULL;
	OSString *nameString = NULL;
	OSNumber *sizeNum = NULL;
	OSDictionary *deviceDict = NULL, *protocolDict = NULL;
	const OSSymbol *virtualSymbol = NULL, *internalSymbol = NULL;
	const char *cstr = NULL;
	char *pstring = NULL;
	int plen = 0;
	bool started = false;

	size = copyProperty(kZFSPoolSizeKey, gIOServicePlane,
	    (kIORegistryIterateRecursively|kIORegistryIterateParents));
	property = copyProperty(kZFSPoolNameKey, gIOServicePlane,
	    (kIORegistryIterateRecursively|kIORegistryIterateParents));

	if (!size || !property) {
		dprintf("couldn't get pool name or size");
		goto error;
	}

	nameString = OSDynamicCast(OSString, property);
	if (!nameString) {
		dprintf("missing pool name");
		goto error;
	}
#if 0
	/* Try hard to get the name string */
	do {
		nameString = OSDynamicCast(OSString, property);

		if (nameString) nameString->retain();

		if (!nameString) {
			OSSymbol *nameSymbol;
		       	nameSymbol = OSDynamicCast(OSSymbol, property);
			if (!nameSymbol) {
				dprintf("couldn't get name");
				goto error;
			}
			nameString = OSString::withCString(
			    nameSymbol->getCStringNoCopy());
		}
	} while (0);
#endif

	sizeNum = OSDynamicCast(OSNumber, size);
	if (!sizeNum) {
		dprintf("invalid size");
		goto error;
	}
	_pool_bcount = sizeNum->unsigned64BitValue() / DEV_BSIZE;
	sizeNum = 0;
	size->release();
	size = 0;

	cstr = nameString->getCStringNoCopy();
	if (!cstr || (plen = strlen(cstr) + 1) == 1) {
		goto error;
	}
	pstring = (char *)IOMalloc(plen);
	if (!pstring) {
		goto error;
	}
	snprintf(pstring, plen, "%s", cstr);
	productString = pstring;
	pstring = 0;

	if (IOBlockStorageDevice::start(provider) == false) {
		dprintf("BlockStorageDevice start failed");
		goto error;
	}
	started = true;

	deviceDict = OSDynamicCast(OSDictionary,
	    getProperty(kIOPropertyDeviceCharacteristicsKey));
	if (deviceDict) {
		/* Clone a new dictionary */
		deviceDict = OSDictionary::withDictionary(deviceDict);
		if (!deviceDict) {
			dprintf("dict clone failed");
			goto error;
		}
	}

	if (!deviceDict) {
		dprintf("creating new device dict");
		deviceDict = OSDictionary::withCapacity(1);
	}

	if (!deviceDict) {
		dprintf("missing device dict");
		goto error;
	}

	deviceDict->setObject(kIOPropertyProductNameKey, nameString);
	OSSafeReleaseNULL(nameString);

	if (setProperty(kIOPropertyDeviceCharacteristicsKey,
	    deviceDict) == false) {
		dprintf("device dict setProperty failed");
		goto error;
	}
	OSSafeReleaseNULL(deviceDict);

	protocolDict = OSDynamicCast(OSDictionary,
	    getProperty(kIOPropertyProtocolCharacteristicsKey));
	if (protocolDict) {
		/* Clone a new dictionary */
		protocolDict = OSDictionary::withDictionary(protocolDict);
		if (!protocolDict) {
			dprintf("dict clone failed");
			goto error;
		}
	}

	if (!protocolDict) {
		dprintf("creating new protocol dict");
		protocolDict = OSDictionary::withCapacity(1);
	}

	if (!protocolDict) {
		dprintf("missing protocol dict");
		goto error;
	}

	virtualSymbol = OSSymbol::withCString(
	    kIOPropertyPhysicalInterconnectTypeVirtual);
	internalSymbol = OSSymbol::withCString(
	    kIOPropertyInternalKey);
	if (!virtualSymbol || !internalSymbol) {
		dprintf("symbol alloc failed");
		goto error;
	}

	protocolDict->setObject(kIOPropertyPhysicalInterconnectTypeKey,
	    virtualSymbol);
	protocolDict->setObject(kIOPropertyPhysicalInterconnectLocationKey,
	    internalSymbol);

	OSSafeReleaseNULL(virtualSymbol);
	OSSafeReleaseNULL(internalSymbol);

	if (setProperty(kIOPropertyProtocolCharacteristicsKey,
	    protocolDict) == false) {
		dprintf("protocol dict setProperty failed");
		goto error;
	}
	OSSafeReleaseNULL(protocolDict);
	registerService(kIOServiceAsynchronous);

	return (true);

error:
	OSSafeReleaseNULL(size);
	OSSafeReleaseNULL(property);
	OSSafeReleaseNULL(deviceDict);
	OSSafeReleaseNULL(protocolDict);
	OSSafeReleaseNULL(nameString);
	OSSafeReleaseNULL(virtualSymbol);
	OSSafeReleaseNULL(internalSymbol);
	if (pstring) IOFree(pstring, plen);
	if (started) IOBlockStorageDevice::stop(provider);
	return (false);
}
예제 #9
0
IOReturn IOHIDevice::setParamProperties( OSDictionary * dict )
{
    IOHIDEventService * eventService = NULL;
    
    if ( dict->getObject(kIOHIDEventServicePropertiesKey) == NULL ) {
        IOService * service = getProvider();
        if ( service )
            eventService = OSDynamicCast(IOHIDEventService, service);
    }

    if ( dict->getObject(kIOHIDDeviceParametersKey) == kOSBooleanTrue ) {
        OSDictionary * deviceParameters = OSDynamicCast(OSDictionary, copyProperty(kIOHIDParametersKey));

        if ( !deviceParameters ) {
            deviceParameters = OSDictionary::withCapacity(4);
        }
        else {
            if (deviceParameters->setOptions(0, 0) & OSDictionary::kImmutable) {
                OSDictionary * temp = deviceParameters;
                deviceParameters = OSDynamicCast(OSDictionary, temp->copyCollection());
                temp->release();
            }
            else {
                // do nothing
            }
        }

        if ( deviceParameters ) {
            // RY: Because K&M Prefs and Admin still expect device props to be
            // top level, let's continue to set them via setProperty. When we get
            // Max to migrate over, we can remove the interator code and use:
            // deviceParameters->merge(dict);
            // deviceParameters->removeObject(kIOHIDResetKeyboardKey);
            // deviceParameters->removeObject(kIOHIDResetPointerKey);
            // setProperty(kIOHIDParametersKey, deviceParameters);
            // deviceParameters->release();

            OSCollectionIterator * iterator = OSCollectionIterator::withCollection(dict);
            if ( iterator ) {
                OSSymbol * key;

                while ( ( key = (OSSymbol *)iterator->getNextObject() ) )
                    if (    !key->isEqualTo(kIOHIDResetKeyboardKey) && 
                            !key->isEqualTo(kIOHIDResetPointerKey) && 
                            !key->isEqualTo(kIOHIDScrollResetKey) && 
                            !key->isEqualTo(kIOHIDDeviceParametersKey) && 
                            !key->isEqualTo(kIOHIDResetLEDsKey) &&
                            !key->isEqualTo(kIOUserClientClassKey) &&
                            !key->isEqualTo(kIOClassKey) &&
                            !key->isEqualTo(kIOProviderClassKey) &&
                            !key->isEqualTo(kIOKitDebugKey)) {
                        OSObject * value = dict->getObject(key);

                        deviceParameters->setObject(key, value);
                        setProperty(key, value);
                    }

                iterator->release();
            }

            setProperty(kIOHIDParametersKey, deviceParameters);
            deviceParameters->release();

            // RY: Propogate up to IOHIDEventService level
            if ( eventService )
                eventService->setSystemProperties(dict);

        }
        else {
            return kIOReturnNoMemory;
        }
    }

    return( kIOReturnSuccess );
}
예제 #10
0
//*********************************************************************************
// printDictionaryKeys
//
// Print the keys for the given dictionary and selected contents.
//*********************************************************************************
void printDictionaryKeys (OSDictionary * inDictionary, char * inMsg)
{
  OSCollectionIterator * mcoll = OSCollectionIterator::withCollection (inDictionary);
  OSSymbol * mkey;
  OSString * ioClass;
  unsigned int i = 0;
 
  mcoll->reset ();

  mkey = OSDynamicCast (OSSymbol, mcoll->getNextObject ());

  while (mkey) {

    // kprintf ("dictionary key #%d: %s\n", i, mkey->getCStringNoCopy () );

    // if this is the IOClass key, print it's contents

    if ( mkey->isEqualTo ("IOClass") ) {
      ioClass = (OSString *) inDictionary->getObject ("IOClass");
      if ( ioClass ) IOLog ("%s IOClass is %s\n", inMsg, ioClass->getCStringNoCopy () );
    }

    // if this is an IOProviderClass key print it

    if ( mkey->isEqualTo ("IOProviderClass") ) {
      ioClass = (OSString *) inDictionary->getObject ("IOProviderClass");
      if ( ioClass ) IOLog ("%s IOProviderClass is %s\n", inMsg, ioClass->getCStringNoCopy () );

    }

    // also print IONameMatch keys
    if ( mkey->isEqualTo ("IONameMatch") ) {
      ioClass = (OSString *) inDictionary->getObject ("IONameMatch");
      if ( ioClass ) IOLog ("%s IONameMatch is %s\n", inMsg, ioClass->getCStringNoCopy () );
    }

    // also print IONameMatched keys

    if ( mkey->isEqualTo ("IONameMatched") ) {
      ioClass = (OSString *) inDictionary->getObject ("IONameMatched");
      if ( ioClass ) IOLog ("%s IONameMatched is %s\n", inMsg, ioClass->getCStringNoCopy () );
    }

#if 0
    // print clock-id

    if ( mkey->isEqualTo ("AAPL,clock-id") ) {
      char * cstr;
      cstr = getCStringForObject (inDictionary->getObject ("AAPL,clock-id"));
      if (cstr)
        kprintf (" ===> AAPL,clock-id is %s\n", cstr );
    }
#endif

    // print name

    if ( mkey->isEqualTo ("name") ) {
      char nameStr[64];
      nameStr[0] = 0;
      getCStringForObject (inDictionary->getObject ("name"), nameStr );
      if (strlen(nameStr) > 0)
        IOLog ("%s name is %s\n", inMsg, nameStr);
    }

    mkey = (OSSymbol *) mcoll->getNextObject ();

    i++;
  }

  mcoll->release ();
}
OSSet * IOPartitionScheme::juxtaposeMediaObjects(OSSet * partitionsOld,
                                                 OSSet * partitionsNew)
{
    //
    // Updates a set of existing partitions, represented by partitionsOld,
    // with possible updates from a rescan of the disk, represented by
    // partitionsNew.  It returns a new set of partitions with the results,
    // removing partitions from partitionsOld where applicable, adding
    // partitions from partitionsNew where applicable, and folding in property
    // changes to partitions from partitionsNew into partitionsOld where
    // applicable.
    //

    OSIterator *   iterator    = 0;
    OSIterator *   iterator1   = 0;
    OSIterator *   iterator2   = 0;
    OSSymbol *     key;
    OSSet *        keys        = 0;
    IOMedia *      partition;
    IOMedia *      partition1;
    IOMedia *      partition2;
    OSSet *        partitions  = 0;
    OSOrderedSet * partitions1 = 0;
    OSOrderedSet * partitions2 = 0;
    UInt32         partitionID = 0;
    OSDictionary * properties;

    // Allocate a set to hold the set of media objects representing partitions.

    partitions = OSSet::withCapacity( partitionsNew->getCapacity( ) );
    if ( partitions == 0 ) goto juxtaposeErr;

    // Prepare the reference set of partitions.

    partitions1 = OSOrderedSet::withCapacity( partitionsOld->getCapacity( ), partitionComparison, 0 );
    if ( partitions1 == 0 ) goto juxtaposeErr;

    iterator1 = OSCollectionIterator::withCollection( partitionsOld );
    if ( iterator1 == 0 ) goto juxtaposeErr;

    while ( ( partition1 = ( IOMedia * ) iterator1->getNextObject( ) ) )
    {
        partitionID = max( partitionID, strtoul( partition1->getLocation( ), NULL, 10 ) );

        partitions1->setObject( partition1 );
    }

    iterator1->release( );
    iterator1 = 0;

    // Prepare the comparison set of partitions.

    partitions2 = OSOrderedSet::withCapacity( partitionsNew->getCapacity( ), partitionComparison, 0 );
    if ( partitions2 == 0 ) goto juxtaposeErr;

    iterator2 = OSCollectionIterator::withCollection( partitionsNew );
    if ( iterator2 == 0 ) goto juxtaposeErr;

    while ( ( partition2 = ( IOMedia * ) iterator2->getNextObject( ) ) )
    {
        partitionID = max( partitionID, strtoul( partition2->getLocation( ), NULL, 10 ) );

        partitions2->setObject( partition2 );
    }

    iterator2->release( );
    iterator2 = 0;

    // Juxtapose the partitions.

    iterator1 = OSCollectionIterator::withCollection( partitions1 );
    if ( iterator1 == 0 ) goto juxtaposeErr;

    iterator2 = OSCollectionIterator::withCollection( partitions2 );
    if ( iterator2 == 0 ) goto juxtaposeErr;

    partition1 = ( IOMedia * ) iterator1->getNextObject( );
    partition2 = ( IOMedia * ) iterator2->getNextObject( );

    while ( partition1 || partition2 )
    {
        UInt64 base1;
        UInt64 base2;

        base1 = partition1 ? partition1->getBase( ) : UINT64_MAX;
        base2 = partition2 ? partition2->getBase( ) : UINT64_MAX;

#if TARGET_OS_EMBEDDED
        if ( partition1 && partition2 )
        {
            OSString * uuid1;
            OSString * uuid2;

            uuid1 = OSDynamicCast( OSString, partition1->getProperty( kIOMediaUUIDKey ) );
            uuid2 = OSDynamicCast( OSString, partition2->getProperty( kIOMediaUUIDKey ) );

            if ( uuid1 || uuid2 )
            {
                if ( uuid1 == 0 )
                {
                   base1 = UINT64_MAX;
                }
                else if ( uuid2 == 0 )
                {
                   base2 = UINT64_MAX;
                }
                else
                {
                    int compare;

                    compare = strcmp( uuid1->getCStringNoCopy( ), uuid2->getCStringNoCopy( ) );

                    if ( compare > 0 )
                    {
                        base1 = UINT64_MAX;
                    }
                    else if ( compare < 0 )
                    {
                        base2 = UINT64_MAX;
                    }
                    else
                    {
                        base1 = base2;
                    }
                }
            }
        }
#endif /* TARGET_OS_EMBEDDED */

        if ( base1 > base2 )
        {
            // A partition was added.

            partition2->setProperty( kIOMediaLiveKey, true );

            iterator = OSCollectionIterator::withCollection( partitions1 );
            if ( iterator == 0 ) goto juxtaposeErr;

            while ( ( partition = ( IOMedia * ) iterator->getNextObject( ) ) )
            {
                if ( strcmp( partition->getLocation( ), partition2->getLocation( ) ) == 0 )
                {
                    // Set a location value for this partition.

                    char location[ 12 ];

                    partitionID++;

                    snprintf( location, sizeof( location ), "%d", ( int ) partitionID );

                    partition2->setLocation( location );

                    partition2->setProperty( kIOMediaLiveKey, false );

                    break;
                }
            }

            iterator->release( );
            iterator = 0;

            if ( partition2->attach( this ) )
            {
                attachMediaObjectToDeviceTree( partition2 );

                partition2->registerService( kIOServiceAsynchronous );
            }

            partitions->setObject( partition2 );

            partition2 = ( IOMedia * ) iterator2->getNextObject( );
        }
        else if ( base1 < base2 )
        {
            // A partition was removed.

            partition1->setProperty( kIOMediaLiveKey, false );

            if ( handleIsOpen( partition1 ) == false )
            {
                partition1->terminate( kIOServiceSynchronous );

                detachMediaObjectFromDeviceTree( partition1 );
            }
            else
            {
                partition1->removeProperty( kIOMediaPartitionIDKey );

                partitions->setObject( partition1 );
            }

            partition1 = ( IOMedia * ) iterator1->getNextObject( );
        }
        else
        {
            // A partition was matched.

            bool edit;
            bool move;

            edit = false;
            move = false;

            keys = OSSet::withCapacity( 1 );
            if ( keys == 0 ) goto juxtaposeErr;

            properties = partition2->getPropertyTable( );

            // Determine which properties were updated.

            if ( partition1->getBase( )               != partition2->getBase( )               ||
                 partition1->getSize( )               != partition2->getSize( )               ||
                 partition1->getPreferredBlockSize( ) != partition2->getPreferredBlockSize( ) ||
                 partition1->getAttributes( )         != partition2->getAttributes( )         ||
                 partition1->isWhole( )               != partition2->isWhole( )               ||
                 partition1->isWritable( )            != partition2->isWritable( )            ||
                 strcmp( partition1->getContentHint( ), partition2->getContentHint( ) )       )
            {
                edit = true;
            }

            if ( strcmp( partition1->getName( ),     partition2->getName( )     ) ||
                 strcmp( partition1->getLocation( ), partition2->getLocation( ) ) )
            {
                move = true;
            }

            iterator = OSCollectionIterator::withCollection( properties );
            if ( iterator == 0 ) goto juxtaposeErr;

            while ( ( key = ( OSSymbol * ) iterator->getNextObject( ) ) )
            {
                OSObject * value1;
                OSObject * value2;

                if ( key->isEqualTo( kIOMediaContentHintKey        ) ||
                     key->isEqualTo( kIOMediaEjectableKey          ) ||
                     key->isEqualTo( kIOMediaPreferredBlockSizeKey ) ||
                     key->isEqualTo( kIOMediaRemovableKey          ) ||
                     key->isEqualTo( kIOMediaSizeKey               ) ||
                     key->isEqualTo( kIOMediaWholeKey              ) ||
                     key->isEqualTo( kIOMediaWritableKey           ) )
                {
                    continue;
                }

                if ( key->isEqualTo( kIOMediaContentKey ) ||
                     key->isEqualTo( kIOMediaLeafKey    ) ||
                     key->isEqualTo( kIOMediaLiveKey    ) ||
                     key->isEqualTo( kIOMediaOpenKey    ) )
                {
                    continue;
                }

                value1 = partition1->getProperty( key );
                value2 = partition2->getProperty( key );

                if ( value1 == 0 || value1->isEqualTo( value2 ) == false )
                {
                    keys->setObject( key );
                }
            }

            iterator->release( );
            iterator = 0;

            // A partition was updated.

            partition1->setProperty( kIOMediaLiveKey, ( move == false ) );

            if ( edit )
            {
                partition1->init( partition2->getBase( ),
                                  partition2->getSize( ),
                                  partition2->getPreferredBlockSize( ),
                                  partition2->getAttributes( ),
                                  partition2->isWhole( ),
                                  partition2->isWritable( ),
                                  partition2->getContentHint( ) );
            }

            if ( keys->getCount( ) )
            {
                iterator = OSCollectionIterator::withCollection( keys );
                if ( iterator == 0 ) goto juxtaposeErr;

                while ( ( key = ( OSSymbol * ) iterator->getNextObject( ) ) )
                {
                    partition1->setProperty( key, partition2->getProperty( key ) );
                }

                iterator->release( );
                iterator = 0;
            }

            if ( edit || keys->getCount( ) )
            {
                partition1->messageClients( kIOMessageServicePropertyChange );

                partition1->registerService( kIOServiceAsynchronous );
            }

            keys->release( );
            keys = 0;

            partitions->setObject( partition1 );

            partition1 = ( IOMedia * ) iterator1->getNextObject( );
            partition2 = ( IOMedia * ) iterator2->getNextObject( );
        }
    }

    // Release our resources.

    iterator1->release( );
    iterator2->release( );
    partitions1->release( );
    partitions2->release( );

    return partitions;

juxtaposeErr:

    // Release our resources.

    if ( iterator    ) iterator->release( );
    if ( iterator1   ) iterator1->release( );
    if ( iterator2   ) iterator2->release( );
    if ( keys        ) keys->release( );
    if ( partitions  ) partitions->release( );
    if ( partitions1 ) partitions1->release( );
    if ( partitions2 ) partitions2->release( );

    return 0;
}
예제 #12
0
static void _OSMetaClassConsiderUnloads(thread_call_param_t p0,
                                        thread_call_param_t p1)
{
    OSSet *kmodClasses;
    OSSymbol *kmodName;
    OSCollectionIterator *kmods;
    OSCollectionIterator *classes;
    OSMetaClass *checkClass;
    kmod_info_t *ki = 0;
    kern_return_t ret;
    bool didUnload;

    mutex_lock(loadLock);

    do {

	kmods = OSCollectionIterator::withCollection(sKModClassesDict);
	if (!kmods)
	    break;

        didUnload = false;
        while ( (kmodName = (OSSymbol *) kmods->getNextObject()) ) {

            if (ki) {
                kfree((vm_offset_t) ki, sizeof(kmod_info_t));
                ki = 0;
            }

            ki = kmod_lookupbyname_locked((char *)kmodName->getCStringNoCopy());
            if (!ki)
                continue;

            if (ki->reference_count) {
                 continue;
            }

            kmodClasses = OSDynamicCast(OSSet,
                                sKModClassesDict->getObject(kmodName));
            classes = OSCollectionIterator::withCollection(kmodClasses);
            if (!classes)
                continue;
    
            while ((checkClass = (OSMetaClass *) classes->getNextObject())
              && (0 == checkClass->getInstanceCount()))
                {}
            classes->release();

            if (0 == checkClass) {
                OSRuntimeUnloadCPP(ki, 0);	// call destructors
                ret = kmod_destroy(host_priv_self(), ki->id);
                didUnload = true;
            }

        }

        kmods->release();

    } while (didUnload);

    mutex_unlock(loadLock);

    kmod_unload_cache();
}
예제 #13
0
IOReturn AppleGPIO::callPlatformFunction(const OSSymbol *functionName,
                                         bool waitForFunction,
                                         void *param1, void *param2,
                                         void *param3, void *param4 )
{
	DLOG("AppleGPIO::callPlatformFunction %s %s %08lx %08lx %08lx %08lx\n",
			functionName->getCStringNoCopy(), waitForFunction ? "TRUE" : "FALSE",
			(UInt32)param1, (UInt32)param2, (UInt32)param3, (UInt32)param4);

	if (fPlatformFuncArray)
	{
		UInt32 i;
		IOPlatformFunction *pfFunc;
		
		UInt32 count = fPlatformFuncArray->getCount();
		for (i = 0; i < count; i++)
		{
			if (pfFunc = OSDynamicCast(IOPlatformFunction, fPlatformFuncArray->getObject(i)))
			{
				DLOG ("AppleGPIO::callPlatformFunction '%s' - got platformFunction object\n",
						functionName->getCStringNoCopy());

				// If param4 is an OSSymbol reference, check for interrupt event registration
				// or enable/disable symbols
				if (pfFunc->platformFunctionMatch(functionName, kIOPFFlagIntGen, NULL))
				{
					OSSymbol *subFunctionSym;
					
					DLOG ("AppleGPIO::callPlatformFunction '%s' - got platformFunction interrupt match\n",
							functionName->getCStringNoCopy());

					if (param4 && (subFunctionSym = OSDynamicCast(OSSymbol, (const OSMetaClassBase *)param4)))
					{
						DLOG ("AppleGPIO::callPlatformFunction '%s', subFunction '%s'\n",
								functionName->getCStringNoCopy(), subFunctionSym->getCStringNoCopy());

						if (subFunctionSym == fSymIntRegister)
							return (registerClient(param1, param2, param3) ? kIOReturnSuccess : kIOReturnBadArgument);
						if (subFunctionSym == fSymIntUnRegister)
							return (unregisterClient(param1, param2, param3) ? kIOReturnSuccess : kIOReturnBadArgument);
						if (subFunctionSym == fSymIntEnable)
							return (enableClient(param1, param2, param3) ? kIOReturnSuccess : kIOReturnBadArgument);
						if (subFunctionSym == fSymIntDisable)
							return (disableClient(param1, param2, param3) ? kIOReturnSuccess : kIOReturnBadArgument);
						return kIOReturnBadArgument;			// Unknown function
					}
					else
					{
						DLOG ("AppleGPIO::callPlatformFunction '%s', param4 not a OSSymbol\n",
								functionName->getCStringNoCopy());
					}
				}

				// Check for on-demand case
				if (pfFunc->platformFunctionMatch (functionName, kIOPFFlagOnDemand, NULL))
				{
					DLOG ("AppleGPIO::callPlatformFunction '%s', calling demand function\n",
							functionName->getCStringNoCopy());

					return (performFunction (pfFunc, param1, param2, param3, param4) ? kIOReturnSuccess : kIOReturnBadArgument);
				}

				DLOG ("AppleGPIO::callPlatformFunction '%s' - got no match\n", functionName->getCStringNoCopy());
			}
		}

#ifdef OLD_STYLE_COMPAT

		// Need to catch old-style register-, unregister-, enable-, disable- commands

		DLOG ("AppleGPIO::callPlatformFunction '%s' - handling old style\n", functionName->getCStringNoCopy());

		// Is it an interrupt notification registration request?
		if (fRegisterStrings &&
		    fRegisterStrings->containsObject(functionName))
		{
			return (registerClient(param1, param2, param3) ? kIOReturnSuccess : kIOReturnBadArgument);
		}
		// unregister?
		else if (fUnregisterStrings && 
		         fUnregisterStrings->containsObject(functionName))
		{
			return (unregisterClient(param1, param2, param3) ? kIOReturnSuccess : kIOReturnBadArgument);
		}
		else if (fEnableStrings &&
		         fEnableStrings->containsObject(functionName))
		{
			return (enableClient(param1, param2, param3) ? kIOReturnSuccess : kIOReturnBadArgument);
		}
		else if (fDisableStrings &&
		         fDisableStrings->containsObject(functionName))
		{
			return (disableClient(param1, param2, param3) ? kIOReturnSuccess : kIOReturnBadArgument);
		}

#endif

	}

	DLOG("AppleGPIO::callPlatformFunction unrecognized function\n");

	return super::callPlatformFunction(functionName, waitForFunction, param1, param2,
			param3, param4);

}
예제 #14
0
IOReturn AppleUSBCDC::setPropertiesWL( OSObject * properties )
{
	IOReturn result = kIOReturnBadArgument;
	OSDictionary *propertyDict;
	
	WWAN_DICTIONARY whichDictionary = WWAN_DICTIONARY_UNKNOWN;
	
	OSObject *	dynamicKey = NULL;
	bool		rc = false;
	
	propertyDict = OSDynamicCast( OSDictionary, properties );

	if ( propertyDict != NULL )
	{
		OSCollectionIterator *propertyIterator;
		
#if TARGET_OS_EMBEDDED
		
		// Suspend support
		OSBoolean *suspendDevice = OSDynamicCast(OSBoolean, propertyDict->getObject("SuspendDevice"));
		
		if ( suspendDevice == kOSBooleanTrue ) 
		{
			Log("AppleUSBCDC::setProperties - SuspendDevice: true\n");
			
			if ( fpDevice->isOpen(this) )
			{
				if ( ( result = fpDevice->SuspendDevice(true) ) != kIOReturnSuccess )
				{
					Log("AppleUSBCDC::setProperties - failed to suspend the device, error: %08x \n", result);
				}
			}
			else
			{
				Log("AppleUSBCDC::setProperties - device was not open \n");
				return kIOReturnError;
			}
			
			return result;			
		}
		else if ( suspendDevice == kOSBooleanFalse )
		{
			Log("AppleUSBCDC::setProperties - SuspendDevice: false\n");
			
			if ( fpDevice->isOpen(this) )
			{
				if ( ( result = fpDevice->SuspendDevice(false) ) != kIOReturnSuccess )
				{
					Log("AppleUSBCDC::setProperties - failed to !suspend the device, error: %08x \n", result);
				}
			}
			else
			{
				IOLog("AppleUSBCDC::setProperties - device was not open \n");
				result = kIOReturnError;
			}
			
			return result;			
		}
		
		
		// Remote Wake-up support
		OSBoolean *remoteWakeup = OSDynamicCast(OSBoolean, propertyDict->getObject("RemoteWakeUp"));
		IOUSBDevRequest	devreq;
		
		if ( remoteWakeup )
		{
			devreq.bmRequestType = USBmakebmRequestType(kUSBOut, kUSBStandard, kUSBDevice);
			if ( remoteWakeup == kOSBooleanTrue )
			{
				devreq.bRequest = kUSBRqSetFeature;
			} else {
				devreq.bRequest = kUSBRqClearFeature;
			}
			devreq.wValue = kUSBFeatureDeviceRemoteWakeup;
			devreq.wIndex = 0;
			devreq.wLength = 0;
			devreq.pData = 0;
			
			result = fpDevice->DeviceRequest(&devreq);
			if ( result == kIOReturnSuccess )
			{
				IOLog("AppleUSBCDC::setProperties - Set/Clear remote wake up feature successful\n");
			} else {
				IOLog("AppleUSBCDC::setProperties - Set/Clear remote wake up feature failed, %08x\n", result);
		}

			return result;			
		}
		
#endif // TARGET_OS_EMBEDDED
		
		if (dynamicKey = propertyDict->getObject(kWWAN_TYPE))
			whichDictionary	= WWAN_SET_DYNAMIC_DICTIONARY;
		else
			if (dynamicKey = propertyDict->getObject(kWWAN_HW_VERSION))					
				whichDictionary	= WWAN_SET_HARDWARE_DICTIONARY;
			else
				if (dynamicKey = propertyDict->getObject("AccessPointName"))
					whichDictionary	= WWAN_SET_MODEM_DICTIONARY;
				else
					if (dynamicKey = propertyDict->getObject("LCPMTU"))
					whichDictionary	= WWAN_SET_PPP_DICTIONARY;
					else
						if (dynamicKey = propertyDict->getObject(kWWAN_UNIQUIFIER))
						whichDictionary	= WWAN_SET_MODEM_DICTIONARY;
					
			// if we still can't determine which dictionary it is
			// Iterate to see if it is a property we know about..
		
		if (whichDictionary == WWAN_DICTIONARY_UNKNOWN) 
		{
		propertyIterator = OSCollectionIterator::withCollection( propertyDict );
		
		if ( propertyIterator != NULL )
		{
			OSSymbol *key;
			
			while( ( key = (OSSymbol *)propertyIterator->getNextObject() ) )
			{
//				Log("[setPropertiesWL] key: %s \n", key->getCStringNoCopy());
//				if (dynamicKey)
//					setProperty(key->getCStringNoCopy(),key);					
//					setProperty(key->getCStringNoCopy(),propertyDict->getObject(key));					
					if (key->isEqualTo(kWWAN_SC_SETUP))
					{
                        if (fTerminate == true)
                            return kIOReturnNoDevice;//We were terminated in the middle of handling a wwand request.
                        
						rc = fpDevice->setProperty(kWWAN_SC_SETUP,propertyDict->getObject(key));
						goto exit;
					}
					/*
					if (key->isEqualTo(kWWAN_UNIQUIFIER))
					{
						rc = fpDevice->setProperty(kWWAN_UNIQUIFIER,propertyDict->getObject(key));
						goto exit;
					}
					*/
					
				}
			propertyIterator->release();
		}
		else
		{
//			Log("[setPropertiesWL] could not obtain an OSCollectionIterator... \n");
			ALERT(0, 0, "setPropertiesWL - Could not obtain an OSCollectionIterator...");
			result = kIOReturnError;
		}
		}
		else
		{		
			switch (whichDictionary)
			{
				case WWAN_SET_DYNAMIC_DICTIONARY:
					rc = fpDevice->setProperty(kWWAN_DynamicDictonary,propertyDict);
//					Log("[setPropertiesWL] setting kWWAN_DynamicDictonary\n");

					break;
				
				case WWAN_SET_HARDWARE_DICTIONARY: 	
				rc = fpDevice->setProperty(kWWAN_HardwareDictionary,propertyDict);
//					Log("[setPropertiesWL] setting kWWAN_HardwareDictionary\n");
					break;
							
				case WWAN_SET_MODEM_DICTIONARY: 	
					rc = fpDevice->setProperty("DeviceModemOverrides",propertyDict);
//					Log("[setPropertiesWL] setting DeviceModemOverrides\n");
					break;
					
				case WWAN_SET_PPP_DICTIONARY: 
					rc = fpDevice->setProperty("DevicePPPOverrides",propertyDict);
//					Log("[setPropertiesWL] setting DevicePPPOverrides\n");
					break;

				case WWAN_DICTIONARY_UNKNOWN: 	
//					Log("AppleWWANSUpport::setPropertiesWL - Unknown Dictionary");
					
					break;

				default:
//					Log("AppleWWANSUpport::setPropertiesWL - default Unknown Dictionary");
					break;
			}
		}

				fpDevice->messageClients ( kIOMessageServicePropertyChange );
//				Log("[setPropertiesWL] set kWWAN_HardwareDictionary [%x] pNub mesaging Clients with  kIOMessageServicePropertyChange \n",rc);
	
	}

exit:
	
	this->messageClients ( kIOMessageServicePropertyChange );
	fpDevice->messageClients ( kIOMessageServicePropertyChange );

	return kIOReturnSuccess;
}