X-Git-Url: https://git.saurik.com/apple/system_cmds.git/blobdiff_plain/1a7e3f61d38d679bba59130891c2031b5a0092b6..d52496fdbb8dd3d53ac142500a42d06f3720ea6c:/nvram.tproj/nvram.c diff --git a/nvram.tproj/nvram.c b/nvram.tproj/nvram.c index 0d82b45..7bdf9c6 100644 --- a/nvram.tproj/nvram.c +++ b/nvram.tproj/nvram.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2000-2012 Apple Computer, Inc. All rights reserved. + * Copyright (c) 2000-2016 Apple Inc. All rights reserved. * * @APPLE_LICENSE_HEADER_START@ * @@ -26,9 +26,11 @@ cc -o nvram nvram.c -framework CoreFoundation -framework IOKit -Wall #include #include #include +#include #include #include #include +#include // Prototypes static void UsageMessage(char *message); @@ -52,7 +54,30 @@ static void NVRamSyncNow(char *name); static char *gToolName; static io_registry_entry_t gOptionsRef; static bool gUseXML; +static bool gUseForceSync; +#if TARGET_OS_BRIDGE /* Stuff for nvram bridge -> intel */ +#include +#include + +static kern_return_t LinkMacNVRAMSymbols(void); +static kern_return_t GetMacOFVariable(char *name, char **value); +static kern_return_t SetMacOFVariable(char *name, char *value); +static kern_return_t DeleteMacOFVariable(char *name); + +static bool gBridgeToIntel; +static void *gDL_handle; +static void *gNvramInterface; + +static void (*hostInterfaceInitialize_fptr)(void); +static void *(*createNvramHostInterface_fptr)(const char *handle); +static kern_return_t (*destroyNvramHostInterface_fptr)(void *interface); +static kern_return_t (*getNVRAMVariable_fptr)(void *interface, char *name, char **buffer, uint32_t *size); +static kern_return_t (*setNVRAMVariable_fptr)(void *interface, char *name, char *buffer); +static kern_return_t (*deleteNVRAMVariable_fptr)(void *interface, char *name); +static void (*hostInterfaceDeinitialize_fptr)(void); /* may not need? */ + +#endif /* TARGET_OS_BRIDGE */ int main(int argc, char **argv) { @@ -60,23 +85,24 @@ int main(int argc, char **argv) char *str, errorMessage[256]; kern_return_t result; mach_port_t masterPort; - + int argcount = 0; + // Get the name of the command. gToolName = strrchr(argv[0], '/'); if (gToolName != 0) gToolName++; else gToolName = argv[0]; - + result = IOMasterPort(bootstrap_port, &masterPort); if (result != KERN_SUCCESS) { errx(1, "Error getting the IOMaster port: %s", mach_error_string(result)); } - + gOptionsRef = IORegistryEntryFromPath(masterPort, "IODeviceTree:/options"); if (gOptionsRef == 0) { errx(1, "nvram is not supported on this system"); } - + for (cnt = 1; cnt < argc; cnt++) { str = argv[cnt]; if (str[0] == '-' && str[1] != 0) { @@ -84,6 +110,12 @@ int main(int argc, char **argv) for (str += 1 ; *str; str++) { switch (*str) { case 'p' : +#if TARGET_OS_BRIDGE + if (gBridgeToIntel) { + fprintf(stderr, "-p not supported for Mac NVRAM store.\n"); + return 1; + } +#endif PrintOFVariables(); break; @@ -92,6 +124,12 @@ int main(int argc, char **argv) break; case 'f': +#if TARGET_OS_BRIDGE + if (gBridgeToIntel) { + fprintf(stderr, "-f not supported for Mac NVRAM store.\n"); + return 1; + } +#endif cnt++; if (cnt < argc && *argv[cnt] != '-') { ParseFile(argv[cnt]); @@ -99,20 +137,52 @@ int main(int argc, char **argv) UsageMessage("missing filename"); } break; - - case 'd': - cnt++; - if (cnt < argc && *argv[cnt] != '-') { - DeleteOFVariable(argv[cnt]); - } else { - UsageMessage("missing name"); - } - break; - + + case 'd': + cnt++; + if (cnt < argc && *argv[cnt] != '-') { +#if TARGET_OS_BRIDGE + if (gBridgeToIntel) { + if ((result = DeleteMacOFVariable(argv[cnt])) != KERN_SUCCESS) { + errx(1, "Error deleting variable - '%s': %s (0x%08x)", argv[cnt], + mach_error_string(result), result); + } + } + else +#endif + { + DeleteOFVariable(argv[cnt]); + } + } else { + UsageMessage("missing name"); + } + break; + case 'c': +#if TARGET_OS_BRIDGE + if (gBridgeToIntel) { + fprintf(stderr, "-c not supported for Mac NVRAM store.\n"); + return 1; + } +#endif ClearOFVariables(); break; - + case 's': + // -s option is unadvertised -- advises the kernel more forcibly to + // commit the variable to nonvolatile storage + gUseForceSync = true; + break; +#if TARGET_OS_BRIDGE + case 'm': + // used to set nvram variables on the Intel side + // from the ARM side (Bridge -> Mac) + fprintf(stdout, "Using Mac NVRAM store.\n"); + + LinkMacNVRAMSymbols(); + gBridgeToIntel = true; + break; +#endif + default: strcpy(errorMessage, "no such option as --"); errorMessage[strlen(errorMessage)-1] = *str; @@ -121,12 +191,18 @@ int main(int argc, char **argv) } } else { // Other arguments will be firmware variable requests. + argcount++; SetOrGetOFVariable(str); } } - + + // radar:25206371 + if (argcount == 0 && gUseForceSync == true) { + NVRamSyncNow(""); + } + IOObjectRelease(gOptionsRef); - + return 0; } @@ -137,7 +213,7 @@ int main(int argc, char **argv) static void UsageMessage(char *message) { warnx("(usage: %s)", message); - + printf("%s [-x] [-p] [-f filename] [-d name] [-c] name[=value] ...\n", gToolName); printf("\t-x use XML format for printing or reading variables\n"); printf("\t (must appear before -p or -f)\n"); @@ -145,10 +221,13 @@ static void UsageMessage(char *message) printf("\t-f set firmware variables from a text file\n"); printf("\t-d delete the named variable\n"); printf("\t-c delete all variables\n"); +#if TARGET_OS_BRIDGE + printf("\t-m set nvram variables on macOS from bridgeOS\n"); +#endif printf("\tname=value set named variable\n"); printf("\tname print variable\n"); printf("Note that arguments and options are executed in order.\n"); - + exit(1); } @@ -163,7 +242,7 @@ enum { kCollectValue, kContinueValue, kSetenv, - + kMaxStringSize = 0x800, kMaxNameSize = 0x100 }; @@ -175,7 +254,8 @@ enum { // static void ParseFile(char *fileName) { - long state, tc, ni = 0, vi = 0; + long state, ni = 0, vi = 0; + int tc; char name[kMaxNameSize]; char value[kMaxStringSize]; FILE *patches; @@ -185,15 +265,15 @@ static void ParseFile(char *fileName) ParseXMLFile(fileName); return; } - + patches = fopen(fileName, "r"); if (patches == 0) { err(1, "Couldn't open patch file - '%s'", fileName); } - + state = kFirstColumn; while ((tc = getc(patches)) != EOF) { - if(ni==(kMaxNameSize-1)) + if(ni==(kMaxNameSize-1)) errx(1, "Name exceeded max length of %d", kMaxNameSize); if(vi==(kMaxStringSize-1)) errx(1, "Value exceeded max length of %d", kMaxStringSize); @@ -212,7 +292,7 @@ static void ParseFile(char *fileName) name[ni++] = tc; } break; - + case kScanComment : if (tc == '\n') { state = kFirstColumn; @@ -220,7 +300,7 @@ static void ParseFile(char *fileName) // state stays kScanComment. } break; - + case kFindName : if (tc == '\n') { state = kFirstColumn; @@ -231,7 +311,7 @@ static void ParseFile(char *fileName) name[ni++] = tc; } break; - + case kCollectName : if (tc == '\n') { name[ni] = 0; @@ -244,7 +324,7 @@ static void ParseFile(char *fileName) // state staus kCollectName. } break; - + case kFindValue : case kContinueValue : if (tc == '\n') { @@ -256,7 +336,7 @@ static void ParseFile(char *fileName) value[vi++] = tc; } break; - + case kCollectValue : if (tc == '\n') { if (value[vi-1] == '\\') { @@ -271,7 +351,7 @@ static void ParseFile(char *fileName) } break; } - + if (state == kSetenv) { name[ni] = 0; value[vi] = 0; @@ -282,13 +362,12 @@ static void ParseFile(char *fileName) state = kFirstColumn; } } - + if (state != kFirstColumn) { errx(1, "Last line ended abruptly"); } } - // ParseXMLFile(fileName) // // Open and parse the specified file in XML format, @@ -297,55 +376,64 @@ static void ParseFile(char *fileName) static void ParseXMLFile(char *fileName) { CFPropertyListRef plist; - CFURLRef fileURL = NULL; - CFStringRef filePath = NULL; - CFStringRef errorString = NULL; - CFDataRef data = NULL; - SInt32 errorCode = 0; - - filePath = CFStringCreateWithCString(kCFAllocatorDefault, fileName, kCFStringEncodingUTF8); - if (filePath == NULL) { - errx(1, "Could not create file path string"); + int fd; + struct stat sb; + char *buffer; + CFReadStreamRef stream; + CFPropertyListFormat format = kCFPropertyListBinaryFormat_v1_0; + + fd = open(fileName, O_RDONLY | O_NOFOLLOW, S_IFREG); + if (fd == -1) { + errx(1, "Could not open %s: %s", fileName, strerror(errno)); } - // Create a URL that specifies the file we will create to - // hold the XML data. - fileURL = CFURLCreateWithFileSystemPath( kCFAllocatorDefault, - filePath, - kCFURLPOSIXPathStyle, - false /* not a directory */ ); - if (fileURL == NULL) { - errx(1, "Could not create file path URL"); + if (fstat(fd, &sb) == -1) { + errx(1, "Could not fstat %s: %s", fileName, strerror(errno)); } - CFRelease(filePath); + if (sb.st_size > UINT32_MAX) { + errx(1, "too big for our purposes"); + } - if (! CFURLCreateDataAndPropertiesFromResource( - kCFAllocatorDefault, - fileURL, - &data, - NULL, - NULL, - &errorCode) || data == NULL ) { - errx(1, "Error reading XML file (%d)", (int)errorCode); + buffer = malloc((size_t)sb.st_size); + if (buffer == NULL) { + errx(1, "Could not allocate buffer"); } - CFRelease(fileURL); + if (read(fd, buffer, (size_t)sb.st_size) != sb.st_size) { + errx(1, "Could not read %s: %s", fileName, strerror(errno)); + } + + close(fd); + + stream = CFReadStreamCreateWithBytesNoCopy(kCFAllocatorDefault, + (const UInt8 *)buffer, + (CFIndex)sb.st_size, + kCFAllocatorNull); + if (stream == NULL) { + errx(1, "Could not create stream from serialized data"); + } - plist = CFPropertyListCreateFromXMLData(kCFAllocatorDefault, - data, - kCFPropertyListImmutable, - &errorString); + if (!CFReadStreamOpen(stream)) { + errx(1, "Could not open the stream"); + } - CFRelease(data); + plist = CFPropertyListCreateWithStream(kCFAllocatorDefault, + stream, + (CFIndex)sb.st_size, + kCFPropertyListImmutable, + &format, + NULL); if (plist == NULL) { errx(1, "Error parsing XML file"); } - if (errorString != NULL) { - errx(1, "Error parsing XML file: %s", CFStringGetCStringPtr(errorString, kCFStringEncodingUTF8)); - } + CFReadStreamClose(stream); + + CFRelease(stream); + + free(buffer); CFDictionaryApplyFunction(plist, &SetOFVariableFromFile, 0); @@ -365,10 +453,10 @@ static void SetOrGetOFVariable(char *str) CFStringRef nameRef; CFTypeRef valueRef; kern_return_t result; - + // OF variable name is first. name = str; - + // Find the equal sign for set while (*str) { if (*str == '=') { @@ -378,30 +466,97 @@ static void SetOrGetOFVariable(char *str) } str++; } - + if (set == 1) { // On sets, the OF variable's value follows the equal sign. value = str; - - result = SetOFVariable(name, value); - NVRamSyncNow(name); /* Try syncing the new data to device, best effort! */ +#if TARGET_OS_BRIDGE + if (gBridgeToIntel) { + result = SetMacOFVariable(name, value); + } + else +#endif + { + result = SetOFVariable(name, value); + NVRamSyncNow(name); /* Try syncing the new data to device, best effort! */ + } if (result != KERN_SUCCESS) { errx(1, "Error setting variable - '%s': %s", name, mach_error_string(result)); } } else { - result = GetOFVariable(name, &nameRef, &valueRef); - if (result != KERN_SUCCESS) { - errx(1, "Error getting variable - '%s': %s", name, - mach_error_string(result)); +#if TARGET_OS_BRIDGE + if (gBridgeToIntel) { + result = GetMacOFVariable(name, &value); + if (result != KERN_SUCCESS) { + errx(1, "Error getting variable - '%s': %s", name, + mach_error_string(result)); + } + nameRef = CFStringCreateWithCString(kCFAllocatorDefault, name, kCFStringEncodingUTF8); + valueRef = CFStringCreateWithCString(kCFAllocatorDefault, value, kCFStringEncodingUTF8); + free(value); } - + else +#endif + { + result = GetOFVariable(name, &nameRef, &valueRef); + if (result != KERN_SUCCESS) { + errx(1, "Error getting variable - '%s': %s", name, + mach_error_string(result)); + } + } + PrintOFVariable(nameRef, valueRef, 0); CFRelease(nameRef); CFRelease(valueRef); } } +#if TARGET_OS_BRIDGE +static kern_return_t LinkMacNVRAMSymbols() +{ + gDL_handle = dlopen("libMacEFIHostInterface.dylib", RTLD_LAZY); + if (gDL_handle == NULL) { + errx(errno, "Failed to dlopen libMacEFIHostInterface.dylib"); + return KERN_FAILURE; /* NOTREACHED */ + } + + hostInterfaceInitialize_fptr = dlsym(gDL_handle, "hostInterfaceInitialize"); + if (hostInterfaceInitialize_fptr == NULL) { + errx(errno, "failed to link hostInterfaceInitialize"); + } + createNvramHostInterface_fptr = dlsym(gDL_handle, "createNvramHostInterface"); + if (createNvramHostInterface_fptr == NULL) { + errx(errno, "failed to link createNvramHostInterface"); + } + destroyNvramHostInterface_fptr = dlsym(gDL_handle, "destroyNvramHostInterface"); + if (destroyNvramHostInterface_fptr == NULL) { + errx(errno, "failed to link destroyNvramHostInterface"); + } + getNVRAMVariable_fptr = dlsym(gDL_handle, "getNVRAMVariable"); + if (getNVRAMVariable_fptr == NULL) { + errx(errno, "failed to link getNVRAMVariable"); + } + setNVRAMVariable_fptr = dlsym(gDL_handle, "setNVRAMVariable"); + if (setNVRAMVariable_fptr == NULL) { + errx(errno, "failed to link setNVRAMVariable"); + } + deleteNVRAMVariable_fptr = dlsym(gDL_handle, "deleteNVRAMVariable"); + if (deleteNVRAMVariable_fptr == NULL) { + errx(errno, "failed to link deleteNVRAMVariable"); + } + hostInterfaceDeinitialize_fptr = dlsym(gDL_handle, "hostInterfaceDeinitialize"); + if (hostInterfaceDeinitialize_fptr == NULL) { + errx(errno, "failed to link hostInterfaceDeinitialize"); + } + + /* also do the initialization */ + hostInterfaceInitialize_fptr(); + gNvramInterface = createNvramHostInterface_fptr(NULL); + + return KERN_SUCCESS; +} +#endif // GetOFVariable(name, nameRef, valueRef) // @@ -416,13 +571,26 @@ static kern_return_t GetOFVariable(char *name, CFStringRef *nameRef, if (*nameRef == 0) { errx(1, "Error creating CFString for key %s", name); } - + *valueRef = IORegistryEntryCreateCFProperty(gOptionsRef, *nameRef, 0, 0); if (*valueRef == 0) return kIOReturnNotFound; - + return KERN_SUCCESS; } +#if TARGET_OS_BRIDGE +// GetMacOFVariable(name, value) +// +// Get the named firmware variable from the Intel side. +// Return the value in value +// +static kern_return_t GetMacOFVariable(char *name, char **value) +{ + uint32_t value_size; + + return getNVRAMVariable_fptr(gNvramInterface, name, value, &value_size); +} +#endif // SetOFVariable(name, value) // @@ -434,84 +602,101 @@ static kern_return_t SetOFVariable(char *name, char *value) CFTypeRef valueRef; CFTypeID typeID; kern_return_t result = KERN_SUCCESS; - - nameRef = CFStringCreateWithCString(kCFAllocatorDefault, name, - kCFStringEncodingUTF8); - if (nameRef == 0) { - errx(1, "Error creating CFString for key %s", name); - } - - valueRef = IORegistryEntryCreateCFProperty(gOptionsRef, nameRef, 0, 0); - if (valueRef) { - typeID = CFGetTypeID(valueRef); - CFRelease(valueRef); - - valueRef = ConvertValueToCFTypeRef(typeID, value); - if (valueRef == 0) { - errx(1, "Error creating CFTypeRef for value %s", value); - } result = IORegistryEntrySetCFProperty(gOptionsRef, nameRef, valueRef); - } else { - while (1) { - // In the default case, try data, string, number, then boolean. - - valueRef = ConvertValueToCFTypeRef(CFDataGetTypeID(), value); - if (valueRef != 0) { - result = IORegistryEntrySetCFProperty(gOptionsRef, nameRef, valueRef); - if (result == KERN_SUCCESS) break; - } - - valueRef = ConvertValueToCFTypeRef(CFStringGetTypeID(), value); - if (valueRef != 0) { - result = IORegistryEntrySetCFProperty(gOptionsRef, nameRef, valueRef); - if (result == KERN_SUCCESS) break; - } - - valueRef = ConvertValueToCFTypeRef(CFNumberGetTypeID(), value); - if (valueRef != 0) { - result = IORegistryEntrySetCFProperty(gOptionsRef, nameRef, valueRef); - if (result == KERN_SUCCESS) break; - } - - valueRef = ConvertValueToCFTypeRef(CFBooleanGetTypeID(), value); - if (valueRef != 0) { - result = IORegistryEntrySetCFProperty(gOptionsRef, nameRef, valueRef); - if (result == KERN_SUCCESS) break; - } - - break; + + nameRef = CFStringCreateWithCString(kCFAllocatorDefault, name, + kCFStringEncodingUTF8); + if (nameRef == 0) { + errx(1, "Error creating CFString for key %s", name); } - } - + + valueRef = IORegistryEntryCreateCFProperty(gOptionsRef, nameRef, 0, 0); + if (valueRef) { + typeID = CFGetTypeID(valueRef); + CFRelease(valueRef); + + valueRef = ConvertValueToCFTypeRef(typeID, value); + if (valueRef == 0) { + errx(1, "Error creating CFTypeRef for value %s", value); + } result = IORegistryEntrySetCFProperty(gOptionsRef, nameRef, valueRef); + } else { + while (1) { + // In the default case, try data, string, number, then boolean. + + valueRef = ConvertValueToCFTypeRef(CFDataGetTypeID(), value); + if (valueRef != 0) { + result = IORegistryEntrySetCFProperty(gOptionsRef, nameRef, valueRef); + if (result == KERN_SUCCESS) break; + } + + valueRef = ConvertValueToCFTypeRef(CFStringGetTypeID(), value); + if (valueRef != 0) { + result = IORegistryEntrySetCFProperty(gOptionsRef, nameRef, valueRef); + if (result == KERN_SUCCESS) break; + } + + valueRef = ConvertValueToCFTypeRef(CFNumberGetTypeID(), value); + if (valueRef != 0) { + result = IORegistryEntrySetCFProperty(gOptionsRef, nameRef, valueRef); + if (result == KERN_SUCCESS) break; + } + + valueRef = ConvertValueToCFTypeRef(CFBooleanGetTypeID(), value); + if (valueRef != 0) { + result = IORegistryEntrySetCFProperty(gOptionsRef, nameRef, valueRef); + if (result == KERN_SUCCESS) break; + } + + break; + } + } + CFRelease(nameRef); - + return result; } +#if TARGET_OS_BRIDGE +static kern_return_t SetMacOFVariable(char *name, char *value) +{ + return setNVRAMVariable_fptr(gNvramInterface, name, value); +} +#endif // DeleteOFVariable(name) // // Delete the named firmware variable. -// +// // static void DeleteOFVariable(char *name) { SetOFVariable(kIONVRAMDeletePropertyKey, name); } +#if TARGET_OS_BRIDGE +static kern_return_t DeleteMacOFVariable(char *name) +{ + return deleteNVRAMVariable_fptr(gNvramInterface, name); +} +#endif + static void NVRamSyncNow(char *name) { - SetOFVariable(kIONVRAMSyncNowPropertyKey, name); + if (!gUseForceSync) { + SetOFVariable(kIONVRAMSyncNowPropertyKey, name); + } else { + SetOFVariable(kIONVRAMForceSyncNowPropertyKey, name); + } } // PrintOFVariables() // // Print all of the firmware variables. // -static void PrintOFVariables() +static void PrintOFVariables(void) { kern_return_t result; CFMutableDictionaryRef dict; - + result = IORegistryEntryCreateCFProperties(gOptionsRef, &dict, 0, 0); if (result != KERN_SUCCESS) { errx(1, "Error getting the firmware variables: %s", mach_error_string(result)); @@ -520,7 +705,7 @@ static void PrintOFVariables() if (gUseXML) { CFDataRef data; - data = CFPropertyListCreateXMLData( kCFAllocatorDefault, dict ); + data = CFPropertyListCreateData( kCFAllocatorDefault, dict, kCFPropertyListXMLFormat_v1_0, 0, NULL ); if (data == NULL) { errx(1, "Error converting variables to xml"); } @@ -534,7 +719,7 @@ static void PrintOFVariables() CFDictionaryApplyFunction(dict, &PrintOFVariable, 0); } - + CFRelease(dict); } @@ -555,11 +740,33 @@ static void PrintOFVariable(const void *key, const void *value, void *context) CFIndex valueLen; char *valueBuffer = 0; const char *valueString = 0; - uint32_t number, length; + uint32_t number; + long length; CFTypeID typeID; - + + if (gUseXML) { + CFDataRef data; + CFDictionaryRef dict = CFDictionaryCreate(kCFAllocatorDefault, &key, &value, 1, + &kCFTypeDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks); + if (dict == NULL) { + errx(1, "Error creating dictionary for variable value"); + } + + data = CFPropertyListCreateData( kCFAllocatorDefault, dict, kCFPropertyListXMLFormat_v1_0, 0, NULL ); + if (data == NULL) { + errx(1, "Error creating xml plist for variable"); + } + + fwrite(CFDataGetBytePtr(data), sizeof(UInt8), CFDataGetLength(data), stdout); + + CFRelease(dict); + CFRelease(data); + return; + } + // Get the OF variable's name. - nameLen = CFStringGetLength(key) + 1; + nameLen = CFStringGetMaximumSizeForEncoding(CFStringGetLength(key), + kCFStringEncodingUTF8) + 1; nameBuffer = malloc(nameLen); if( nameBuffer && CFStringGetCString(key, nameBuffer, nameLen, kCFStringEncodingUTF8) ) nameString = nameBuffer; @@ -567,10 +774,10 @@ static void PrintOFVariable(const void *key, const void *value, void *context) warnx("Unable to convert property name to C string"); nameString = ""; } - + // Get the OF variable's type. typeID = CFGetTypeID(value); - + if (typeID == CFBooleanGetTypeID()) { if (CFBooleanGetValue(value)) valueString = "true"; else valueString = "false"; @@ -581,7 +788,8 @@ static void PrintOFVariable(const void *key, const void *value, void *context) else sprintf(numberBuffer, "0x%x", number); valueString = numberBuffer; } else if (typeID == CFStringGetTypeID()) { - valueLen = CFStringGetLength(value) + 1; + valueLen = CFStringGetMaximumSizeForEncoding(CFStringGetLength(value), + kCFStringEncodingUTF8) + 1; valueBuffer = malloc(valueLen + 1); if ( valueBuffer && CFStringGetCString(value, valueBuffer, valueLen, kCFStringEncodingUTF8) ) valueString = valueBuffer; @@ -612,10 +820,10 @@ static void PrintOFVariable(const void *key, const void *value, void *context) } else { valueString=""; } - + if ((nameString != 0) && (valueString != 0)) printf("%s\t%s\n", nameString, valueString); - + if (dataBuffer != 0) free(dataBuffer); if (nameBuffer != 0) free(nameBuffer); if (valueBuffer != 0) free(valueBuffer); @@ -655,39 +863,39 @@ static void ClearOFVariable(const void *key, const void *value, void *context) // static CFTypeRef ConvertValueToCFTypeRef(CFTypeID typeID, char *value) { - CFTypeRef valueRef = 0; - long cnt, cnt2, length; - unsigned long number, tmp; - - if (typeID == CFBooleanGetTypeID()) { - if (!strcmp("true", value)) valueRef = kCFBooleanTrue; - else if (!strcmp("false", value)) valueRef = kCFBooleanFalse; - } else if (typeID == CFNumberGetTypeID()) { - number = strtol(value, 0, 0); - valueRef = CFNumberCreate(kCFAllocatorDefault, kCFNumberSInt32Type, - &number); - } else if (typeID == CFStringGetTypeID()) { - valueRef = CFStringCreateWithCString(kCFAllocatorDefault, value, - kCFStringEncodingUTF8); - } else if (typeID == CFDataGetTypeID()) { - length = strlen(value); - for (cnt = cnt2 = 0; cnt < length; cnt++, cnt2++) { - if (value[cnt] == '%') { - if (!ishexnumber(value[cnt + 1]) || - !ishexnumber(value[cnt + 2])) return 0; - number = toupper(value[++cnt]) - '0'; - if (number > 9) number -= 7; - tmp = toupper(value[++cnt]) - '0'; - if (tmp > 9) tmp -= 7; - number = (number << 4) + tmp; - value[cnt2] = number; - } else value[cnt2] = value[cnt]; - } - valueRef = CFDataCreateWithBytesNoCopy(kCFAllocatorDefault, (const UInt8 *)value, - cnt2, kCFAllocatorDefault); - } else return 0; - - return valueRef; + CFTypeRef valueRef = 0; + long cnt, cnt2, length; + unsigned long number, tmp; + + if (typeID == CFBooleanGetTypeID()) { + if (!strcmp("true", value)) valueRef = kCFBooleanTrue; + else if (!strcmp("false", value)) valueRef = kCFBooleanFalse; + } else if (typeID == CFNumberGetTypeID()) { + number = strtol(value, 0, 0); + valueRef = CFNumberCreate(kCFAllocatorDefault, kCFNumberSInt32Type, + &number); + } else if (typeID == CFStringGetTypeID()) { + valueRef = CFStringCreateWithCString(kCFAllocatorDefault, value, + kCFStringEncodingUTF8); + } else if (typeID == CFDataGetTypeID()) { + length = strlen(value); + for (cnt = cnt2 = 0; cnt < length; cnt++, cnt2++) { + if (value[cnt] == '%') { + if (!ishexnumber(value[cnt + 1]) || + !ishexnumber(value[cnt + 2])) return 0; + number = toupper(value[++cnt]) - '0'; + if (number > 9) number -= 7; + tmp = toupper(value[++cnt]) - '0'; + if (tmp > 9) tmp -= 7; + number = (number << 4) + tmp; + value[cnt2] = number; + } else value[cnt2] = value[cnt]; + } + valueRef = CFDataCreateWithBytesNoCopy(kCFAllocatorDefault, (const UInt8 *)value, + cnt2, kCFAllocatorDefault); + } else return 0; + + return valueRef; } static void SetOFVariableFromFile(const void *key, const void *value, void *context) @@ -696,12 +904,13 @@ static void SetOFVariableFromFile(const void *key, const void *value, void *cont result = IORegistryEntrySetCFProperty(gOptionsRef, key, value); if ( result != KERN_SUCCESS ) { - int nameLen; + long nameLen; char *nameBuffer; char *nameString; // Get the variable's name. - nameLen = CFStringGetLength(key) + 1; + nameLen = CFStringGetMaximumSizeForEncoding(CFStringGetLength(key), + kCFStringEncodingUTF8) + 1; nameBuffer = malloc(nameLen); if( nameBuffer && CFStringGetCString(key, nameBuffer, nameLen, kCFStringEncodingUTF8) ) nameString = nameBuffer;