#include <SystemConfiguration/SystemConfiguration.h>
#include <CoreFoundation/CoreFoundation.h>
#include <IOKit/pwr_mgt/IOPM.h>
#include "IOPMLib.h"
#include "IOPMLibPrivate.h"
#include <IOKit/network/IOEthernetController.h>
#include <IOKit/IOKitLib.h>
#include <IOKit/IOBSD.h>
#include <IOKit/network/IONetworkLib.h>
#include <IOKit/network/IOEthernetInterface.h>
#define kIOPMPrefsPath CFSTR("com.apple.PowerManagement.xml")
#define kIOPMAppName CFSTR("PowerManagement configd")
#define kACMinutesToDim 5
#define kACMinutesToSpin 5
#define kACMinutesToSleep 20
#define kACWakeOnRing 0
#define kACAutomaticRestart 0
#define kACWakeOnLAN 1
#define kACReduceProcessorSpeed 0
#define kACDynamicPowerStep 0
#define kBatteryMinutesToDim 5
#define kBatteryMinutesToSpin 5
#define kBatteryMinutesToSleep 5
#define kBatteryWakeOnRing 0
#define kBatteryAutomaticRestart 0
#define kBatteryWakeOnLAN 0
#define kBatteryReduceProcessorSpeed 0
#define kBatteryDynamicPowerStep 1
#define kCheetahDimKey CFSTR("MinutesUntilDisplaySleeps")
#define kCheetahDiskKey CFSTR("MinutesUntilHardDiskSleeps")
#define kCheetahSleepKey CFSTR("MinutesUntilSystemSleeps")
#define kCheetahRestartOnPowerLossKey CFSTR("RestartOnPowerLoss")
#define kCheetahWakeForNetworkAccessKey CFSTR("WakeForNetworkAdministrativeAccess")
#define kCheetahWakeOnRingKey CFSTR("WakeOnRing")
#define kApplePMUUserClientMagicCookie 0x0101BEEF
typedef struct {
unsigned int fMinutesToDim;
unsigned int fMinutesToSpin;
unsigned int fMinutesToSleep;
unsigned int fWakeOnLAN;
unsigned int fWakeOnRing;
unsigned int fAutomaticRestart;
} IOPMAggressivenessFactors;
static IOReturn IOPMFunctionIsAvailable(CFStringRef);
static int getDefaultEnergySettings(CFMutableDictionaryRef sys)
{
CFMutableDictionaryRef batt = NULL;
CFMutableDictionaryRef ac = NULL;
int i;
CFNumberRef val;
CFStringRef key;
batt = CFDictionaryCreateMutable(kCFAllocatorDefault,
0, &kCFTypeDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks);
ac = CFDictionaryCreateMutable(kCFAllocatorDefault,
0, &kCFTypeDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks);
i = kBatteryMinutesToDim;
key = CFSTR(kIOPMDisplaySleepKey);
val = CFNumberCreate(kCFAllocatorDefault, kCFNumberSInt32Type, &i);
CFDictionaryAddValue(batt, key, val);
CFRelease(val);
i = kBatteryMinutesToSpin;
key = CFSTR(kIOPMDiskSleepKey);
val = CFNumberCreate(kCFAllocatorDefault, kCFNumberSInt32Type, &i);
CFDictionaryAddValue(batt, key, val);
CFRelease(val);
i = kBatteryMinutesToSleep;
key = CFSTR(kIOPMSystemSleepKey);
val = CFNumberCreate(kCFAllocatorDefault, kCFNumberSInt32Type, &i);
CFDictionaryAddValue(batt, key, val);
CFRelease(val);
i = kBatteryWakeOnRing;
key = CFSTR(kIOPMWakeOnRingKey);
val = CFNumberCreate(kCFAllocatorDefault, kCFNumberSInt32Type, &i);
CFDictionaryAddValue(batt, key, val);
CFRelease(val);
i = kBatteryAutomaticRestart;
key = CFSTR(kIOPMRestartOnPowerLossKey);
val = CFNumberCreate(kCFAllocatorDefault, kCFNumberSInt32Type, &i);
CFDictionaryAddValue(batt, key, val);
CFRelease(val);
i = kBatteryWakeOnLAN;
key = CFSTR(kIOPMWakeOnLANKey);
val = CFNumberCreate(kCFAllocatorDefault, kCFNumberSInt32Type, &i);
CFDictionaryAddValue(batt, key, val);
CFRelease(val);
i = kBatteryReduceProcessorSpeed;
key = CFSTR(kIOPMReduceSpeedKey);
val = CFNumberCreate(kCFAllocatorDefault, kCFNumberSInt32Type, &i);
CFDictionaryAddValue(batt, key, val);
CFRelease(val);
i = kBatteryDynamicPowerStep;
key = CFSTR(kIOPMDynamicPowerStepKey);
val = CFNumberCreate(kCFAllocatorDefault, kCFNumberSInt32Type, &i);
CFDictionaryAddValue(batt, key, val);
CFRelease(val);
i = kACMinutesToDim;
key = CFSTR(kIOPMDisplaySleepKey);
val = CFNumberCreate(kCFAllocatorDefault, kCFNumberSInt32Type, &i);
CFDictionaryAddValue(ac, key, val);
CFRelease(val);
i = kACMinutesToSpin;
key = CFSTR(kIOPMDiskSleepKey);
val = CFNumberCreate(kCFAllocatorDefault, kCFNumberSInt32Type, &i);
CFDictionaryAddValue(ac, key, val);
CFRelease(val);
i = kACMinutesToSleep;
key = CFSTR(kIOPMSystemSleepKey);
val = CFNumberCreate(kCFAllocatorDefault, kCFNumberSInt32Type, &i);
CFDictionaryAddValue(ac, key, val);
CFRelease(val);
i = kACWakeOnRing;
key = CFSTR(kIOPMWakeOnRingKey);
val = CFNumberCreate(kCFAllocatorDefault, kCFNumberSInt32Type, &i);
CFDictionaryAddValue(ac, key, val);
CFRelease(val);
i = kACAutomaticRestart;
key = CFSTR(kIOPMRestartOnPowerLossKey);
val = CFNumberCreate(kCFAllocatorDefault, kCFNumberSInt32Type, &i);
CFDictionaryAddValue(ac, key, val);
CFRelease(val);
i = kACWakeOnLAN;
key = CFSTR(kIOPMWakeOnLANKey);
val = CFNumberCreate(kCFAllocatorDefault, kCFNumberSInt32Type, &i);
CFDictionaryAddValue(ac, key, val);
CFRelease(val);
i = kACReduceProcessorSpeed;
key = CFSTR(kIOPMReduceSpeedKey);
val = CFNumberCreate(kCFAllocatorDefault, kCFNumberSInt32Type, &i);
CFDictionaryAddValue(ac, key, val);
CFRelease(val);
i = kACDynamicPowerStep;
key = CFSTR(kIOPMDynamicPowerStepKey);
val = CFNumberCreate(kCFAllocatorDefault, kCFNumberSInt32Type, &i);
CFDictionaryAddValue(ac, key, val);
CFRelease(val);
CFDictionaryAddValue(sys, CFSTR(kIOPMBatteryPowerKey), batt);
CFDictionaryAddValue(sys, CFSTR(kIOPMACPowerKey), ac);
CFRelease(batt);
CFRelease(ac);
return 0;
}
static io_registry_entry_t getCudaPMURef(void)
{
io_iterator_t tmp = NULL;
io_registry_entry_t cudaPMU = NULL;
mach_port_t masterPort;
IOMasterPort(bootstrap_port,&masterPort);
IOServiceGetMatchingServices(masterPort, IOServiceNameMatching("ApplePMU"), &tmp);
if(tmp) {
cudaPMU = IOIteratorNext(tmp);
IOObjectRelease(tmp);
}
if(!cudaPMU) {
IOServiceGetMatchingServices(masterPort, IOServiceNameMatching("AppleCuda"), &tmp);
if(tmp) {
cudaPMU = IOIteratorNext(tmp);
IOObjectRelease(tmp);
}
}
return cudaPMU;
}
static int sendEnergySettingsToKernel(IOPMAggressivenessFactors *p)
{
mach_port_t master_device_port;
io_connect_t PM_connection = NULL;
kern_return_t kr;
IOReturn err, ret;
int type;
CFDataRef on;
io_registry_entry_t cudaPMU;
io_connect_t connection;
UInt32 i;
kr = IOMasterPort(bootstrap_port,&master_device_port);
if ( kr == kIOReturnSuccess )
{
PM_connection = IOPMFindPowerManagement(master_device_port);
if ( !PM_connection )
{
printf("IOPMconfigd: Error connecting to Power Management\n"); fflush(stdout);
return -1;
}
}
type = kPMMinutesToDim;
err = IOPMSetAggressiveness(PM_connection, type, p->fMinutesToDim);
type = kPMMinutesToSpinDown;
err = IOPMSetAggressiveness(PM_connection, type, p->fMinutesToSpin);
type = kPMMinutesToSleep;
err = IOPMSetAggressiveness(PM_connection, type, p->fMinutesToSleep);
if(kIOReturnSuccess == IOPMFunctionIsAvailable(CFSTR(kIOPMWakeOnLANKey)))
{
type = kPMEthernetWakeOnLANSettings;
err = IOPMSetAggressiveness(PM_connection, type, p->fWakeOnLAN);
}
IOServiceClose(PM_connection);
if(kIOReturnSuccess == IOPMFunctionIsAvailable(CFSTR(kIOPMWakeOnRingKey)))
{
cudaPMU = getCudaPMURef();
ret = IOServiceOpen((io_service_t)cudaPMU, mach_task_self(), kApplePMUUserClientMagicCookie, &connection);
if(p->fWakeOnRing) i = 0xFFFFFFFF;
else i = 0x0;
on = CFDataCreate(kCFAllocatorDefault, (void *)&i, 4);
ret = IOConnectSetCFProperty(connection, CFSTR("WakeOnRing"), on);
CFRelease(on);
IOServiceClose(connection);
IOObjectRelease(cudaPMU);
}
if(kIOReturnSuccess == IOPMFunctionIsAvailable(CFSTR(kIOPMRestartOnPowerLossKey)))
{
cudaPMU = getCudaPMURef();
ret = IOServiceOpen((io_service_t)cudaPMU, mach_task_self(), kApplePMUUserClientMagicCookie, &connection);
if(p->fAutomaticRestart) i = 0xFFFFFFFF;
else i = 0x0;
on = CFDataCreate(kCFAllocatorDefault, (void *)&i, 4);
ret = IOConnectSetCFProperty(connection, CFSTR("FileServer"), on);
CFRelease(on);
IOServiceClose(connection);
IOObjectRelease(cudaPMU);
}
return 0;
}
static int getAggressivenessFactorsFromProfile(CFDictionaryRef System, CFStringRef prof, IOPMAggressivenessFactors *agg)
{
CFDictionaryRef p = NULL;
CFNumberRef val;
if( !(p = CFDictionaryGetValue(System, prof)) )
{
printf("IOPMconfigd: error getting agg factors from profile!\n");
return -1;
}
if(!agg) return -1;
val = (CFNumberRef)CFDictionaryGetValue(p, CFSTR(kIOPMDisplaySleepKey));
if (val)
{
CFNumberGetValue(val, kCFNumberSInt32Type, &(agg->fMinutesToDim));
}
val = CFDictionaryGetValue(p, CFSTR(kIOPMDiskSleepKey));
if (val)
{
CFNumberGetValue(val, kCFNumberSInt32Type, &(agg->fMinutesToSpin));
}
val = CFDictionaryGetValue(p, CFSTR(kIOPMSystemSleepKey));
if (val)
{
CFNumberGetValue(val, kCFNumberSInt32Type, &(agg->fMinutesToSleep));
}
val = CFDictionaryGetValue(p, CFSTR(kIOPMWakeOnLANKey));
if (val)
{
CFNumberGetValue(val, kCFNumberSInt32Type, &(agg->fWakeOnLAN));
}
val = CFDictionaryGetValue(p, CFSTR(kIOPMWakeOnRingKey));
if (val)
{
CFNumberGetValue(val, kCFNumberSInt32Type, &(agg->fWakeOnRing));
}
val = CFDictionaryGetValue(p, CFSTR(kIOPMRestartOnPowerLossKey));
if (val)
{
CFNumberGetValue(val, kCFNumberSInt32Type, &(agg->fAutomaticRestart));
}
return 0;
}
static io_object_t getNetworkInterfaceWithBSDName( const char * name )
{
kern_return_t kr;
io_iterator_t ite;
io_object_t obj = 0;
mach_port_t masterPort;
IOMasterPort(bootstrap_port, &masterPort);
kr = IOServiceGetMatchingServices( masterPort,
IOBSDNameMatching(masterPort, 0, name),
&ite);
if ( (kr != kIOReturnSuccess) || (ite == 0) ) return 0;
obj = IOIteratorNext(ite);
IORegistryDisposeEnumerator(ite);
return obj;
}
static IOReturn supportsWakeForNetworkAdministrativeAccess(void)
{
int theResult = 0;
io_iterator_t iter;
kern_return_t kr;
static mach_port_t masterPort = NULL;
if(!masterPort) IOMasterPort(bootstrap_port, &masterPort);
kr = IOServiceGetMatchingServices(masterPort, IOServiceMatching(kIOEthernetInterfaceClass), &iter);
if(iter) {
io_object_t obj;
char path[512];
while((obj = IOIteratorNext(iter))) {
kr = IORegistryEntryGetPath((io_registry_entry_t)obj, kIOServicePlane, path);
if(kr == KERN_SUCCESS) {
CFStringRef bsdName = IORegistryEntryCreateCFProperty(obj, CFSTR(kIOBSDNameKey), kCFAllocatorDefault, 0);
if(bsdName) {
io_object_t netif;
netif = getNetworkInterfaceWithBSDName(CFStringGetCStringPtr(bsdName, kCFStringEncodingMacRoman));
if(netif) {
io_connect_t connect;
kr = IONetworkOpen(netif, &connect);
if(kr == KERN_SUCCESS) {
UInt32 filters;
kr = IONetworkGetPacketFiltersMask(connect, kIOEthernetWakeOnLANFilterGroup, &filters, kIONetworkSupportedPacketFilters);
if(kr != KERN_SUCCESS);
if(filters & kIOEthernetWakeOnMagicPacket) theResult = 1;
IONetworkClose(connect);
}
IOObjectRelease(netif);
} CFRelease( bsdName );
} }
IOObjectRelease(obj);
if(theResult) break;
}
IOObjectRelease(iter);
}
if(theResult) return kIOReturnSuccess;
else return kIOReturnError;
}
static IOReturn IOPMFunctionIsAvailable(CFStringRef f)
{
CFDictionaryRef supportedFeatures = NULL;
CFPropertyListRef izzo;
io_registry_entry_t registry_entry;
io_iterator_t tmp;
mach_port_t masterPort;
IOReturn ret;
IOMasterPort(bootstrap_port, &masterPort);
IOServiceGetMatchingServices(masterPort, IOServiceNameMatching("IOPMrootDomain"), &tmp);
registry_entry = IOIteratorNext(tmp);
IOObjectRelease(tmp);
supportedFeatures = IORegistryEntryCreateCFProperty(registry_entry, CFSTR("Supported Features"),
kCFAllocatorDefault, NULL);
IOObjectRelease(registry_entry);
if(CFEqual(f, CFSTR(kIOPMDisplaySleepKey))
|| CFEqual(f, CFSTR(kIOPMSystemSleepKey))
|| CFEqual(f, CFSTR(kIOPMDiskSleepKey)))
{
ret = kIOReturnSuccess;
goto IOPMFunctionIsAvailable_exitpoint;
}
if(CFEqual(f, CFSTR(kIOPMReduceSpeedKey)))
{
if(!supportedFeatures) return kIOReturnError;
if(CFDictionaryGetValue(supportedFeatures, f))
ret = kIOReturnSuccess;
else ret = kIOReturnError;
goto IOPMFunctionIsAvailable_exitpoint;
}
if(CFEqual(f, CFSTR(kIOPMDynamicPowerStepKey)))
{
if(!supportedFeatures) return kIOReturnError;
if(CFDictionaryGetValue(supportedFeatures, f))
ret = kIOReturnSuccess;
else ret = kIOReturnError;
goto IOPMFunctionIsAvailable_exitpoint;
}
if(CFEqual(f, CFSTR(kIOPMWakeOnLANKey)))
{
ret = supportsWakeForNetworkAdministrativeAccess();
goto IOPMFunctionIsAvailable_exitpoint;
}
if(CFEqual(f, CFSTR(kIOPMWakeOnRingKey)))
{
registry_entry = getCudaPMURef();
if((izzo = IORegistryEntryCreateCFProperty(registry_entry, CFSTR("WakeOnRing"),
kCFAllocatorDefault, NULL)))
{
CFRelease(izzo);
IOObjectRelease(registry_entry);
ret = kIOReturnSuccess;
} else {
IOObjectRelease(registry_entry);
ret = kIOReturnError;
}
goto IOPMFunctionIsAvailable_exitpoint;
}
if(CFEqual(f, CFSTR(kIOPMRestartOnPowerLossKey)))
{
registry_entry = getCudaPMURef();
if((izzo = IORegistryEntryCreateCFProperty(registry_entry, CFSTR("FileServer"),
kCFAllocatorDefault, NULL)))
{
CFRelease(izzo);
IOObjectRelease(registry_entry);
ret = kIOReturnSuccess;
} else {
IOObjectRelease(registry_entry);
ret = kIOReturnError;
}
goto IOPMFunctionIsAvailable_exitpoint;
}
IOPMFunctionIsAvailable_exitpoint:
if(supportedFeatures) CFRelease(supportedFeatures);
IOObjectRelease(masterPort);
return ret;
}
static void IOPMRemoveIrrelevantProperties(CFMutableDictionaryRef energyPrefs)
{
CFArrayRef tmp = NULL;
mach_port_t masterPort;
int profile_count = 0;
int dict_count = 0;
CFStringRef *profile_keys = NULL;
CFDictionaryRef *profile_vals = NULL;
CFStringRef *dict_keys = NULL;
CFDictionaryRef *dict_vals = NULL;
CFMutableDictionaryRef this_profile;
IOMasterPort(bootstrap_port,&masterPort);
IOPMCopyBatteryInfo(masterPort, &tmp);
if(!tmp)
{
CFDictionaryRemoveValue(energyPrefs, CFSTR(kIOPMBatteryPowerKey));
} else {
CFRelease(tmp);
}
profile_count = CFDictionaryGetCount(energyPrefs);
profile_keys = (CFStringRef *)malloc(sizeof(CFStringRef) * profile_count);
profile_vals = (CFDictionaryRef *)malloc(sizeof(CFDictionaryRef) * profile_count);
if(!profile_keys || !profile_vals) return;
CFDictionaryGetKeysAndValues(energyPrefs, (void **)profile_keys, (void **)profile_vals);
while(--profile_count >= 0)
{
this_profile = (CFMutableDictionaryRef)CFDictionaryGetValue(energyPrefs, profile_keys[profile_count]);
dict_count = CFDictionaryGetCount(this_profile);
dict_keys = (CFStringRef *)malloc(sizeof(CFStringRef) * dict_count);
dict_vals = (CFDictionaryRef *)malloc(sizeof(CFDictionaryRef) * dict_count);
CFDictionaryGetKeysAndValues(this_profile, (void **)dict_keys, (void **)dict_vals);
while(--dict_count >= 0)
if( kIOReturnError == IOPMFunctionIsAvailable((CFStringRef)dict_keys[dict_count]) )
{
CFDictionaryRemoveValue(this_profile, (CFStringRef)dict_keys[dict_count]);
}
free(dict_keys);
free(dict_vals);
}
free(profile_keys);
free(profile_vals);
IOObjectRelease(masterPort);
return;
}
static int getCheetahPumaEnergySettings(CFMutableDictionaryRef energyPrefs)
{
SCPreferencesRef CheetahPrefs = NULL;
CFMutableDictionaryRef s = NULL;
CFNumberRef n;
CFBooleanRef b;
CheetahPrefs = SCPreferencesCreate (kCFAllocatorDefault,
CFSTR("I/O Kit PM Library"),
CFSTR("/Library/Preferences/com.apple.PowerManagement.plist"));
if(!CheetahPrefs) return 0;
s = (CFMutableDictionaryRef)CFDictionaryGetValue(energyPrefs, CFSTR(kIOPMBatteryPowerKey));
n = (CFNumberRef)SCPreferencesGetValue(CheetahPrefs, kCheetahDimKey);
if(n) CFDictionarySetValue(s, CFSTR(kIOPMDisplaySleepKey), n);
n = (CFNumberRef)SCPreferencesGetValue(CheetahPrefs, kCheetahDiskKey);
if(n) CFDictionarySetValue(s, CFSTR(kIOPMDiskSleepKey), n);
n = (CFNumberRef)SCPreferencesGetValue(CheetahPrefs, kCheetahSleepKey);
if(n) CFDictionarySetValue(s, CFSTR(kIOPMSystemSleepKey), n);
b = (CFBooleanRef)SCPreferencesGetValue(CheetahPrefs, kCheetahRestartOnPowerLossKey);
if(b) CFDictionarySetValue(s, CFSTR(kIOPMRestartOnPowerLossKey), b);
b = (CFBooleanRef)SCPreferencesGetValue(CheetahPrefs, kCheetahWakeForNetworkAccessKey);
if(b) CFDictionarySetValue(s, CFSTR(kIOPMWakeOnLANKey), b);
b = (CFBooleanRef)SCPreferencesGetValue(CheetahPrefs, kCheetahWakeOnRingKey);
if(b) CFDictionarySetValue(s, CFSTR(kIOPMWakeOnRingKey), b);
CFDictionarySetValue(energyPrefs, CFSTR(kIOPMBatteryPowerKey), s);
s = (CFMutableDictionaryRef)CFDictionaryGetValue(energyPrefs, CFSTR(kIOPMACPowerKey));
n = (CFNumberRef)SCPreferencesGetValue(CheetahPrefs, kCheetahDimKey);
if(n) CFDictionarySetValue(s, CFSTR(kIOPMDisplaySleepKey), n);
n = (CFNumberRef)SCPreferencesGetValue(CheetahPrefs, kCheetahDiskKey);
if(n) CFDictionarySetValue(s, CFSTR(kIOPMDiskSleepKey), n);
n = (CFNumberRef)SCPreferencesGetValue(CheetahPrefs, kCheetahSleepKey);
if(n) CFDictionarySetValue(s, CFSTR(kIOPMSystemSleepKey), n);
b = (CFBooleanRef)SCPreferencesGetValue(CheetahPrefs, kCheetahRestartOnPowerLossKey);
if(b) CFDictionarySetValue(s, CFSTR(kIOPMRestartOnPowerLossKey), b);
b = (CFBooleanRef)SCPreferencesGetValue(CheetahPrefs, kCheetahWakeForNetworkAccessKey);
if(b) CFDictionarySetValue(s, CFSTR(kIOPMWakeOnLANKey), b);
b = (CFBooleanRef)SCPreferencesGetValue(CheetahPrefs, kCheetahWakeOnRingKey);
if(b) CFDictionarySetValue(s, CFSTR(kIOPMWakeOnRingKey), b);
CFDictionarySetValue(energyPrefs, CFSTR(kIOPMACPowerKey), s);
CFRelease(CheetahPrefs);
return 1; }
extern CFMutableDictionaryRef IOPMCopyPMPreferences(void)
{
CFMutableDictionaryRef energyDict = NULL;
SCPreferencesRef energyPrefs = NULL;
CFDictionaryRef batterySettings = NULL;
CFDictionaryRef ACSettings = NULL;
energyDict = CFDictionaryCreateMutable(kCFAllocatorDefault, 0,
&kCFTypeDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks);
energyPrefs = SCPreferencesCreate( kCFAllocatorDefault, kIOPMAppName, kIOPMPrefsPath );
batterySettings = (CFDictionaryRef)SCPreferencesGetValue(energyPrefs, CFSTR(kIOPMBatteryPowerKey));
ACSettings = (CFDictionaryRef)SCPreferencesGetValue(energyPrefs, CFSTR(kIOPMACPowerKey));
if( batterySettings || ACSettings )
{
if(batterySettings)
CFDictionaryAddValue(energyDict, CFSTR(kIOPMBatteryPowerKey), batterySettings);
if(ACSettings)
CFDictionaryAddValue(energyDict, CFSTR(kIOPMACPowerKey), ACSettings);
} else {
getDefaultEnergySettings(energyDict);
getCheetahPumaEnergySettings(energyDict);
}
CFRelease(energyPrefs);
IOPMRemoveIrrelevantProperties(energyDict);
return energyDict;
}
extern IOReturn IOPMActivatePMPreference(CFDictionaryRef SystemProfiles, CFStringRef profile)
{
IOPMAggressivenessFactors *agg = NULL;
CFDictionaryRef activePMPrefs = NULL;
CFDictionaryRef newPMPrefs = NULL;
SCDynamicStoreRef dynamic_store = NULL;
agg = (IOPMAggressivenessFactors *)malloc(sizeof(IOPMAggressivenessFactors));
getAggressivenessFactorsFromProfile(SystemProfiles, profile, agg);
sendEnergySettingsToKernel(agg);
free(agg);
dynamic_store = SCDynamicStoreCreate(kCFAllocatorDefault,
CFSTR("IOKit User Library"),
NULL, NULL);
if(dynamic_store == NULL) return kIOReturnError;
activePMPrefs = (CFDictionaryRef)SCDynamicStoreCopyValue(dynamic_store,
CFSTR(kIOPMDynamicStoreSettingsKey));
newPMPrefs = CFDictionaryGetValue(SystemProfiles, profile);
if( !activePMPrefs || (newPMPrefs && !CFEqual(activePMPrefs, newPMPrefs)) )
{
SCDynamicStoreSetValue(dynamic_store,
CFSTR(kIOPMDynamicStoreSettingsKey),
newPMPrefs);
}
if(activePMPrefs) CFRelease(activePMPrefs);
CFRelease(dynamic_store);
return kIOReturnSuccess;
}
extern IOReturn IOPMSetPMPreferences(CFDictionaryRef ESPrefs)
{
SCPreferencesRef energyPrefs = NULL;
int i;
int dict_count = 0;
CFStringRef *dict_keys;
CFDictionaryRef *dict_vals;
energyPrefs = SCPreferencesCreate( kCFAllocatorDefault, kIOPMAppName, kIOPMPrefsPath );
if(!energyPrefs) return kIOReturnError;
dict_count = CFDictionaryGetCount(ESPrefs);
dict_keys = (CFStringRef *)malloc(sizeof(CFStringRef) * dict_count);
dict_vals = (CFDictionaryRef *)malloc(sizeof(CFDictionaryRef) * dict_count);
CFDictionaryGetKeysAndValues(ESPrefs, (void **)dict_keys, (void **)dict_vals);
if(!dict_keys || !dict_vals) return kIOReturnError;
for(i=0; i<dict_count; i++)
{
if(!SCPreferencesSetValue(energyPrefs, dict_keys[i], dict_vals[i]))
{
return kIOReturnError;
}
}
SCPreferencesCommitChanges(energyPrefs);
SCPreferencesApplyChanges(energyPrefs);
return kIOReturnSuccess;
}