1/*
2 *  kextutil_main.h
3 *  kext_tools
4 *
5 *  Created by Nik Gervae on 4/24/08.
6 *  Copyright 2008 Apple Inc. All rights reserved.
7 *
8 */
9#ifndef _KEXTUTIL_MAIN_H
10#define _KEXTUTIL_MAIN_H
11
12#include <CoreFoundation/CoreFoundation.h>
13#include <IOKit/kext/OSKext.h>
14
15#include <getopt.h>
16#include <sysexits.h>
17
18#include <IOKit/kext/OSKext.h>
19
20#include "kext_tools_util.h"
21
22#pragma mark Basic Types & Constants
23/*******************************************************************************
24* Constants
25*******************************************************************************/
26
27enum {
28    kKextutilExitOK          = EX_OK,
29    kKextutilExitNotFound,
30    kKextutilExitArchNotFound,
31    kKextutilExitUserAbort,
32    kKextutilExitKextBad,
33    kKextutilExitSafeBoot,
34    kKextutilExitLoadFailed,
35    kKextutilExitInteractionRequired,
36
37    // don't think we use it
38    kKextutilExitUnspecified = 11,
39
40    // don't actually exit with this, it's just a sentinel value
41    kKextutilExitHelp        = 33,
42    kKextutilExitNoStart
43};
44
45#pragma mark Command-line Option Definitions
46/*******************************************************************************
47* Command-line options. This data is used by getopt_long_only().
48*
49* Options common to all kext tools are in kext_tools_util.h.
50*******************************************************************************/
51#define kOptNamePersonality             "personality"
52#define kOptNameDependency              "dependency"
53
54#define kOptNameNoCaches                "no-caches"
55#define kOptNameNoLoadedCheck           "no-loaded-check"
56#define kOptNameNoSystemExtensions      "no-system-extensions"
57
58#define kOptNameInteractive             "interactive"
59#define kOptNameInteractiveAll          "interactive-all"
60
61#define kOptNameLoadOnly                "load-only"
62#define kOptNameMatchOnly               "match-only"
63#define kOptNameNoLoad                  "no-load"
64#define kOptNameSymbolsDirectory        "symbols"
65#define kOptNameAddress                 "address"
66#define kOptNameUseKernelAddresses      "use-load-addresses"
67
68#define kOptNameTests                   "print-diagnostics"
69#define kOptNameNoResolveDependencies   "no-resolve-dependencies"
70
71#define kOptNameLongindexHack           "________"
72
73#define kOptPersonality           'p'
74#define kOptKernel                'k'
75#define kOptDependency            'd'
76#define kOptRepository            'r'
77
78#define kOptNoCaches              'c'
79#define kOptNoLoadedCheck         'D'
80#define kOptNoSystemExtensions    'e'
81
82#define kOptInteractive           'i'
83#define kOptInteractiveAll        'I'
84
85#define kOptLoadOnly              'l'
86#define kOptMatchOnly             'm'
87#define kOptNoLoad                'n'
88#define kOptSymbolsDirectory      's'
89#define kOptAddress               'a'
90#define kOptUseKernelAddresses    'A'
91    // arch is down below
92
93#define kOptTests                 't'
94#define kOptSafeBoot              'x'
95#define kOptNoAuthentication      'z'
96#define kOptNoResolveDependencies 'Z'
97
98/* Options with no single-letter variant.  */
99// Do not use -1, that's getopt() end-of-args return value
100// and can cause confusion
101#define kLongOptLongindexHack    (-2)
102#define kLongOptArch             (-3)
103#define kLongOptLegacyLayout     (-4)
104
105#define kOptChars                "a:Ab:cd:DehiIk:lmnp:qr:s:tvxzZ"
106
107int longopt = 0;
108
109struct option sOptInfo[] = {
110    { kOptNameLongindexHack,         no_argument,        &longopt, kLongOptLongindexHack },
111    { kOptNameHelp,                  no_argument,        NULL,     kOptHelp },
112    { kOptNameBundleIdentifier,      required_argument,  NULL,     kOptBundleIdentifier },
113    { kOptNamePersonality,           required_argument,  NULL,     kOptPersonality },
114    { kOptNameKernel,                required_argument,  NULL,     kOptKernel },
115    { kOptNameDependency,            required_argument,  NULL,     kOptDependency },
116    { kOptNameRepository,            required_argument,  NULL,     kOptRepository },
117    { kOptNameNoCaches,              no_argument,        NULL,     kOptNoCaches },
118    { kOptNameNoLoadedCheck,         no_argument,        NULL,     kOptNoLoadedCheck },
119    { kOptNameNoSystemExtensions,    no_argument,        NULL,     kOptNoSystemExtensions },
120    { kOptNameInteractive,           no_argument,        NULL,     kOptInteractive },
121    { kOptNameInteractiveAll,        no_argument,        NULL,     kOptInteractiveAll },
122    { kOptNameLoadOnly,              no_argument,        NULL,     kOptLoadOnly },
123    { kOptNameMatchOnly,             no_argument,        NULL,     kOptMatchOnly },
124    { kOptNameNoLoad,                no_argument,        NULL,     kOptNoLoad },
125    { kOptNameSymbolsDirectory,      required_argument,  NULL,     kOptSymbolsDirectory },
126    { kOptNameAddress,               required_argument,  NULL,     kOptAddress },
127    { kOptNameUseKernelAddresses,    no_argument,        NULL,     kOptUseKernelAddresses },
128    { kOptNameQuiet,                 no_argument,        NULL,     kOptQuiet },
129    { kOptNameVerbose,               optional_argument,  NULL,     kOptVerbose },
130    { kOptNameTests,                 no_argument,        NULL,     kOptTests },
131    { kOptNameSafeBoot,              no_argument,        NULL,     kOptSafeBoot },
132    { kOptNameNoAuthentication,      no_argument,        NULL,     kOptNoAuthentication },
133    { kOptNameNoResolveDependencies, no_argument,        NULL,     kOptNoResolveDependencies },
134    { kOptNameArch,                  required_argument,  &longopt, kLongOptArch },
135
136    { NULL, 0, NULL, 0 }  // sentinel to terminate list
137};
138
139typedef struct {
140   /* These are ints so we can check for multiply set real easy.
141    */
142    int                    flag_n;  // used to sanity-check -n, -l, -m
143    int                    flag_l;  // before setting behavior-changing
144    int                    flag_m;  // variables doLoad & doStartMatching
145
146    Boolean                getAddressesFromKernel;          // -A
147    Boolean                useRepositoryCaches;             // -c to turn off
148    Boolean                useSystemExtensions;             // -e to turn off
149
150    Boolean                overwriteSymbols;     // -i/-I turns off
151    OSKextExcludeLevel     interactiveLevel;     // -i/-I turns on
152
153    Boolean                doLoad;                          // -l: load but no matching
154    Boolean                doStartMatching;                 // -m: don't load, start matching
155                                             // -n: don't do either
156
157    Boolean                printDiagnostics;                // -t
158    Boolean                safeBootMode;                    // -x
159    Boolean                skipAuthentication;              // -z
160    Boolean                skipDependencies;                // -Z (and with -t only!)
161    Boolean                checkLoadedForDependencies;      // -D to turn off (obsolete)
162    Boolean                logFilterChanged;
163
164    CFMutableDictionaryRef loadAddresses;    // -a; must release
165    CFMutableArrayRef      kextIDs;          // -b; must release
166    CFMutableArrayRef      personalityNames; // -p; must release
167    CFMutableArrayRef      dependencyURLs;   // -d; must release
168    CFMutableArrayRef      repositoryURLs;   // -r; must release
169    CFMutableArrayRef      kextURLs;         // kext args; must release
170    CFMutableArrayRef      scanURLs;         // all URLs to scan
171
172    CFURLRef               kernelURL;        // overriden by -k option
173    CFDataRef              kernelFile;       // contents of kernelURL
174    CFURLRef               symbolDirURL;     // -s option;
175    const NXArchInfo     * archInfo;         // set by -arch
176} KextutilArgs;
177
178#pragma mark Function Prototypes
179/*******************************************************************************
180* Function Prototypes
181*******************************************************************************/
182
183ExitStatus readArgs(
184    int argc,
185    char * const * argv,
186    KextutilArgs * toolArgs);
187ExitStatus checkArgs(KextutilArgs * toolArgs);
188void adjustLogFilterForInteractive(KextutilArgs * toolArgs);
189ExitStatus createKextsToProcess(
190    KextutilArgs * toolArgs,
191    CFArrayRef   * outArray,
192    Boolean      * fatal);
193ExitStatus processKexts(
194    CFArrayRef     kextURLsToUse,
195    KextutilArgs * toolArgs);
196ExitStatus processKext(
197    OSKextRef      aKext,
198    KextutilArgs * toolArgs,
199    Boolean      * fatal);
200ExitStatus runTestsOnKext(
201    OSKextRef aKext,
202    char         * kextPathCString,
203    KextutilArgs * toolArgs,
204    Boolean      * fatal);
205ExitStatus loadKext(
206    OSKextRef     aKext,
207    char         * kextPathCString,
208    KextutilArgs * toolArgs,
209    Boolean      * fatal);
210
211void notifyNonsecureKextload(OSKextRef aKext);
212
213ExitStatus generateKextSymbols(
214    OSKextRef      aKext,
215    char         * kextPathCString,
216    KextutilArgs * toolArgs,
217    Boolean        saveFlag,
218    Boolean      * fatal);
219void setKextLoadAddress(
220    const void * vKey,
221    const void * vValue,
222    void       * vContext);
223int requestLoadAddress(
224    OSKextRef aKext);
225ExitStatus startKextsAndSendPersonalities(
226    OSKextRef      aKext,
227    KextutilArgs * toolArgs,
228    Boolean       * fatal);
229ExitStatus startKext(
230    OSKextRef      aKext,
231    char         * kextPathCString,
232    KextutilArgs * toolArgs,
233    Boolean      * started,
234    Boolean       * yesToAll,
235    Boolean      * fatal);
236ExitStatus sendPersonalities(
237    OSKextRef      aKext,
238    char         * kextPathCString,
239    KextutilArgs * toolArgs,
240    Boolean        isMainFlag,
241    Boolean      * yesToAll,
242    Boolean      * fatal);
243
244Boolean serializeLoad(
245    KextutilArgs * toolArgs,
246    Boolean        loadFlag);
247static void usage(UsageLevel usageLevel);
248
249extern kern_return_t kextmanager_lock_kextload(
250    mach_port_t server,
251    mach_port_t client,
252    int * lockstatus);
253kern_return_t kextmanager_unlock_kextload(
254    mach_port_t server,
255    mach_port_t client);
256
257#endif /* _KEXTUTIL_MAIN_H */
258