2 * Copyright (c) 2000-2016 Apple Inc. All rights reserved.
4 * @APPLE_LICENSE_HEADER_START@
6 * The contents of this file constitute Original Code as defined in and
7 * are subject to the Apple Public Source License Version 1.1 (the
8 * "License"). You may not use this file except in compliance with the
9 * License. Please obtain a copy of the License at
10 * http://www.apple.com/publicsource and read it before using this file.
12 * This Original Code and all software distributed under the License are
13 * distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY KIND, EITHER
14 * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
15 * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
16 * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT. Please see the
17 * License for the specific language governing rights and limitations
20 * @APPLE_LICENSE_HEADER_END@
23 cc -o nvram nvram.c -framework CoreFoundation -framework IOKit -Wall
27 #include <IOKit/IOKitLib.h>
28 #include <IOKit/IOKitKeys.h>
29 #include <IOKit/IOKitKeysPrivate.h>
30 #include <CoreFoundation/CoreFoundation.h>
32 #include <mach/mach_error.h>
36 static void UsageMessage(char *message
);
37 static void ParseFile(char *fileName
);
38 static void ParseXMLFile(char *fileName
);
39 static void SetOrGetOFVariable(char *str
);
40 static kern_return_t
GetOFVariable(char *name
, CFStringRef
*nameRef
,
42 static kern_return_t
SetOFVariable(char *name
, char *value
);
43 static void DeleteOFVariable(char *name
);
44 static void PrintOFVariables(void);
45 static void PrintOFVariable(const void *key
,const void *value
,void *context
);
46 static void SetOFVariableFromFile(const void *key
, const void *value
, void *context
);
47 static void ClearOFVariables(void);
48 static void ClearOFVariable(const void *key
,const void *value
,void *context
);
49 static CFTypeRef
ConvertValueToCFTypeRef(CFTypeID typeID
, char *value
);
51 static void NVRamSyncNow(char *name
);
54 static char *gToolName
;
55 static io_registry_entry_t gOptionsRef
;
57 static bool gUseForceSync
;
59 #if TARGET_OS_BRIDGE /* Stuff for nvram bridge -> intel */
61 #include <libMacEFIManager/MacEFIHostInterfaceAPI.h>
63 static kern_return_t
LinkMacNVRAMSymbols(void);
64 static kern_return_t
GetMacOFVariable(char *name
, char **value
);
65 static kern_return_t
SetMacOFVariable(char *name
, char *value
);
66 static void DeleteMacOFVariable(char *name
);
68 static bool gBridgeToIntel
;
69 static void *gDL_handle
;
70 static void *gNvramInterface
;
72 static void (*hostInterfaceInitialize_fptr
)(void);
73 static void *(*createNvramHostInterface_fptr
)(const char *handle
);
74 static kern_return_t (*destroyNvramHostInterface_fptr
)(void *interface
);
75 static kern_return_t (*getNVRAMVariable_fptr
)(void *interface
, char *name
, char **buffer
, uint32_t *size
);
76 static kern_return_t (*setNVRAMVariable_fptr
)(void *interface
, char *name
, char *buffer
, uint32_t size
);
77 static void (*hostInterfaceDeinitialize_fptr
)(void); /* may not need? */
79 #endif /* TARGET_OS_BRIDGE */
81 int main(int argc
, char **argv
)
84 char *str
, errorMessage
[256];
86 mach_port_t masterPort
;
89 // Get the name of the command.
90 gToolName
= strrchr(argv
[0], '/');
91 if (gToolName
!= 0) gToolName
++;
92 else gToolName
= argv
[0];
94 result
= IOMasterPort(bootstrap_port
, &masterPort
);
95 if (result
!= KERN_SUCCESS
) {
96 errx(1, "Error getting the IOMaster port: %s",
97 mach_error_string(result
));
100 gOptionsRef
= IORegistryEntryFromPath(masterPort
, "IODeviceTree:/options");
101 if (gOptionsRef
== 0) {
102 errx(1, "nvram is not supported on this system");
105 for (cnt
= 1; cnt
< argc
; cnt
++) {
107 if (str
[0] == '-' && str
[1] != 0) {
108 // Parse the options.
109 for (str
+= 1 ; *str
; str
++) {
113 if (gBridgeToIntel
) {
114 fprintf(stderr
, "-p not supported for Mac NVRAM store.\n");
127 if (gBridgeToIntel
) {
128 fprintf(stderr
, "-f not supported for Mac NVRAM store.\n");
133 if (cnt
< argc
&& *argv
[cnt
] != '-') {
134 ParseFile(argv
[cnt
]);
136 UsageMessage("missing filename");
142 if (gBridgeToIntel
) {
143 fprintf(stderr
, "-d not supported for Mac NVRAM store.\n");
148 if (cnt
< argc
&& *argv
[cnt
] != '-') {
149 DeleteOFVariable(argv
[cnt
]);
151 UsageMessage("missing name");
157 if (gBridgeToIntel
) {
158 fprintf(stderr
, "-c not supported for Mac NVRAM store.\n");
165 // -s option is unadvertised -- advises the kernel more forcibly to
166 // commit the variable to nonvolatile storage
167 gUseForceSync
= true;
171 // -m option is unadvertised -- used to set nvram variables on the Intel side
172 // from the ARM side (Bridge -> Mac)
173 fprintf(stdout
, "Using Mac NVRAM store.\n");
175 LinkMacNVRAMSymbols();
176 gBridgeToIntel
= true;
181 strcpy(errorMessage
, "no such option as --");
182 errorMessage
[strlen(errorMessage
)-1] = *str
;
183 UsageMessage(errorMessage
);
187 // Other arguments will be firmware variable requests.
189 SetOrGetOFVariable(str
);
194 if (argcount
== 0 && gUseForceSync
== true) {
198 IOObjectRelease(gOptionsRef
);
203 // UsageMessage(message)
205 // Print the usage information and exit.
207 static void UsageMessage(char *message
)
209 warnx("(usage: %s)", message
);
211 printf("%s [-x] [-p] [-f filename] [-d name] [-c] name[=value] ...\n", gToolName
);
212 printf("\t-x use XML format for printing or reading variables\n");
213 printf("\t (must appear before -p or -f)\n");
214 printf("\t-p print all firmware variables\n");
215 printf("\t-f set firmware variables from a text file\n");
216 printf("\t-d delete the named variable\n");
217 printf("\t-c delete all variables\n");
218 printf("\tname=value set named variable\n");
219 printf("\tname print variable\n");
220 printf("Note that arguments and options are executed in order.\n");
226 // States for ParseFile.
237 kMaxStringSize
= 0x800,
242 // ParseFile(fileName)
244 // Open and parse the specified file.
246 static void ParseFile(char *fileName
)
248 long state
, ni
= 0, vi
= 0;
250 char name
[kMaxNameSize
];
251 char value
[kMaxStringSize
];
256 ParseXMLFile(fileName
);
260 patches
= fopen(fileName
, "r");
262 err(1, "Couldn't open patch file - '%s'", fileName
);
265 state
= kFirstColumn
;
266 while ((tc
= getc(patches
)) != EOF
) {
267 if(ni
==(kMaxNameSize
-1))
268 errx(1, "Name exceeded max length of %d", kMaxNameSize
);
269 if(vi
==(kMaxStringSize
-1))
270 errx(1, "Value exceeded max length of %d", kMaxStringSize
);
276 state
= kScanComment
;
277 } else if (tc
== '\n') {
278 // state stays kFirstColumn.
279 } else if (isspace(tc
)) {
282 state
= kCollectName
;
289 state
= kFirstColumn
;
291 // state stays kScanComment.
297 state
= kFirstColumn
;
298 } else if (isspace(tc
)) {
299 // state stays kFindName.
301 state
= kCollectName
;
309 warnx("Name must be followed by white space - '%s'", name
);
310 state
= kFirstColumn
;
311 } else if (isspace(tc
)) {
315 // state staus kCollectName.
320 case kContinueValue
:
323 } else if (isspace(tc
)) {
324 // state stays kFindValue or kContinueValue.
326 state
= kCollectValue
;
333 if (value
[vi
-1] == '\\') {
335 state
= kContinueValue
;
340 // state stays kCollectValue.
346 if (state
== kSetenv
) {
349 if ((kret
= SetOFVariable(name
, value
)) != KERN_SUCCESS
) {
350 errx(1, "Error setting variable - '%s': %s", name
,
351 mach_error_string(kret
));
353 state
= kFirstColumn
;
357 if (state
!= kFirstColumn
) {
358 errx(1, "Last line ended abruptly");
362 // ParseXMLFile(fileName)
364 // Open and parse the specified file in XML format,
365 // and set variables appropriately.
367 static void ParseXMLFile(char *fileName
)
369 CFPropertyListRef plist
;
373 CFReadStreamRef stream
;
374 CFPropertyListFormat format
= kCFPropertyListBinaryFormat_v1_0
;
376 fd
= open(fileName
, O_RDONLY
| O_NOFOLLOW
, S_IFREG
);
378 errx(1, "Could not open %s: %s", fileName
, strerror(errno
));
381 if (fstat(fd
, &sb
) == -1) {
382 errx(1, "Could not fstat %s: %s", fileName
, strerror(errno
));
385 if (sb
.st_size
> UINT32_MAX
) {
386 errx(1, "too big for our purposes");
389 buffer
= malloc((size_t)sb
.st_size
);
390 if (buffer
== NULL
) {
391 errx(1, "Could not allocate buffer");
394 if (read(fd
, buffer
, (size_t)sb
.st_size
) != sb
.st_size
) {
395 errx(1, "Could not read %s: %s", fileName
, strerror(errno
));
400 stream
= CFReadStreamCreateWithBytesNoCopy(kCFAllocatorDefault
,
401 (const UInt8
*)buffer
,
404 if (stream
== NULL
) {
405 errx(1, "Could not create stream from serialized data");
408 if (!CFReadStreamOpen(stream
)) {
409 errx(1, "Could not open the stream");
412 plist
= CFPropertyListCreateWithStream(kCFAllocatorDefault
,
415 kCFPropertyListImmutable
,
420 errx(1, "Error parsing XML file");
423 CFReadStreamClose(stream
);
429 CFDictionaryApplyFunction(plist
, &SetOFVariableFromFile
, 0);
434 // SetOrGetOFVariable(str)
436 // Parse the input string, then set or get the specified
437 // firmware variable.
439 static void SetOrGetOFVariable(char *str
)
446 kern_return_t result
;
448 // OF variable name is first.
451 // Find the equal sign for set
462 // On sets, the OF variable's value follows the equal sign.
465 if (gBridgeToIntel
) {
466 result
= SetMacOFVariable(name
, value
);
471 result
= SetOFVariable(name
, value
);
472 NVRamSyncNow(name
); /* Try syncing the new data to device, best effort! */
474 if (result
!= KERN_SUCCESS
) {
475 errx(1, "Error setting variable - '%s': %s", name
,
476 mach_error_string(result
));
480 if (gBridgeToIntel
) {
481 result
= GetMacOFVariable(name
, &value
);
482 if (result
!= KERN_SUCCESS
) {
483 errx(1, "Error getting variable - '%s': %s", name
,
484 mach_error_string(result
));
486 nameRef
= CFStringCreateWithCString(kCFAllocatorDefault
, name
, kCFStringEncodingUTF8
);
487 valueRef
= CFStringCreateWithCString(kCFAllocatorDefault
, value
, kCFStringEncodingUTF8
);
492 result
= GetOFVariable(name
, &nameRef
, &valueRef
);
493 if (result
!= KERN_SUCCESS
) {
494 errx(1, "Error getting variable - '%s': %s", name
,
495 mach_error_string(result
));
499 PrintOFVariable(nameRef
, valueRef
, 0);
506 static kern_return_t
LinkMacNVRAMSymbols()
508 gDL_handle
= dlopen("libMacEFIHostInterface.dylib", RTLD_LAZY
);
509 if (gDL_handle
== NULL
) {
510 errx(errno
, "Failed to dlopen libMacEFIHostInterface.dylib");
511 return KERN_FAILURE
; /* NOTREACHED */
514 hostInterfaceInitialize_fptr
= dlsym(gDL_handle
, "hostInterfaceInitialize");
515 if (hostInterfaceInitialize_fptr
== NULL
) {
516 errx(errno
, "failed to link hostInterfaceInitialize");
518 createNvramHostInterface_fptr
= dlsym(gDL_handle
, "createNvramHostInterface");
519 if (createNvramHostInterface_fptr
== NULL
) {
520 errx(errno
, "failed to link createNvramHostInterface");
522 destroyNvramHostInterface_fptr
= dlsym(gDL_handle
, "destroyNvramHostInterface");
523 if (destroyNvramHostInterface_fptr
== NULL
) {
524 errx(errno
, "failed to link destroyNvramHostInterface");
526 getNVRAMVariable_fptr
= dlsym(gDL_handle
, "getNVRAMVariable");
527 if (getNVRAMVariable_fptr
== NULL
) {
528 errx(errno
, "failed to link getNVRAMVariable");
530 setNVRAMVariable_fptr
= dlsym(gDL_handle
, "setNVRAMVariable");
531 if (setNVRAMVariable_fptr
== NULL
) {
532 errx(errno
, "failed to link setNVRAMVariable");
534 hostInterfaceDeinitialize_fptr
= dlsym(gDL_handle
, "hostInterfaceDeinitialize");
535 if (hostInterfaceDeinitialize_fptr
== NULL
) {
536 errx(errno
, "failed to link hostInterfaceDeinitialize");
539 /* also do the initialization */
540 hostInterfaceInitialize_fptr();
541 gNvramInterface
= createNvramHostInterface_fptr(NULL
);
547 // GetOFVariable(name, nameRef, valueRef)
549 // Get the named firmware variable.
550 // Return it and it's symbol in valueRef and nameRef.
552 static kern_return_t
GetOFVariable(char *name
, CFStringRef
*nameRef
,
555 *nameRef
= CFStringCreateWithCString(kCFAllocatorDefault
, name
,
556 kCFStringEncodingUTF8
);
558 errx(1, "Error creating CFString for key %s", name
);
561 *valueRef
= IORegistryEntryCreateCFProperty(gOptionsRef
, *nameRef
, 0, 0);
562 if (*valueRef
== 0) return kIOReturnNotFound
;
568 // GetMacOFVariable(name, value)
570 // Get the named firmware variable from the Intel side.
571 // Return the value in value
573 static kern_return_t
GetMacOFVariable(char *name
, char **value
)
576 kern_return_t result
= KERN_FAILURE
;
577 assert(getNVRAMVariable_fptr
!= NULL
);
579 result
= getNVRAMVariable_fptr(gNvramInterface
, name
, value
, &value_size
);
585 // SetOFVariable(name, value)
587 // Set or create an firmware variable with name and value.
589 static kern_return_t
SetOFVariable(char *name
, char *value
)
594 kern_return_t result
= KERN_SUCCESS
;
596 nameRef
= CFStringCreateWithCString(kCFAllocatorDefault
, name
,
597 kCFStringEncodingUTF8
);
599 errx(1, "Error creating CFString for key %s", name
);
602 valueRef
= IORegistryEntryCreateCFProperty(gOptionsRef
, nameRef
, 0, 0);
604 typeID
= CFGetTypeID(valueRef
);
607 valueRef
= ConvertValueToCFTypeRef(typeID
, value
);
609 errx(1, "Error creating CFTypeRef for value %s", value
);
610 } result
= IORegistryEntrySetCFProperty(gOptionsRef
, nameRef
, valueRef
);
613 // In the default case, try data, string, number, then boolean.
615 valueRef
= ConvertValueToCFTypeRef(CFDataGetTypeID(), value
);
617 result
= IORegistryEntrySetCFProperty(gOptionsRef
, nameRef
, valueRef
);
618 if (result
== KERN_SUCCESS
) break;
621 valueRef
= ConvertValueToCFTypeRef(CFStringGetTypeID(), value
);
623 result
= IORegistryEntrySetCFProperty(gOptionsRef
, nameRef
, valueRef
);
624 if (result
== KERN_SUCCESS
) break;
627 valueRef
= ConvertValueToCFTypeRef(CFNumberGetTypeID(), value
);
629 result
= IORegistryEntrySetCFProperty(gOptionsRef
, nameRef
, valueRef
);
630 if (result
== KERN_SUCCESS
) break;
633 valueRef
= ConvertValueToCFTypeRef(CFBooleanGetTypeID(), value
);
635 result
= IORegistryEntrySetCFProperty(gOptionsRef
, nameRef
, valueRef
);
636 if (result
== KERN_SUCCESS
) break;
649 static kern_return_t
SetMacOFVariable(char *name
, char *value
)
651 kern_return_t result
= KERN_FAILURE
;
652 assert(setNVRAMVariable_fptr
!= NULL
);
654 result
= setNVRAMVariable_fptr(gNvramInterface
, name
, value
, strlen(value
));
660 // DeleteOFVariable(name)
662 // Delete the named firmware variable.
665 static void DeleteOFVariable(char *name
)
667 SetOFVariable(kIONVRAMDeletePropertyKey
, name
);
671 static void DeleteMacOFVariable(char *name
)
673 /* Not yet implementable */
677 static void NVRamSyncNow(char *name
)
679 if (!gUseForceSync
) {
680 SetOFVariable(kIONVRAMSyncNowPropertyKey
, name
);
682 SetOFVariable(kIONVRAMForceSyncNowPropertyKey
, name
);
686 // PrintOFVariables()
688 // Print all of the firmware variables.
690 static void PrintOFVariables(void)
692 kern_return_t result
;
693 CFMutableDictionaryRef dict
;
695 result
= IORegistryEntryCreateCFProperties(gOptionsRef
, &dict
, 0, 0);
696 if (result
!= KERN_SUCCESS
) {
697 errx(1, "Error getting the firmware variables: %s", mach_error_string(result
));
703 data
= CFPropertyListCreateData( kCFAllocatorDefault
, dict
, kCFPropertyListXMLFormat_v1_0
, 0, NULL
);
705 errx(1, "Error converting variables to xml");
708 fwrite(CFDataGetBytePtr(data
), sizeof(UInt8
), CFDataGetLength(data
), stdout
);
714 CFDictionaryApplyFunction(dict
, &PrintOFVariable
, 0);
721 // PrintOFVariable(key, value, context)
723 // Print the given firmware variable.
725 static void PrintOFVariable(const void *key
, const void *value
, void *context
)
729 char *nameBuffer
= 0;
730 const char *nameString
;
731 char numberBuffer
[10];
732 const uint8_t *dataPtr
;
734 char *dataBuffer
= 0;
736 char *valueBuffer
= 0;
737 const char *valueString
= 0;
744 CFDictionaryRef dict
= CFDictionaryCreate(kCFAllocatorDefault
, &key
, &value
, 1,
745 &kCFTypeDictionaryKeyCallBacks
, &kCFTypeDictionaryValueCallBacks
);
747 errx(1, "Error creating dictionary for variable value");
750 data
= CFPropertyListCreateData( kCFAllocatorDefault
, dict
, kCFPropertyListXMLFormat_v1_0
, 0, NULL
);
752 errx(1, "Error creating xml plist for variable");
755 fwrite(CFDataGetBytePtr(data
), sizeof(UInt8
), CFDataGetLength(data
), stdout
);
762 // Get the OF variable's name.
763 nameLen
= CFStringGetLength(key
) + 1;
764 nameBuffer
= malloc(nameLen
);
765 if( nameBuffer
&& CFStringGetCString(key
, nameBuffer
, nameLen
, kCFStringEncodingUTF8
) )
766 nameString
= nameBuffer
;
768 warnx("Unable to convert property name to C string");
769 nameString
= "<UNPRINTABLE>";
772 // Get the OF variable's type.
773 typeID
= CFGetTypeID(value
);
775 if (typeID
== CFBooleanGetTypeID()) {
776 if (CFBooleanGetValue(value
)) valueString
= "true";
777 else valueString
= "false";
778 } else if (typeID
== CFNumberGetTypeID()) {
779 CFNumberGetValue(value
, kCFNumberSInt32Type
, &number
);
780 if (number
== 0xFFFFFFFF) sprintf(numberBuffer
, "-1");
781 else if (number
< 1000) sprintf(numberBuffer
, "%d", number
);
782 else sprintf(numberBuffer
, "0x%x", number
);
783 valueString
= numberBuffer
;
784 } else if (typeID
== CFStringGetTypeID()) {
785 valueLen
= CFStringGetLength(value
) + 1;
786 valueBuffer
= malloc(valueLen
+ 1);
787 if ( valueBuffer
&& CFStringGetCString(value
, valueBuffer
, valueLen
, kCFStringEncodingUTF8
) )
788 valueString
= valueBuffer
;
790 warnx("Unable to convert value to C string");
791 valueString
= "<UNPRINTABLE>";
793 } else if (typeID
== CFDataGetTypeID()) {
794 length
= CFDataGetLength(value
);
795 if (length
== 0) valueString
= "";
797 dataBuffer
= malloc(length
* 3 + 1);
798 if (dataBuffer
!= 0) {
799 dataPtr
= CFDataGetBytePtr(value
);
800 for (cnt
= cnt2
= 0; cnt
< length
; cnt
++) {
801 dataChar
= dataPtr
[cnt
];
802 if (isprint(dataChar
) && dataChar
!= '%') {
803 dataBuffer
[cnt2
++] = dataChar
;
805 sprintf(dataBuffer
+ cnt2
, "%%%02x", dataChar
);
809 dataBuffer
[cnt2
] = '\0';
810 valueString
= dataBuffer
;
814 valueString
="<INVALID>";
817 if ((nameString
!= 0) && (valueString
!= 0))
818 printf("%s\t%s\n", nameString
, valueString
);
820 if (dataBuffer
!= 0) free(dataBuffer
);
821 if (nameBuffer
!= 0) free(nameBuffer
);
822 if (valueBuffer
!= 0) free(valueBuffer
);
825 // ClearOFVariables()
827 // Deletes all OF variables
829 static void ClearOFVariables(void)
831 kern_return_t result
;
832 CFMutableDictionaryRef dict
;
834 result
= IORegistryEntryCreateCFProperties(gOptionsRef
, &dict
, 0, 0);
835 if (result
!= KERN_SUCCESS
) {
836 errx(1, "Error getting the firmware variables: %s", mach_error_string(result
));
838 CFDictionaryApplyFunction(dict
, &ClearOFVariable
, 0);
843 static void ClearOFVariable(const void *key
, const void *value
, void *context
)
845 kern_return_t result
;
846 result
= IORegistryEntrySetCFProperty(gOptionsRef
,
847 CFSTR(kIONVRAMDeletePropertyKey
), key
);
848 if (result
!= KERN_SUCCESS
) {
849 errx(1, "Error clearing firmware variables: %s", mach_error_string(result
));
853 // ConvertValueToCFTypeRef(typeID, value)
855 // Convert the value into a CFType given the typeID.
857 static CFTypeRef
ConvertValueToCFTypeRef(CFTypeID typeID
, char *value
)
859 CFTypeRef valueRef
= 0;
860 long cnt
, cnt2
, length
;
861 unsigned long number
, tmp
;
863 if (typeID
== CFBooleanGetTypeID()) {
864 if (!strcmp("true", value
)) valueRef
= kCFBooleanTrue
;
865 else if (!strcmp("false", value
)) valueRef
= kCFBooleanFalse
;
866 } else if (typeID
== CFNumberGetTypeID()) {
867 number
= strtol(value
, 0, 0);
868 valueRef
= CFNumberCreate(kCFAllocatorDefault
, kCFNumberSInt32Type
,
870 } else if (typeID
== CFStringGetTypeID()) {
871 valueRef
= CFStringCreateWithCString(kCFAllocatorDefault
, value
,
872 kCFStringEncodingUTF8
);
873 } else if (typeID
== CFDataGetTypeID()) {
874 length
= strlen(value
);
875 for (cnt
= cnt2
= 0; cnt
< length
; cnt
++, cnt2
++) {
876 if (value
[cnt
] == '%') {
877 if (!ishexnumber(value
[cnt
+ 1]) ||
878 !ishexnumber(value
[cnt
+ 2])) return 0;
879 number
= toupper(value
[++cnt
]) - '0';
880 if (number
> 9) number
-= 7;
881 tmp
= toupper(value
[++cnt
]) - '0';
882 if (tmp
> 9) tmp
-= 7;
883 number
= (number
<< 4) + tmp
;
884 value
[cnt2
] = number
;
885 } else value
[cnt2
] = value
[cnt
];
887 valueRef
= CFDataCreateWithBytesNoCopy(kCFAllocatorDefault
, (const UInt8
*)value
,
888 cnt2
, kCFAllocatorDefault
);
894 static void SetOFVariableFromFile(const void *key
, const void *value
, void *context
)
896 kern_return_t result
;
898 result
= IORegistryEntrySetCFProperty(gOptionsRef
, key
, value
);
899 if ( result
!= KERN_SUCCESS
) {
904 // Get the variable's name.
905 nameLen
= CFStringGetLength(key
) + 1;
906 nameBuffer
= malloc(nameLen
);
907 if( nameBuffer
&& CFStringGetCString(key
, nameBuffer
, nameLen
, kCFStringEncodingUTF8
) )
908 nameString
= nameBuffer
;
910 warnx("Unable to convert property name to C string");
911 nameString
= "<UNPRINTABLE>";
913 errx(1, "Error setting variable - '%s': %s", nameString
,
914 mach_error_string(result
));