#ifndef _KEXTCACHE_MAIN_H
#define _KEXTCACHE_MAIN_H
#include <CoreFoundation/CoreFoundation.h>
#include <IOKit/kext/OSKext.h>
#include <getopt.h>
#include <sysexits.h>
#include <IOKit/kext/OSKext.h>
#include "kext_tools_util.h"
#pragma mark Basic Types & Constants
enum {
kKextcacheExitOK = EX_OK,
kKextcacheExitNotFound,
kKextcacheExitArchNotFound,
kKextcacheExitKextBad,
kKextcacheExitStale,
kKextcacheExitUnspecified = 11,
kKextcacheExitHelp = 33,
kKextcacheExitNoStart
};
#pragma mark Command-line Option Definitions
#define kOptNameMkext "mkext"
#define kOptNameMkext1 "mkext1"
#define kOptNameMkext2 "mkext2"
#define kOptNameSystemMkext "system-mkext"
#define kOptNameVolumeRoot "volume-root"
#define kOptNameLocalRoot "local-root"
#define kOptNameLocalRootAll "local-root-all"
#define kOptNameNetworkRoot "network-root"
#define kOptNameNetworkRootAll "network-root-all"
#define kOptNameSafeBoot "safe-boot"
#define kOptNameSafeBootAll "safe-boot-all"
#define kOptNamePrelinkedKernel "prelinked-kernel"
#define kOptNameSystemPrelinkedKernel "system-prelinked-kernel"
#define kOptNameKernel "kernel"
#define kOptNameAllLoaded "all-loaded"
#define kOptNameSymbols "symbols"
#define kOptNameAllPersonalities "all-personalities"
#define kOptNameOmitLinkState "omit-link-state"
#define kOptNameSystemCaches "system-caches"
#define kOptNameUpdate "update-volume"
#define kOptNameForce "force"
#define kOptNameNoAuthentication "no-authentication"
#define kOptNameTests "print-diagnostics"
#define kOptNameCompressed "compressed"
#define kOptNameUncompressed "uncompressed"
#define kOptArch 'a'
#define kOptPrelinkedKernel 'c'
#define kOptSystemMkext 'e'
#define kOptForce 'f'
#define kOptLowPriorityFork 'F'
#define kOptRepositoryCaches 'k'
#define kOptKernel 'K'
#define kOptLocalRoot 'l'
#define kOptLocalRootAll 'L'
#define kOptMkext 'm'
#define kOptNetworkRoot 'n'
#define kOptNetworkRootAll 'N'
#define kOptAllLoaded 'r'
#define kOptSafeBoot 's'
#define kOptSafeBootAll 'S'
#define kOptTests 't'
#define kOptUpdate 'u'
#define kOptCheckUpdate 'U'
#define kOptNoAuthentication 'z'
#define kLongOptLongindexHack (-2)
#define kLongOptMkext1 (-3)
#define kLongOptMkext2 (-4)
#define kLongOptMkext kLongOptMkext2
#define kLongOptCompressed (-5)
#define kLongOptUncompressed (-6)
#define kLongOptSymbols (-7)
#define kLongOptSystemCaches (-8)
#define kLongOptSystemPrelinkedKernel (-9)
#define kLongOptVolumeRoot (-10)
#define kLongOptAllPersonalities (-11)
#define kLongOptOmitLinkState (-12)
#define kOptChars ":a:b:c:efFhkK:lLm:nNqrsStu:U:vz"
int longopt = 0;
struct option sOptInfo[] = {
{ kOptNameLongindexHack, no_argument, &longopt, kLongOptLongindexHack },
{ kOptNameHelp, no_argument, NULL, kOptHelp },
{ kOptNameQuiet, no_argument, NULL, kOptQuiet },
{ kOptNameVerbose, optional_argument, NULL, kOptVerbose },
{ kOptNameCompressed, no_argument, &longopt, kLongOptCompressed },
{ kOptNameUncompressed, no_argument, &longopt, kLongOptUncompressed },
{ kOptNameArch, required_argument, NULL, kOptArch },
{ kOptNameMkext1, required_argument, &longopt, kLongOptMkext1 },
{ kOptNameMkext2, required_argument, &longopt, kLongOptMkext2 },
{ kOptNameMkext, required_argument, NULL, kOptMkext },
{ kOptNameSystemMkext, no_argument, NULL, kOptSystemMkext },
{ kOptNameVolumeRoot, required_argument, &longopt, kLongOptVolumeRoot },
{ kOptNameSystemCaches, no_argument, &longopt, kLongOptSystemCaches },
{ kOptNameBundleIdentifier, required_argument, NULL, kOptBundleIdentifier },
{ kOptNameLocalRoot, no_argument, NULL, kOptLocalRoot },
{ kOptNameLocalRootAll, no_argument, NULL, kOptLocalRootAll },
{ kOptNameNetworkRoot, no_argument, NULL, kOptNetworkRoot },
{ kOptNameNetworkRootAll, no_argument, NULL, kOptNetworkRootAll, },
{ kOptNameSafeBoot, no_argument, NULL, kOptSafeBoot },
{ kOptNameSafeBootAll, no_argument, NULL, kOptSafeBootAll },
{ kOptNamePrelinkedKernel, optional_argument, NULL, kOptPrelinkedKernel },
{ kOptNameSystemPrelinkedKernel, no_argument, &longopt, kLongOptSystemPrelinkedKernel },
{ kOptNameKernel, required_argument, NULL, kOptKernel },
{ kOptNameAllLoaded, no_argument, NULL, kOptAllLoaded },
{ kOptNameSymbols, required_argument, &longopt, kLongOptSymbols },
{ kOptNameAllPersonalities, no_argument, &longopt, kLongOptAllPersonalities },
{ kOptNameOmitLinkState, no_argument, &longopt, kLongOptOmitLinkState },
{ kOptNameUpdate, required_argument, NULL, kOptUpdate },
{ kOptNameForce, no_argument, NULL, kOptForce },
{ kOptNameNoAuthentication, no_argument, NULL, kOptNoAuthentication },
{ kOptNameTests, no_argument, NULL, kOptTests },
{ NULL, required_argument, NULL, kOptCheckUpdate },
{ NULL, no_argument, NULL, kOptLowPriorityFork },
{ NULL, 0, NULL, 0 } };
#define kMaxNumArches (64)
#define kDefaultKernelFile "/mach_kernel"
typedef struct {
OSKextRequiredFlags requiredFlagsRepositoriesOnly; OSKextRequiredFlags requiredFlagsAll;
Boolean updateSystemMkext; Boolean updateSystemCaches; Boolean lowPriorityFlag; Boolean printTestResults; Boolean skipAuthentication;
CFURLRef volumeRootURL;
CFURLRef mkextURL; int mkextVersion;
CFURLRef prelinkedKernelURL; Boolean needDefaultPrelinkedKernelInfo; Boolean needLoadedKextInfo; Boolean prelinkedKernelErrorRequired;
Boolean generatePrelinkedSymbols; Boolean includeAllPersonalities; Boolean omitLinkState; CFURLRef compressedPrelinkedKernelURL;
CFURLRef updateVolumeURL; Boolean expectUpToDate; Boolean forceUpdateFlag;
CFURLRef kernelURL; CFDataRef kernelFile; CFURLRef symbolDirURL;
const NXArchInfo * archInfo[kMaxNumArches]; uint32_t numArches;
Boolean explicitArch;
CFMutableSetRef kextIDs; CFMutableArrayRef argURLs; CFMutableArrayRef repositoryURLs; CFMutableArrayRef namedKextURLs;
CFArrayRef allKexts; CFArrayRef repositoryKexts; CFArrayRef namedKexts;
struct stat kernelStatBuffer;
struct stat firstFolderStatBuffer;
Boolean haveFolderMtime;
Boolean compress;
Boolean uncompress;
} KextcacheArgs;
#define PLATFORM_NAME_LEN 64
#define ROOT_PATH_LEN 256
typedef struct prelinked_kernel_header {
uint32_t signature;
uint32_t compressType;
uint32_t adler32;
uint32_t uncompressedSize;
uint32_t compressedSize;
uint32_t reserved[11];
char platformName[PLATFORM_NAME_LEN];
char rootPath[ROOT_PATH_LEN];
char data[0];
} PrelinkedKernelHeader;
typedef struct platform_info {
char platformName[PLATFORM_NAME_LEN];
char rootPath[ROOT_PATH_LEN];
} PlatformInfo;
#pragma mark Function Prototypes
ExitStatus readArgs(
int * argc,
char * const ** argv,
KextcacheArgs * toolArgs);
const NXArchInfo * addArchForName(
KextcacheArgs * toolArgs,
const char * archname);
ExitStatus readPrelinkedKernelArgs(
KextcacheArgs * toolArgs,
int argc,
char * const * argv,
Boolean isLongopt);
ExitStatus setPrelinkedKernelArgs(
KextcacheArgs * toolArgs,
char * filename);
void setNeededLoadedKextInfo(KextcacheArgs * toolArgs);
void checkKextdSpawnedFilter(Boolean kernelFlag);
ExitStatus checkArgs(KextcacheArgs * toolArgs);
ExitStatus statURL(CFURLRef anURL, struct stat * statBuffer);
ExitStatus updateSystemDirectoryCaches(
KextcacheArgs * toolArgs);
ExitStatus updateDirectoryCaches(
KextcacheArgs * toolArgs,
CFURLRef folderURL);
ExitStatus createMkext(
KextcacheArgs * toolArgs,
Boolean * fatalOut);
ExitStatus filterKextsForMkext(
KextcacheArgs * toolArgs,
CFMutableArrayRef kextArray,
const NXArchInfo * arch,
Boolean * fatalOut);
Boolean checkKextForArchive(
KextcacheArgs toolArgs,
OSKextRef aKext,
const char * archiveTypeName,
const NXArchInfo * archInfo,
OSKextRequiredFlags requiredFlags);
ExitStatus writeToFile(
int fileDescriptor,
const UInt8 * data,
CFIndex length);
int getFileOffsetAndSizeForArch(
int fileDescriptor,
const NXArchInfo * archInfo,
off_t * sliceOffsetOut,
size_t * sliceSizeOut);
int readFileAtOffset(
int fileDescriptor,
off_t fileOffset,
size_t fileSize,
u_char * buf);
int verifyMachOIsArch(
u_char * fileBuf,
size_t size,
const NXArchInfo * archInfo);
void getPlatformInfo(
KextcacheArgs * toolArgs,
PlatformInfo * platformInfo);
CFDataRef readMachOFileWithURL(
CFURLRef kernelURL,
const NXArchInfo * archInfo);
CFDataRef uncompressPrelinkedKernel(
CFDataRef prelinkImage);
CFDataRef compressPrelinkedKernel(
CFDataRef prelinkImage,
PlatformInfo *platformInfo);
ExitStatus createPrelinkedKernel(
KextcacheArgs * toolArgs,
CFDataRef * prelinkedKernelOut,
CFDictionaryRef * prelinkedSymbolsOut,
const NXArchInfo * archInfo,
PlatformInfo * platformInfo);
ExitStatus savePrelinkedKernel(
KextcacheArgs * toolArgs,
CFDataRef prelinkedKernel,
CFDictionaryRef prelinkedSymbols);
void usage(UsageLevel usageLevel);
#endif