}
}
-kern_return_t collect_per_task_info(my_per_task_info_t *taskinfo, task_t target_task)
+kern_return_t collect_per_task_info(my_per_task_info_t *taskinfo, task_read_t target_task)
{
int i;
kern_return_t ret = KERN_SUCCESS;
taskinfo->task = target_task;
pid_for_task(target_task, &taskinfo->pid);
- ret = task_get_exception_ports(taskinfo->task, EXC_MASK_ALL, taskinfo->exceptionInfo.masks, &taskinfo->exceptionInfo.count, taskinfo->exceptionInfo.ports, taskinfo->exceptionInfo.behaviors, taskinfo->exceptionInfo.flavors);
+ ret = task_get_exception_ports_info(taskinfo->task, EXC_MASK_ALL, taskinfo->exceptionInfo.masks, &taskinfo->exceptionInfo.count, taskinfo->exceptionInfo.ports_info, taskinfo->exceptionInfo.behaviors, taskinfo->exceptionInfo.flavors);
if (ret != KERN_SUCCESS) {
- fprintf(stderr, "task_get_exception_ports() failed: pid:%d error: %s\n",taskinfo->pid, mach_error_string(ret));
+ fprintf(stderr, "task_get_exception_ports_info() failed: pid:%d error: %s\n",taskinfo->pid, mach_error_string(ret));
taskinfo->pid = 0;
}
mach_msg_type_number_t th_info_count = THREAD_IDENTIFIER_INFO_COUNT;
struct exc_port_info *excinfo = &(taskinfo->threadExceptionInfos[i]);
- ret = thread_get_exception_ports(threadPorts[i], EXC_MASK_ALL, excinfo->masks, &excinfo->count, excinfo->ports, excinfo->behaviors, excinfo->flavors);
+ ret = thread_get_exception_ports_info(threadPorts[i], EXC_MASK_ALL, excinfo->masks, &excinfo->count, excinfo->ports_info, excinfo->behaviors, excinfo->flavors);
if (ret != KERN_SUCCESS){
- fprintf(stderr, "thread_get_exception_ports() failed: pid: %d thread: %d error %s\n", taskinfo->pid, threadPorts[i], mach_error_string(ret));
+ fprintf(stderr, "thread_get_exception_ports_info() failed: pid: %d thread: %d error %s\n", taskinfo->pid, threadPorts[i], mach_error_string(ret));
}
if (excinfo->count != 0) {
proc_pid_to_name(taskinfo->pid, taskinfo->processName);
ret = mach_port_kernel_object(mach_task_self(), taskinfo->task, &kotype, (unsigned *)&kobject);
-
- if (ret == KERN_SUCCESS && kotype == IKOT_TASK_CONTROL) {
+
+ /* Now that we are using read ports, kotype should be checked against IKOT_TASK_READ */
+ if (ret == KERN_SUCCESS && kotype == IKOT_TASK_READ) {
taskinfo->task_kobject = kobject;
taskinfo->valid = TRUE;
}
boolean_t header_required = TRUE;
for (int i = 0; i < taskinfo->exceptionInfo.count; i++) {
- if (taskinfo->exceptionInfo.ports[i] != MACH_PORT_NULL) {
+ if (taskinfo->exceptionInfo.ports_info[i].iip_port_object != 0) {
+ my_per_task_info_t * _found_task;
+
if (header_required) {
- printf(" exc_port flavor <behaviors> mask \n");
+ printf(" exc_port_object receiver_task flavor <behaviors> mask \n");
header_required = FALSE;
}
get_exc_behavior_string(taskinfo->exceptionInfo.behaviors[i], behavior_string, sizeof(behavior_string));
get_exc_mask_string(taskinfo->exceptionInfo.masks[i], mask_string, sizeof(mask_string));
JSON_OBJECT_BEGIN(json);
- JSON_OBJECT_SET(json, port, "0x%08x", taskinfo->exceptionInfo.ports[i]);
+ JSON_OBJECT_SET(json, port_object, "0x%08x", taskinfo->exceptionInfo.ports_info[i].iip_port_object);
+ JSON_OBJECT_SET(json, receiver_object, "0x%08x", taskinfo->exceptionInfo.ports_info[i].iip_receiver_object);
JSON_OBJECT_SET(json, flavor, "0x%03x", taskinfo->exceptionInfo.flavors[i]);
JSON_OBJECT_SET(json, behavior, "%s", behavior_string);
JSON_OBJECT_SET(json, mask, "%s", mask_string);
JSON_OBJECT_END(json); // exception port
-
- printf(" 0x%08x 0x%03x <%s> %s \n" , taskinfo->exceptionInfo.ports[i], taskinfo->exceptionInfo.flavors[i], behavior_string, mask_string);
+
+ _found_task = get_taskinfo_by_kobject((natural_t)taskinfo->exceptionInfo.ports_info[i].iip_receiver_object);
+
+ printf(" 0x%08x (%d) %s 0x%03x <%s> %s \n",
+ taskinfo->exceptionInfo.ports_info[i].iip_port_object,
+ _found_task->pid,
+ _found_task->processName,
+ taskinfo->exceptionInfo.flavors[i], behavior_string, mask_string);
}
}
for (int i = 0; i < excinfo->count; i++) {
JSON_OBJECT_BEGIN(json);
- if (excinfo->ports[i] != MACH_PORT_NULL) {
+ if (excinfo->ports_info[i].iip_port_object != 0) {
if (header_required) {
- printf("\n exc_port flavor <behaviors> mask -> name owner\n");
+ printf("\n exc_port_object exc_port_receiver flavor <behaviors> mask -> name owner\n");
header_required = FALSE;
}
get_exc_behavior_string(excinfo->behaviors[i], behavior_string, sizeof(behavior_string));
get_exc_mask_string(excinfo->masks[i], mask_string, sizeof(mask_string));
- JSON_OBJECT_SET(json, port, "0x%08x", excinfo->ports[i]);
+ JSON_OBJECT_SET(json, port_object, "0x%08x", excinfo->ports_info[i].iip_port_object);
+ JSON_OBJECT_SET(json, receiver_object, "0x%08x", excinfo->ports_info[i].iip_receiver_object);
JSON_OBJECT_SET(json, flavor, "0x%03x", excinfo->flavors[i]);
JSON_OBJECT_SET(json, behavior, "%s", behavior_string);
JSON_OBJECT_SET(json, mask, "%s", mask_string);
- printf(" 0x%08x 0x%03x <%s> %s " , excinfo->ports[i], excinfo->flavors[i], behavior_string, mask_string);
-
- ipc_info_name_t actual_sendinfo;
- if (KERN_SUCCESS == get_ipc_info_from_lsmp_spaceinfo(excinfo->ports[i], &actual_sendinfo)) {
- my_per_task_info_t *recv_holder_taskinfo;
- mach_port_name_t recv_name = MACH_PORT_NULL;
- if (KERN_SUCCESS == get_taskinfo_of_receiver_by_send_right(&actual_sendinfo, &recv_holder_taskinfo, &recv_name)) {
-
- JSON_OBJECT_SET(json, name, "0x%08x", recv_name);
- JSON_OBJECT_SET(json, ipc-object, "0x%08x", actual_sendinfo.iin_object);
- JSON_OBJECT_SET(json, pid, %d, recv_holder_taskinfo->pid);
- JSON_OBJECT_SET(json, process, "%s", recv_holder_taskinfo->processName);
-
- printf(" -> 0x%08x 0x%08x (%d) %s\n",
- recv_name,
- actual_sendinfo.iin_object,
- recv_holder_taskinfo->pid,
- recv_holder_taskinfo->processName);
- }
-
+ printf(" 0x%08x 0x%08x 0x%03x <%s> %s " , excinfo->ports_info[i].iip_port_object, excinfo->ports_info[i].iip_receiver_object, excinfo->flavors[i], behavior_string, mask_string);
+
+ my_per_task_info_t *recv_holder_taskinfo;
+ mach_port_name_t recv_name = MACH_PORT_NULL;
+ if (KERN_SUCCESS == get_taskinfo_of_receiver_by_send_right_info(excinfo->ports_info[i], &recv_holder_taskinfo, &recv_name)) {
+ JSON_OBJECT_SET(json, name, "0x%08x", recv_name);
+ JSON_OBJECT_SET(json, ipc-object, "0x%08x", excinfo->ports_info[i].iip_port_object);
+ JSON_OBJECT_SET(json, pid, %d, recv_holder_taskinfo->pid);
+ JSON_OBJECT_SET(json, process, "%s", recv_holder_taskinfo->processName);
+
+ printf(" -> 0x%08x 0x%08x (%d) %s\n",
+ recv_name,
+ excinfo->ports_info[i].iip_port_object,
+ recv_holder_taskinfo->pid,
+ recv_holder_taskinfo->processName);
} else {
fprintf(stderr, "failed to find");
}
return retval;
}
-kern_return_t get_taskinfo_of_receiver_by_send_right(ipc_info_name_t *sendright, my_per_task_info_t **out_taskinfo, mach_port_name_t *out_recv_info)
+static kern_return_t _get_taskinfo_of_receiver_by_send_right(natural_t kobject, my_per_task_info_t **out_taskinfo, mach_port_name_t *out_recv_info)
{
*out_taskinfo = &NOT_FOUND_TASK_INFO;
struct k2n_table_node *k2nnode;
- for (int j = 0; j < global_taskcount; j++) {
- if ((k2nnode = k2n_table_lookup(global_taskinfo[j].k2ntable, sendright->iin_object))) {
- assert(k2nnode->info_name->iin_object == sendright->iin_object);
+ for (unsigned int j = 0; j < global_taskcount; j++) {
+ if ((k2nnode = k2n_table_lookup(global_taskinfo[j].k2ntable, kobject))) {
+ assert(k2nnode->info_name->iin_object == kobject);
if (k2nnode->info_name->iin_type & MACH_PORT_TYPE_RECEIVE) {
*out_taskinfo = &global_taskinfo[j];
return KERN_FAILURE;
}
-kern_return_t get_ipc_info_from_lsmp_spaceinfo(mach_port_t port_name, ipc_info_name_t *out_sendright){
- kern_return_t retval = KERN_FAILURE;
- bzero(out_sendright, sizeof(ipc_info_name_t));
- my_per_task_info_t *mytaskinfo = NULL;
- for (int i = global_taskcount - 1; i >= 0; i--){
- if (global_taskinfo[i].task == mach_task_self()){
- mytaskinfo = &global_taskinfo[i];
- break;
- }
- }
- if (mytaskinfo) {
- for (int k = 0; k < mytaskinfo->tableCount; k++) {
- if (port_name == mytaskinfo->table[k].iin_name){
- bcopy(&mytaskinfo->table[k], out_sendright, sizeof(ipc_info_name_t));
- retval = KERN_SUCCESS;
- break;
- }
- }
- }
- return retval;
+kern_return_t get_taskinfo_of_receiver_by_send_right(ipc_info_name_t sendright, my_per_task_info_t **out_taskinfo, mach_port_name_t *out_recv_info)
+{
+ return _get_taskinfo_of_receiver_by_send_right(sendright.iin_object, out_taskinfo, out_recv_info);
+}
+kern_return_t get_taskinfo_of_receiver_by_send_right_info(ipc_info_port_t sendright_info, my_per_task_info_t **out_taskinfo, mach_port_name_t *out_recv_info)
+{
+ return _get_taskinfo_of_receiver_by_send_right(sendright_info.iip_port_object, out_taskinfo, out_recv_info);
}
#include <sys/stat.h>
// Prototypes
-static void UsageMessage(char *message);
-static void ParseFile(char *fileName);
-static void ParseXMLFile(char *fileName);
+static void UsageMessage(const char *message);
+static void ParseFile(const char *fileName);
+static void ParseXMLFile(const char *fileName);
static void SetOrGetOFVariable(char *str);
-static kern_return_t GetOFVariable(char *name, CFStringRef *nameRef,
- CFTypeRef *valueRef);
-static kern_return_t SetOFVariable(char *name, char *value);
-static void DeleteOFVariable(char *name);
+static kern_return_t GetOFVariable(const char *name, CFStringRef *nameRef,
+ CFTypeRef *valueRef);
+static kern_return_t SetOFVariable(const char *name, const char *value);
+static void DeleteOFVariable(const char *name);
static void PrintOFVariables(void);
static void PrintOFVariable(const void *key,const void *value,void *context);
static void SetOFVariableFromFile(const void *key, const void *value, void *context);
static void ClearOFVariables(void);
static void ClearOFVariable(const void *key,const void *value,void *context);
-static CFTypeRef ConvertValueToCFTypeRef(CFTypeID typeID, char *value);
+static CFTypeRef ConvertValueToCFTypeRef(CFTypeID typeID, const char *value);
-static void NVRamSyncNow(char *name);
+static void NVRamSyncNow(void);
// Global Variables
-static char *gToolName;
static io_registry_entry_t gOptionsRef;
+static io_registry_entry_t gSystemOptionsRef;
+static io_registry_entry_t gSelectedOptionsRef;
static bool gUseXML;
static bool gUseForceSync;
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];
+ int argcount = 0;
result = IOMasterPort(bootstrap_port, &masterPort);
if (result != KERN_SUCCESS) {
errx(1, "nvram is not supported on this system");
}
+ gSystemOptionsRef = IORegistryEntryFromPath(masterPort, "IOService:/options/options-system");
+
+ gSelectedOptionsRef = gOptionsRef;
+
for (cnt = 1; cnt < argc; cnt++) {
str = argv[cnt];
if (str[0] == '-' && str[1] != 0) {
// Parse the options.
for (str += 1 ; *str; str++) {
- switch (*str) {
- case 'p' :
+ switch (*str) {
+ case 'p' :
#if TARGET_OS_BRIDGE
- if (gBridgeToIntel) {
- fprintf(stderr, "-p not supported for Mac NVRAM store.\n");
- return 1;
- }
+ if (gBridgeToIntel) {
+ fprintf(stderr, "-p not supported for Mac NVRAM store.\n");
+ return 1;
+ }
#endif
- PrintOFVariables();
- break;
+ PrintOFVariables();
+ break;
- case 'x' :
- gUseXML = true;
- break;
+ case 'x' :
+ gUseXML = true;
+ break;
- case 'f':
+ case 'f':
#if TARGET_OS_BRIDGE
- if (gBridgeToIntel) {
- fprintf(stderr, "-f not supported for Mac NVRAM store.\n");
- return 1;
- }
+ if (gBridgeToIntel) {
+ fprintf(stderr, "-f not supported for Mac NVRAM store.\n");
+ return 1;
+ }
#endif
- cnt++;
- if (cnt < argc && *argv[cnt] != '-') {
- ParseFile(argv[cnt]);
- } else {
- UsageMessage("missing filename");
- }
- break;
-
- case 'd':
- cnt++;
- if (cnt < argc && *argv[cnt] != '-') {
+ cnt++;
+ if (cnt < argc && *argv[cnt] != '-') {
+ ParseFile(argv[cnt]);
+ } else {
+ UsageMessage("missing filename");
+ }
+ break;
+
+ case 'd':
+ cnt++;
+ if (cnt < argc && *argv[cnt] != '-') {
#if TARGET_OS_BRIDGE
- if (gBridgeToIntel) {
- if ((result = DeleteMacOFVariable(argv[cnt])) != KERN_SUCCESS) {
+ 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
+ else
#endif
- {
- DeleteOFVariable(argv[cnt]);
- }
- } else {
- UsageMessage("missing name");
- }
- break;
+ {
+ DeleteOFVariable(argv[cnt]);
+ }
+ } else {
+ UsageMessage("missing name");
+ }
+ break;
- case 'c':
+ case 'c':
#if TARGET_OS_BRIDGE
- if (gBridgeToIntel) {
- fprintf(stderr, "-c not supported for Mac NVRAM store.\n");
- return 1;
- }
+ 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;
+ 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;
+ 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;
- UsageMessage(errorMessage);
- }
+ case 'z':
+ // -z option is unadvertised -- attempts to use the options-system node
+ // to write to the system NVRAM region if available
+ if (gSystemOptionsRef) {
+ fprintf(stderr, "Selecting options-system node.\n");
+ gSelectedOptionsRef = gSystemOptionsRef;
+ } else {
+ fprintf(stderr, "No options-system node, using options.\n");
+ }
+ break;
+
+ default:
+ strcpy(errorMessage, "no such option as --");
+ errorMessage[strlen(errorMessage)-1] = *str;
+ UsageMessage(errorMessage);
+ }
+ }
+ } else {
+ // Other arguments will be firmware variable requests.
+ argcount++;
+ SetOrGetOFVariable(str);
}
- } else {
- // Other arguments will be firmware variable requests.
- argcount++;
- SetOrGetOFVariable(str);
- }
}
// radar:25206371
if (argcount == 0 && gUseForceSync == true) {
- NVRamSyncNow("");
+ NVRamSyncNow();
}
IOObjectRelease(gOptionsRef);
+ if (gSystemOptionsRef) {
+ IOObjectRelease(gSystemOptionsRef);
+ }
+
return 0;
}
//
// Print the usage information and exit.
//
-static void UsageMessage(char *message)
+static void UsageMessage(const char *message)
{
warnx("(usage: %s)", message);
- printf("%s [-x] [-p] [-f filename] [-d name] [-c] name[=value] ...\n", gToolName);
+ printf("nvram [-x] [-p] [-f filename] [-d name] [-c] name[=value] ...\n");
printf("\t-x use XML format for printing or reading variables\n");
printf("\t (must appear before -p or -f)\n");
printf("\t-p print all firmware variables\n");
//
// Open and parse the specified file.
//
-static void ParseFile(char *fileName)
+static void ParseFile(const char *fileName)
{
long state, ni = 0, vi = 0;
int tc;
ni = 0;
vi = 0;
if (tc == '#') {
- state = kScanComment;
+ state = kScanComment;
} else if (tc == '\n') {
- // state stays kFirstColumn.
+ // state stays kFirstColumn.
} else if (isspace(tc)) {
- state = kFindName;
+ state = kFindName;
} else {
- state = kCollectName;
- name[ni++] = tc;
+ state = kCollectName;
+ name[ni++] = tc;
}
break;
case kScanComment :
if (tc == '\n') {
- state = kFirstColumn;
+ state = kFirstColumn;
} else {
- // state stays kScanComment.
+ // state stays kScanComment.
}
break;
case kFindName :
if (tc == '\n') {
- state = kFirstColumn;
+ state = kFirstColumn;
} else if (isspace(tc)) {
- // state stays kFindName.
+ // state stays kFindName.
} else {
- state = kCollectName;
- name[ni++] = tc;
+ state = kCollectName;
+ name[ni++] = tc;
}
break;
case kCollectName :
if (tc == '\n') {
- name[ni] = 0;
- warnx("Name must be followed by white space - '%s'", name);
- state = kFirstColumn;
+ name[ni] = 0;
+ warnx("Name must be followed by white space - '%s'", name);
+ state = kFirstColumn;
} else if (isspace(tc)) {
- state = kFindValue;
+ state = kFindValue;
} else {
- name[ni++] = tc;
- // state staus kCollectName.
+ name[ni++] = tc;
+ // state staus kCollectName.
}
break;
case kFindValue :
case kContinueValue :
if (tc == '\n') {
- state = kSetenv;
+ state = kSetenv;
} else if (isspace(tc)) {
- // state stays kFindValue or kContinueValue.
+ // state stays kFindValue or kContinueValue.
} else {
- state = kCollectValue;
- value[vi++] = tc;
+ state = kCollectValue;
+ value[vi++] = tc;
}
break;
case kCollectValue :
if (tc == '\n') {
- if (value[vi-1] == '\\') {
- value[vi-1] = '\r';
- state = kContinueValue;
- } else {
- state = kSetenv;
- }
+ if (value[vi-1] == '\\') {
+ value[vi-1] = '\r';
+ state = kContinueValue;
+ } else {
+ state = kSetenv;
+ }
} else {
- // state stays kCollectValue.
- value[vi++] = tc;
+ // state stays kCollectValue.
+ value[vi++] = tc;
}
break;
}
// Open and parse the specified file in XML format,
// and set variables appropriately.
//
-static void ParseXMLFile(char *fileName)
+static void ParseXMLFile(const char *fileName)
{
- CFPropertyListRef plist;
- 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));
- }
+ CFPropertyListRef plist;
+ 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));
+ }
- if (fstat(fd, &sb) == -1) {
- errx(1, "Could not fstat %s: %s", fileName, strerror(errno));
- }
+ if (fstat(fd, &sb) == -1) {
+ errx(1, "Could not fstat %s: %s", fileName, strerror(errno));
+ }
- if (sb.st_size > UINT32_MAX) {
- errx(1, "too big for our purposes");
- }
+ if (sb.st_size > UINT32_MAX) {
+ errx(1, "too big for our purposes");
+ }
- buffer = malloc((size_t)sb.st_size);
- if (buffer == NULL) {
- errx(1, "Could not allocate buffer");
- }
+ buffer = malloc((size_t)sb.st_size);
+ if (buffer == NULL) {
+ errx(1, "Could not allocate buffer");
+ }
- if (read(fd, buffer, (size_t)sb.st_size) != sb.st_size) {
- errx(1, "Could not read %s: %s", fileName, strerror(errno));
- }
+ if (read(fd, buffer, (size_t)sb.st_size) != sb.st_size) {
+ errx(1, "Could not read %s: %s", fileName, strerror(errno));
+ }
- close(fd);
+ 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");
- }
+ stream = CFReadStreamCreateWithBytesNoCopy(kCFAllocatorDefault,
+ (const UInt8 *)buffer,
+ (CFIndex)sb.st_size,
+ kCFAllocatorNull);
+ if (stream == NULL) {
+ errx(1, "Could not create stream from serialized data");
+ }
- if (!CFReadStreamOpen(stream)) {
- errx(1, "Could not open the stream");
- }
+ if (!CFReadStreamOpen(stream)) {
+ errx(1, "Could not open the stream");
+ }
- plist = CFPropertyListCreateWithStream(kCFAllocatorDefault,
- stream,
- (CFIndex)sb.st_size,
- kCFPropertyListImmutable,
- &format,
- NULL);
+ plist = CFPropertyListCreateWithStream(kCFAllocatorDefault,
+ stream,
+ (CFIndex)sb.st_size,
+ kCFPropertyListImmutable,
+ &format,
+ NULL);
- if (plist == NULL) {
- errx(1, "Error parsing XML file");
- }
+ if (plist == NULL) {
+ errx(1, "Error parsing XML file");
+ }
- CFReadStreamClose(stream);
+ CFReadStreamClose(stream);
- CFRelease(stream);
+ CFRelease(stream);
- free(buffer);
+ free(buffer);
- CFDictionaryApplyFunction(plist, &SetOFVariableFromFile, 0);
+ CFDictionaryApplyFunction(plist, &SetOFVariableFromFile, 0);
- CFRelease(plist);
+ CFRelease(plist);
}
// SetOrGetOFVariable(str)
//
static void SetOrGetOFVariable(char *str)
{
- long set = 0;
- long append = 0;
- char *name;
- char *value;
+ long set = 0;
+ long append = 0;
+ const char *name;
+ char *value;
CFStringRef nameRef = NULL;
CFTypeRef valueRef = NULL;
CFMutableStringRef appended = NULL;
- kern_return_t result;
+ kern_return_t result;
// OF variable name is first.
name = str;
#endif
{
result = SetOFVariable(name, value);
- NVRamSyncNow(name); /* Try syncing the new data to device, best effort! */
+ /* Try syncing the new data to device, best effort! */
+ NVRamSyncNow();
}
if (result != KERN_SUCCESS) {
errx(1, "Error setting variable - '%s': %s", name,
} else {
PrintOFVariable(nameRef, valueRef, 0);
}
- if ( nameRef ) CFRelease(nameRef);
- if ( valueRef ) CFRelease(valueRef);
- if ( appended ) CFRelease(appended);
+ if (nameRef) CFRelease(nameRef);
+ if (valueRef) CFRelease(valueRef);
+ if (appended) CFRelease(appended);
}
#if TARGET_OS_BRIDGE
// Get the named firmware variable.
// Return it and it's symbol in valueRef and nameRef.
//
-static kern_return_t GetOFVariable(char *name, CFStringRef *nameRef,
- CFTypeRef *valueRef)
+static kern_return_t GetOFVariable(const char *name, CFStringRef *nameRef,
+ CFTypeRef *valueRef)
{
*nameRef = CFStringCreateWithCString(kCFAllocatorDefault, name,
- kCFStringEncodingUTF8);
+ kCFStringEncodingUTF8);
if (*nameRef == 0) {
errx(1, "Error creating CFString for key %s", name);
}
- *valueRef = IORegistryEntryCreateCFProperty(gOptionsRef, *nameRef, 0, 0);
+ *valueRef = IORegistryEntryCreateCFProperty(gSelectedOptionsRef, *nameRef, 0, 0);
if (*valueRef == 0) return kIOReturnNotFound;
return KERN_SUCCESS;
//
// Set or create an firmware variable with name and value.
//
-static kern_return_t SetOFVariable(char *name, char *value)
+static kern_return_t SetOFVariable(const char *name, const char *value)
{
CFStringRef nameRef;
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);
- }
+ 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 = IORegistryEntryCreateCFProperty(gSelectedOptionsRef, nameRef, 0, 0);
+ if (valueRef) {
+ typeID = CFGetTypeID(valueRef);
+ CFRelease(valueRef);
- valueRef = ConvertValueToCFTypeRef(CFStringGetTypeID(), value);
- if (valueRef != 0) {
- result = IORegistryEntrySetCFProperty(gOptionsRef, nameRef, valueRef);
- if (result == KERN_SUCCESS) break;
- }
+ valueRef = ConvertValueToCFTypeRef(typeID, value);
+ if (valueRef == 0) {
+ errx(1, "Error creating CFTypeRef for value %s", value);
+ } result = IORegistryEntrySetCFProperty(gSelectedOptionsRef, nameRef, valueRef);
+ } else {
+ while (1) {
+ // In the default case, try data, string, number, then boolean.
- valueRef = ConvertValueToCFTypeRef(CFNumberGetTypeID(), value);
- if (valueRef != 0) {
- result = IORegistryEntrySetCFProperty(gOptionsRef, nameRef, valueRef);
- if (result == KERN_SUCCESS) break;
- }
+ valueRef = ConvertValueToCFTypeRef(CFDataGetTypeID(), value);
+ if (valueRef != 0) {
+ result = IORegistryEntrySetCFProperty(gSelectedOptionsRef, nameRef, valueRef);
+ if (result == KERN_SUCCESS) break;
+ }
- valueRef = ConvertValueToCFTypeRef(CFBooleanGetTypeID(), value);
- if (valueRef != 0) {
- result = IORegistryEntrySetCFProperty(gOptionsRef, nameRef, valueRef);
- if (result == KERN_SUCCESS) break;
- }
+ valueRef = ConvertValueToCFTypeRef(CFStringGetTypeID(), value);
+ if (valueRef != 0) {
+ result = IORegistryEntrySetCFProperty(gSelectedOptionsRef, nameRef, valueRef);
+ if (result == KERN_SUCCESS) break;
+ }
- break;
- }
- }
+ valueRef = ConvertValueToCFTypeRef(CFNumberGetTypeID(), value);
+ if (valueRef != 0) {
+ result = IORegistryEntrySetCFProperty(gSelectedOptionsRef, nameRef, valueRef);
+ if (result == KERN_SUCCESS) break;
+ }
+
+ valueRef = ConvertValueToCFTypeRef(CFBooleanGetTypeID(), value);
+ if (valueRef != 0) {
+ result = IORegistryEntrySetCFProperty(gSelectedOptionsRef, nameRef, valueRef);
+ if (result == KERN_SUCCESS) break;
+ }
+
+ break;
+ }
+ }
CFRelease(nameRef);
//
// Delete the named firmware variable.
//
-//
-static void DeleteOFVariable(char *name)
+static void DeleteOFVariable(const char *name)
{
SetOFVariable(kIONVRAMDeletePropertyKey, name);
}
#if TARGET_OS_BRIDGE
static kern_return_t DeleteMacOFVariable(char *name)
{
- return deleteNVRAMVariable_fptr(gNvramInterface, name);
+ return deleteNVRAMVariable_fptr(gNvramInterface, name);
}
#endif
-static void NVRamSyncNow(char *name)
+static void NVRamSyncNow(void)
{
if (!gUseForceSync) {
- SetOFVariable(kIONVRAMSyncNowPropertyKey, name);
+ SetOFVariable(kIONVRAMSyncNowPropertyKey, kIONVRAMSyncNowPropertyKey);
} else {
- SetOFVariable(kIONVRAMForceSyncNowPropertyKey, name);
+ SetOFVariable(kIONVRAMForceSyncNowPropertyKey, kIONVRAMForceSyncNowPropertyKey);
}
}
kern_return_t result;
CFMutableDictionaryRef dict;
- result = IORegistryEntryCreateCFProperties(gOptionsRef, &dict, 0, 0);
+ result = IORegistryEntryCreateCFProperties(gSelectedOptionsRef, &dict, 0, 0);
if (result != KERN_SUCCESS) {
errx(1, "Error getting the firmware variables: %s", mach_error_string(result));
}
char *valueBuffer = 0;
const char *valueString = 0;
uint32_t number;
- long length;
+ long length;
CFTypeID typeID;
if (gUseXML) {
else {
dataBuffer = malloc(length * 3 + 1);
if (dataBuffer != 0) {
- dataPtr = CFDataGetBytePtr(value);
- for (cnt = cnt2 = 0; cnt < length; cnt++) {
- dataChar = dataPtr[cnt];
- if (isprint(dataChar) && dataChar != '%') {
- dataBuffer[cnt2++] = dataChar;
- } else {
- sprintf(dataBuffer + cnt2, "%%%02x", dataChar);
- cnt2 += 3;
- }
- }
- dataBuffer[cnt2] = '\0';
- valueString = dataBuffer;
+ dataPtr = CFDataGetBytePtr(value);
+ for (cnt = cnt2 = 0; cnt < length; cnt++) {
+ dataChar = dataPtr[cnt];
+ if (isprint(dataChar) && dataChar != '%') {
+ dataBuffer[cnt2++] = dataChar;
+ } else {
+ sprintf(dataBuffer + cnt2, "%%%02x", dataChar);
+ cnt2 += 3;
+ }
+ }
+ dataBuffer[cnt2] = '\0';
+ valueString = dataBuffer;
}
}
} else {
kern_return_t result;
CFMutableDictionaryRef dict;
- result = IORegistryEntryCreateCFProperties(gOptionsRef, &dict, 0, 0);
+ result = IORegistryEntryCreateCFProperties(gSelectedOptionsRef, &dict, 0, 0);
if (result != KERN_SUCCESS) {
errx(1, "Error getting the firmware variables: %s", mach_error_string(result));
}
static void ClearOFVariable(const void *key, const void *value, void *context)
{
kern_return_t result;
- result = IORegistryEntrySetCFProperty(gOptionsRef,
+ result = IORegistryEntrySetCFProperty(gSelectedOptionsRef,
CFSTR(kIONVRAMDeletePropertyKey), key);
if (result != KERN_SUCCESS) {
assert(CFGetTypeID(key) == CFStringGetTypeID());
//
// Convert the value into a CFType given the typeID.
//
-static CFTypeRef ConvertValueToCFTypeRef(CFTypeID typeID, char *value)
+static CFTypeRef ConvertValueToCFTypeRef(CFTypeID typeID, const 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;
+ 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);
+ number = strtol(value, 0, 0);
+ valueRef = CFNumberCreate(kCFAllocatorDefault, kCFNumberSInt32Type,
+ &number);
} else if (typeID == CFStringGetTypeID()) {
- valueRef = CFStringCreateWithCString(kCFAllocatorDefault, value,
- kCFStringEncodingUTF8);
+ 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);
+ length = strlen(value);
+ char valueCopy[length + 1];
+
+ for (cnt = cnt2 = 0; cnt < length; cnt++, cnt2++) {
+ if (value[cnt] == '%') {
+ if ((cnt + 2 > length) ||
+ !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;
+ valueCopy[cnt2] = number;
+ } else valueCopy[cnt2] = value[cnt];
+ }
+ valueRef = CFDataCreate(kCFAllocatorDefault, (const UInt8 *)valueCopy, cnt2);
} else return 0;
return valueRef;
{
kern_return_t result;
- result = IORegistryEntrySetCFProperty(gOptionsRef, key, value);
+ result = IORegistryEntrySetCFProperty(gSelectedOptionsRef, key, value);
if ( result != KERN_SUCCESS ) {
- long nameLen;
- char *nameBuffer;
- char *nameString;
-
- // Get the variable's name.
- nameLen = CFStringGetMaximumSizeForEncoding(CFStringGetLength(key),
- kCFStringEncodingUTF8) + 1;
- nameBuffer = malloc(nameLen);
- if( nameBuffer && CFStringGetCString(key, nameBuffer, nameLen, kCFStringEncodingUTF8) )
- nameString = nameBuffer;
- else {
- warnx("Unable to convert property name to C string");
- nameString = "<UNPRINTABLE>";
- }
- errx(1, "Error setting variable - '%s': %s", nameString,
- mach_error_string(result));
+ long nameLen;
+ char *nameBuffer;
+ char *nameString;
+
+ // Get the variable's name.
+ nameLen = CFStringGetMaximumSizeForEncoding(CFStringGetLength(key),
+ kCFStringEncodingUTF8) + 1;
+ nameBuffer = malloc(nameLen);
+ if( nameBuffer && CFStringGetCString(key, nameBuffer, nameLen, kCFStringEncodingUTF8) )
+ nameString = nameBuffer;
+ else {
+ warnx("Unable to convert property name to C string");
+ nameString = "<UNPRINTABLE>";
+ }
+ errx(1, "Error setting variable - '%s': %s", nameString,
+ mach_error_string(result));
}
}