IOPMRepeatingPower.c [plain text]
#include <SystemConfiguration/SystemConfiguration.h>
#include <SystemConfiguration/SCValidation.h>
#include <CoreFoundation/CoreFoundation.h>
#include <IOKit/IOKitLib.h>
#include <IOKit/pwr_mgt/IOPMLib.h>
#include <IOKit/pwr_mgt/IOPMLibPrivate.h>
#define kIOPMRepeatingAppName "Repeating"
static bool is_valid_repeating_dictionary(CFDictionaryRef event)
{
CFNumberRef tmp_num;
CFStringRef tmp_str;
int val;
if(NULL == event) return true;
if(!isA_CFDictionary(event)) return false;
tmp_num = (CFNumberRef)CFDictionaryGetValue(event, CFSTR(kIOPMPowerEventTimeKey));
if(!isA_CFNumber(tmp_num)) return false;
CFNumberGetValue(tmp_num, kCFNumberIntType, &val);
if(val < 0 || val >= (24*60)) return false;
tmp_num = (CFNumberRef)CFDictionaryGetValue(event, CFSTR(kIOPMDaysOfWeekKey));
if(!isA_CFNumber(tmp_num)) return false;
tmp_str = (CFStringRef)CFDictionaryGetValue(event, CFSTR(kIOPMPowerEventTypeKey));
if(!isA_CFString(tmp_str)) return false;
if( (kCFCompareEqualTo != CFStringCompare(tmp_str, CFSTR(kIOPMAutoSleep), 0)) &&
(kCFCompareEqualTo != CFStringCompare(tmp_str, CFSTR(kIOPMAutoShutdown), 0)) &&
(kCFCompareEqualTo != CFStringCompare(tmp_str, CFSTR(kIOPMAutoWakeOrPowerOn), 0)) &&
(kCFCompareEqualTo != CFStringCompare(tmp_str, CFSTR(kIOPMAutoPowerOn), 0)) &&
(kCFCompareEqualTo != CFStringCompare(tmp_str, CFSTR(kIOPMAutoWake), 0)) )
{
return false;
}
return true;
}
extern IOReturn IOPMScheduleRepeatingPowerEvent(CFDictionaryRef events)
{
SCPreferencesRef prefs = 0;
IOReturn ret = kIOReturnError;
CFDictionaryRef repeating_on, repeating_off;
if(!isA_CFDictionary(events)) return kIOReturnBadArgument;
repeating_on = CFDictionaryGetValue(events, CFSTR(kIOPMRepeatingPowerOnKey));
repeating_off = CFDictionaryGetValue(events, CFSTR(kIOPMRepeatingPowerOffKey));
if(!is_valid_repeating_dictionary(repeating_on) ||
!is_valid_repeating_dictionary(repeating_off)) return kIOReturnBadArgument;
prefs = SCPreferencesCreate(0, CFSTR("IOKit-AutoWake"), CFSTR(kIOPMAutoWakePrefsPath));
if(!prefs || !SCPreferencesLock(prefs, true))
{
if(kSCStatusAccessError == SCError())
ret = kIOReturnNotPrivileged;
else ret = kIOReturnError;
goto exit;
}
if(repeating_on)
SCPreferencesSetValue(prefs, CFSTR(kIOPMRepeatingPowerOnKey), repeating_on);
else SCPreferencesRemoveValue(prefs, CFSTR(kIOPMRepeatingPowerOnKey));
if(repeating_off)
SCPreferencesSetValue(prefs, CFSTR(kIOPMRepeatingPowerOffKey), repeating_off);
else SCPreferencesRemoveValue(prefs, CFSTR(kIOPMRepeatingPowerOffKey));
if(!SCPreferencesCommitChanges(prefs))
{
ret = kIOReturnError;
goto exit;
}
ret = kIOReturnSuccess;
exit:
if(prefs) SCPreferencesUnlock(prefs);
if(prefs) CFRelease(prefs);
return ret;
}
extern CFDictionaryRef IOPMCopyRepeatingPowerEvents(void)
{
SCPreferencesRef prefs;
CFMutableDictionaryRef return_dict = NULL;
CFDictionaryRef rep_power_on_dict;
CFDictionaryRef rep_power_off_dict;
prefs = SCPreferencesCreate(0, CFSTR("IOKit-AutoWake"), CFSTR(kIOPMAutoWakePrefsPath));
if(!prefs)
{
return_dict = NULL;
goto exit;
}
rep_power_on_dict = isA_CFDictionary(SCPreferencesGetValue(prefs, CFSTR(kIOPMRepeatingPowerOnKey)));
rep_power_off_dict = isA_CFDictionary(SCPreferencesGetValue(prefs, CFSTR(kIOPMRepeatingPowerOffKey)));
if(rep_power_on_dict || rep_power_off_dict)
{
return_dict = CFDictionaryCreateMutable(kCFAllocatorDefault, 2,
&kCFTypeDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks);
if(rep_power_on_dict)
CFDictionaryAddValue(return_dict, CFSTR(kIOPMRepeatingPowerOnKey), rep_power_on_dict);
if(rep_power_off_dict)
CFDictionaryAddValue(return_dict, CFSTR(kIOPMRepeatingPowerOffKey), rep_power_off_dict);
} else {
return_dict = NULL;
}
exit:
if(prefs) CFRelease(prefs);
return return_dict;
}
extern IOReturn IOPMCancelAllRepeatingPowerEvents(void)
{
SCPreferencesRef prefs = 0;
IOReturn ret = kIOReturnError;
prefs = SCPreferencesCreate(0, CFSTR("IOKit-AutoWake"), CFSTR(kIOPMAutoWakePrefsPath));
if(!prefs || !SCPreferencesLock(prefs, true))
{
if(kSCStatusAccessError == SCError())
ret = kIOReturnNotPrivileged;
else ret = kIOReturnError;
goto exit;
}
SCPreferencesRemoveValue(prefs, CFSTR(kIOPMRepeatingPowerOnKey));
SCPreferencesRemoveValue(prefs, CFSTR(kIOPMRepeatingPowerOffKey));
if(!SCPreferencesCommitChanges(prefs))
{
ret = kIOReturnError;
goto exit;
}
ret = kIOReturnSuccess;
exit:
if(prefs) SCPreferencesUnlock(prefs);
if(prefs) CFRelease(prefs);
return ret;
}