diff --git a/src/detection/physicaldisk/physicaldisk_apple.c b/src/detection/physicaldisk/physicaldisk_apple.c index 2f7d1cc16..faeaa3a59 100644 --- a/src/detection/physicaldisk/physicaldisk_apple.c +++ b/src/detection/physicaldisk/physicaldisk_apple.c @@ -7,6 +7,7 @@ #include #include #include +#include static inline void wrapIoObjectRelease(io_service_t* service) { @@ -16,6 +17,35 @@ static inline void wrapIoObjectRelease(io_service_t* service) } #define FF_IOOBJECT_AUTO_RELEASE __attribute__((__cleanup__(wrapIoObjectRelease))) +static inline void wrapIoDestroyPlugInInterface(IOCFPlugInInterface*** pluginInf) +{ + assert(pluginInf); + if (*pluginInf) + IODestroyPlugInInterface(*pluginInf); +} + +static const char* detectSsdTemp(io_service_t entryPhysical, double* temp) +{ + __attribute__((__cleanup__(wrapIoDestroyPlugInInterface))) IOCFPlugInInterface** pluginInf = NULL; + int32_t score; + if (IOCreatePlugInInterfaceForService(entryPhysical, kIONVMeSMARTUserClientTypeID, kIOCFPlugInInterfaceID, &pluginInf, &score) != kIOReturnSuccess) + return "IOCreatePlugInInterfaceForService() failed"; + + IONVMeSMARTInterface** smartInf = NULL; + if ((*pluginInf)->QueryInterface(pluginInf, CFUUIDGetUUIDBytes(kIONVMeSMARTInterfaceID), (LPVOID) &smartInf) != kIOReturnSuccess) + return "QueryInterface() failed"; + + NVMeSMARTData smartData; + const char* error = NULL; + if ((*smartInf)->SMARTReadData(smartInf, &smartData) == kIOReturnSuccess) + *temp = smartData.TEMPERATURE - 273; + else + error = "SMARTReadData() failed"; + + (*pluginInf)->Release(smartInf); + return error; +} + const char* ffDetectPhysicalDisk(FFlist* result, FFPhysicalDiskOptions* options) { FF_IOOBJECT_AUTO_RELEASE io_iterator_t iterator = 0; @@ -49,6 +79,7 @@ const char* ffDetectPhysicalDisk(FFlist* result, FFPhysicalDiskOptions* options) ffStrbufInit(&device->interconnect); device->type = FF_PHYSICALDISK_TYPE_NONE; device->size = 0; + device->temperature = FF_PHYSICALDISK_TEMP_UNSET; FF_CFTYPE_AUTO_RELEASE CFBooleanRef removable = IORegistryEntryCreateCFProperty(entryPartition, CFSTR(kIOMediaRemovableKey), kCFAllocatorDefault, kNilOptions); device->type |= CFBooleanGetValue(removable) ? FF_PHYSICALDISK_TYPE_REMOVABLE : FF_PHYSICALDISK_TYPE_FIXED; @@ -91,8 +122,14 @@ const char* ffDetectPhysicalDisk(FFlist* result, FFPhysicalDiskOptions* options) device->type |= FF_PHYSICALDISK_TYPE_HDD; } } + + if (options->temp) + { + FF_CFTYPE_AUTO_RELEASE CFBooleanRef nvmeSMARTCapable = IORegistryEntryCreateCFProperty(entryPhysical, CFSTR(kIOPropertyNVMeSMARTCapableKey), kCFAllocatorDefault, kNilOptions); + if (CFBooleanGetValue(nvmeSMARTCapable)) + detectSsdTemp(entryPhysical, &device->temperature); + } } - device->temperature = FF_PHYSICALDISK_TEMP_UNSET; } return NULL;