BLCreateEFIXMLRepresentationForElToritoEntry.c [plain text]
#include <TargetConditionals.h>
#import <IOKit/IOKitLib.h>
#import <IOKit/IOCFSerialize.h>
#import <IOKit/IOBSD.h>
#import <IOKit/IOKitKeys.h>
#import <IOKit/storage/IOMedia.h>
#import <CoreFoundation/CoreFoundation.h>
#include <string.h>
#include <sys/param.h>
#include <sys/stat.h>
#include "bless.h"
#include "bless_private.h"
static bool appendIOMedia (BLContextPtr inContext, const char* inBSDName, CFMutableArrayRef inoutArray)
{
bool retSuccess = false;
CFMutableDictionaryRef dict;
CFMutableDictionaryRef match;
io_service_t media;
kern_return_t kr;
uint64_t entryID;
CFStringRef string;
match = IOBSDNameMatching (kIOMasterPortDefault, 0, inBSDName);
media = IOServiceGetMatchingService (kIOMasterPortDefault, match);
kr = IORegistryEntryGetRegistryEntryID (media, &entryID);
if (kr != KERN_SUCCESS)
{
contextprintf (inContext, kBLLogLevelVerbose, "IODVDMedia get registry ID failed\n");
goto Exit;
}
match = IORegistryEntryIDMatching (entryID);
dict = CFDictionaryCreateMutable (kCFAllocatorDefault, 0, &kCFTypeDictionaryKeyCallBacks,
&kCFTypeDictionaryValueCallBacks);
CFDictionaryAddValue (dict, CFSTR("IOMatch"), match);
CFRelease (match);
string = CFStringCreateWithCString (kCFAllocatorDefault, inBSDName, kCFStringEncodingUTF8);
CFDictionaryAddValue (dict, CFSTR("BLLastBSDName"), string);
CFArrayAppendValue (inoutArray, dict);
CFRelease (dict);
retSuccess = true;
Exit:;
return retSuccess;
}
static void appendMediaCDROM (BLContextPtr inContext, CFMutableArrayRef inoutArray, uint32_t inBootEntry, uint32_t inMSDOSRegionOffset, uint32_t inMSDOSRegionSize)
{
CFMutableDictionaryRef dict;
CFNumberRef number;
uint32_t value;
dict = CFDictionaryCreateMutable(kCFAllocatorDefault, 0, &kCFTypeDictionaryKeyCallBacks,
&kCFTypeDictionaryValueCallBacks);
CFDictionaryAddValue(dict, CFSTR("IOEFIDevicePathType"), CFSTR("MediaCDROM"));
value = inBootEntry;
number = CFNumberCreate(kCFAllocatorDefault, kCFNumberSInt32Type, &value);
CFDictionaryAddValue(dict, CFSTR("BootEntry"), number);
CFRelease(number);
value = inMSDOSRegionOffset;
number = CFNumberCreate(kCFAllocatorDefault, kCFNumberSInt32Type, &value);
CFDictionaryAddValue(dict, CFSTR("PartitionStart"), number);
CFRelease(number);
value = inMSDOSRegionSize;
number = CFNumberCreate(kCFAllocatorDefault, kCFNumberSInt32Type, &value);
CFDictionaryAddValue(dict, CFSTR("PartitionSize"), number);
CFRelease(number);
CFArrayAppendValue(inoutArray, dict);
CFRelease(dict);
}
static void appendMediaFilePath (BLContextPtr inContext, CFMutableArrayRef inoutArray)
{
CFMutableDictionaryRef dict;
CFStringRef string;
const char * filePath = "\\EFI\\BOOT\\BOOTX64.efi";
dict = CFDictionaryCreateMutable(kCFAllocatorDefault, 0, &kCFTypeDictionaryKeyCallBacks,
&kCFTypeDictionaryValueCallBacks);
CFDictionaryAddValue(dict, CFSTR("IOEFIDevicePathType"), CFSTR("MediaFilePath"));
string = CFStringCreateWithCString(kCFAllocatorDefault, filePath, kCFStringEncodingUTF8);
CFDictionaryAddValue(dict, CFSTR("Path"), string);
CFRelease(string);
CFArrayAppendValue(inoutArray, dict);
CFRelease(dict);
}
int BLCreateEFIXMLRepresentationForElToritoEntry(BLContextPtr inContext,
const char * inBSDName,
int inBootEntry,
int inPartitionStart,
int inPartitionSize,
CFStringRef * outXMLString)
{
bool retErr = 0;
CFMutableArrayRef arrayOfDicts = NULL;
CFDataRef xmlData = NULL;
CFIndex count;
const UInt8 * xmlBuffer = NULL;
UInt8 * outBuffer = NULL;
char buff [2048];
bool aBool;
contextprintf(inContext, kBLLogLevelVerbose, "Creating XML representation for ElTorito entry\n");
arrayOfDicts = CFArrayCreateMutable (kCFAllocatorDefault, 0, &kCFTypeArrayCallBacks);
aBool = appendIOMedia (inContext, inBSDName, arrayOfDicts);
if (false == aBool)
{
CFRelease (arrayOfDicts);
retErr = 1;
goto Exit;
}
appendMediaCDROM (inContext, arrayOfDicts, inBootEntry, inPartitionStart, inPartitionSize);
appendMediaFilePath (inContext, arrayOfDicts);
CFStringRef desc = CFCopyDescription (arrayOfDicts);
CFStringGetCString (desc, buff, sizeof(buff)-1, kCFStringEncodingUTF8);
contextprintf (inContext, kBLLogLevelVerbose, "array destined for XML then IORegistryEntrySetCFProperty() then NVRAM:\n\"\n%s\n\"\n", buff);
xmlData = IOCFSerialize (arrayOfDicts, 0);
CFRelease (arrayOfDicts);
if (xmlData == NULL) {
contextprintf (inContext, kBLLogLevelVerbose, "Can't create XML representation\n");
retErr = 2;
goto Exit;
}
count = CFDataGetLength (xmlData);
xmlBuffer = CFDataGetBytePtr (xmlData);
outBuffer = calloc (count+1, sizeof(char)); memcpy (outBuffer, xmlBuffer, count);
CFRelease (xmlData);
contextprintf (inContext, kBLLogLevelVerbose, "array in XML form:\n\"\n%s\n\"\n", outBuffer);
*outXMLString = CFStringCreateWithCString(kCFAllocatorDefault, (const char *)outBuffer, kCFStringEncodingUTF8);
free(outBuffer);
Exit:;
return retErr;
}