Root/
Source at commit 284 created 13 years 10 months ago. By blackosx, Amended my mistake by updating the Default theme images in the trunk. Now put them back as they were.. (Sorry) | |
---|---|
1 | /*␊ |
2 | * Copyright (c) 1999-2003 Apple Computer, Inc. All rights reserved.␊ |
3 | *␊ |
4 | * @APPLE_LICENSE_HEADER_START@␊ |
5 | * ␊ |
6 | * Portions Copyright (c) 1999-2003 Apple Computer, Inc. All Rights␊ |
7 | * Reserved. This file contains Original Code and/or Modifications of␊ |
8 | * Original Code as defined in and that are subject to the Apple Public␊ |
9 | * Source License Version 2.0 (the 'License'). You may not use this file␊ |
10 | * except in compliance with the License. Please obtain a copy of the␊ |
11 | * License at http://www.apple.com/publicsource and read it before using␊ |
12 | * this file.␊ |
13 | * ␊ |
14 | * The Original Code and all software distributed under the License are␊ |
15 | * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER␊ |
16 | * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,␊ |
17 | * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,␊ |
18 | * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT. Please see the␊ |
19 | * License for the specific language governing rights and limitations␊ |
20 | * under the License.␊ |
21 | * ␊ |
22 | * @APPLE_LICENSE_HEADER_END@␊ |
23 | */␊ |
24 | /*␊ |
25 | * drivers.c - Driver Loading Functions.␊ |
26 | *␊ |
27 | * Copyright (c) 2000 Apple Computer, Inc.␊ |
28 | *␊ |
29 | * DRI: Josh de Cesare␊ |
30 | */␊ |
31 | ␊ |
32 | #include <mach-o/fat.h>␊ |
33 | #include <libkern/OSByteOrder.h>␊ |
34 | #include <mach/machine.h>␊ |
35 | ␊ |
36 | #include "sl.h"␊ |
37 | #include "boot.h"␊ |
38 | #include "bootstruct.h"␊ |
39 | #include "xml.h"␊ |
40 | #include "ramdisk.h"␊ |
41 | #include "kernel_patcher.h"␊ |
42 | ␊ |
43 | extern char gMacOSVersion;␊ |
44 | extern int␉recoveryMode;␊ |
45 | ␊ |
46 | ␊ |
47 | struct Module { ␊ |
48 | struct Module *nextModule;␊ |
49 | long willLoad;␊ |
50 | TagPtr dict;␊ |
51 | char *plistAddr;␊ |
52 | long plistLength;␊ |
53 | char *executablePath;␊ |
54 | char *bundlePath;␊ |
55 | long bundlePathLength;␊ |
56 | };␊ |
57 | typedef struct Module Module, *ModulePtr;␊ |
58 | ␊ |
59 | struct DriverInfo {␊ |
60 | char *plistAddr;␊ |
61 | long plistLength;␊ |
62 | void *executableAddr;␊ |
63 | long executableLength;␊ |
64 | void *bundlePathAddr;␊ |
65 | long bundlePathLength;␊ |
66 | };␊ |
67 | typedef struct DriverInfo DriverInfo, *DriverInfoPtr;␊ |
68 | ␊ |
69 | #define kDriverPackageSignature1 'MKXT'␊ |
70 | #define kDriverPackageSignature2 'MOSX'␊ |
71 | ␊ |
72 | struct DriversPackage {␊ |
73 | unsigned long signature1;␊ |
74 | unsigned long signature2;␊ |
75 | unsigned long length;␊ |
76 | unsigned long alder32;␊ |
77 | unsigned long version;␊ |
78 | unsigned long numDrivers;␊ |
79 | unsigned long reserved1;␊ |
80 | unsigned long reserved2;␊ |
81 | };␊ |
82 | typedef struct DriversPackage DriversPackage;␊ |
83 | ␊ |
84 | enum {␊ |
85 | kCFBundleType2,␊ |
86 | kCFBundleType3␊ |
87 | };␊ |
88 | ␊ |
89 | long (*LoadExtraDrivers_p)(FileLoadDrivers_t FileLoadDrivers_p);␊ |
90 | ␊ |
91 | static unsigned long Alder32( unsigned char * buffer, long length );␊ |
92 | ␊ |
93 | static long FileLoadDrivers(char *dirSpec, long plugin);␊ |
94 | static long NetLoadDrivers(char *dirSpec);␊ |
95 | static long LoadDriverMKext(char *fileSpec);␊ |
96 | static long LoadDriverPList(char *dirSpec, char *name, long bundleType);␊ |
97 | static long LoadMatchedModules(void);␊ |
98 | static long MatchPersonalities(void);␊ |
99 | static long MatchLibraries(void);␊ |
100 | #ifdef NOTDEF␊ |
101 | static ModulePtr FindModule(char *name);␊ |
102 | static void ThinFatFile(void **loadAddrP, unsigned long *lengthP);␊ |
103 | #endif␊ |
104 | static long ParseXML(char *buffer, ModulePtr *module, TagPtr *personalities);␊ |
105 | static long InitDriverSupport(void);␊ |
106 | ␊ |
107 | static ModulePtr gModuleHead, gModuleTail;␊ |
108 | static TagPtr gPersonalityHead, gPersonalityTail;␊ |
109 | static char * gExtensionsSpec;␊ |
110 | static char * gDriverSpec;␊ |
111 | static char * gFileSpec;␊ |
112 | static char * gTempSpec;␊ |
113 | static char * gFileName;␊ |
114 | ␊ |
115 | static unsigned long␊ |
116 | Alder32( unsigned char * buffer, long length )␊ |
117 | {␊ |
118 | long cnt;␊ |
119 | unsigned long result, lowHalf, highHalf;␊ |
120 | ␊ |
121 | lowHalf = 1;␊ |
122 | highHalf = 0;␊ |
123 | ␊ |
124 | ␉for ( cnt = 0; cnt < length; cnt++ )␊ |
125 | {␊ |
126 | if ((cnt % 5000) == 0)␊ |
127 | {␊ |
128 | lowHalf %= 65521L;␊ |
129 | highHalf %= 65521L;␊ |
130 | }␊ |
131 | ␊ |
132 | lowHalf += buffer[cnt];␊ |
133 | highHalf += lowHalf;␊ |
134 | }␊ |
135 | ␊ |
136 | ␉lowHalf %= 65521L;␊ |
137 | ␉highHalf %= 65521L;␊ |
138 | ␊ |
139 | ␉result = (highHalf << 16) | lowHalf;␊ |
140 | ␊ |
141 | ␉return result;␊ |
142 | }␊ |
143 | ␊ |
144 | ␊ |
145 | //==========================================================================␊ |
146 | // InitDriverSupport␊ |
147 | ␊ |
148 | static long␊ |
149 | InitDriverSupport( void )␊ |
150 | {␊ |
151 | gExtensionsSpec = malloc( 4096 );␊ |
152 | gDriverSpec = malloc( 4096 );␊ |
153 | gFileSpec = malloc( 4096 );␊ |
154 | gTempSpec = malloc( 4096 );␊ |
155 | gFileName = malloc( 4096 );␊ |
156 | ␊ |
157 | if ( !gExtensionsSpec || !gDriverSpec || !gFileSpec || !gTempSpec || !gFileName )␊ |
158 | stop("InitDriverSupport error");␊ |
159 | ␊ |
160 | return 0;␊ |
161 | }␊ |
162 | ␊ |
163 | //==========================================================================␊ |
164 | // LoadDrivers␊ |
165 | ␊ |
166 | long LoadDrivers( char * dirSpec )␊ |
167 | {␊ |
168 | char dirSpecExtra[1024];␊ |
169 | ␊ |
170 | if ( InitDriverSupport() != 0 )␊ |
171 | return 0;␊ |
172 | ␊ |
173 | // Load extra drivers if a hook has been installed.␊ |
174 | if (LoadExtraDrivers_p != NULL)␊ |
175 | {␊ |
176 | (*LoadExtraDrivers_p)(&FileLoadDrivers);␊ |
177 | }␊ |
178 | ␊ |
179 | if ( gBootFileType == kNetworkDeviceType )␊ |
180 | {␊ |
181 | if (NetLoadDrivers(dirSpec) != 0) {␊ |
182 | error("Could not load drivers from the network\n");␊ |
183 | return -1;␊ |
184 | }␊ |
185 | }␊ |
186 | else if ( gBootFileType == kBlockDeviceType )␊ |
187 | {␊ |
188 | // First try to load Extra extensions from the ramdisk if isn't aliased as bt(0,0).␊ |
189 | ␉␉if(recoveryMode) ␊ |
190 | ␉␉{␊ |
191 | ␉␉␉verbose("Loading recovery extensions\n");␊ |
192 | ␊ |
193 | ␉␉␉const char* recoveryFolder;␊ |
194 | ␉␉␉int len;␊ |
195 | ␉␉␉if (getValueForKey(kWakeImage, &recoveryFolder, &len, &bootInfo->bootConfig))␊ |
196 | ␉␉␉{␊ |
197 | ␉␉␉␉sprintf(dirSpecExtra, "/Extra/%s/", &recoveryFolder);␊ |
198 | ␉␉␉␉if(FileLoadDrivers(dirSpecExtra, 0) != 0)␊ |
199 | ␉␉␉␉{␊ |
200 | ␉␉␉␉␉verbose("Unable to locate recovery extensions\n");␊ |
201 | ␉␉␉␉}␊ |
202 | ␉␉␉}␊ |
203 | ␉␉␉else {␊ |
204 | ␉␉␉␉verbose("Unable to locate recovery extensions\n");␊ |
205 | ␉␉␉}␊ |
206 | ␊ |
207 | ␉␉}␊ |
208 | ␉␉else␊ |
209 | ␉␉{␊ |
210 | ␉␉␉if (gRAMDiskVolume && !gRAMDiskBTAliased)␊ |
211 | ␉␉␉{␊ |
212 | ␉␉␉␉strcpy(dirSpecExtra, "rd(0,0)/Extra/");␊ |
213 | ␉␉␉␉FileLoadDrivers(dirSpecExtra, 0);␊ |
214 | ␉␉␉}␊ |
215 | ␉␉␉␊ |
216 | ␉␉␉// Next try to load Extra extensions from the selected root partition.␊ |
217 | ␉␉␉strcpy(dirSpecExtra, "/Extra/");␊ |
218 | ␉␉␉if (FileLoadDrivers(dirSpecExtra, 0) != 0)␊ |
219 | ␉␉␉{␊ |
220 | ␉␉␉␉// If failed, then try to load Extra extensions from the boot partition␊ |
221 | ␉␉␉␉// in case we have a separate booter partition or a bt(0,0) aliased ramdisk.␊ |
222 | ␉␉␉␉if ( !(gBIOSBootVolume->biosdev == gBootVolume->biosdev && gBIOSBootVolume->part_no == gBootVolume->part_no)␊ |
223 | ␉␉␉␉␉|| (gRAMDiskVolume && gRAMDiskBTAliased) )␊ |
224 | ␉␉␉␉{␊ |
225 | ␉␉␉␉␉// First try a specfic OS version folder ie 10.5␊ |
226 | ␉␉␉␉␉sprintf(dirSpecExtra, "bt(0,0)/Extra/%s/", &gMacOSVersion);␊ |
227 | ␉␉␉␉␉if (FileLoadDrivers(dirSpecExtra, 0) != 0)␊ |
228 | ␉␉␉␉␉{␉␊ |
229 | ␉␉␉␉␉␉// Next we'll try the base␊ |
230 | ␉␉␉␉␉␉strcpy(dirSpecExtra, "bt(0,0)/Extra/");␊ |
231 | ␉␉␉␉␉␉FileLoadDrivers(dirSpecExtra, 0);␊ |
232 | ␉␉␉␉␉}␊ |
233 | ␉␉␉␉}␊ |
234 | ␉␉␉}␊ |
235 | ␉␉␉␊ |
236 | ␉␉}␊ |
237 | ␊ |
238 | // Also try to load Extensions from boot helper partitions.␊ |
239 | strcpy(dirSpecExtra, "/com.apple.boot.P/System/Library/");␊ |
240 | if (FileLoadDrivers(dirSpecExtra, 0) != 0)␊ |
241 | {␊ |
242 | strcpy(dirSpecExtra, "/com.apple.boot.R/System/Library/");␊ |
243 | if (FileLoadDrivers(dirSpecExtra, 0) != 0)␊ |
244 | {␊ |
245 | strcpy(dirSpecExtra, "/com.apple.boot.S/System/Library/");␊ |
246 | FileLoadDrivers(dirSpecExtra, 0);␊ |
247 | }␊ |
248 | }␊ |
249 | ␊ |
250 | if (gMKextName[0] != '\0')␊ |
251 | {␊ |
252 | verbose("LoadDrivers: Loading from [%s]\n", gMKextName);␊ |
253 | if ( LoadDriverMKext(gMKextName) != 0 )␊ |
254 | {␊ |
255 | error("Could not load %s\n", gMKextName);␊ |
256 | return -1;␊ |
257 | }␊ |
258 | }␊ |
259 | else␊ |
260 | {␊ |
261 | strcpy(gExtensionsSpec, dirSpec);␊ |
262 | strcat(gExtensionsSpec, "System/Library/");␊ |
263 | FileLoadDrivers(gExtensionsSpec, 0);␊ |
264 | }␊ |
265 | }␊ |
266 | else␊ |
267 | {␊ |
268 | return 0;␊ |
269 | }␊ |
270 | ␊ |
271 | MatchPersonalities();␊ |
272 | ␊ |
273 | MatchLibraries();␊ |
274 | ␊ |
275 | LoadMatchedModules();␊ |
276 | ␊ |
277 | return 0;␊ |
278 | }␊ |
279 | ␊ |
280 | //==========================================================================␊ |
281 | // FileLoadDrivers␊ |
282 | ␊ |
283 | static long␊ |
284 | FileLoadDrivers( char * dirSpec, long plugin )␊ |
285 | {␊ |
286 | long ret, length, index, flags, time, bundleType;␊ |
287 | long result = -1;␊ |
288 | const char * name;␊ |
289 | ␊ |
290 | if ( !plugin )␊ |
291 | {␊ |
292 | long time2;␊ |
293 | ␊ |
294 | // TODO: refactor this part of code.␊ |
295 | char altDirSpec[4500];␊ |
296 | sprintf (altDirSpec,"%sCaches/com.apple.kext.caches/Startup/",dirSpec);␊ |
297 | ret = GetFileInfo(altDirSpec, "Extensions.mkext", &flags, &time);␊ |
298 | if ((ret == 0) && ((flags & kFileTypeMask) == kFileTypeFlat))␊ |
299 | {␊ |
300 | ret = GetFileInfo(dirSpec, "Extensions", &flags, &time2);␊ |
301 | if ((ret != 0) || ((flags & kFileTypeMask) != kFileTypeDirectory) ||␊ |
302 | (((gBootMode & kBootModeSafe) == 0) && (time == (time2 + 1))))␊ |
303 | {␊ |
304 | sprintf(gDriverSpec, "%sExtensions.mkext", altDirSpec);␊ |
305 | verbose("LoadDrivers: Loading from [%s]\n", gDriverSpec);␊ |
306 | if (LoadDriverMKext(gDriverSpec) == 0) return 0;␊ |
307 | }␊ |
308 | }␊ |
309 | //␊ |
310 | ␊ |
311 | ret = GetFileInfo(dirSpec, "Extensions.mkext", &flags, &time);␊ |
312 | if ((ret == 0) && ((flags & kFileTypeMask) == kFileTypeFlat))␊ |
313 | {␊ |
314 | ret = GetFileInfo(dirSpec, "Extensions", &flags, &time2);␊ |
315 | if ((ret != 0) || ((flags & kFileTypeMask) != kFileTypeDirectory) ||␊ |
316 | (((gBootMode & kBootModeSafe) == 0) && (time == (time2 + 1))))␊ |
317 | {␊ |
318 | sprintf(gDriverSpec, "%sExtensions.mkext", dirSpec);␊ |
319 | verbose("LoadDrivers: Loading from [%s]\n", gDriverSpec);␊ |
320 | if (LoadDriverMKext(gDriverSpec) == 0) return 0;␊ |
321 | }␊ |
322 | }␊ |
323 | ␊ |
324 | strcat(dirSpec, "Extensions");␊ |
325 | }␊ |
326 | ␊ |
327 | index = 0;␊ |
328 | while (1) {␊ |
329 | ret = GetDirEntry(dirSpec, &index, &name, &flags, &time);␊ |
330 | if (ret == -1) break;␊ |
331 | ␊ |
332 | // Make sure this is a directory.␊ |
333 | if ((flags & kFileTypeMask) != kFileTypeDirectory) continue;␊ |
334 | ␊ |
335 | // Make sure this is a kext.␊ |
336 | length = strlen(name);␊ |
337 | if (strcmp(name + length - 5, ".kext")) continue;␊ |
338 | ␊ |
339 | // Save the file name.␊ |
340 | strcpy(gFileName, name);␊ |
341 | ␊ |
342 | // Determine the bundle type.␊ |
343 | sprintf(gTempSpec, "%s/%s", dirSpec, gFileName);␊ |
344 | ret = GetFileInfo(gTempSpec, "Contents", &flags, &time);␊ |
345 | if (ret == 0) bundleType = kCFBundleType2;␊ |
346 | else bundleType = kCFBundleType3;␊ |
347 | ␊ |
348 | if (!plugin)␊ |
349 | sprintf(gDriverSpec, "%s/%s/%sPlugIns", dirSpec, gFileName,␊ |
350 | (bundleType == kCFBundleType2) ? "Contents/" : "");␊ |
351 | ␊ |
352 | ret = LoadDriverPList(dirSpec, gFileName, bundleType);␊ |
353 | ␊ |
354 | if (result != 0)␊ |
355 | result = ret;␊ |
356 | ␊ |
357 | if (!plugin) ␊ |
358 | result = FileLoadDrivers(gDriverSpec, 1);␊ |
359 | }␊ |
360 | ␊ |
361 | return result;␊ |
362 | }␊ |
363 | ␊ |
364 | //==========================================================================␊ |
365 | // ␊ |
366 | ␊ |
367 | static long␊ |
368 | NetLoadDrivers( char * dirSpec )␊ |
369 | {␊ |
370 | long tries;␊ |
371 | ␊ |
372 | #if NODEF␊ |
373 | long cnt;␊ |
374 | ␊ |
375 | // Get the name of the kernel␊ |
376 | cnt = strlen(gBootFile);␊ |
377 | while (cnt--) {␊ |
378 | if ((gBootFile[cnt] == '\\') || (gBootFile[cnt] == ',')) {␊ |
379 | cnt++;␊ |
380 | break;␊ |
381 | }␊ |
382 | }␊ |
383 | #endif␊ |
384 | ␊ |
385 | // INTEL modification␊ |
386 | sprintf(gDriverSpec, "%s%s.mkext", dirSpec, bootInfo->bootFile);␊ |
387 | ␊ |
388 | verbose("NetLoadDrivers: Loading from [%s]\n", gDriverSpec);␊ |
389 | ␊ |
390 | tries = 3;␊ |
391 | while (tries--)␊ |
392 | {␊ |
393 | if (LoadDriverMKext(gDriverSpec) == 0) break;␊ |
394 | }␊ |
395 | if (tries == -1) return -1;␊ |
396 | ␊ |
397 | return 0;␊ |
398 | }␊ |
399 | ␊ |
400 | //==========================================================================␊ |
401 | // loadDriverMKext␊ |
402 | ␊ |
403 | static long␊ |
404 | LoadDriverMKext( char * fileSpec )␊ |
405 | {␊ |
406 | unsigned long driversAddr, driversLength;␊ |
407 | long length;␊ |
408 | char segName[32];␊ |
409 | DriversPackage * package;␊ |
410 | ␊ |
411 | #define GetPackageElement(e) OSSwapBigToHostInt32(package->e)␊ |
412 | ␊ |
413 | // Load the MKext.␊ |
414 | length = LoadThinFatFile(fileSpec, (void **)&package);␊ |
415 | if (length < sizeof (DriversPackage)) return -1;␊ |
416 | ␊ |
417 | // Verify the MKext.␊ |
418 | if (( GetPackageElement(signature1) != kDriverPackageSignature1) ||␊ |
419 | ( GetPackageElement(signature2) != kDriverPackageSignature2) ||␊ |
420 | ( GetPackageElement(length) > kLoadSize ) ||␊ |
421 | ( GetPackageElement(alder32) !=␊ |
422 | Alder32((unsigned char *)&package->version, GetPackageElement(length) - 0x10) ) )␊ |
423 | {␊ |
424 | return -1;␊ |
425 | }␊ |
426 | ␊ |
427 | // Make space for the MKext.␊ |
428 | driversLength = GetPackageElement(length);␊ |
429 | driversAddr = AllocateKernelMemory(driversLength);␊ |
430 | ␊ |
431 | // Copy the MKext.␊ |
432 | memcpy((void *)driversAddr, (void *)package, driversLength);␊ |
433 | ␊ |
434 | // Add the MKext to the memory map.␊ |
435 | sprintf(segName, "DriversPackage-%lx", driversAddr);␊ |
436 | AllocateMemoryRange(segName, driversAddr, driversLength,␊ |
437 | kBootDriverTypeMKEXT);␊ |
438 | ␊ |
439 | return 0;␊ |
440 | }␊ |
441 | ␊ |
442 | //==========================================================================␊ |
443 | // LoadDriverPList␊ |
444 | ␊ |
445 | static long␊ |
446 | LoadDriverPList( char * dirSpec, char * name, long bundleType )␊ |
447 | {␊ |
448 | long length, executablePathLength, bundlePathLength;␊ |
449 | ModulePtr module;␊ |
450 | TagPtr personalities;␊ |
451 | char * buffer = 0;␊ |
452 | char * tmpExecutablePath = 0;␊ |
453 | char * tmpBundlePath = 0;␊ |
454 | long ret = -1;␊ |
455 | ␊ |
456 | do {␊ |
457 | // Save the driver path.␊ |
458 | ␊ |
459 | sprintf(gFileSpec, "%s/%s/%s", dirSpec, name,␊ |
460 | (bundleType == kCFBundleType2) ? "Contents/MacOS/" : "");␊ |
461 | executablePathLength = strlen(gFileSpec) + 1;␊ |
462 | ␊ |
463 | tmpExecutablePath = malloc(executablePathLength);␊ |
464 | if (tmpExecutablePath == 0) break;␊ |
465 | ␊ |
466 | strcpy(tmpExecutablePath, gFileSpec);␊ |
467 | ␊ |
468 | sprintf(gFileSpec, "%s/%s", dirSpec, name);␊ |
469 | bundlePathLength = strlen(gFileSpec) + 1;␊ |
470 | ␊ |
471 | tmpBundlePath = malloc(bundlePathLength);␊ |
472 | if (tmpBundlePath == 0) break;␊ |
473 | ␊ |
474 | strcpy(tmpBundlePath, gFileSpec);␊ |
475 | ␊ |
476 | // Construct the file spec to the plist, then load it.␊ |
477 | ␊ |
478 | sprintf(gFileSpec, "%s/%s/%sInfo.plist", dirSpec, name,␊ |
479 | (bundleType == kCFBundleType2) ? "Contents/" : "");␊ |
480 | ␊ |
481 | length = LoadFile(gFileSpec);␊ |
482 | if (length == -1) break;␊ |
483 | ␊ |
484 | length = length + 1;␊ |
485 | buffer = malloc(length);␊ |
486 | if (buffer == 0) break;␊ |
487 | ␊ |
488 | strlcpy(buffer, (char *)kLoadAddr, length);␊ |
489 | ␊ |
490 | // Parse the plist.␊ |
491 | ␊ |
492 | ret = ParseXML(buffer, &module, &personalities);␊ |
493 | if (ret != 0) { break; }␊ |
494 | ␊ |
495 | // Allocate memory for the driver path and the plist.␊ |
496 | ␊ |
497 | module->executablePath = tmpExecutablePath;␊ |
498 | module->bundlePath = tmpBundlePath;␊ |
499 | module->bundlePathLength = bundlePathLength;␊ |
500 | module->plistAddr = malloc(length);␊ |
501 | ␊ |
502 | if ((module->executablePath == 0) || (module->bundlePath == 0) || (module->plistAddr == 0))␊ |
503 | break;␊ |
504 | ␊ |
505 | // Save the driver path in the module.␊ |
506 | //strcpy(module->driverPath, tmpDriverPath);␊ |
507 | tmpExecutablePath = 0;␊ |
508 | tmpBundlePath = 0;␊ |
509 | ␊ |
510 | // Add the plist to the module.␊ |
511 | ␊ |
512 | strlcpy(module->plistAddr, (char *)kLoadAddr, length);␊ |
513 | module->plistLength = length;␊ |
514 | ␊ |
515 | // Add the module to the end of the module list.␊ |
516 | ␊ |
517 | if (gModuleHead == 0)␊ |
518 | gModuleHead = module;␊ |
519 | else␊ |
520 | gModuleTail->nextModule = module;␊ |
521 | gModuleTail = module;␊ |
522 | ␊ |
523 | // Add the persionalities to the personality list.␊ |
524 | ␊ |
525 | if (personalities) personalities = personalities->tag;␊ |
526 | while (personalities != 0)␊ |
527 | {␊ |
528 | if (gPersonalityHead == 0)␊ |
529 | gPersonalityHead = personalities->tag;␊ |
530 | else␊ |
531 | gPersonalityTail->tagNext = personalities->tag;␊ |
532 | ␊ |
533 | gPersonalityTail = personalities->tag;␊ |
534 | personalities = personalities->tagNext;␊ |
535 | }␊ |
536 | ␊ |
537 | ret = 0;␊ |
538 | }␊ |
539 | while (0);␊ |
540 | ␊ |
541 | if ( buffer ) free( buffer );␊ |
542 | if ( tmpExecutablePath ) free( tmpExecutablePath );␊ |
543 | if ( tmpBundlePath ) free( tmpBundlePath );␊ |
544 | ␊ |
545 | return ret;␊ |
546 | }␊ |
547 | ␊ |
548 | ␊ |
549 | //==========================================================================␊ |
550 | // LoadMatchedModules␊ |
551 | ␊ |
552 | static long␊ |
553 | LoadMatchedModules( void )␊ |
554 | {␊ |
555 | TagPtr prop;␊ |
556 | ModulePtr module;␊ |
557 | char *fileName, segName[32];␊ |
558 | DriverInfoPtr driver;␊ |
559 | long length, driverAddr, driverLength;␊ |
560 | void *executableAddr = 0;␊ |
561 | ␊ |
562 | ␊ |
563 | module = gModuleHead;␊ |
564 | ␊ |
565 | while (module != 0)␊ |
566 | {␊ |
567 | if (module->willLoad)␊ |
568 | {␊ |
569 | prop = XMLGetProperty(module->dict, kPropCFBundleExecutable);␊ |
570 | ␊ |
571 | if (prop != 0)␊ |
572 | {␊ |
573 | fileName = prop->string;␊ |
574 | sprintf(gFileSpec, "%s%s", module->executablePath, fileName);␊ |
575 | length = LoadThinFatFile(gFileSpec, &executableAddr);␊ |
576 | ␉␉␉␉if (length == 0)␊ |
577 | ␉␉␉␉{␊ |
578 | ␉␉␉␉␉length = LoadFile(gFileSpec);␊ |
579 | ␉␉␉␉␉executableAddr = (void *)kLoadAddr;␊ |
580 | ␉␉␉␉}␊ |
581 | //printf("%s length = %d addr = 0x%x\n", gFileSpec, length, driverModuleAddr); getc();␊ |
582 | }␊ |
583 | else␊ |
584 | length = 0;␊ |
585 | ␊ |
586 | if (length != -1)␊ |
587 | {␊ |
588 | ␉␉//driverModuleAddr = (void *)kLoadAddr;␊ |
589 | //if (length != 0)␊ |
590 | //{␊ |
591 | ␉␉// ThinFatFile(&driverModuleAddr, &length);␊ |
592 | ␉␉//}␊ |
593 | ␊ |
594 | // Make make in the image area.␊ |
595 | driverLength = sizeof(DriverInfo) + module->plistLength + length + module->bundlePathLength;␊ |
596 | driverAddr = AllocateKernelMemory(driverLength);␊ |
597 | ␊ |
598 | // Set up the DriverInfo.␊ |
599 | driver = (DriverInfoPtr)driverAddr;␊ |
600 | driver->plistAddr = (char *)(driverAddr + sizeof(DriverInfo));␊ |
601 | driver->plistLength = module->plistLength;␊ |
602 | if (length != 0)␊ |
603 | {␊ |
604 | driver->executableAddr = (void *)(driverAddr + sizeof(DriverInfo) +␊ |
605 | ␉␉␉␉␉ module->plistLength);␊ |
606 | driver->executableLength = length;␊ |
607 | }␊ |
608 | else␊ |
609 | {␊ |
610 | driver->executableAddr = 0;␊ |
611 | driver->executableLength = 0;␊ |
612 | }␊ |
613 | driver->bundlePathAddr = (void *)(driverAddr + sizeof(DriverInfo) +␊ |
614 | ␉␉␉␉ module->plistLength + driver->executableLength);␊ |
615 | driver->bundlePathLength = module->bundlePathLength;␊ |
616 | ␊ |
617 | // Save the plist, module and bundle.␊ |
618 | strcpy(driver->plistAddr, module->plistAddr);␊ |
619 | if (length != 0)␊ |
620 | {␊ |
621 | memcpy(driver->executableAddr, executableAddr, length);␊ |
622 | }␊ |
623 | strcpy(driver->bundlePathAddr, module->bundlePath);␊ |
624 | ␊ |
625 | // Add an entry to the memory map.␊ |
626 | sprintf(segName, "Driver-%lx", (unsigned long)driver);␊ |
627 | AllocateMemoryRange(segName, driverAddr, driverLength,␊ |
628 | kBootDriverTypeKEXT);␊ |
629 | }␊ |
630 | }␊ |
631 | module = module->nextModule;␊ |
632 | }␊ |
633 | ␊ |
634 | return 0;␊ |
635 | }␊ |
636 | ␊ |
637 | //==========================================================================␊ |
638 | // MatchPersonalities␊ |
639 | ␊ |
640 | static long␊ |
641 | MatchPersonalities( void )␊ |
642 | {␊ |
643 | /* IONameMatch support not implemented */␊ |
644 | return 0;␊ |
645 | }␊ |
646 | ␊ |
647 | //==========================================================================␊ |
648 | // MatchLibraries␊ |
649 | ␊ |
650 | static long␊ |
651 | MatchLibraries( void )␊ |
652 | {␊ |
653 | TagPtr prop, prop2;␊ |
654 | ModulePtr module, module2;␊ |
655 | long done;␊ |
656 | ␊ |
657 | do {␊ |
658 | done = 1;␊ |
659 | module = gModuleHead;␊ |
660 | ␊ |
661 | while (module != 0)␊ |
662 | {␊ |
663 | if (module->willLoad == 1)␊ |
664 | {␊ |
665 | prop = XMLGetProperty(module->dict, kPropOSBundleLibraries);␊ |
666 | if (prop != 0)␊ |
667 | {␊ |
668 | prop = prop->tag;␊ |
669 | while (prop != 0)␊ |
670 | {␊ |
671 | module2 = gModuleHead;␊ |
672 | while (module2 != 0)␊ |
673 | {␊ |
674 | prop2 = XMLGetProperty(module2->dict, kPropCFBundleIdentifier);␊ |
675 | if ((prop2 != 0) && (!strcmp(prop->string, prop2->string)))␊ |
676 | {␊ |
677 | if (module2->willLoad == 0) module2->willLoad = 1;␊ |
678 | break;␊ |
679 | }␊ |
680 | module2 = module2->nextModule;␊ |
681 | }␊ |
682 | prop = prop->tagNext;␊ |
683 | }␊ |
684 | }␊ |
685 | module->willLoad = 2;␊ |
686 | done = 0;␊ |
687 | }␊ |
688 | module = module->nextModule;␊ |
689 | }␊ |
690 | }␊ |
691 | while (!done);␊ |
692 | ␊ |
693 | return 0;␊ |
694 | }␊ |
695 | ␊ |
696 | ␊ |
697 | //==========================================================================␊ |
698 | // FindModule␊ |
699 | ␊ |
700 | #if NOTDEF␊ |
701 | static ModulePtr␊ |
702 | FindModule( char * name )␊ |
703 | {␊ |
704 | ModulePtr module;␊ |
705 | TagPtr prop;␊ |
706 | ␊ |
707 | module = gModuleHead;␊ |
708 | ␊ |
709 | while (module != 0)␊ |
710 | {␊ |
711 | prop = GetProperty(module->dict, kPropCFBundleIdentifier);␊ |
712 | if ((prop != 0) && !strcmp(name, prop->string)) break;␊ |
713 | module = module->nextModule;␊ |
714 | }␊ |
715 | ␊ |
716 | return module;␊ |
717 | }␊ |
718 | #endif /* NOTDEF */␊ |
719 | ␊ |
720 | //==========================================================================␊ |
721 | // ParseXML␊ |
722 | ␊ |
723 | static long␊ |
724 | ParseXML( char * buffer, ModulePtr * module, TagPtr * personalities )␊ |
725 | {␊ |
726 | ␉long length, pos;␊ |
727 | ␉TagPtr moduleDict, required;␊ |
728 | ␉ModulePtr tmpModule;␊ |
729 | ␊ |
730 | pos = 0;␊ |
731 | ␊ |
732 | while (1)␊ |
733 | {␊ |
734 | length = XMLParseNextTag(buffer + pos, &moduleDict);␊ |
735 | if (length == -1) break;␊ |
736 | ␊ |
737 | pos += length;␊ |
738 | ␊ |
739 | if (moduleDict == 0) continue;␊ |
740 | if (moduleDict->type == kTagTypeDict) break;␊ |
741 | ␊ |
742 | XMLFreeTag(moduleDict);␊ |
743 | }␊ |
744 | ␊ |
745 | if (length == -1) return -1;␊ |
746 | ␊ |
747 | required = XMLGetProperty(moduleDict, kPropOSBundleRequired);␊ |
748 | if ( (required == 0) ||␊ |
749 | (required->type != kTagTypeString) ||␊ |
750 | !strcmp(required->string, "Safe Boot"))␊ |
751 | {␊ |
752 | XMLFreeTag(moduleDict);␊ |
753 | return -2;␊ |
754 | }␊ |
755 | ␊ |
756 | tmpModule = malloc(sizeof(Module));␊ |
757 | if (tmpModule == 0)␊ |
758 | {␊ |
759 | XMLFreeTag(moduleDict);␊ |
760 | return -1;␊ |
761 | }␊ |
762 | tmpModule->dict = moduleDict;␊ |
763 | ␊ |
764 | // For now, load any module that has OSBundleRequired != "Safe Boot".␊ |
765 | ␊ |
766 | tmpModule->willLoad = 1;␊ |
767 | ␊ |
768 | *module = tmpModule;␊ |
769 | ␊ |
770 | // Get the personalities.␊ |
771 | ␊ |
772 | *personalities = XMLGetProperty(moduleDict, kPropIOKitPersonalities);␊ |
773 | ␊ |
774 | return 0;␊ |
775 | }␊ |
776 | ␊ |
777 | #if NOTDEF␊ |
778 | static char gPlatformName[64];␊ |
779 | #endif␊ |
780 | ␊ |
781 | long ␊ |
782 | DecodeKernel(void *binary, entry_t *rentry, char **raddr, int *rsize)␊ |
783 | {␊ |
784 | long ret;␊ |
785 | compressed_kernel_header * kernel_header = (compressed_kernel_header *) binary;␊ |
786 | u_int32_t uncompressed_size, size;␊ |
787 | void *buffer;␊ |
788 | ␉unsigned long len;␊ |
789 | ␊ |
790 | #if 0␊ |
791 | printf("kernel header:\n");␊ |
792 | printf("signature: 0x%x\n", kernel_header->signature);␊ |
793 | printf("compress_type: 0x%x\n", kernel_header->compress_type);␊ |
794 | printf("adler32: 0x%x\n", kernel_header->adler32);␊ |
795 | printf("uncompressed_size: 0x%x\n", kernel_header->uncompressed_size);␊ |
796 | printf("compressed_size: 0x%x\n", kernel_header->compressed_size);␊ |
797 | getc();␊ |
798 | #endif␊ |
799 | ␊ |
800 | if (kernel_header->signature == OSSwapBigToHostConstInt32('comp')) {␊ |
801 | if (kernel_header->compress_type != OSSwapBigToHostConstInt32('lzss')) {␊ |
802 | error("kernel compression is bad\n");␊ |
803 | return -1;␊ |
804 | }␊ |
805 | #if NOTDEF␊ |
806 | if (kernel_header->platform_name[0] && strcmp(gPlatformName, kernel_header->platform_name))␊ |
807 | return -1;␊ |
808 | if (kernel_header->root_path[0] && strcmp(gBootFile, kernel_header->root_path))␊ |
809 | return -1;␊ |
810 | #endif␊ |
811 | ␊ |
812 | uncompressed_size = OSSwapBigToHostInt32(kernel_header->uncompressed_size);␊ |
813 | binary = buffer = malloc(uncompressed_size);␊ |
814 | ␊ |
815 | size = decompress_lzss((u_int8_t *) binary, &kernel_header->data[0],␊ |
816 | OSSwapBigToHostInt32(kernel_header->compressed_size));␊ |
817 | if (uncompressed_size != size) {␊ |
818 | error("size mismatch from lzss: %x\n", size);␊ |
819 | return -1;␊ |
820 | }␊ |
821 | if (OSSwapBigToHostInt32(kernel_header->adler32) !=␊ |
822 | Alder32(binary, uncompressed_size)) {␊ |
823 | printf("adler mismatch\n");␊ |
824 | return -1;␊ |
825 | }␊ |
826 | }␊ |
827 | ␊ |
828 | ret = ThinFatFile(&binary, &len);␊ |
829 | if (ret == 0 && len == 0 && archCpuType==CPU_TYPE_X86_64)␊ |
830 | {␊ |
831 | ␉ archCpuType=CPU_TYPE_I386;␊ |
832 | ␉ ret = ThinFatFile(&binary, &len);␊ |
833 | }␊ |
834 | ␊ |
835 | patch_kernel(binary);␊ |
836 | ␉␊ |
837 | ret = DecodeMachO(binary, rentry, raddr, rsize);␊ |
838 | ␉␊ |
839 | if (ret<0 && archCpuType==CPU_TYPE_X86_64)␊ |
840 | {␊ |
841 | ␉ archCpuType=CPU_TYPE_I386;␊ |
842 | ␉ ret = DecodeMachO(binary, rentry, raddr, rsize);␊ |
843 | }␊ |
844 | ␉␊ |
845 | ␊ |
846 | return ret;␊ |
847 | }␊ |
848 |