/* * Copyright (c) 2001 Apple Computer, Inc. All rights reserved. * * @APPLE_LICENSE_HEADER_START@ * * The contents of this file constitute Original Code as defined in and * are subject to the Apple Public Source License Version 1.1 (the * "License"). You may not use this file except in compliance with the * License. Please obtain a copy of the License at * http://www.apple.com/publicsource and read it before using this file. * * This Original Code and all software distributed under the License are * distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY KIND, EITHER * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT. Please see the * License for the specific language governing rights and limitations * under the License. * * @APPLE_LICENSE_HEADER_END@ */ #include #include #include #include "IOPMLib.h" #include "IOPMLibPrivate.h" #include #include #include #include #include #define kIOPMPrefsPath CFSTR("com.apple.PowerManagement.xml") #define kIOPMAppName CFSTR("PowerManagement configd") /* Default Energy Saver settings for IOPMCopyPMPreferences * * AC */ #define kACMinutesToDim 5 #define kACMinutesToSpin 5 #define kACMinutesToSleep 20 #define kACWakeOnRing 0 #define kACAutomaticRestart 0 #define kACWakeOnLAN 1 #define kACReduceProcessorSpeed 0 #define kACDynamicPowerStep 0 /* * Battery */ #define kBatteryMinutesToDim 5 #define kBatteryMinutesToSpin 5 #define kBatteryMinutesToSleep 5 #define kBatteryWakeOnRing 0 #define kBatteryAutomaticRestart 0 #define kBatteryWakeOnLAN 0 #define kBatteryReduceProcessorSpeed 0 #define kBatteryDynamicPowerStep 1 /* Keys for Cheetah Energy Settings shim */ #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 /* IOPMAggressivenessFactors * * The form of data that the kernel understands. */ typedef struct { unsigned int fMinutesToDim; unsigned int fMinutesToSpin; unsigned int fMinutesToSleep; unsigned int fWakeOnLAN; unsigned int fWakeOnRing; unsigned int fAutomaticRestart; // FIXME: Got to add support for timed shutdown/restart /* unsigned int SleepAtTime; unsigned int WakeAtTime; unsigned int ShutdownAtTime; unsigned int PowerOnAtTime; */ } 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); /* * Populate default battery dictionary */ 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); /* * Populate default AC dictionary */ 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); /* * Stuff the default values into the "system settings" */ 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); // Search for PMU IOServiceGetMatchingServices(masterPort, IOServiceNameMatching("ApplePMU"), &tmp); if(tmp) { cudaPMU = IOIteratorNext(tmp); //if(cudaPMU) magicCookie = kAppleMagicPMUCookie; IOObjectRelease(tmp); } // No? Search for Cuda if(!cudaPMU) { IOServiceGetMatchingServices(masterPort, IOServiceNameMatching("AppleCuda"), &tmp); if(tmp) { cudaPMU = IOIteratorNext(tmp); //if(cudaPMU) magicCookie = kAppleMagicCudaCookie; 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); // Wake On Ring 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); } // Automatic Restart On Power Loss, aka FileServer mode 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); } /* PowerStep and Reduce Processor Speed are handled by a separate configd plugin that's watching the SCDynamicStore key State:/IOKit/PowerManagement/CurrentSettings. Changes to the settings notify the configd plugin, which then activates th processor speed settings. Note that IOPMActivatePMPreference updates that key in the SCDynamicStore when we activate new settings. */ return 0; } /* For internal use only */ 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; /* * Extract battery settings into s->battery */ // dim val = (CFNumberRef)CFDictionaryGetValue(p, CFSTR(kIOPMDisplaySleepKey)); if (val) { CFNumberGetValue(val, kCFNumberSInt32Type, &(agg->fMinutesToDim)); } // spin down val = CFDictionaryGetValue(p, CFSTR(kIOPMDiskSleepKey)); if (val) { CFNumberGetValue(val, kCFNumberSInt32Type, &(agg->fMinutesToSpin)); } // sleep val = CFDictionaryGetValue(p, CFSTR(kIOPMSystemSleepKey)); if (val) { CFNumberGetValue(val, kCFNumberSInt32Type, &(agg->fMinutesToSleep)); } // Wake On Magic Packet val = CFDictionaryGetValue(p, CFSTR(kIOPMWakeOnLANKey)); if (val) { CFNumberGetValue(val, kCFNumberSInt32Type, &(agg->fWakeOnLAN)); } // Wake On Ring val = CFDictionaryGetValue(p, CFSTR(kIOPMWakeOnRingKey)); if (val) { CFNumberGetValue(val, kCFNumberSInt32Type, &(agg->fWakeOnRing)); } // AutomaticRestartOnPowerLoss val = CFDictionaryGetValue(p, CFSTR(kIOPMRestartOnPowerLossKey)); if (val) { CFNumberGetValue(val, kCFNumberSInt32Type, &(agg->fAutomaticRestart)); } return 0; } //--------------------------------------------------------------------------- // Searches the IOKit registry and return an interface object with the // given BSD interface name, i.e. "en0". // Taken from Admin framework 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); // Caller must release object by calling IOObjectRelease(). return obj; } /* supportsWakeForNetworkAdministrativeAccess "borrowed" from Admin framework */ 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); // NSLog(@"IONetworkGetPacketFiltersMask failed with error %i", kr); if(filters & kIOEthernetWakeOnMagicPacket) theResult = 1; IONetworkClose(connect); } //else NSLog(@"IONetworkOpen failed with error error %i", kr); IOObjectRelease(netif); } //else NSLog(@"getNetworkInterfaceWithBSDName returned nil"); CFRelease( bsdName ); } //else NSLog(@"IORegistryEntryCreateCFProperty returned nil name"); } //else NSLog(@"IORegistryEntryGetPath failed with error error %i", kr); IOObjectRelease(obj); if(theResult) break; } IOObjectRelease(iter); } //else NSLog(@"IOServiceGetMatchingServices returned nil iterator (error=%i)", kr); 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; } // reduce processor speed if(CFEqual(f, CFSTR(kIOPMReduceSpeedKey))) { if(!supportedFeatures) return kIOReturnError; if(CFDictionaryGetValue(supportedFeatures, f)) ret = kIOReturnSuccess; else ret = kIOReturnError; goto IOPMFunctionIsAvailable_exitpoint; } // dynamic powerstep if(CFEqual(f, CFSTR(kIOPMDynamicPowerStepKey))) { if(!supportedFeatures) return kIOReturnError; if(CFDictionaryGetValue(supportedFeatures, f)) ret = kIOReturnSuccess; else ret = kIOReturnError; goto IOPMFunctionIsAvailable_exitpoint; } // wake on magic packet if(CFEqual(f, CFSTR(kIOPMWakeOnLANKey))) { ret = supportsWakeForNetworkAdministrativeAccess(); goto IOPMFunctionIsAvailable_exitpoint; } if(CFEqual(f, CFSTR(kIOPMWakeOnRingKey))) { // Check for WakeOnRing property under PMU 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; } // restart on power loss if(CFEqual(f, CFSTR(kIOPMRestartOnPowerLossKey))) { registry_entry = getCudaPMURef(); // Check for fileserver property under PMU 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; } /*** * removeIrrelevantPMProperties * * Prunes unsupported properties from the energy dictionary. * e.g. If your machine doesn't have a modem, this removes the Wake On Ring property. ***/ 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; /* * Remove battery dictionary on desktop machines */ IOMasterPort(bootstrap_port,&masterPort); IOPMCopyBatteryInfo(masterPort, &tmp); if(!tmp) { // no batteries CFDictionaryRemoveValue(energyPrefs, CFSTR(kIOPMBatteryPowerKey)); } else { // Batteries are present, cleanup the dummy battery array CFRelease(tmp); } /* * Remove features when not supported - Wake On Administrative Access, Dynamic Speed Step, etc. */ 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); // For each CFDictionary at the top level (battery, AC) 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); // For each specific property within each dictionary while(--dict_count >= 0) if( kIOReturnError == IOPMFunctionIsAvailable((CFStringRef)dict_keys[dict_count]) ) { // If the property isn't supported, remove it CFDictionaryRemoveValue(this_profile, (CFStringRef)dict_keys[dict_count]); } free(dict_keys); free(dict_vals); } free(profile_keys); free(profile_vals); IOObjectRelease(masterPort); return; } /*** * getCheetahPumaEnergySettings * * Reads the old Energy Saver preferences file from /Library/Preferences/com.apple.PowerManagement.xml * ***/ 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; // success //return 0; // failure } 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 ); // Attempt to read battery & AC settings batterySettings = (CFDictionaryRef)SCPreferencesGetValue(energyPrefs, CFSTR(kIOPMBatteryPowerKey)); ACSettings = (CFDictionaryRef)SCPreferencesGetValue(energyPrefs, CFSTR(kIOPMACPowerKey)); // If com.apple.PowerManagement.xml opened correctly, read data from it if( batterySettings || ACSettings ) { if(batterySettings) CFDictionaryAddValue(energyDict, CFSTR(kIOPMBatteryPowerKey), batterySettings); if(ACSettings) CFDictionaryAddValue(energyDict, CFSTR(kIOPMACPowerKey), ACSettings); } else { // Fill dictionaries with default settings getDefaultEnergySettings(energyDict); // If Cheetah settings exist, use those 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; // Activate settings by sending them to the kernel agg = (IOPMAggressivenessFactors *)malloc(sizeof(IOPMAggressivenessFactors)); getAggressivenessFactorsFromProfile(SystemProfiles, profile, agg); sendEnergySettingsToKernel(agg); free(agg); // Put the new settings in the SCDynamicStore for interested apps 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 there isn't currently a value for kIOPMDynamicStoreSettingsKey // or the current value is different than the new value if( !activePMPrefs || (newPMPrefs && !CFEqual(activePMPrefs, newPMPrefs)) ) { // Then set the kIOPMDynamicStoreSettingsKey to the new value 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