IOPlatformSupport.c [plain text]
#if !TARGET_OS_EMBEDDED
#include "IOPlatformSupportPrivate.h"
#include <IOKit/IOKitLib.h>
#include <IOKit/pwr_mgt/IOPMLibPrivate.h>
#include <sys/sysctl.h>
#include <sys/syslog.h>
#include <notify.h>
#if 0
#define DLOG(format) syslog(LOG_DEBUG, "IONTSLib: " format)
#define DLOG1(format, args ...) syslog(LOG_DEBUG, "IONTSLib: " format, args)
#define DLOG_ERROR(format) syslog(LOG_ERR, "IONTSLib: " format)
#define DLOG_ERROR1(format, args ...) syslog(LOG_ERR, "IONTSLib: " format, args)
#else
#define DLOG(format)
#define DLOG1(format, args ...)
#define DLOG_ERROR(format)
#define DLOG_ERROR1(format, args ...)
#endif
static Boolean CopyModel(char** model, UInt32 *majorRev, UInt32 *minorRev)
{
int mib[2];
char *machineModel; char *revStr;
int count;
unsigned long modelLen;
Boolean success = true;
size_t length = 1024;
if (!model || !majorRev || !minorRev) {
DLOG_ERROR("CopyModel: Passing NULL arguments\n");
return false;
}
machineModel = malloc(length);
mib[0] = CTL_HW;
mib[1] = HW_MODEL;
if (sysctl(mib, 2, machineModel, &length, NULL, 0)) {
printf("CopyModel: sysctl (error %d)\n", errno);
success = false;
goto exit;
}
modelLen = strcspn(machineModel, "0123456789");
if (modelLen == 0) {
DLOG_ERROR("CopyModel: Could not find machine model name\n");
success = false;
goto exit;
}
*model = strndup(machineModel, modelLen);
if (*model == NULL) {
DLOG_ERROR("CopyModel: Could not find machine model name\n");
success = false;
goto exit;
}
*majorRev = 0;
*minorRev = 0;
revStr = strpbrk(machineModel, "0123456789");
if (!revStr) {
DLOG_ERROR("CopyModel: Could not find machine version number, inferred value is 0,0\n");
success = true;
goto exit;
}
count = sscanf(revStr, "%d,%d", majorRev, minorRev);
if (count < 2) {
DLOG_ERROR("CopyModel: Could not find machine version number\n");
if (count<1) {
*majorRev = 0;
}
*minorRev = 0;
success = true;
goto exit;
}
exit:
if (machineModel) free(machineModel);
if (!success) {
if (*model) free(*model);
*model = NULL;
*majorRev = 0;
*minorRev = 0;
}
return success;
}
Boolean IOAuthenticatedRestartSupported()
{
char* model = NULL; UInt32 majorRev;
UInt32 minorRev;
Boolean success = false;
Boolean modelFound = CopyModel(&model, &majorRev, &minorRev);
if (!modelFound) {
DLOG_ERROR("IOAuthenticatedRestartSupported: Could not find machine model\n");
return false;
}
if (!strncmp(model, "MacBookPro", 10) && (majorRev < 5 || (majorRev == 5 && minorRev <= 2)))
goto exit;
if (!strncmp(model, "MacBookAir", 10) && (majorRev <=2))
goto exit;
if (!strncmp(model, "MacBook", 10) && (majorRev <=5))
goto exit;
if (!strncmp(model, "iMac", 10) && (majorRev <=9))
goto exit;
if (!strncmp(model, "Macmini", 10) && (majorRev <=3))
goto exit;
if (!strncmp(model, "MacPro", 10) && (majorRev <=5))
goto exit;
if (!strncmp(model, "Xserve", 10))
goto exit;
success = true;
DLOG("Machine appears to be auth restart capable\n");
exit:
if (model) free(model);
return success;
}
static CFTypeRef _copyRootDomainProperty(CFStringRef key)
{
io_registry_entry_t platformReg = IO_OBJECT_NULL;
CFTypeRef obj = NULL;
platformReg = IORegistryEntryFromPath( kIOMasterPortDefault,
kIOPowerPlane ":/IOPowerConnection/IOPMrootDomain");
if (IO_OBJECT_NULL != platformReg)
{
obj = IORegistryEntryCreateCFProperty(
platformReg,
key,
kCFAllocatorDefault,
kNilOptions);
}
IOObjectRelease(platformReg);
return obj;
}
IOReturn IOPlatformCopyFeatureDefault(
CFStringRef platformSettingKey,
CFTypeRef *outValue)
{
CFDictionaryRef platformFeatures = NULL;
CFTypeRef returnObj = NULL;
if (!platformSettingKey || !outValue) {
return kIOReturnBadArgument;
}
platformFeatures = _copyRootDomainProperty(CFSTR("IOPlatformFeatureDefaults"));
if (platformFeatures) {
returnObj = CFDictionaryGetValue(platformFeatures, platformSettingKey);
if (returnObj) {
*outValue = CFRetain(returnObj);
}
CFRelease(platformFeatures);
}
if (*outValue) {
return kIOReturnSuccess;
} else {
return kIOReturnUnsupported;
}
}
IOReturn IOPlatformCopyFeatureActive(
CFStringRef platformSettingKey,
CFTypeRef *outValue)
{
if (!platformSettingKey || !outValue) {
return kIOReturnBadArgument;
}
if (CFEqual(platformSettingKey, kIOPlatformTCPKeepAliveDuringSleep))
{
#if TCPKEEPALIVE
int keepAliveIsValid = 0;
keepAliveIsValid = IOPMGetValueInt(kIOPMTCPKeepAliveIsActive);
if (keepAliveIsValid) {
*outValue = kCFBooleanTrue;
} else {
*outValue = kCFBooleanFalse;
}
#else
*outValue = kCFBooleanFalse;
#endif
return kIOReturnSuccess;
} else
{
return IOPlatformCopyFeatureDefault(platformSettingKey, outValue);
}
}
#endif