#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <unistd.h>
#include <time.h>
#include <mach-o/dyld.h>
#include "Log.h"
#include "main.h"
typedef struct _Text_DisplayContext {
} *DisplayContext;
static void* (*fInitDisplayContext)(void) = NULL;
static void (*fFreeDisplayContext)(DisplayContext) = NULL;
static int (*fDisplayStatus )(DisplayContext, CFStringRef) = NULL;
static int (*fDisplayProgress )(DisplayContext, float ) = NULL;
static int (*fDisplaySafeBootMsg)(DisplayContext, CFStringRef) = NULL;
#define _StartupDisplay_C_
#include "StartupDisplay.h"
#define getSymbol(aSymbolName, aPointer) \
{ NSSymbol aSymbol = NSLookupSymbolInModule(aModule, aSymbolName); aPointer = NSAddressOfSymbol(aSymbol); }
void LoadDisplayPlugIn(CFStringRef aPath)
{
NSModule aModule = NULL;
NSObjectFileImage anImage;
CFIndex aPathLength = CFStringGetLength(aPath);
CFIndex aPathSize = CFStringGetMaximumSizeForEncoding(aPathLength, kCFStringEncodingUTF8) + 1;
char* aBundlePath = (char*)malloc(aPathSize);
CFStringGetCString(aPath, aBundlePath, aPathSize, kCFStringEncodingUTF8);
if (gDebugFlag) debug(CFSTR("Trying plugin %s..."), aBundlePath);
if (NSCreateObjectFileImageFromFile(aBundlePath, &anImage) != NSObjectFileImageSuccess ||
!(aModule = NSLinkModule(anImage, "Display", NSLINKMODULE_OPTION_PRIVATE |
NSLINKMODULE_OPTION_RETURN_ON_ERROR)))
{
debug(CFSTR("failed\n"));
}
else
{
getSymbol("__initDisplayContext", fInitDisplayContext);
getSymbol("__freeDisplayContext", fFreeDisplayContext);
getSymbol("__displayStatus" , fDisplayStatus );
getSymbol("__displayProgress" , fDisplayProgress );
getSymbol("__displaySafeBootMsg" , fDisplaySafeBootMsg);
if (fInitDisplayContext &&
fFreeDisplayContext &&
fDisplayStatus &&
fDisplayProgress &&
fDisplaySafeBootMsg )
{
if (gDebugFlag) debug(CFSTR("loaded\n"));
}
else
{
debug(CFSTR("failed to lookup symbols\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 busted plugin.\n"));
}
fInitDisplayContext = NULL;
fFreeDisplayContext = NULL;
fDisplayStatus = NULL;
fDisplayProgress = NULL;
fDisplaySafeBootMsg = NULL;
}
}
}
void UnloadDisplayPlugIn()
{
fInitDisplayContext = NULL;
fFreeDisplayContext = NULL;
fDisplayStatus = NULL;
fDisplayProgress = NULL;
fDisplaySafeBootMsg = NULL;
}
DisplayContext initDisplayContext()
{
if (fInitDisplayContext) return fInitDisplayContext();
{
DisplayContext aContext = (DisplayContext)malloc(sizeof(struct _Text_DisplayContext));
return(aContext);
}
}
void freeDisplayContext (DisplayContext aContext)
{
if (fFreeDisplayContext) return fFreeDisplayContext(aContext);
if (aContext)
{
free(aContext);
}
}
int displayStatus (DisplayContext aDisplayContext, CFStringRef aMessage)
{
if (fDisplayStatus) return fDisplayStatus(aDisplayContext, aMessage);
if (aMessage)
{
message(CFSTR("%@\n"), aMessage);
return(0);
}
return(1);
}
int displayProgress (DisplayContext aDisplayContext, float aPercentage)
{
if (fDisplayProgress) return fDisplayProgress(aDisplayContext, aPercentage);
return(0);
}
int displaySafeBootMsg (DisplayContext aDisplayContext, CFStringRef aMessage)
{
if (fDisplaySafeBootMsg) return fDisplaySafeBootMsg(aDisplayContext, aMessage);
if (aMessage)
{
message(CFSTR("%@\n"), aMessage);
return(0);
}
return(1);
}