#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <mach-o/dyld.h>
#include "Log.h"
#include "main.h"
typedef struct _SafeBootContext {
} * SafeBootContext;
static void* (*fInitSafeBoot)(void) = NULL;
static void (*fFreeSafeBootContext)(SafeBootContext) = NULL;
static Boolean (*fCheckSafeBootList)(SafeBootContext, char*) = NULL;
#define _SafeBoot_C_
#include "SafeBoot.h"
#define getSymbol(aSymbolName, aPointer) \
{ NSSymbol aSymbol = NSLookupSymbolInModule(aModule, aSymbolName); aPointer = NSAddressOfSymbol(aSymbol); }
static void autoLoadSafeBootPlugIn()
{
char* aPluginList[] = { "SafeBootResources", NULL };
char* aPlugin;
int aPluginIndex;
for (aPluginIndex = 0; (aPlugin = aPluginList[aPluginIndex]); aPluginIndex++)
{
NSModule aModule = NULL;
NSObjectFileImage anImage;
char* aBundlePath = (char*)malloc(strlen(kBundleDirectory) + 1 +
(strlen(aPlugin)*2) +
strlen(kBundleExtension) + 2);
sprintf(aBundlePath, "%s/%s.%s/%s", kBundleDirectory, aPlugin, kBundleExtension, aPlugin);
if (gDebugFlag) debug(CFSTR("Trying plugin %s..."), aBundlePath);
if (NSCreateObjectFileImageFromFile(aBundlePath, &anImage) != NSObjectFileImageSuccess ||
!(aModule = NSLinkModule(anImage, "SafeBootResources", NSLINKMODULE_OPTION_PRIVATE |
NSLINKMODULE_OPTION_RETURN_ON_ERROR)))
{
debug(CFSTR("failed\n"));
}
else
{
getSymbol("_InitSafeBoot", fInitSafeBoot);
getSymbol("_FreeSafeBootContext", fFreeSafeBootContext);
getSymbol("_CheckSafeBootList", fCheckSafeBootList);
if (fInitSafeBoot &&
fFreeSafeBootContext &&
fCheckSafeBootList)
{
if (gDebugFlag) debug(CFSTR("SafeBootResources functions loaded\n"));
break;
}
else
{
debug(CFSTR("failed to lookup symbols in SafeBootResources\n"));
error(CFSTR("Load failure for possibly damaged plugin %s.\n"), aBundlePath);
if (!NSUnLinkModule(aModule, NSUNLINKMODULE_OPTION_NONE))
{
error(CFSTR("Failed to unload symbols for broken plugin.\n"));
}
fInitSafeBoot = NULL;
fFreeSafeBootContext = NULL;
fCheckSafeBootList = NULL;
}
}
}
}
SafeBootContext InitSafeBoot()
{
autoLoadSafeBootPlugIn();
if (fInitSafeBoot)
{
return fInitSafeBoot();
}
{
SafeBootContext aContext = (SafeBootContext)malloc(sizeof(struct _SafeBootContext));
return(aContext);
}
}
void FreeSafeBootContext (SafeBootContext aContext)
{
if (fFreeSafeBootContext)
{
return fFreeSafeBootContext(aContext);
}
if (aContext)
{
free(aContext);
aContext = NULL;
}
}
Boolean CheckSafeBootList(SafeBootContext aContext, char *aBundleName)
{
if (fCheckSafeBootList) return fCheckSafeBootList(aContext, aBundleName);
return TRUE;
}