+static CFStringRef
+__SC_IORegistryEntryCopyPath(io_registry_entry_t entry, const io_name_t plane)
+{
+ /*
+ * Create a path for a registry entry.
+ */
+ io_string_t path;
+ IOReturn status;
+ CFStringRef str = NULL;
+
+ status = IORegistryEntryGetPath(entry, plane, path);
+ if (status == kIOReturnSuccess) {
+ str = CFStringCreateWithCString(NULL, path, kCFStringEncodingUTF8);
+ } else if (status == kIOReturnBadArgument) {
+ io_registry_entry_t parent;
+
+ status = IORegistryEntryGetParentEntry(entry, plane, &parent);
+ if (status == kIOReturnSuccess) {
+ CFStringRef str_parent;
+
+ str_parent = __SC_IORegistryEntryCopyPath(parent, plane);
+ if (str_parent != NULL) {
+ io_name_t name;
+
+ status = IORegistryEntryGetNameInPlane(entry, plane, name);
+ if (status == kIOReturnSuccess) {
+ io_name_t location;
+
+ status = IORegistryEntryGetLocationInPlane(entry, plane, location);
+ if (status == kIOReturnSuccess) {
+ str = CFStringCreateWithFormat(NULL,
+ NULL,
+ CFSTR("%@/%s@%s"),
+ str_parent,
+ name,
+ location);
+ } else {
+ str = CFStringCreateWithFormat(NULL,
+ NULL,
+ CFSTR("%@/%s"),
+ str_parent,
+ name);
+ }
+ }
+
+ CFRelease(str_parent);
+ }
+
+ IOObjectRelease(parent);
+ }
+ }
+
+ return str;
+}
+
+