␊ |
␊ |
extern char gMacOSVersion;␊ |
extern int␉recoveryMode;␊ |
␊ |
␊ |
struct Module { ␊ |
struct Module *nextModule;␊ |
long willLoad;␊ |
TagPtr dict;␊ |
char *plistAddr;␊ |
long plistLength;␊ |
char *executablePath;␊ |
char *bundlePath;␊ |
long bundlePathLength;␊ |
␉struct Module *nextModule;␊ |
␉long willLoad;␊ |
␉TagPtr dict;␊ |
␉char *plistAddr;␊ |
␉long plistLength;␊ |
␉char *executablePath;␊ |
␉char *bundlePath;␊ |
␉long bundlePathLength;␊ |
};␊ |
typedef struct Module Module, *ModulePtr;␊ |
␊ |
struct DriverInfo {␊ |
char *plistAddr;␊ |
long plistLength;␊ |
void *executableAddr;␊ |
long executableLength;␊ |
void *bundlePathAddr;␊ |
long bundlePathLength;␊ |
␉char *plistAddr;␊ |
␉long plistLength;␊ |
␉void *executableAddr;␊ |
␉long executableLength;␊ |
␉void *bundlePathAddr;␊ |
␉long bundlePathLength;␊ |
};␊ |
typedef struct DriverInfo DriverInfo, *DriverInfoPtr;␊ |
␊ |
|
#define kDriverPackageSignature2 'MOSX'␊ |
␊ |
struct DriversPackage {␊ |
unsigned long signature1;␊ |
unsigned long signature2;␊ |
unsigned long length;␊ |
unsigned long alder32;␊ |
unsigned long version;␊ |
unsigned long numDrivers;␊ |
unsigned long reserved1;␊ |
unsigned long reserved2;␊ |
␉unsigned long signature1;␊ |
␉unsigned long signature2;␊ |
␉unsigned long length;␊ |
␉unsigned long alder32;␊ |
␉unsigned long version;␊ |
␉unsigned long numDrivers;␊ |
␉unsigned long reserved1;␊ |
␉unsigned long reserved2;␊ |
};␊ |
typedef struct DriversPackage DriversPackage;␊ |
␊ |
enum {␊ |
kCFBundleType2,␊ |
kCFBundleType3␊ |
␉kCFBundleType2,␊ |
␉kCFBundleType3␊ |
};␊ |
␊ |
#ifndef OPTION_ROM␊ |
long (*LoadExtraDrivers_p)(FileLoadDrivers_t FileLoadDrivers_p);␊ |
#endif␊ |
␊ |
static unsigned long Alder32( unsigned char * buffer, long length );␊ |
␊ |
static long FileLoadDrivers(char *dirSpec, long plugin);␊ |
#ifndef OPTION_ROM␊ |
static long NetLoadDrivers(char *dirSpec);␊ |
#endif␊ |
static long LoadDriverMKext(char *fileSpec);␊ |
static long LoadDriverPList(char *dirSpec, char *name, long bundleType);␊ |
static long LoadMatchedModules(void);␊ |
|
␊ |
lowHalf = 1;␊ |
highHalf = 0;␊ |
␊ |
␉␊ |
␉for ( cnt = 0; cnt < length; cnt++ )␊ |
{␊ |
if ((cnt % 5000) == 0)␊ |
|
lowHalf %= 65521L;␊ |
highHalf %= 65521L;␊ |
}␊ |
␊ |
␉␉␊ |
lowHalf += buffer[cnt];␊ |
highHalf += lowHalf;␊ |
}␊ |
␊ |
␉␊ |
␉lowHalf %= 65521L;␊ |
␉highHalf %= 65521L;␊ |
␊ |
␉␊ |
␉result = (highHalf << 16) | lowHalf;␊ |
␊ |
␉␊ |
␉return result;␊ |
}␊ |
␊ |
|
gFileSpec = malloc( 4096 );␊ |
gTempSpec = malloc( 4096 );␊ |
gFileName = malloc( 4096 );␊ |
␊ |
␉␊ |
if ( !gExtensionsSpec || !gDriverSpec || !gFileSpec || !gTempSpec || !gFileName )␊ |
stop("InitDriverSupport error");␊ |
␊ |
␉␊ |
return 0;␊ |
}␊ |
␊ |
|
long LoadDrivers( char * dirSpec )␊ |
{␊ |
char dirSpecExtra[1024];␊ |
␊ |
␉␊ |
if ( InitDriverSupport() != 0 )␊ |
return 0;␊ |
␊ |
␉␊ |
#ifndef OPTION_ROM␊ |
// Load extra drivers if a hook has been installed.␊ |
if (LoadExtraDrivers_p != NULL)␊ |
{␊ |
(*LoadExtraDrivers_p)(&FileLoadDrivers);␊ |
}␊ |
␊ |
␉␊ |
if ( gBootFileType == kNetworkDeviceType )␊ |
{␊ |
if (NetLoadDrivers(dirSpec) != 0) {␊ |
|
return -1;␊ |
}␊ |
}␊ |
else if ( gBootFileType == kBlockDeviceType )␊ |
{␊ |
// First try to load Extra extensions from the ramdisk if isn't aliased as bt(0,0).␊ |
␉␉if(recoveryMode) ␊ |
else␊ |
#endif␊ |
␉␉if ( gBootFileType == kBlockDeviceType )␊ |
␉␉{␊ |
␉␉␉verbose("Loading recovery extensions\n");␊ |
␊ |
// Next try to load Extra extensions from the selected root partition.␊ |
strcpy(dirSpecExtra, "/Extra/");␊ |
if (FileLoadDrivers(dirSpecExtra, 0) != 0)␊ |
{␊ |
// If failed, then try to load Extra extensions from the boot partition␊ |
// in case we have a separate booter partition or a bt(0,0) aliased ramdisk.␊ |
if ( !(gBIOSBootVolume->biosdev == gBootVolume->biosdev && gBIOSBootVolume->part_no == gBootVolume->part_no)␊ |
|| (gRAMDiskVolume && gRAMDiskBTAliased) )␊ |
{␊ |
// Next try a specfic OS version folder ie 10.5␊ |
sprintf(dirSpecExtra, "bt(0,0)/Extra/%s/", &gMacOSVersion);␊ |
if (FileLoadDrivers(dirSpecExtra, 0) != 0)␊ |
{␉␊ |
// Next we'll try the base␊ |
strcpy(dirSpecExtra, "bt(0,0)/Extra/");␊ |
FileLoadDrivers(dirSpecExtra, 0);␊ |
}␊ |
}␊ |
}␊ |
␊ |
␉␉}␊ |
␉␉else␊ |
␉␉{␊ |
␉␉␉// First try to load Extra extensions from the ramdisk if isn't aliased as bt(0,0).␊ |
#ifndef OPTION_ROM␊ |
␉␉␉if (gRAMDiskVolume && !gRAMDiskBTAliased)␊ |
␉␉␉{␊ |
␉␉␉␉strcpy(dirSpecExtra, "rd(0,0)/Extra/");␊ |
␉␉␉␉FileLoadDrivers(dirSpecExtra, 0);␊ |
␉␉␉}␊ |
␉␉␉␊ |
#endif␊ |
␉␉␉// Next try to load Extra extensions from the selected root partition.␊ |
␉␉␉strcpy(dirSpecExtra, "/Extra/");␊ |
␉␉␉if (FileLoadDrivers(dirSpecExtra, 0) != 0)␊ |
|
␉␉␉␉// If failed, then try to load Extra extensions from the boot partition␊ |
␉␉␉␉// in case we have a separate booter partition or a bt(0,0) aliased ramdisk.␊ |
␉␉␉␉if ( !(gBIOSBootVolume->biosdev == gBootVolume->biosdev && gBIOSBootVolume->part_no == gBootVolume->part_no)␊ |
#ifndef OPTION_ROM␊ |
␉␉␉␉␉|| (gRAMDiskVolume && gRAMDiskBTAliased) )␊ |
#else␊ |
␉␉␉␉␉)␊ |
#endif␊ |
␉␉␉␉{␊ |
␉␉␉␉␉// First try a specfic OS version folder ie 10.5␊ |
␉␉␉␉␉sprintf(dirSpecExtra, "bt(0,0)/Extra/%s/", &gMacOSVersion);␊ |
|
␉␉␉␉}␊ |
␉␉␉}␊ |
␉␉␉␊ |
␉␉␉// TODO: fix this, the order does matter, and it's not correct now.␊ |
␉␉␉// Also try to load Extensions from boot helper partitions.␊ |
␉␉␉if (gBootVolume->flags & kBVFlagBooter)␊ |
␉␉␉{␊ |
␉␉␉␉strcpy(dirSpecExtra, "/com.apple.boot.P/System/Library/");␊ |
␉␉␉␉if (FileLoadDrivers(dirSpecExtra, 0) != 0)␊ |
␉␉␉␉{␊ |
␉␉␉␉␉strcpy(dirSpecExtra, "/com.apple.boot.R/System/Library/");␊ |
␉␉␉␉␉if (FileLoadDrivers(dirSpecExtra, 0) != 0)␊ |
␉␉␉␉␉{␊ |
␉␉␉␉␉␉strcpy(dirSpecExtra, "/com.apple.boot.S/System/Library/");␊ |
␉␉␉␉␉␉FileLoadDrivers(dirSpecExtra, 0);␊ |
␉␉␉␉␉}␊ |
␉␉␉␉}␊ |
␉␉␉}␊ |
␉␉␉␊ |
␉␉␉if (gMKextName[0] != '\0')␊ |
␉␉␉{␊ |
␉␉␉␉verbose("LoadDrivers: Loading from [%s]\n", gMKextName);␊ |
␉␉␉␉if ( LoadDriverMKext(gMKextName) != 0 )␊ |
␉␉␉␉{␊ |
␉␉␉␉␉error("Could not load %s\n", gMKextName);␊ |
␉␉␉␉␉return -1;␊ |
␉␉␉␉}␊ |
␉␉␉}␊ |
␉␉␉else␊ |
␉␉␉{␊ |
␉␉␉␉strcpy(gExtensionsSpec, dirSpec);␊ |
␉␉␉␉strcat(gExtensionsSpec, "System/Library/");␊ |
␉␉␉␉FileLoadDrivers(gExtensionsSpec, 0);␊ |
␉␉␉}␊ |
␉␉}␊ |
␊ |
// Also try to load Extensions from boot helper partitions.␊ |
if (gBootVolume->flags & kBVFlagBooter)␊ |
{␊ |
strcpy(dirSpecExtra, "/com.apple.boot.P/System/Library/");␊ |
if (FileLoadDrivers(dirSpecExtra, 0) != 0)␊ |
{␊ |
strcpy(dirSpecExtra, "/com.apple.boot.R/System/Library/");␊ |
if (FileLoadDrivers(dirSpecExtra, 0) != 0)␊ |
{␊ |
strcpy(dirSpecExtra, "/com.apple.boot.S/System/Library/");␊ |
FileLoadDrivers(dirSpecExtra, 0);␊ |
}␊ |
}␊ |
}␊ |
␊ |
if (gMKextName[0] != '\0')␊ |
{␊ |
verbose("LoadDrivers: Loading from [%s]\n", gMKextName);␊ |
if ( LoadDriverMKext(gMKextName) != 0 )␊ |
{␊ |
error("Could not load %s\n", gMKextName);␊ |
return -1;␊ |
}␊ |
}␊ |
else␊ |
{␊ |
strcpy(gExtensionsSpec, dirSpec);␊ |
strcat(gExtensionsSpec, "System/Library/");␊ |
FileLoadDrivers(gExtensionsSpec, 0);␊ |
}␊ |
}␊ |
else␊ |
{␊ |
return 0;␊ |
}␊ |
␊ |
␉␉else␊ |
␉␉{␊ |
␉␉␉return 0;␊ |
␉␉}␊ |
␉␊ |
MatchPersonalities();␊ |
␊ |
␉␊ |
MatchLibraries();␊ |
␊ |
␉␊ |
LoadMatchedModules();␊ |
␊ |
␉␊ |
return 0;␊ |
}␊ |
␊ |
|
static long␊ |
FileLoadMKext( const char * dirSpec, const char * extDirSpec )␊ |
{␊ |
long ret, flags, time, time2;␊ |
char altDirSpec[512];␊ |
␉long ret, flags, time, time2;␊ |
␉char altDirSpec[512];␊ |
␉␊ |
sprintf (altDirSpec, "%s%s", dirSpec, extDirSpec);␊ |
ret = GetFileInfo(altDirSpec, "Extensions.mkext", &flags, &time);␊ |
if ((ret == 0) && ((flags & kFileTypeMask) == kFileTypeFlat))␊ |
{␊ |
ret = GetFileInfo(dirSpec, "Extensions", &flags, &time2);␊ |
if ((ret != 0) || ((flags & kFileTypeMask) != kFileTypeDirectory) ||␊ |
(((gBootMode & kBootModeSafe) == 0) && (time == (time2 + 1))))␊ |
{␊ |
sprintf(gDriverSpec, "%sExtensions.mkext", altDirSpec);␊ |
verbose("LoadDrivers: Loading from [%s]\n", gDriverSpec);␊ |
if (LoadDriverMKext(gDriverSpec) == 0) return 0;␊ |
}␊ |
}␊ |
return -1;␊ |
␉sprintf (altDirSpec, "%s%s", dirSpec, extDirSpec);␊ |
␉ret = GetFileInfo(altDirSpec, "Extensions.mkext", &flags, &time);␊ |
␉if ((ret == 0) && ((flags & kFileTypeMask) == kFileTypeFlat))␊ |
␉{␊ |
␉␉ret = GetFileInfo(dirSpec, "Extensions", &flags, &time2);␊ |
␉␉if ((ret != 0) || ((flags & kFileTypeMask) != kFileTypeDirectory) ||␊ |
␉␉␉(((gBootMode & kBootModeSafe) == 0) && (time == (time2 + 1))))␊ |
␉␉{␊ |
␉␉␉sprintf(gDriverSpec, "%sExtensions.mkext", altDirSpec);␊ |
␉␉␉verbose("LoadDrivers: Loading from [%s]\n", gDriverSpec);␊ |
␉␉␉if (LoadDriverMKext(gDriverSpec) == 0) return 0;␊ |
␉␉}␊ |
␉}␊ |
␉return -1;␊ |
}␊ |
␊ |
//==========================================================================␊ |
|
long long␉ index;␊ |
long result = -1;␊ |
const char * name;␊ |
␊ |
␉␊ |
if ( !plugin )␊ |
{␊ |
// First try 10.6's path for loading Extensions.mkext.␊ |
if (FileLoadMKext(dirSpec, "Caches/com.apple.kext.caches/Startup/") == 0)␊ |
return 0;␊ |
␊ |
␉␉␉return 0;␊ |
␉␉␊ |
// Next try the legacy path.␊ |
else if (FileLoadMKext(dirSpec, "") == 0)␊ |
return 0;␊ |
␊ |
␉␉␉return 0;␊ |
␉␉␊ |
strcat(dirSpec, "Extensions");␊ |
}␊ |
␊ |
␉␊ |
index = 0;␊ |
while (1) {␊ |
ret = GetDirEntry(dirSpec, &index, &name, &flags, &time);␊ |
if (ret == -1) break;␊ |
␊ |
␉␉␊ |
// Make sure this is a directory.␊ |
if ((flags & kFileTypeMask) != kFileTypeDirectory) continue;␊ |
␊ |
// Make sure this is a kext.␊ |
length = strlen(name);␊ |
if (strcmp(name + length - 5, ".kext")) continue;␊ |
␊ |
␉␉␊ |
// Save the file name.␊ |
strcpy(gFileName, name);␊ |
␊ |
␉␉␊ |
// Determine the bundle type.␊ |
sprintf(gTempSpec, "%s/%s", dirSpec, gFileName);␊ |
ret = GetFileInfo(gTempSpec, "Contents", &flags, &time);␊ |
if (ret == 0) bundleType = kCFBundleType2;␊ |
else bundleType = kCFBundleType3;␊ |
␊ |
␉␉␊ |
if (!plugin)␊ |
sprintf(gDriverSpec, "%s/%s/%sPlugIns", dirSpec, gFileName,␊ |
(bundleType == kCFBundleType2) ? "Contents/" : "");␊ |
␊ |
␉␉␊ |
ret = LoadDriverPList(dirSpec, gFileName, bundleType);␊ |
␊ |
␉␉␊ |
if (result != 0)␊ |
result = ret;␊ |
␊ |
␉␉␉result = ret;␊ |
␉␉␊ |
if (!plugin) ␊ |
FileLoadDrivers(gDriverSpec, 1);␊ |
␉␉␉FileLoadDrivers(gDriverSpec, 1);␊ |
}␊ |
␊ |
␉␊ |
return result;␊ |
}␊ |
␊ |
//==========================================================================␊ |
// ␊ |
␊ |
#ifndef OPTION_ROM␊ |
static long␊ |
NetLoadDrivers( char * dirSpec )␊ |
{␊ |
long tries;␊ |
␊ |
␉␊ |
#if NODEF␊ |
long cnt;␊ |
␊ |
␉␊ |
// Get the name of the kernel␊ |
cnt = strlen(gBootFile);␊ |
while (cnt--) {␊ |
if ((gBootFile[cnt] == '\\') || (gBootFile[cnt] == ',')) {␊ |
cnt++;␊ |
break;␊ |
␉␉␉cnt++;␊ |
␉␉␉break;␊ |
}␊ |
}␊ |
#endif␊ |
␊ |
␉␊ |
// INTEL modification␊ |
sprintf(gDriverSpec, "%s%s.mkext", dirSpec, bootInfo->bootFile);␊ |
␊ |
|
if (LoadDriverMKext(gDriverSpec) == 0) break;␊ |
}␊ |
if (tries == -1) return -1;␊ |
␊ |
␉␊ |
return 0;␊ |
}␊ |
␊ |
#endif␊ |
//==========================================================================␊ |
// loadDriverMKext␊ |
␊ |
|
long length;␊ |
char segName[32];␊ |
DriversPackage * package;␊ |
␊ |
␉␊ |
#define GetPackageElement(e) OSSwapBigToHostInt32(package->e)␊ |
␊ |
␉␊ |
// Load the MKext.␊ |
length = LoadThinFatFile(fileSpec, (void **)&package);␊ |
if (length < sizeof (DriversPackage)) return -1;␊ |
␊ |
␉␊ |
␉// call hook to notify modules that the mkext has been loaded␊ |
␉execute_hook("LoadDriverMKext", (void*)fileSpec, (void*)package, (void*) length, NULL);␊ |
␊ |
␉␊ |
␉␊ |
// Verify the MKext.␊ |
if (( GetPackageElement(signature1) != kDriverPackageSignature1) ||␊ |
( GetPackageElement(signature2) != kDriverPackageSignature2) ||␊ |
( GetPackageElement(length) > kLoadSize ) ||␊ |
( GetPackageElement(alder32) !=␊ |
Alder32((unsigned char *)&package->version, GetPackageElement(length) - 0x10) ) )␊ |
␉␉ Alder32((unsigned char *)&package->version, GetPackageElement(length) - 0x10) ) )␊ |
{␊ |
return -1;␊ |
}␊ |
␉␊ |
␊ |
␉␊ |
// Make space for the MKext.␊ |
driversLength = GetPackageElement(length);␊ |
driversAddr = AllocateKernelMemory(driversLength);␊ |
␊ |
␉␊ |
// Copy the MKext.␊ |
memcpy((void *)driversAddr, (void *)package, driversLength);␊ |
␊ |
␉␊ |
// Add the MKext to the memory map.␊ |
sprintf(segName, "DriversPackage-%lx", driversAddr);␊ |
AllocateMemoryRange(segName, driversAddr, driversLength,␊ |
kBootDriverTypeMKEXT);␊ |
␊ |
␉␊ |
return 0;␊ |
}␊ |
␊ |
|
char * tmpExecutablePath = 0;␊ |
char * tmpBundlePath = 0;␊ |
long ret = -1;␊ |
␊ |
␉␊ |
do {␊ |
// Save the driver path.␊ |
␊ |
sprintf(gFileSpec, "%s/%s/%s", dirSpec, name,␊ |
(bundleType == kCFBundleType2) ? "Contents/MacOS/" : "");␊ |
executablePathLength = strlen(gFileSpec) + 1;␊ |
␊ |
␉␉␊ |
tmpExecutablePath = malloc(executablePathLength);␊ |
if (tmpExecutablePath == 0) break;␊ |
␊ |
␉␉␊ |
strcpy(tmpExecutablePath, gFileSpec);␊ |
␊ |
␉␉␊ |
sprintf(gFileSpec, "%s/%s", dirSpec, name);␊ |
bundlePathLength = strlen(gFileSpec) + 1;␊ |
␊ |
␉␉␊ |
tmpBundlePath = malloc(bundlePathLength);␊ |
if (tmpBundlePath == 0) break;␊ |
␊ |
␉␉␊ |
strcpy(tmpBundlePath, gFileSpec);␊ |
␊ |
␉␉␊ |
// Construct the file spec to the plist, then load it.␊ |
␊ |
␉␉␊ |
sprintf(gFileSpec, "%s/%s/%sInfo.plist", dirSpec, name,␊ |
(bundleType == kCFBundleType2) ? "Contents/" : "");␊ |
␊ |
␉␉␊ |
length = LoadFile(gFileSpec);␊ |
if (length == -1) break;␊ |
␊ |
␉␉␊ |
length = length + 1;␊ |
buffer = malloc(length);␊ |
if (buffer == 0) break;␊ |
␊ |
␉␉␊ |
strlcpy(buffer, (char *)kLoadAddr, length);␊ |
␊ |
␉␉␊ |
// Parse the plist.␊ |
␊ |
␉␉␊ |
ret = ParseXML(buffer, &module, &personalities);␊ |
if (ret != 0) { break; }␊ |
␊ |
␉␉␊ |
// Allocate memory for the driver path and the plist.␊ |
␊ |
␉␉␊ |
module->executablePath = tmpExecutablePath;␊ |
module->bundlePath = tmpBundlePath;␊ |
module->bundlePathLength = bundlePathLength;␊ |
module->plistAddr = malloc(length);␊ |
␊ |
␉␉␊ |
if ((module->executablePath == 0) || (module->bundlePath == 0) || (module->plistAddr == 0))␊ |
break;␊ |
␊ |
␉␉␊ |
// Save the driver path in the module.␊ |
//strcpy(module->driverPath, tmpDriverPath);␊ |
tmpExecutablePath = 0;␊ |
tmpBundlePath = 0;␊ |
␊ |
␉␉␊ |
// Add the plist to the module.␊ |
␊ |
␉␉␊ |
strlcpy(module->plistAddr, (char *)kLoadAddr, length);␊ |
module->plistLength = length;␊ |
␊ |
␉␉␊ |
// Add the module to the end of the module list.␊ |
␊ |
if (gModuleHead == 0)␊ |
|
else␊ |
gModuleTail->nextModule = module;␊ |
gModuleTail = module;␊ |
␊ |
␉␉␊ |
// Add the persionalities to the personality list.␊ |
␊ |
␉␉␊ |
if (personalities) personalities = personalities->tag;␊ |
while (personalities != 0)␊ |
{␊ |
|
if ( buffer ) free( buffer );␊ |
if ( tmpExecutablePath ) free( tmpExecutablePath );␊ |
if ( tmpBundlePath ) free( tmpBundlePath );␊ |
␊ |
␉␊ |
return ret;␊ |
}␊ |
␊ |
|
DriverInfoPtr driver;␊ |
long length, driverAddr, driverLength;␊ |
void *executableAddr = 0;␊ |
␊ |
␊ |
␉␊ |
␉␊ |
module = gModuleHead;␊ |
␊ |
␉␊ |
while (module != 0)␊ |
{␊ |
if (module->willLoad)␊ |
{␊ |
prop = XMLGetProperty(module->dict, kPropCFBundleExecutable);␊ |
␊ |
␉␉␉␊ |
if (prop != 0)␊ |
{␊ |
fileName = prop->string;␊ |
|
}␊ |
else␊ |
length = 0;␊ |
␊ |
␉␉␉␊ |
if (length != -1)␊ |
{␊ |
␉␉//driverModuleAddr = (void *)kLoadAddr;␊ |
␉␉␉␉//driverModuleAddr = (void *)kLoadAddr;␊ |
//if (length != 0)␊ |
//{␊ |
␉␉// ThinFatFile(&driverModuleAddr, &length);␊ |
␉␉//}␊ |
␊ |
␉␉␉␉// ThinFatFile(&driverModuleAddr, &length);␊ |
␉␉␉␉//}␊ |
␉␉␉␉␊ |
// Make make in the image area.␊ |
␉␉␉␉␊ |
␉␉␉␉execute_hook("LoadMatchedModules", module, &length, executableAddr, NULL);␊ |
␊ |
␉␉␉␉␊ |
driverLength = sizeof(DriverInfo) + module->plistLength + length + module->bundlePathLength;␊ |
driverAddr = AllocateKernelMemory(driverLength);␊ |
␊ |
␉␉␉␉␊ |
// Set up the DriverInfo.␊ |
driver = (DriverInfoPtr)driverAddr;␊ |
driver->plistAddr = (char *)(driverAddr + sizeof(DriverInfo));␊ |
|
if (length != 0)␊ |
{␊ |
driver->executableAddr = (void *)(driverAddr + sizeof(DriverInfo) +␊ |
␉␉␉␉␉ module->plistLength);␊ |
␉␉␉␉␉␉␉␉␉␉␉␉␉ module->plistLength);␊ |
driver->executableLength = length;␊ |
}␊ |
else␊ |
|
driver->executableLength = 0;␊ |
}␊ |
driver->bundlePathAddr = (void *)(driverAddr + sizeof(DriverInfo) +␊ |
␉␉␉␉ module->plistLength + driver->executableLength);␊ |
␉␉␉␉␉␉␉␉␉␉␉␉ module->plistLength + driver->executableLength);␊ |
driver->bundlePathLength = module->bundlePathLength;␊ |
␊ |
␉␉␉␉␊ |
// Save the plist, module and bundle.␊ |
strcpy(driver->plistAddr, module->plistAddr);␊ |
if (length != 0)␊ |
|
memcpy(driver->executableAddr, executableAddr, length);␊ |
}␊ |
strcpy(driver->bundlePathAddr, module->bundlePath);␊ |
␊ |
␉␉␉␉␊ |
// Add an entry to the memory map.␊ |
sprintf(segName, "Driver-%lx", (unsigned long)driver);␊ |
AllocateMemoryRange(segName, driverAddr, driverLength,␊ |
|
}␊ |
module = module->nextModule;␊ |
}␊ |
␊ |
␉␊ |
return 0;␊ |
}␊ |
␊ |
|
TagPtr prop, prop2;␊ |
ModulePtr module, module2;␊ |
long done;␊ |
␊ |
␉␊ |
do {␊ |
done = 1;␊ |
module = gModuleHead;␊ |
|
}␊ |
}␊ |
while (!done);␊ |
␊ |
␉␊ |
return 0;␊ |
}␊ |
␊ |
|
␉long length, pos;␊ |
␉TagPtr moduleDict, required;␊ |
␉ModulePtr tmpModule;␊ |
␊ |
␉␊ |
pos = 0;␊ |
␊ |
␉␊ |
while (1)␊ |
{␊ |
length = XMLParseNextTag(buffer + pos, &moduleDict);␊ |
if (length == -1) break;␊ |
␊ |
␉␉␊ |
pos += length;␊ |
␊ |
␉␉␊ |
if (moduleDict == 0) continue;␊ |
if (moduleDict->type == kTagTypeDict) break;␊ |
␊ |
␉␉␊ |
XMLFreeTag(moduleDict);␊ |
}␊ |
␊ |
␉␊ |
if (length == -1) return -1;␊ |
␊ |
␉␊ |
required = XMLGetProperty(moduleDict, kPropOSBundleRequired);␊ |
if ( (required == 0) ||␊ |
(required->type != kTagTypeString) ||␊ |
!strcmp(required->string, "Safe Boot"))␊ |
␉␉(required->type != kTagTypeString) ||␊ |
␉␉!strcmp(required->string, "Safe Boot"))␊ |
{␊ |
XMLFreeTag(moduleDict);␊ |
return -2;␊ |
}␊ |
␊ |
␉␊ |
tmpModule = malloc(sizeof(Module));␊ |
if (tmpModule == 0)␊ |
{␊ |
|
return -1;␊ |
}␊ |
tmpModule->dict = moduleDict;␊ |
␊ |
␉␊ |
// For now, load any module that has OSBundleRequired != "Safe Boot".␊ |
␊ |
␉␊ |
tmpModule->willLoad = 1;␊ |
␊ |
␉␊ |
*module = tmpModule;␊ |
␊ |
␉␊ |
// Get the personalities.␊ |
␊ |
␉␊ |
*personalities = XMLGetProperty(moduleDict, kPropIOKitPersonalities);␊ |
␊ |
␉␊ |
return 0;␊ |
}␊ |
␊ |
|
u_int32_t uncompressed_size, size;␊ |
void *buffer;␊ |
␉unsigned long len;␊ |
␊ |
␉␊ |
#if 0␊ |
printf("kernel header:\n");␊ |
printf("signature: 0x%x\n", kernel_header->signature);␊ |
|
printf("compressed_size: 0x%x\n", kernel_header->compressed_size);␊ |
getc();␊ |
#endif␊ |
␊ |
␉␊ |
if (kernel_header->signature == OSSwapBigToHostConstInt32('comp')) {␊ |
if (kernel_header->compress_type != OSSwapBigToHostConstInt32('lzss')) {␊ |
error("kernel compression is bad\n");␊ |
|
if (kernel_header->root_path[0] && strcmp(gBootFile, kernel_header->root_path))␊ |
return -1;␊ |
#endif␊ |
␊ |
␉␉␊ |
uncompressed_size = OSSwapBigToHostInt32(kernel_header->uncompressed_size);␊ |
binary = buffer = malloc(uncompressed_size);␊ |
␊ |
␉␉␊ |
size = decompress_lzss((u_int8_t *) binary, &kernel_header->data[0],␊ |
OSSwapBigToHostInt32(kernel_header->compressed_size));␊ |
if (uncompressed_size != size) {␊ |
|
return -1;␊ |
}␊ |
}␊ |
␊ |
ret = ThinFatFile(&binary, &len);␊ |
if (ret == 0 && len == 0 && archCpuType==CPU_TYPE_X86_64)␊ |
{␊ |
␉ archCpuType=CPU_TYPE_I386;␊ |
␉ ret = ThinFatFile(&binary, &len);␊ |
}␊ |
␊ |
␉␊ |
␉ret = ThinFatFile(&binary, &len);␊ |
␉if (ret == 0 && len == 0 && archCpuType==CPU_TYPE_X86_64)␊ |
␉{␊ |
␉␉archCpuType=CPU_TYPE_I386;␊ |
␉␉ret = ThinFatFile(&binary, &len);␊ |
␉}␊ |
␉␊ |
␉//patch_kernel(binary);␊ |
␉␊ |
ret = DecodeMachO(binary, rentry, raddr, rsize);␊ |
␉ret = DecodeMachO(binary, rentry, raddr, rsize);␊ |
␉␊ |
if (ret<0 && archCpuType==CPU_TYPE_X86_64)␊ |
{␊ |
␉ archCpuType=CPU_TYPE_I386;␊ |
␉ ret = DecodeMachO(binary, rentry, raddr, rsize);␊ |
}␊ |
␉if (ret<0 && archCpuType==CPU_TYPE_X86_64)␊ |
␉{␊ |
␉␉archCpuType=CPU_TYPE_I386;␊ |
␉␉ret = DecodeMachO(binary, rentry, raddr, rsize);␊ |
␉}␊ |
␉␊ |
␊ |
return ret;␊ |
␉␊ |
␉return ret;␊ |
}␊ |