16#include <IOKit/graphics/IOGraphicsLib.h>
17#include <CoreFoundation/CoreFoundation.h>
19#define LILU_SERVICE_NAME "Lilu"
20#define ALC_SERVICE_NAME "AppleALC"
21#define ARPT_SERVICE_NAME "AirportBrcmFixup"
22#define BRKEYS_SERVICE_NAME "BrightnessKeys"
23#define CPUF_SERVICE_NAME "CPUFriend"
24#define CPUTSC_SERVICE_NAME "CpuTscSync"
25#define DBGEN_SERVICE_NAME "DebugEnhancer"
26#define HBFX_SERVICE_NAME "HibernationFixup"
27#define NVMEF_SERVICE_NAME "NVMeFix"
28#define RSTREV_SERVICE_NAME "RestrictEvents"
29#define RTCFX_SERVICE_NAME "RTCMemoryFixup"
30#define SMCBAT_SERVICE_NAME "SMCBatteryManager"
31#define SMCCPU_SERVICE_NAME "SMCProcessor"
32#define SMCDELL_SERVICE_NAME "SMCDellSensors"
33#define SMCLIGH_SERVICE_NAME "SMCLightSensor"
34#define SMCSSIO_SERVICE_NAME "SMCSuperIO"
35#define VSMC_SERVICE_NAME "VirtualSMC"
36#define WEG_SERVICE_NAME "WhateverGreen"
38#define ACDT_VERSION_NAME "VersionInfo"
39#define ACDT_VERSION_LENGTH 32
55static CFStringRef acdt_kext_list[] = {
56 CFSTR(LILU_SERVICE_NAME),
57 CFSTR(ALC_SERVICE_NAME),
58 CFSTR(ARPT_SERVICE_NAME),
59 CFSTR(BRKEYS_SERVICE_NAME),
60 CFSTR(CPUF_SERVICE_NAME),
61 CFSTR(CPUTSC_SERVICE_NAME),
62 CFSTR(DBGEN_SERVICE_NAME),
63 CFSTR(HBFX_SERVICE_NAME),
64 CFSTR(NVMEF_SERVICE_NAME),
65 CFSTR(RSTREV_SERVICE_NAME),
66 CFSTR(RTCFX_SERVICE_NAME),
67 CFSTR(SMCBAT_SERVICE_NAME),
68 CFSTR(SMCCPU_SERVICE_NAME),
69 CFSTR(SMCDELL_SERVICE_NAME),
70 CFSTR(SMCLIGH_SERVICE_NAME),
71 CFSTR(SMCSSIO_SERVICE_NAME),
72 CFSTR(VSMC_SERVICE_NAME),
73 CFSTR(WEG_SERVICE_NAME),
76#define ACDT_KEXT_NUM (sizeof(acdt_kext_list)/sizeof(acdt_kext_list[0]))
78io_object_t acdt_get_service_worker(CFStringRef service_name, io_iterator_t device_iterator) {
80 while ((
object = IOIteratorNext(device_iterator))) {
81 CFTypeRef class_name = IORegistryEntryCreateCFProperty(
object, CFSTR(
"IOClass"), kCFAllocatorDefault, 0);
82 if (class_name != NULL
83 && CFGetTypeID(class_name) == CFStringGetTypeID()
84 && CFEqual(class_name, service_name)) {
88 IOObjectRelease(
object);
90 kern_return_t result = IORegistryIteratorEnterEntry(device_iterator);
91 if (result == kIOReturnSuccess) {
92 object = acdt_get_service_worker(service_name, device_iterator);
93 IORegistryIteratorExitEntry(device_iterator);
103io_object_t acdt_get_service(CFStringRef service_name) {
104 io_iterator_t device_iterator;
105 kern_return_t result = IORegistryCreateIterator(kIOMasterPortDefault,
106 kIOServicePlane, 0, &device_iterator);
107 if (result != kIOReturnSuccess) {
108 fprintf(stderr,
"ERROR: Unable to connect to access IOService - %d\n", result);
112 io_object_t
object = acdt_get_service_worker(service_name, device_iterator);
113 IOObjectRelease(device_iterator);
117bool acdt_detect_kext(CFStringRef service,
char *
version) {
123 io_object_t
object = acdt_get_service(service);
129 CFTypeRef version_name = IORegistryEntryCreateCFProperty(
object,
130 CFSTR(ACDT_VERSION_NAME), kCFAllocatorDefault, 0);
131 if (version_name != NULL && CFGetTypeID(version_name) == CFStringGetTypeID()) {
132 if (!CFStringGetCString(version_name,
version, ACDT_VERSION_LENGTH, kCFStringEncodingUTF8)) {
133 fprintf(stderr,
"ERROR: Unable to decode version string\n");
137 fprintf(stderr,
"ERROR: Kext has no version info, make sure you have the latest version.\n");
140 IOObjectRelease(
object);
145const char *acdt_get_build_type(acdt_version_t *
version) {
146 if (strncmp(
version->build_type,
"DBG", 3) == 0) {
149 if (strncmp(
version->build_type,
"REL", 3) == 0) {
152 if (strncmp(
version->build_type,
"NPT", 3) == 0) {
159 char tmp_version[ACDT_VERSION_LENGTH];
160 acdt_version_t acdt_version;
161 printf(
"Installed kexts:\n");
162 for (
size_t i = 0; i < ACDT_KEXT_NUM; ++i) {
163 bool has_kext = acdt_detect_kext(acdt_kext_list[i], tmp_version);
164 printf(
"- %-32s: ", CFStringGetCStringPtr(acdt_kext_list[i], kCFStringEncodingUTF8));
165 if (has_kext && tmp_version[0] !=
'\0') {
166 memcpy(&acdt_version, tmp_version,
sizeof(acdt_version));
167 printf(
"Yes (%c.%c.%c, published %.2s.%.2s.%.4s, %s)\n", acdt_version.version_major,
168 acdt_version.version_minor, acdt_version.version_patch,
169 acdt_version.day, acdt_version.month, acdt_version.year,
170 acdt_get_build_type(&acdt_version));
171 }
else if (has_kext) {
182 fprintf(stderr,
"This utility requires macOS\n");
#define memcpy(Dst, Src, Size)