17#include <IOKit/IOKitLib.h>
18#include <IOKit/IOKitKeys.h>
19#include <CoreFoundation/CoreFoundation.h>
21#include <mach/mach_error.h>
24static io_registry_entry_t gOptionsRef;
31static kern_return_t GetOFVariable(
char *name, CFStringRef *nameRef,
34 *nameRef = CFStringCreateWithCString(kCFAllocatorDefault, name,
35 kCFStringEncodingUTF8);
37 errx(1,
"Error creating CFString for key %s", name);
40 *valueRef = IORegistryEntryCreateCFProperty(gOptionsRef, *nameRef, 0, 0);
41 if (*valueRef == 0)
return kIOReturnNotFound;
43 if (CFGetTypeID(*valueRef) == CFStringGetTypeID()) {
44 CFTypeRef oldValue = *valueRef;
45 *valueRef = CFStringCreateExternalRepresentation(kCFAllocatorDefault, *valueRef, kCFStringEncodingUTF8, 0);
47 if (*valueRef == 0)
return kIOReturnNotFound;
53static CFMutableDictionaryRef dict4;
55static void ConvertStringValues (
const void* key,
const void*
value,
void* context) {
56 if (CFGetTypeID(
value) == CFStringGetTypeID()) {
57 CFDataRef dataValue = CFStringCreateExternalRepresentation(kCFAllocatorDefault,
value, kCFStringEncodingUTF8, 0);
58 if (dataValue != NULL) {
59 CFDictionaryAddValue(dict4, key, dataValue);
62 CFDictionaryAddValue(dict4, key,
value);
67CFDictionaryRef CreateMyDictionary(
void) {
71 CFMutableDictionaryRef dict = CFDictionaryCreateMutable(kCFAllocatorDefault, 0,
72 &kCFTypeDictionaryKeyCallBacks,
73 &kCFTypeDictionaryValueCallBacks);
76 CFNumberRef num = CFNumberCreate(kCFAllocatorDefault, kCFNumberIntType, &
version);
77 CFDictionarySetValue(dict, CFSTR(
"Version"), num);
80 CFMutableDictionaryRef dict0 = CFDictionaryCreateMutable(NULL, 0, &kCFTypeDictionaryKeyCallBacks,
81 &kCFTypeDictionaryValueCallBacks);
82 CFDictionarySetValue(dict, CFSTR(
"Add"), dict0);
87 CFMutableDictionaryRef dict1;
89 result = IORegistryEntryCreateCFProperties(gOptionsRef, &dict1, 0, 0);
90 if (result != KERN_SUCCESS) {
91 errx(1,
"Error getting the firmware variables: %s", mach_error_string(result));
96 dict4 = CFDictionaryCreateMutable(kCFAllocatorDefault, 0,
97 &kCFTypeDictionaryKeyCallBacks,
98 &kCFTypeDictionaryValueCallBacks);
99 CFDictionaryApplyFunction(dict1, ConvertStringValues, NULL);
101 CFDictionarySetValue(dict0, CFSTR(
"7C436110-AB2A-4BBB-A880-FE41995C9F82"), dict4);
105 CFMutableDictionaryRef dict2 = CFDictionaryCreateMutable(NULL, 0, &kCFTypeDictionaryKeyCallBacks,
106 &kCFTypeDictionaryValueCallBacks);
107 CFDictionarySetValue(dict0, CFSTR(
"8BE4DF61-93CA-11D2-AA0D-00E098032B8C"), dict2);
121 key[1] =
"BootOrder";
126 key[6] =
"BootCurrent";
127 guid =
"8BE4DF61-93CA-11D2-AA0D-00E098032B8C";
129 for ( i = 0; i < n; i++ ) {
130 snprintf(name,
sizeof(name),
"%s:%s", guid, key[i]);
131 var = CFStringCreateWithCString(NULL, key[i], kCFStringEncodingUTF8);
132 result = GetOFVariable(name, &nameRef, &valueRef);
133 if (result == KERN_SUCCESS) {
134 CFDictionaryAddValue (dict2, var, valueRef);
142 CFMutableDictionaryRef dict3 = CFDictionaryCreateMutable(NULL, 0, &kCFTypeDictionaryKeyCallBacks,
143 &kCFTypeDictionaryValueCallBacks);
144 CFDictionarySetValue(dict0, CFSTR(
"36C28AB5-6566-4C50-9EBD-CBB920F83843"), dict3);
146 key[0] =
"current-network";
147 key[1] =
"preferred-count";
148 key[2] =
"preferred-networks";
149 guid =
"36C28AB5-6566-4C50-9EBD-CBB920F83843";
151 for ( i = 0; i < n; i++ ) {
152 snprintf(name,
sizeof(name),
"%s:%s", guid, key[i]);
153 var = CFStringCreateWithCString(NULL, key[i], kCFStringEncodingUTF8);
154 result = GetOFVariable(name, &nameRef, &valueRef);
155 if (result == KERN_SUCCESS) {
156 CFDictionaryAddValue (dict3, var, valueRef);
166int main(
int argc,
const char * argv[]) {
169 kern_return_t result;
170 mach_port_t masterPort;
172 result = IOMasterPort(bootstrap_port, &masterPort);
173 if (result != KERN_SUCCESS) {
174 errx(1,
"Error getting the IOMaster port: %s",
175 mach_error_string(result));
178 gOptionsRef = IORegistryEntryFromPath(masterPort,
"IODeviceTree:/options");
179 if (gOptionsRef == 0) {
180 errx(1,
"nvram is not supported on this system");
182 CFPropertyListRef propertyList = CreateMyDictionary();
183 data = CFPropertyListCreateData( kCFAllocatorDefault, propertyList, kCFPropertyListXMLFormat_v1_0, 0, NULL );
185 errx(1,
"Error converting variables to xml");
187 fp = fopen (
"/tmp/nvram.plist",
"w");
189 errx(1,
"Error opening /tmp/nvram.plist");
191 fwrite(CFDataGetBytePtr(data),
sizeof(UInt8), CFDataGetLength(data), fp);
194 IOObjectRelease(gOptionsRef);
201 fprintf(stderr,
"This utility is only supported on macOS\n");