Esempio n. 1
0
bool 
IOUSBNub::USBCompareProperty( OSDictionary   * matching, const OSSymbol     * key )
{
    // We return success iff we match the key in the dictionary with the key in
    // the property table.
    //
    OSObject 	*value;
    bool		matches = false;
	OSObject	*myProperty = NULL;

    value = matching->getObject( key );
	
    if ( value)
	{
		myProperty = copyProperty(key);
		if (myProperty)
		{
			matches = value->isEqualTo( myProperty);
			myProperty->release();
		}
	}
    else
        matches = false;
	
    return matches;
}
Esempio n. 2
0
OSObject * FileNVRAM::getProperty(const OSSymbol *aKey) const
{
	OSObject* value = IOService::getProperty(aKey);

	if (value)
	{
		OSSerialize *s = OSSerialize::withCapacity(1000);

		if (value->serialize(s))
		{
			LOG(INFO, "getProperty(%s) = %s called\n", aKey->getCStringNoCopy(), s->text());
		}
		else
		{
			LOG(INFO, "getProperty(%s) = %p called\n", aKey->getCStringNoCopy(), value);
		}

		s->release();
	}
	else
	{

		// Ignore BSD Name for now in logs, it pollutes
		if (!aKey->isEqualTo("BSD Name"))
		{
			LOG(INFO, "getProperty(%s) = %p called\n", aKey->getCStringNoCopy(), (void*)NULL);
		}
	}

	return value;
}
//---------------------------------------------------------------------------
// Compare the properties in the supplied table to this object's properties.
bool CompareProperty( IOService * owner, OSDictionary * matching, const char * key, SInt32 * score, SInt32 increment)
{
    // We return success if we match the key in the dictionary with the key in
    // the property table, or if the prop isn't present
    //
    OSObject 	* value;
    OSObject    * property;
    bool        matches = true;
    
    value = matching->getObject( key );

    if( value)
    {
        property = owner->copyProperty( key );
        
        if ( property )
        {
            matches = value->isEqualTo( property );
            
            if (matches && score) 
                *score += increment;
            
            property->release();
        }
        else
            matches = false;
    }

    return matches;
}
IOACPIPlatformDevice * ACPIBacklightPanel::getChildWithBacklightMethods(IOACPIPlatformDevice * GPUdevice)
{
    DbgLog("%s::%s()\n", this->getName(),__FUNCTION__);
    
	OSIterator * 		iter = NULL;
	OSObject *		entry;
    
	iter =  GPUdevice->getChildIterator(gIOACPIPlane);
	if (iter)
	{
		while ( true )
		{			
			entry = iter->getNextObject();
			if (NULL == entry)
				break;
			
			if (entry->metaCast("IOACPIPlatformDevice"))
			{
				IOACPIPlatformDevice * device = (IOACPIPlatformDevice *) entry;
				
				if (hasBacklightMethods(device))
				{
					IOLog("ACPIBacklight: Found Backlight Device: %s\n", device->getName());
					return device;
				}
			}
			else {
				DbgLog("%s: getChildWithBacklightMethods() Cast Error\n", this->getName());
			}
		} //end while
		iter->release();
		DbgLog("%s: getChildWithBacklightMethods() iterator end\n", this->getName());
	}
	return NULL;
}
Esempio n. 5
0
IOMapper * IOMapper::copyMapperForDevice(IOService * device)
{
    OSObject * obj;
    IOMapper * mapper;
    OSDictionary * matching;
    
    obj = device->copyProperty("iommu-parent");
    if (!obj)
	return (NULL);

    if ((mapper = OSDynamicCast(IOMapper, obj)))
	return (mapper);

    matching = IOService::propertyMatching(gIOMapperIDKey, obj);
    if (matching)
    {
	mapper = OSDynamicCast(IOMapper, IOService::waitForMatchingService(matching));
    	matching->release();
    }
    if (mapper)
	device->setProperty("iommu-parent", mapper);
    else
	obj->release();
    
    return (mapper);
}
Esempio n. 6
0
kern_return_t pmem_iokit_enumerate_pci(pmem_pci_callback_t callback,
                                       void *ctx) {
    kern_return_t error = KERN_FAILURE;
    OSObject *obj = nullptr;
    OSDictionary *search = nullptr;
    OSIterator *iter = nullptr;
    IOPCIDevice *dev = nullptr;
    IODeviceMemory *mem = nullptr;
    IOItemCount mem_count = 0;
    int cmp;

    search = IOService::serviceMatching("IOPCIDevice");
    iter = IOService::getMatchingServices(search);
    if (!iter) {
        pmem_error("Couldn't find any PCI devices.");
        goto bail;
    }

    while ((obj = iter->getNextObject())) {
        cmp = strncmp("IOPCIDevice",
                      obj->getMetaClass()->getClassName(),
                      strlen("IOPCIDevice"));
        if (cmp != 0) {
            // I haven't seen the above return anything other than
            // PCI devices, but Apple's documentation is sparse (which
            // is a nice word for what it is) and doesn't actually
            // say anything about what's guaranteed to be returned.
            // I'd just as well rather not chance it.
            pmem_warn("Expected IOPCIDevice but got %s - skipping.",
                      obj->getMetaClass()->getClassName());
            continue;
        }
        dev = (IOPCIDevice *)obj;
        mem_count = dev->getDeviceMemoryCount();
        pmem_debug("Found PCI device %s", dev->getName());

        for (unsigned idx = 0; idx < mem_count; ++idx) {
            pmem_debug("Memory segment %d found.", idx);
            mem = dev->getDeviceMemoryWithIndex(idx);
            pmem_signal_t signal = callback(dev, mem, idx, ctx);
            if (signal == pmem_Stop) {
                error = KERN_FAILURE;
                goto bail;
            }
        }
    }

    error = KERN_SUCCESS;

bail:
    if (iter) {
        iter->release();
    }

    if (search) {
        search->release();
    }

    return error;
}
Esempio n. 7
0
void iokit_post_constructor_init(void)
{
    IORegistryEntry *		root;
    OSObject *			obj;

    root = IORegistryEntry::initialize();
    assert( root );
    IOService::initialize();
    IOCatalogue::initialize();
    IOStatistics::initialize();
    OSKext::initialize();
    IOUserClient::initialize();
    IOMemoryDescriptor::initialize();
    IORootParent::initialize();

    // Initializes IOPMinformeeList class-wide shared lock
    IOPMinformeeList::getSharedRecursiveLock();

    obj = OSString::withCString( version );
    assert( obj );
    if( obj ) {
        root->setProperty( kIOKitBuildVersionKey, obj );
	obj->release();
    }
    obj = IOKitDiagnostics::diagnostics();
    if( obj ) {
        root->setProperty( kIOKitDiagnosticsKey, obj );
	obj->release();
    }
}
Esempio n. 8
0
/******************************************************************************
 * ACPIDebug::PrintTraces
 ******************************************************************************/
void ACPIDebug::PrintTraces()
{
    for (;;)
    {
        // see if there are any trace items in the RING
        UInt32 count = 0;
        if (kIOReturnSuccess != m_pDevice->evaluateInteger("COUN", &count))
        {
            IOLog("ACPIDebug: evaluateObject of COUN method failed\n");
            break;
            
        }
        if (!count)
            break;
        
        // gather the next item from RING and print it
        OSObject* debug;
        if (kIOReturnSuccess == m_pDevice->evaluateObject("FTCH", &debug) &&
            NULL != debug)
        {
            static char buf[2048];
            // got a valid object, format and print it...
            FormatDebugString(debug, buf, sizeof(buf)/sizeof(buf[0]));
            IOLog("ACPIDebug: %s\n", buf);
            debug->release();
        }
    }
}
bool IOHIDEventSystemUserClient::
initWithTask(task_t owningTask, void * /* security_id */, UInt32 /* type */)
{
    bool result = false;
    
    OSObject* entitlement = copyClientEntitlement(owningTask, kIOHIDSystemUserAccessServiceEntitlement);
    if (entitlement) {
        result = (entitlement == kOSBooleanTrue);
        entitlement->release();
    }
    if (!result) {
        proc_t      process;
        process = (proc_t)get_bsdtask_info(owningTask);
        char name[255];
        bzero(name, sizeof(name));
        proc_name(proc_pid(process), name, sizeof(name));
        HIDLogError("%s is not entitled", name);
        goto exit;
    }
    
    result = super::init();
    require_action(result, exit, HIDLogError("failed"));
    
exit:
    return result;
}
bool IOFireWireMagicMatchingNub::matchPropertyTable( OSDictionary * table )
{
    OSObject *clientClass;
    clientClass = table->getObject("IOClass");
    if(!clientClass)
        return false;
        
    return clientClass->isEqualTo( getProperty( "IODesiredChild" ) );
}
Esempio n. 11
0
IOReturn
IOI2CDevice::newUserClient(
	task_t			owningTask,
	void			*securityID,
	UInt32			type,
	OSDictionary	*properties,
	IOUserClient	**handler)
{
	IOUserClient	*client;
	OSObject		*temp;

	DLOG("%s::newUserClient\n", getName());

	if (type != kIOI2CUserClientType)
		return super::newUserClient(owningTask,securityID,type,properties,handler);

	if (IOUserClient::clientHasPrivilege(securityID, "root") != kIOReturnSuccess)
	{
		ERRLOG("%s::newUserClient: Can't create user client, not privileged\n", getName());
		return kIOReturnNotPrivileged;
	}

	temp = OSMetaClass::allocClassWithName("IOI2CUserClient");
	if (!temp)
		return kIOReturnNoMemory;

	if (OSDynamicCast(IOUserClient, temp))
		client = (IOUserClient *) temp;
	else
	{
		temp->release();
		return kIOReturnUnsupported;
	}

	if ( !client->initWithTask(owningTask, securityID, type, properties) )
	{
		client->release();
		return kIOReturnBadArgument;
	}

	if ( !client->attach(this) )
	{
		client->release();
		return kIOReturnUnsupported;
	}

	if ( !client->start(this) )
	{
		client->detach(this);
		client->release();
		return kIOReturnUnsupported;
	}

	*handler = client;
	return kIOReturnSuccess;
}
Esempio n. 12
0
IOMapper * IOMapper::copyMapperForDeviceWithIndex(IOService * device, unsigned int index)
{
    OSData *data;
    OSObject * obj;
    IOMapper * mapper = NULL;
    OSDictionary * matching;
    
    obj = device->copyProperty("iommu-parent");
    if (!obj) return (NULL);

    if ((mapper = OSDynamicCast(IOMapper, obj))) goto found;

    if ((data = OSDynamicCast(OSData, obj)))
    {
        if (index >= data->getLength() / sizeof(UInt32)) goto done;
        
        data = OSData::withBytesNoCopy((UInt32 *)data->getBytesNoCopy() + index, sizeof(UInt32));
        if (!data) goto done;

        matching = IOService::propertyMatching(gIOMapperIDKey, data);
        data->release();
    }
    else
        matching = IOService::propertyMatching(gIOMapperIDKey, obj);

    if (matching)
    {
        mapper = OSDynamicCast(IOMapper, IOService::waitForMatchingService(matching));
        matching->release();
    }

done:
    if (obj) obj->release();
found:
    if (mapper)
    {
        if (!mapper->fAllocName)
        {
            char name[MACH_ZONE_NAME_MAX_LEN];
            char kmodname[KMOD_MAX_NAME];
            vm_tag_t tag;
            uint32_t kmodid;

            tag = IOMemoryTag(kernel_map);
            if (!(kmodid = vm_tag_get_kext(tag, &kmodname[0], KMOD_MAX_NAME)))
            {
                snprintf(kmodname, sizeof(kmodname), "%d", tag);
            }
            snprintf(name, sizeof(name), "%s.DMA.%s", kmodname, device->getName());
            mapper->fAllocName = kern_allocation_name_allocate(name, 16);
        }
    }

    return (mapper);
}
bool CompareDeviceUsage( IOService * owner, OSDictionary * matching, SInt32 * score, SInt32 increment)
{
    // We return success if we match the key in the dictionary with the key in
    // the property table, or if the prop isn't present
    //
    OSObject * 		usage;
    OSObject *		usagePage;
    OSArray *		functions;
    OSDictionary * 	pair;
    bool		matches = true;
    int			count;
    
    usage = matching->getObject( kIOHIDDeviceUsageKey );
    usagePage = matching->getObject( kIOHIDDeviceUsagePageKey );
    functions = OSDynamicCast(OSArray, owner->copyProperty( kIOHIDDeviceUsagePairsKey ));
    
    if ( functions )
    {
        if ( usagePage || usage )
        {
            count = functions->getCount();
            
            for (int i=0; i<count; i++)
            {
                if ( !(pair = (OSDictionary *)functions->getObject(i)) )
                    continue;
            
                if ( !usagePage || 
                    !(matches = usagePage->isEqualTo(pair->getObject(kIOHIDDeviceUsagePageKey))) )
                    continue;

                if ( score && !usage ) 
                {
                    *score += increment / 2;
                    break;
                }
                    
                if ( !usage || 
                    !(matches = usage->isEqualTo(pair->getObject(kIOHIDDeviceUsageKey))) )            
                    continue;
        
                if ( score ) 
                    *score += increment;
                
                break;
            }
        }
        
        functions->release();
    } else {
		matches = false;
	}
    
    return matches;
}
Esempio n. 14
0
void SessionObjectTests::testDestroyObjectFails()
{
	// Create test object instance
    SessionObject testObject(NULL, 1, 1);

	CPPUNIT_ASSERT(testObject.isValid());

	OSObject* testIF = (OSObject*) &testObject;

	CPPUNIT_ASSERT(!testIF->destroyObject());
}
Esempio n. 15
0
OSObject * FileNVRAM::copyProperty(const char *aKey) const
{
	OSObject* prop = getProperty(aKey);

	if (prop)
	{
		prop->retain();
	}

	return prop;
}
Esempio n. 16
0
void USBInterfaceShim::setInterface(IOService* interface)
{
    OSObject* prev = m_pInterface;

    m_pInterface = OSDynamicCast(IOUSBInterface, interface);
    
    if (m_pInterface)
        m_pInterface->retain();
    if (prev)
        prev->release();
}
Esempio n. 17
0
void USBDeviceShim::setDevice(IOService* provider)
{
    OSObject* prev = m_pDevice;
    
    m_pDevice = OSDynamicCast(IOUSBDevice, provider);
    
    if (m_pDevice)
        m_pDevice->retain();
    
    if (prev)
        prev->release();
}
Esempio n. 18
0
bool FakeSMC::start(IOService *provider)
{
	if (!super::start(provider)) 
        return false;
    
    int arg_value = 1;
    
    // Check if we have SMC already
    if (OSDictionary *matching = serviceMatching("IOACPIPlatformDevice")) {
        if (OSIterator *iterator = getMatchingServices(matching)) {
            
            OSString *smcNameProperty = OSString::withCString("APP0001");

            while (IOService *service = (IOService*)iterator->getNextObject()) {
                
                OSObject *serviceNameProperty = service->getProperty("name");
                
                if (serviceNameProperty && serviceNameProperty->isEqualTo(smcNameProperty)) {
                    HWSensorsFatalLog("SMC device detected, will not create another one");
                    return false;
                }
            }
            
            OSSafeRelease(iterator);
        }
        
        OSSafeRelease(matching);
    }
    
	if (!smcDevice->initAndStart(provider, this)) {
        HWSensorsInfoLog("failed to initialize SMC device");
		return false;
    }

	registerService();
    
    // Load keys from NVRAM
    if (PE_parse_boot_argn("-fakesmc-use-nvram", &arg_value, sizeof(arg_value))) {
        if (UInt32 count = smcDevice->loadKeysFromNVRAM())
            HWSensorsInfoLog("%d key%s loaded from NVRAM", count, count == 1 ? "" : "s");
        else
            HWSensorsInfoLog("NVRAM will be used to store system written keys...");
    }

	return true;
}
OSDictionary*
IOFireWireUserClientIniter::dictionaryDeepCopy(
	OSDictionary*	srcDictionary)
{
	//IOLog( "IOFireWireUserClientIniter<0x%08lx>::dictionaryDeepCopy - srcDictionary = 0x%08lx\n", this, srcDictionary );

	OSDictionary*			result			= NULL;
	OSObject*				srcObject		= NULL;
	OSCollectionIterator*	srcIterator		= NULL;
	OSSymbol*				keyObject		= NULL;
	
	result = OSDictionary::withCapacity(srcDictionary->getCount());
	if (result)
	{
		srcIterator = OSCollectionIterator::withCollection(srcDictionary);
		if (srcIterator)
		{
			while ( (keyObject = OSDynamicCast(OSSymbol, srcIterator->getNextObject())) )
			{
				srcObject	= srcDictionary->getObject(keyObject);
				if (OSDynamicCast(OSDictionary, srcObject))
				{
					srcObject = dictionaryDeepCopy((OSDictionary*)srcObject);
					
					result->setObject(keyObject, srcObject);
					
					// copyDictionaryProperty creates a new dictionary, so we should release 
					// it after we add it to our dictionary
					
					srcObject->release();
				}
				else
				{
					result->setObject(keyObject, srcObject);
				}
			}
		
			srcIterator->release();
		}
	}

	//IOLog( "IOFireWireUserClientIniter<0x%08lx>::dictionaryDeepCopy - return\n", this );
	
	return result;
}
OSArray * ACPIBacklightPanel::queryACPISupportedBrightnessLevels()
{
    DbgLog("%s::%s()\n", this->getName(),__FUNCTION__);
    
	OSObject * ret;
	backLightDevice->evaluateObject("_BCL", &ret);
	OSArray * data = OSDynamicCast(OSArray, ret);
	if (data)
	{
		DbgLog("%s: %s _BCL %d\n", this->getName(), backLightDevice->getName(), data->getCount() );
		return data;
	}
	else
    {
		DbgLog("%s: Cast Error _BCL is %s\n", this->getName(), ret ? ret->getMetaClass()->getClassName() : "ret=NULL");
	}
	OSSafeRelease(ret);
	return NULL;
}
Esempio n. 21
0
bool NullEthernet::initMACfromACPI()
{
    bool result = false;
    OSObject *ret = NULL;
    IOACPIPlatformDevice* pACPI = OSDynamicCast(IOACPIPlatformDevice, m_pProvider);
    if (NULL != pACPI && kIOReturnSuccess == pACPI->evaluateObject("MAC", &ret) && NULL != ret)
    {
        // get MAC address from DSDT if provided...
        OSData* pData = OSDynamicCast(OSData, ret);
        if (pData && pData->getLength() == kIOEthernetAddressSize)
        {
            bcopy(pData->getBytesNoCopy(), m_rgMacAddr, kIOEthernetAddressSize);
            AlwaysLog("Using MAC address from DSDT: %02x:%02x:%02x:%02x:%02x:%02x\n", m_rgMacAddr[0], m_rgMacAddr[1], m_rgMacAddr[2], m_rgMacAddr[3], m_rgMacAddr[4], m_rgMacAddr[5]);
            result = true;
        }
        ret->release();
    }
    return result;
}
// Received an update of a specific value
void WirelessHIDDevice::receivedUpdate(unsigned char type, unsigned char *data)
{
    switch (type)
    {
        case 0x13:  // Battery level
            battery = data[0];
            {
                OSObject *prop = OSNumber::withNumber(battery, 8);
                if (prop != NULL)
                {
                    setProperty(kIOWirelessBatteryLevel, prop);
                    prop->release();
                }
            }
            break;
            
        default:
            break;
    }
}
Esempio n. 23
0
static bool
getPCSPortMapping(
    IORegistryEntry * root,
    UInt32     portNum,
    UInt8 *    enableOffset,
    UInt8 *    enableMask,
    UInt8 *    presenceOffset,
    UInt8 *    presenceMask )
{
    OSObject *  prop;
    OSData *    data;

    const PCSPortMap * portMap = gDefaultPortMap;

    if (!root || (portNum > kSerialATAPort3) ||
        root->getProperty( kSerialATAKey ) != kOSBooleanTrue)
        return false;

    prop = root->copyProperty( kPCSPortMapKey );
    data = OSDynamicCast(OSData, prop);

    if (data && (data->getLength() == sizeof(gDefaultPortMap)))
    {
        portMap = (const PCSPortMap *) data->getBytesNoCopy();
    }

    if (enableOffset)
        *enableOffset = portMap[portNum].enableOffset;
    if (enableMask)
        *enableMask = portMap[portNum].enableMask;
    if (presenceOffset)
        *presenceOffset = portMap[portNum].presenceOffset;
    if (presenceMask)
        *presenceMask = portMap[portNum].presenceMask;

    if (prop) prop->release();

    return true;
}
OSReturn NoSleepExtension::readNVRAM(UInt8 *value)
{
#ifdef DEBUG
    IOLog("%s[%p]::%s(%p)\n", getName(), this, __FUNCTION__, value);
#endif
    
    OSReturn ret = kOSReturnError;
    IORegistryEntry *entry = IORegistryEntry::fromPath( "/options", gIODTPlane );
    if ( entry )
    {
        OSObject *rawValue = entry->getProperty(IORegistrySleepSuppressionMode);

        if(rawValue != NULL) {
#ifdef DEBUG
            IOLog("%s: rawValueClassName: %s\n", getName(), rawValue->getMetaClass()->getClassName());
#endif
            OSData *data = OSDynamicCast(OSData, rawValue);
            if(data->getLength() == 1) {
                *value = ((UInt8 *)data->getBytesNoCopy())[0];
                
                ret = kOSReturnSuccess;
#ifdef DEBUG
                IOLog("%s: reading nvram, value: 0x%02x\n", getName(), (*value));
#endif
            }
#ifdef DEBUG
            else {
                IOLog("%s: read error: data->Len %s 1\n", getName(),
                      (data->getLength() == 1)?"==":"!=");
            }
#endif

        }
        entry->release();
    }
    
    return ret;
}
Esempio n. 25
0
void testDictionary()
{
    bool res = true;
    void *spaceCheck, *spaceCheck2, *spaceCheck3;
    OSObject *cache[numStrCache];
    OSString *str;
    const OSSymbol *symCache[numStrCache], *sym;
    OSDictionary *dict1, *dict2;
    int i, numSymbols, count1, count2;

    // Do first test without memory leak tests to initialise the metaclass
    dict1 = OSDictionary::withCapacity(1);
    TEST_ASSERT('D', "0a", dict1);
    if (dict1)
        dict1->release();

    // Grow the symbol pool to maximum
    for (i = 0; i < numStrCache; i++)
        symCache[i] = OSSymbol::withCStringNoCopy(strCache[i]);
    for (i = 0; i < numStrCache; i++)
        symCache[i]->release();

    // Create and destroy a dictionary
    spaceCheck = checkPointSpace();
    dict1 = OSDictionary::withCapacity(1);
    TEST_ASSERT('D', "1a", dict1);
    if (dict1) {
        TEST_ASSERT('D', "1b", !dict1->getCount());
        TEST_ASSERT('D', "1c", 1 == dict1->getCapacity());
        TEST_ASSERT('D', "1d", 1 == dict1->getCapacityIncrement());
        TEST_ASSERT('D', "1e", 4 == dict1->setCapacityIncrement(4));
        TEST_ASSERT('D', "1f", 4 == dict1->getCapacityIncrement());
        TEST_ASSERT('D', "1g", 8 == dict1->ensureCapacity(5));

        spaceCheck2 = checkPointSpace();
        sym = OSSymbol::withCStringNoCopy(strCache[0]);

        spaceCheck3 = checkPointSpace();
        TEST_ASSERT('D', "1h", dict1->setObject((OSObject *) sym, sym));
        TEST_ASSERT('D', "1i", (OSObject *) sym == dict1->getObject(sym));
        sym->release();
        TEST_ASSERT('D', "1i", 2 == sym->getRetainCount());
        res = res && checkSpace("(D)1j", spaceCheck3, 0);

        TEST_ASSERT('D', "1k", 1 == dict1->getCount());
        dict1->flushCollection();
        TEST_ASSERT('D', "1l", !dict1->getCount());
        res = res && checkSpace("(D)1m", spaceCheck2, 0);

        dict1->release();
    }
    res = res && checkSpace("(D)1", spaceCheck, 0);

    // Check the creation of a sizable OSDictionary from an array of IOObjects
    // Also check indexing into the array.
    spaceCheck = checkPointSpace();
    for (i = 0, numSymbols = 0; i < numStrCache; i++) {
        sym = OSSymbol::withCStringNoCopy(strCache[i]);
        if (1 == sym->getRetainCount())
            symCache[numSymbols++] = sym;
        else
            sym->release();
    }
    dict1 = OSDictionary::withObjects(
                (OSObject **) symCache, symCache, numSymbols, numSymbols);
    TEST_ASSERT('D', "2a", dict1);
    count1 = count2 = 0;
    for (i = 0; i < numSymbols; i++)
        count1 += (symCache[i]->getRetainCount() == 3);
    TEST_ASSERT('D', "2b", count1 == numSymbols);
    if (dict1) {
        TEST_ASSERT('D', "2c", numSymbols == (int) dict1->getCount());
        TEST_ASSERT('D', "2d", numSymbols == (int) dict1->getCapacity());
        TEST_ASSERT('D', "2e",
                    numSymbols == (int) dict1->getCapacityIncrement());

        for (i = dict1->getCount(); --i >= 0; ) {
            str = (OSString *) dict1->getObject(symCache[i]);
            if (str != (OSString *) symCache[i]) {
                verPrintf(("testDictionary(D) test 2f%d failed\n", i));
                res = false;
            }
        }
        dict1->release();
    }
    count1 = count2 = 0;
    for (i = 0; i < numSymbols; i++) {
        count1 += (symCache[i]->getRetainCount() == 1);
        symCache[i]->release();
    }
    TEST_ASSERT('D', "2g", count1 == numSymbols);
    res = res && checkSpace("(D)2", spaceCheck, 0);

    // Check the creation of a sizable Dictionary from an array of IOStrings
    // Also check searching dictionary use OSString for a key.
    spaceCheck = checkPointSpace();
    for (i = 0, numSymbols = 0; i < numStrCache; i++) {
        sym = OSSymbol::withCStringNoCopy(strCache[i]);
        if (1 == sym->getRetainCount()) {
            cache[numSymbols] = OSString::withCStringNoCopy(strCache[i]);
            symCache[numSymbols] = sym;
            numSymbols++;
        }
        else
            sym->release();
    }
    dict1 = OSDictionary::withObjects((OSObject **) symCache,
                                      (OSString **) cache,
                                      numSymbols, numSymbols);
    TEST_ASSERT('D', "3a", dict1);
    count1 = count2 = 0;
    for (i = 0; i < numSymbols; i++) {
        count1 += (symCache[i]->getRetainCount() == 3);
        count2 += (cache[i]->getRetainCount() == 1);
    }
    TEST_ASSERT('D', "3b", count1 == numSymbols);
    TEST_ASSERT('D', "3c", count2 == numSymbols);
    if (dict1) {
        count1 = count2 = 0;
        for (i = 0; i < numSymbols; i++) {
            str = (OSString *) cache[i];
            count1 += (symCache[i] == (const OSSymbol *) dict1->getObject(str));
            count2 += (symCache[i]->getRetainCount() == 3);
        }
        TEST_ASSERT('D', "3d", count1 == numSymbols);
        TEST_ASSERT('D', "3e", count2 == numSymbols);

        count1 = count2 = 0;
        for (i = 0; i < numSymbols; i++) {
            const char *cStr = ((OSString *) cache[i])->getCStringNoCopy();

            count1 += (symCache[i] == (const OSSymbol *) dict1->getObject(cStr));
            count2 += (symCache[i]->getRetainCount() == 3);
        }
        TEST_ASSERT('D', "3f", count1 == numSymbols);
        TEST_ASSERT('D', "3g", count2 == numSymbols);

        dict1->release();
    }
    count1 = count2 = 0;
    for (i = 0; i < numSymbols; i++) {
        count1 += (symCache[i]->getRetainCount() == 1);
        count2 += (cache[i]->getRetainCount() == 1);
        symCache[i]->release();
        cache[i]->release();
    }
    TEST_ASSERT('D', "3h", count1 == numSymbols);
    res = res && checkSpace("(D)3", spaceCheck, 0);

    // Check the creation of a small dictionary then grow it one item at a time
    // Create a new dictionary from the old dictionary.
    // Finally remove each item permanently.
    spaceCheck = checkPointSpace();
    for (i = 0, numSymbols = 0; i < numStrCache; i++) {
        sym = OSSymbol::withCStringNoCopy(strCache[i]);
        if (1 == sym->getRetainCount()) {
            cache[numSymbols] = OSString::withCStringNoCopy(strCache[i]);
            symCache[numSymbols] = sym;
            numSymbols++;
        }
        else
            sym->release();
    }
    dict2 = 0;
    dict1 = OSDictionary::withCapacity(1);
    TEST_ASSERT('D', "4a", dict1);
    if (dict1) {
        count1 = count2 = 0;
        for (i = 0; i < numSymbols; i++) {
            sym = symCache[i];
            count1 += ((OSObject *) sym == dict1->setObject((OSObject *) sym,
                       sym->getCStringNoCopy()));
            count2 += (sym->getRetainCount() == 3);
        }
        TEST_ASSERT('D', "4b", numSymbols == (int) dict1->getCount());
        TEST_ASSERT('D', "4c", numSymbols == count1);
        TEST_ASSERT('D', "4d", numSymbols == count2);

        dict2 = OSDictionary::withDictionary(dict1, numSymbols-1);
        TEST_ASSERT('D', "4b", !dict2);
        dict2 = OSDictionary::withDictionary(dict1, numSymbols);
    }
    TEST_ASSERT('D', "4e", dict2);
    if (dict2) {
        dict1->release();
        dict1 = 0;

        TEST_ASSERT('D', "4f", numSymbols == (int) dict2->getCount());

        count1 = count2 = 0;
        for (i = 0; i < numSymbols; i++) {
            OSObject *replacedObject;

            sym = symCache[i];
            str = (OSString *) cache[i];
            replacedObject = dict2->setObject(str, str);
            count1 += ((OSString *) sym == replacedObject);
            replacedObject->release();
            count2 += (sym->getRetainCount() == 2);
            str->release();
        }
        TEST_ASSERT('D', "4g", numSymbols == count1);
        TEST_ASSERT('D', "4h", numSymbols == count2);

        count1 = count2 = 0;
        for (i = 0; i < numSymbols; i++) {
            sym = symCache[i];
            str = (OSString *) cache[i];
            count1 += (str == dict2->__takeObject(sym));
            str->release();
            count2 += (sym->getRetainCount() == 1);
            sym->release();
        }
        TEST_ASSERT('D', "4i", numSymbols == count1);
        TEST_ASSERT('D', "4j", numSymbols == count2);
        TEST_ASSERT('D', "4k", !dict2->getCount());
        dict2->release();
        dict2 = 0;
    }
    else if (dict1)
        dict1->release();
    res = res && checkSpace("(D)4", spaceCheck, 0);

    if (res)
        verPrintf(("testDictionary: All OSDictionary Tests passed\n"));
    else
        logPrintf(("testDictionary: Some OSDictionary Tests failed\n"));
}
IOReturn
com_evoluent_driver_VerticalMouse::StartFinalProcessing()
{
    OSNumber 		*curResPtr, *resPrefPtr;
    UInt32			curResInt, resPrefInt;
    IOFixed			curRes, resPref;
    IOReturn		err = kIOReturnSuccess;
    OSBoolean * 	boolObj;
    OSObject *		propertyObj = NULL;
	
    USBLog(3, "com_evoluent_driver_VerticalMouse[%p]::StartFinalProcessing", this);
	_switchBackOnRestart = FALSE;
    propertyObj = copyProperty("SwitchTo800DPI");
    boolObj = OSDynamicCast( OSBoolean, propertyObj );
    if ( boolObj && boolObj->isTrue() )
    {
		// USBLog(3, "com_evoluent_driver_VerticalMouse[%p]::StartFinalProcessing - found switchTo800DPI resolution property", this);
        _switchTo800dpiFlag = true;
    }
	if (propertyObj)
		propertyObj->release();
	
    propertyObj = copyProperty("SwitchTo2000FPS");
    boolObj = OSDynamicCast( OSBoolean, propertyObj );
    if ( boolObj && boolObj->isTrue() )
    {
		// USBLog(3, "com_evoluent_driver_VerticalMouse[%p]::StartFinalProcessing - found switchTo2000fps resolution property", this);
        _switchTo2000fpsFlag = true;
    }
	if (propertyObj)
		propertyObj->release();
	
    if ( _switchTo2000fpsFlag )
    {
        IOUSBDevRequest		devReq;
        
        // Write the 2000 FPS value to the mouse
        //
        devReq.bmRequestType = 0x40;
        devReq.bRequest = 0x01;
        devReq.wValue = 0x05AC;
        devReq.wIndex = 0xd810;
        devReq.wLength = 0x0000;
        devReq.pData = NULL;
		
        err = _device->DeviceRequest(&devReq, 5000, 0);
		
        if (err)
		{
            USBLog(3, "com_evoluent_driver_VerticalMouse[%p]::StartFinalProcessing - sending 1st part of FPS change received error 0x%x", this, err);
		}
        else
        {
            devReq.bmRequestType = 0x40;
            devReq.bRequest = 0x01;
            devReq.wValue = 0x05AC;
            devReq.wIndex = 0xdc11;
            devReq.wLength = 0x0000;
            devReq.pData = NULL;
			
            err = _device->DeviceRequest(&devReq, 5000, 0);
			
            if (err)
			{
                USBLog(3, "com_evoluent_driver_VerticalMouse[%p]::StartFinalProcessing - sending 2nd part of FPS change received error 0x%x", this, err);
			}
        }
		
#if FORMOUSETESTING
        UInt8			hi,lo;
        UInt16			fps;
		
        // Read back the value:
        //
        devReq.bmRequestType = 0xc0;
        devReq.bRequest = 0x01;
        devReq.wValue = 0x05AC;
        devReq.wIndex = 0x0011;
        devReq.wLength = 1;
        devReq.pData = &hi;
		
        err = _device->DeviceRequest(&devReq, 5000, 0);
        if (err)
            USBLog(3, "com_evoluent_driver_VerticalMouse[%p]::StartFinalProcessing - error reading hi byte: 0x%x", this, err);
		
        devReq.bmRequestType = 0xc0;
        devReq.bRequest = 0x01;
        devReq.wValue = 0x05AC;
        devReq.wIndex = 0x0010;
        devReq.wLength = 1;
        devReq.pData = &lo;
		
        err = _device->DeviceRequest(&devReq, 5000, 0);
        if (err)
            USBLog(3, "com_evoluent_driver_VerticalMouse[%p]::StartFinalProcessing - read reading lo byte: 0x%x", this, err);
		
        fps = hi;
        fps = (fps << 8) | lo;
		
        USBLog(3, "com_evoluent_driver_VerticalMouse[%p]::StartFinalProcessing - read : 0x%x", this, fps );
		
#endif
        
        err = super::StartFinalProcessing();
        if (err)
		{
            USBLog(3, "com_evoluent_driver_VerticalMouse[%p]::StartFinalProcessing - super returned error 0x%x", this, err);
		}
		
    }
	
    if ( _switchTo800dpiFlag )
    {
		propertyObj = copyProperty(kIOHIDPointerResolutionKey);
        curResPtr = OSDynamicCast( OSNumber, propertyObj );
        if (curResPtr)
        {
            curResInt = curResPtr->unsigned32BitValue();
            USBLog(3, "com_evoluent_driver_VerticalMouse[%p]::StartFinalProcessing - found current resolution property - value 0x%lx", this, curResInt);
        }
        else
        {
            curResInt = kDefaultFixedResolution;
            USBLog(3, "com_evoluent_driver_VerticalMouse[%p]::StartFinalProcessing - no current property found - using default 0x%lx", this, curResInt);
        }
		if (propertyObj)
			propertyObj->release();
		
		propertyObj = copyProperty(("xResolutionPref"));
        resPrefPtr = OSDynamicCast( OSNumber, propertyObj );
        if (resPrefPtr)
            resPrefInt = resPrefPtr->unsigned32BitValue();
        else
        {
            resPrefInt = kDefaultFixedResolution * 2;
            USBLog(3, "com_evoluent_driver_VerticalMouse[%p]::StartFinalProcessing - no preference property found - using default 0x%lx", this, resPrefInt);
        }
		if (propertyObj)
			propertyObj->release();
		
        resPref = (IOFixed) resPrefInt;
        curRes = (IOFixed) curResInt;
		
        if (resPref != curRes)
        {
            if (switchTo800dpi)
            {
                IOUSBDevRequest		devReq;
				
                devReq.bmRequestType = 0x40;
                devReq.bRequest = 0x01;
                devReq.wValue = 0x05AC;
                devReq.wIndex = 0x0452;
                devReq.wLength = 0x0000;
                devReq.pData = NULL;
				
                err = _device->DeviceRequest(&devReq, 5000, 0);
				
                if (err)
				{
                    USBLog(3, "com_evoluent_driver_VerticalMouse[%p]::StartFinalProcessing - error (%x) setting resolution", this, err);
				}
                else
				{
					// with this mouse, we do NOT want to start reading on the interrupt pipe, nor do
					// we want to call super::start. We just want to wait for the device to get terminated
                    USBLog(3, "com_evoluent_driver_VerticalMouse[%p]::StartFinalProcessing - waiting for click mouse termination", this);
				}
            }
        }
        else
        {
            // If we are already at the correct resolution for OSX, OK. But what if we are going
            // back to OS 9? On restart, switch back to boot setup. Power Manager will tell us
            // when we are going to restart.
            //
			_switchBackOnRestart = TRUE;
            err = super::StartFinalProcessing();
            if (err)
            {
				USBLog(1, "com_evoluent_driver_VerticalMouse[%p]::StartFinalProcessing - error (%p) from super::StartFinalProcessing", this, (void*)err);
            }
        }
    }
    
    return err;
}
Esempio n. 27
0
bool FakeSMC::start(IOService *provider)
{
	if (!super::start(provider)) 
        return false;

    if (!(keyStore = OSDynamicCast(FakeSMCKeyStore, waitForMatchingService(serviceMatching(kFakeSMCKeyStoreService), kFakeSMCDefaultWaitTimeout)))) {
        HWSensorsInfoLog("still waiting for FakeSMCKeyStore...");
        return false;
//        HWSensorsDebugLog("creating FakeSMCKeyStore");
//        
//        if (!(keyStore = new FakeSMCKeyStore)) {
//            HWSensorsInfoLog("failed to create FakeSMCKeyStore");
//            return false;
//        }
//
//        HWSensorsDebugLog("initializing FakeSMCKeyStore");
//
//        if (keyStore->initAndStart(this, configuration)) {
//            keyStore->setProperty("IOUserClientClass", "FakeSMCKeyStoreUserClient");
//        }
//        else {
//            keyStore->release();
//            HWSensorsFatalLog("failed to initialize FakeSMCKeyStore device");
//            return false;
//        }
    }

//    if (IOService *resources = waitForMatchingService(serviceMatching("IOResources"), 0))
//        this->attach(resources);

    OSDictionary *configuration = OSDynamicCast(OSDictionary, getProperty("Configuration"));

    // Load preconfigured keys
    HWSensorsDebugLog("loading keys...");

    if (!configuration) {
        HWSensorsFatalLog("no configuration node found!");
        return false;
    }

    if (UInt32 count = keyStore->addKeysFromDictionary(OSDynamicCast(OSDictionary, configuration->getObject("Keys")))) {
        HWSensorsInfoLog("%d preconfigured key%s added", count, count == 1 ? "" : "s");
    }
	else {
		HWSensorsWarningLog("no preconfigured keys found");
	}

    // Load wellknown type names
    HWSensorsDebugLog("loading types...");

    keyStore->addWellKnownTypesFromDictionary(OSDynamicCast(OSDictionary, configuration->getObject("Types")));

    // Set Clover platform keys
    if (OSDictionary *dictionary = OSDynamicCast(OSDictionary, configuration->getObject("Clover"))) {
        UInt32 count = 0;
        if (IORegistryEntry* cloverPlatformNode = fromPath("/efi/platform", gIODTPlane)) {
            if (OSIterator *iterator = OSCollectionIterator::withCollection(dictionary)) {
                while (OSString *name = OSDynamicCast(OSString, iterator->getNextObject())) {
                    if (OSData *data = OSDynamicCast(OSData, cloverPlatformNode->getProperty(name))) {
                        if (OSArray *items = OSDynamicCast(OSArray, dictionary->getObject(name))) {
                            OSString *key = OSDynamicCast(OSString, items->getObject(0));
                            OSString *type = OSDynamicCast(OSString, items->getObject(1));

                            if (keyStore->addKeyWithValue(key->getCStringNoCopy(), type->getCStringNoCopy(), data->getLength(), data->getBytesNoCopy()))
                                count++;
                        }
                    }
                }
                OSSafeRelease(iterator);
            }
        }

        if (count)
            HWSensorsInfoLog("%d key%s exported by Clover EFI", count, count == 1 ? "" : "s");
    }

    // Check if we have SMC already
    bool smcDeviceFound = false;

    if (OSDictionary *matching = serviceMatching("IOACPIPlatformDevice")) {
        if (OSIterator *iterator = getMatchingServices(matching)) {
            
            OSString *smcNameProperty = OSString::withCString("APP0001");

            while (IOService *service = (IOService*)iterator->getNextObject()) {
                
                OSObject *serviceNameProperty = service->getProperty("name");
                
                if (serviceNameProperty && serviceNameProperty->isEqualTo(smcNameProperty)) {
                    smcDeviceFound = true;
                }
            }
            
            OSSafeRelease(iterator);
        }
        
        OSSafeRelease(matching);
    }

    if (!smcDeviceFound) {
        if (!(smcDevice = new FakeSMCDevice)) {
            HWSensorsInfoLog("failed to create SMC device");
            return false;
        }

        IOService *platformExpert = waitForMatchingService(serviceMatching("IOACPIPlatformExpert"), kFakeSMCDefaultWaitTimeout);

        if (!smcDevice->initAndStart(platformExpert, this)) {
            HWSensorsFatalLog("failed to initialize SMC device");
            return false;
        }
    }
    else {
        HWSensorsInfoLog("found physical SMC device, will not create virtual one. Providing only basic plugins functionality");
    }

    int arg_value = 1;

    // Load keys from NVRAM
    if (PE_parse_boot_argn("-fakesmc-use-nvram", &arg_value, sizeof(arg_value))) {
        if (UInt32 count = keyStore->loadKeysFromNVRAM())
            HWSensorsInfoLog("%d key%s loaded from NVRAM", count, count == 1 ? "" : "s");
        else
            HWSensorsInfoLog("NVRAM will be used to store system written keys...");
    }

  	registerService();

	return true;
}
Esempio n. 28
0
void StartIOKit( void * p1, void * p2, void * p3, void * p4 )
{
    IOPlatformExpertDevice *	rootNub;
    int				debugFlags;
    IORegistryEntry *		root;
    OSObject *			obj;
    extern const char *         gIOKernelKmods;
    OSString *                  errorString = NULL; // must release
    OSDictionary *              fakeKmods;  // must release
    OSCollectionIterator *      kmodIter;   // must release
    OSString *                  kmodName;   // don't release

    IOLog( iokit_version );

    if( PE_parse_boot_arg( "io", &debugFlags ))
	gIOKitDebug = debugFlags;

    // Check for the log synchronous bit set in io
    if (gIOKitDebug & kIOLogSynchronous)
        debug_mode = true;

    //
    // Have to start IOKit environment before we attempt to start
    // the C++ runtime environment.  At some stage we have to clean up
    // the initialisation path so that OS C++ can initialise independantly
    // of iokit basic service initialisation, or better we have IOLib stuff
    // initialise as basic OS services.
    //
    IOLibInit(); 
    OSlibkernInit();

   /*****
    * Declare the fake kmod_info structs for built-in components
    * that must be tracked as independent units for dependencies.
    */
    fakeKmods = OSDynamicCast(OSDictionary,
        OSUnserialize(gIOKernelKmods, &errorString));

    if (!fakeKmods) {
        if (errorString) {
            panic("Kernel kmod list syntax error: %s\n",
                    errorString->getCStringNoCopy());
            errorString->release();
        } else {
            panic("Error loading kernel kmod list.\n");
        }
    }

    kmodIter = OSCollectionIterator::withCollection(fakeKmods);
    if (!kmodIter) {
        panic("Can't declare in-kernel kmods.\n");
    }
    while ((kmodName = OSDynamicCast(OSString, kmodIter->getNextObject()))) {

        OSString * kmodVersion = OSDynamicCast(OSString,
            fakeKmods->getObject(kmodName));
        if (!kmodVersion) {
            panic("Can't declare in-kernel kmod; \"%s\" has "
                "an invalid version.\n",
                kmodName->getCStringNoCopy());
        }
        if (KERN_SUCCESS != kmod_create_fake(kmodName->getCStringNoCopy(),
                kmodVersion->getCStringNoCopy())) {
            panic("Failure declaring in-kernel kmod \"%s\".\n",
                kmodName->getCStringNoCopy());
        }
    }

    kmodIter->release();
    fakeKmods->release();



    root = IORegistryEntry::initialize();
    assert( root );
    IOService::initialize();
    IOCatalogue::initialize();
    IOUserClient::initialize();
    IOMemoryDescriptor::initialize();

    obj = OSString::withCString( iokit_version );
    assert( obj );
    if( obj ) {
        root->setProperty( kIOKitBuildVersionKey, obj );
	obj->release();
    }
    obj = IOKitDiagnostics::diagnostics();
    if( obj ) {
        root->setProperty( kIOKitDiagnosticsKey, obj );
	obj->release();
    }

    rootNub = new IOPlatformExpertDevice;

    if( rootNub && rootNub->initWithArgs( p1, p2, p3, p4)) {
        rootNub->attach( 0 );

       /* Enter into the catalogue the drivers
        * provided by BootX.
        */
        gIOCatalogue->recordStartupExtensions();

        rootNub->registerService();
    }
}
Esempio n. 29
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);
}
Esempio n. 30
0
void FileNVRAM::timeoutOccurred(OSObject *target, IOTimerEventSource* timer)
{
	static int retryCount;

	if (target)
	{
		FileNVRAM* self = OSDynamicCast(FileNVRAM, target);

		if (self)
		{
			uint64_t timeout = 20000; // 20ms
			// Check to see if BSD has been published, if so sync();

			OSDictionary *  dict = 0;
			IOService *     match = 0;
			boolean_t		found = false;

			do
			{
				dict = IOService::resourceMatching("IOBSD");

				if (dict)
				{
					if (IOService::waitForMatchingService(dict, timeout))
					{
						found = true;
					}
				}
			} while (false);

			OSSafeReleaseNULL(dict);
			OSSafeReleaseNULL(match);

			if (found)
			{
				UInt8 mLoggingLevel = self->mLoggingLevel;
				LOG(NOTICE, "BSD found, syncing\n");

				// TODO: Read /Extra/NVRAM/nvram.plist and populate the device tree.
				char* buffer;
				uint64_t len;

				if (self->read_buffer(&buffer, &len, self->mCtx))
				{
					retryCount++;
					LOG(ERROR, "Unable to read in nvram data at %s\n", self->mFilePath->getCStringNoCopy());
					// TODO: Check if / is mounted, and if not, try again until it is.
					if (retryCount < 100)
					{
						timer->setTimeoutMS(100);
					}
					else
					{
						self->mSafeToSync = true;
						self->registerNVRAM();
					}
				}
				else
				{
					self->mSafeToSync = false;

					timer->cancelTimeout();
					self->getWorkLoop()->removeEventSource(timer);
					timer->release();
					self->mTimer = NULL;

					if (len > strlen(NVRAM_FILE_HEADER) + strlen(NVRAM_FILE_FOOTER) + 1)
					{
						char* xml = buffer + strlen(NVRAM_FILE_HEADER);
						size_t xmllen = (size_t)len - strlen(NVRAM_FILE_HEADER) - strlen(NVRAM_FILE_FOOTER);
						xml[xmllen-1] = 0;
						OSString *errmsg = 0;
						OSObject* nvram = OSUnserializeXML(xml, &errmsg);

						if (nvram)
						{
							OSDictionary* data = OSDynamicCast(OSDictionary, nvram);
							//if(data) self->setPropertyTable(data);

							if (data)
							{
								self->copyUnserialzedData(NULL, data);
							}

							nvram->release();
						}
					}

					IOFree(buffer, (size_t)len);


					self->mSafeToSync = true;
					self->registerNVRAM();
					//self->sync();
				}
			}
			else
			{
				timer->setTimeoutMS(50);
			}
		}
		else
		{
			//printf("Self is not of type FileNVRAM.\n");
		}
	}
}