kern_return_t SMCReadKey(io_connect_t conn, const UInt32Char_t key, SMCVal_t *val) { kern_return_t result; SMCKeyData_t inputStructure; SMCKeyData_t outputStructure; memset(&inputStructure, 0, sizeof(SMCKeyData_t)); memset(&outputStructure, 0, sizeof(SMCKeyData_t)); memset(val, 0, sizeof(SMCVal_t)); inputStructure.key = _strtoul(key, 4, 16); snprintf(val->key, 5, "%s", key); inputStructure.data8 = SMC_CMD_READ_KEYINFO; result = SMCCall(conn, KERNEL_INDEX_SMC, &inputStructure, &outputStructure); if (result != kIOReturnSuccess) return result; val->dataSize = outputStructure.keyInfo.dataSize; _ultostr(val->dataType, outputStructure.keyInfo.dataType); inputStructure.keyInfo.dataSize = val->dataSize; inputStructure.data8 = SMC_CMD_READ_BYTES; result = SMCCall(conn, KERNEL_INDEX_SMC, &inputStructure, &outputStructure); if (result != kIOReturnSuccess) return result; memcpy(val->bytes, outputStructure.bytes, sizeof(outputStructure.bytes)); return kIOReturnSuccess; }
kern_return_t SMCReadKey(io_connect_t conn, const UInt32Char_t key, SMCVal_t *val) { kern_return_t result; SMCKeyData_t inputStructure; SMCKeyData_t outputStructure; memset(&inputStructure, 0, sizeof(SMCKeyData_t)); memset(&outputStructure, 0, sizeof(SMCKeyData_t)); memset(val, 0, sizeof(SMCVal_t)); inputStructure.key = _strtoul(key, 4, 16); //REVEIW_REHABMAN: mempcy used to avoid deprecated strcpy... //strcpy(val->key, key); memcpy(val->key, key, sizeof(val->key)); result = SMCGetKeyInfo(conn, inputStructure.key, &outputStructure.keyInfo); if (result != kIOReturnSuccess) return result; val->dataSize = outputStructure.keyInfo.dataSize; _ultostr(val->dataType, outputStructure.keyInfo.dataType); inputStructure.keyInfo.dataSize = val->dataSize; inputStructure.data8 = SMC_CMD_READ_BYTES; result = SMCCall(conn, KERNEL_INDEX_SMC, &inputStructure, &outputStructure); if (result != kIOReturnSuccess) return result; memcpy(val->bytes, outputStructure.bytes, sizeof(outputStructure.bytes)); return kIOReturnSuccess; }
// Provides key info, using a cache to dramatically improve the energy impact of smcFanControl kern_return_t SMCGetKeyInfo(io_connect_t conn, UInt32 key, SMCKeyData_keyInfo_t* keyInfo) { SMCKeyData_t inputStructure; SMCKeyData_t outputStructure; kern_return_t result = kIOReturnSuccess; int i = 0; OSSpinLockLock(&g_keyInfoSpinLock); for (; i < g_keyInfoCacheCount; ++i) { if (key == g_keyInfoCache[i].key) { *keyInfo = g_keyInfoCache[i].keyInfo; break; } } if (i == g_keyInfoCacheCount) { // Not in cache, must look it up. memset(&inputStructure, 0, sizeof(inputStructure)); memset(&outputStructure, 0, sizeof(outputStructure)); inputStructure.key = key; inputStructure.data8 = SMC_CMD_READ_KEYINFO; result = SMCCall(conn, KERNEL_INDEX_SMC, &inputStructure, &outputStructure); if (result == kIOReturnSuccess) { *keyInfo = outputStructure.keyInfo; if (g_keyInfoCacheCount < KEY_INFO_CACHE_SIZE) { g_keyInfoCache[g_keyInfoCacheCount].key = key; g_keyInfoCache[g_keyInfoCacheCount].keyInfo = outputStructure.keyInfo; ++g_keyInfoCacheCount; } } } OSSpinLockUnlock(&g_keyInfoSpinLock); return result; }
kern_return_t SMCWriteKeyUnsafe(io_connect_t conn, const SMCVal_t *val) { kern_return_t result; SMCKeyData_t inputStructure; SMCKeyData_t outputStructure; memset(&inputStructure, 0, sizeof(SMCKeyData_t)); memset(&outputStructure, 0, sizeof(SMCKeyData_t)); inputStructure.key = _strtoul(val->key, 4, 16); inputStructure.data8 = SMC_CMD_WRITE_BYTES; inputStructure.keyInfo.dataSize = val->dataSize; memcpy(inputStructure.bytes, val->bytes, sizeof(val->bytes)); result = SMCCall(conn, KERNEL_INDEX_SMC, &inputStructure, &outputStructure); if (result != kIOReturnSuccess) return result; return kIOReturnSuccess; }