]> git.saurik.com Git - apple/xnu.git/blame - iokit/Families/IOStorage/IOApplePartitionScheme.cpp
xnu-124.13.tar.gz
[apple/xnu.git] / iokit / Families / IOStorage / IOApplePartitionScheme.cpp
CommitLineData
1c79356b
A
1/*
2 * Copyright (c) 1998-2000 Apple Computer, Inc. All rights reserved.
3 *
4 * @APPLE_LICENSE_HEADER_START@
5 *
6 * The contents of this file constitute Original Code as defined in and
7 * are subject to the Apple Public Source License Version 1.1 (the
8 * "License"). You may not use this file except in compliance with the
9 * License. Please obtain a copy of the License at
10 * http://www.apple.com/publicsource and read it before using this file.
11 *
12 * This Original Code and all software distributed under the License are
13 * distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY KIND, EITHER
14 * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
15 * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
16 * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT. Please see the
17 * License for the specific language governing rights and limitations
18 * under the License.
19 *
20 * @APPLE_LICENSE_HEADER_END@
21 */
22
23#include <IOKit/assert.h>
24#include <IOKit/IOBufferMemoryDescriptor.h>
25#include <IOKit/IODeviceTreeSupport.h>
26#include <IOKit/IOLib.h>
27#include <IOKit/storage/IOApplePartitionScheme.h>
28#include <libkern/OSByteOrder.h>
29
30#define super IOPartitionScheme
31OSDefineMetaClassAndStructors(IOApplePartitionScheme, IOPartitionScheme);
32
33// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
34// Notes
35//
36// o the on-disk structure's fields are: 16-bit packed, big-endian formatted
37// o the dpme_pblock_start and dpme_pblocks block values are:
38// o for media without a driver map:
39// o natural block size based
40// o for media with a driver map:
41// o driver map block size based, unless the driver map block size is 2048
42// and a valid partition entry exists at a 512 byte offset into the disk,
43// in which case, assume a 512 byte block size, except for the partition
44// entries that lie on a 2048 byte multiple and are one of the following
45// types: Apple_Patches, Apple_Driver, Apple_Driver43, Apple_Driver43_CD,
46// Apple_Driver_ATA, Apple_Driver_ATAPI; in which case, we assume a 2048
47// byte block size (for the one partition)
48// o the dpme_pblock_start block value is relative to the media container
49//
50
51// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
52
53#define kIOApplePartitionSchemeContentTable "Content Table"
54
55// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
56
57bool IOApplePartitionScheme::init(OSDictionary * properties = 0)
58{
59 //
60 // Initialize this object's minimal state.
61 //
62
63 // State our assumptions.
64
65 assert(sizeof(dpme) == 512); // (compiler/platform check)
66 assert(sizeof(DDMap) == 8); // (compiler/platform check)
67 assert(sizeof(Block0) == 512); // (compiler/platform check)
68
69 // Ask our superclass' opinion.
70
71 if (super::init(properties) == false) return false;
72
73 // Initialize our state.
74
75 _partitions = 0;
76
77 return true;
78}
79
80// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
81
82void IOApplePartitionScheme::free()
83{
84 //
85 // Free all of this object's outstanding resources.
86 //
87
88 if ( _partitions ) _partitions->release();
89
90 super::free();
91}
92
93// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
94
95IOService * IOApplePartitionScheme::probe(IOService * provider, SInt32 * score)
96{
97 //
98 // Determine whether the provider media contains an Apple partition map.
99 //
100
101 // State our assumptions.
102
103 assert(OSDynamicCast(IOMedia, provider));
104
105 // Ask superclass' opinion.
106
107 if (super::probe(provider, score) == 0) return 0;
108
109 // Scan the provider media for an Apple partition map.
110
111 _partitions = scan(score);
112
113 return ( _partitions ) ? this : 0;
114}
115
116// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
117
118bool IOApplePartitionScheme::start(IOService * provider)
119{
120 //
121 // Publish the new media objects which represent our partitions.
122 //
123
124 IOMedia * partition;
125 OSIterator * partitionIterator;
126
127 // State our assumptions.
128
129 assert(_partitions);
130
131 // Ask our superclass' opinion.
132
133 if ( super::start(provider) == false ) return false;
134
135 // Attach and register the new media objects representing our partitions.
136
137 partitionIterator = OSCollectionIterator::withCollection(_partitions);
138 if ( partitionIterator == 0 ) return false;
139
140 while ( (partition = (IOMedia *) partitionIterator->getNextObject()) )
141 {
142 if ( partition->attach(this) )
143 {
144 attachMediaObjectToDeviceTree(partition);
145
146 partition->registerService();
147 }
148 }
149
150 partitionIterator->release();
151
152 return true;
153}
154
155// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
156
157void IOApplePartitionScheme::stop(IOService * provider)
158{
159 //
160 // Clean up after the media objects we published before terminating.
161 //
162
163 IOMedia * partition;
164 OSIterator * partitionIterator;
165
166 // State our assumptions.
167
168 assert(_partitions);
169
170 // Detach the media objects we previously attached to the device tree.
171
172 partitionIterator = OSCollectionIterator::withCollection(_partitions);
173
174 if ( partitionIterator )
175 {
176 while ( (partition = (IOMedia *) partitionIterator->getNextObject()) )
177 {
178 detachMediaObjectFromDeviceTree(partition);
179 }
180
181 partitionIterator->release();
182 }
183
184 super::stop(provider);
185}
186
187// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
188
189OSSet * IOApplePartitionScheme::scan(SInt32 * score)
190{
191 //
192 // Scan the provider media for an Apple partition map. Returns the set
193 // of media objects representing each of the partitions (the retain for
194 // the set is passed to the caller), or null should no partition map be
195 // found. The default probe score can be adjusted up or down, based on
196 // the confidence of the scan.
197 //
198
199 IOBufferMemoryDescriptor * buffer = 0;
200 UInt32 bufferReadAt = 0;
201 UInt32 bufferSize = 0;
202 UInt32 dpmeBlockSize = 0;
203 UInt32 dpmeCount = 0;
204 UInt32 dpmeID = 0;
205 dpme * dpmeMap = 0;
206 UInt32 dpmeMaxCount = 0;
207 bool dpmeOldSchool = false;
208 Block0 * driverMap = 0;
209 IOMedia * media = getProvider();
210 UInt64 mediaBlockSize = media->getPreferredBlockSize();
211 bool mediaIsOpen = false;
212 OSSet * partitions = 0;
213 IOReturn status = kIOReturnError;
214
215 // Determine whether this media is formatted.
216
217 if ( media->isFormatted() == false ) goto scanErr;
218
219 // Determine whether this media has an appropriate block size.
220
221 if ( (mediaBlockSize % sizeof(dpme)) ) goto scanErr;
222
223 // Allocate a buffer large enough to hold one map, rounded to a media block.
224
225 bufferSize = IORound(max(sizeof(Block0), sizeof(dpme)), mediaBlockSize);
226 buffer = IOBufferMemoryDescriptor::withCapacity(
227 /* capacity */ bufferSize,
228 /* withDirection */ kIODirectionIn );
229 if ( buffer == 0 ) goto scanErr;
230
231 // Allocate a set to hold the set of media objects representing partitions.
232
233 partitions = OSSet::withCapacity(8);
234 if ( partitions == 0 ) goto scanErr;
235
236 // Open the media with read access.
237
238 mediaIsOpen = media->open(this, 0, kIOStorageAccessReader);
239 if ( mediaIsOpen == false ) goto scanErr;
240
241 // Read the driver map into our buffer.
242
243 bufferReadAt = 0;
244
245///m:2333367:workaround:commented:start
246// status = media->read(this, bufferReadAt, buffer);
247///m:2333367:workaround:commented:stop
248///m:2333367:workaround:added:start
249 status = media->IOStorage::read(this, bufferReadAt, buffer);
250///m:2333367:workaround:added:stop
251 if ( status != kIOReturnSuccess ) goto scanErr;
252
253 driverMap = (Block0 *) buffer->getBytesNoCopy();
254
255 // Determine the official block size to use to scan the partition entries.
256
257 dpmeBlockSize = mediaBlockSize; // (natural block size)
258
259 if ( driverMap->sbSig == BLOCK0_SIGNATURE )
260 {
261 dpmeBlockSize = driverMap->sbBlkSize; // (driver map block size)
262
263 // Determine whether we have an old school partition map, where there is
264 // a partition entry at a 512 byte offset into the disk, even though the
265 // driver map block size is 2048.
266
267 if ( dpmeBlockSize == 2048 )
268 {
269 if ( bufferSize >= sizeof(Block0) + sizeof(dpme) ) // (in buffer?)
270 {
271 dpmeMap = (dpme *) (driverMap + 1);
272 }
273 else // (not in buffer)
274 {
275 // Read the partition entry at byte offset 512 into our buffer.
276
277 bufferReadAt = sizeof(dpme);
278
279///m:2333367:workaround:commented:start
280// status = media->read(this, bufferReadAt, buffer);
281///m:2333367:workaround:commented:stop
282///m:2333367:workaround:added:start
283 status = media->IOStorage::read(this, bufferReadAt, buffer);
284///m:2333367:workaround:added:stop
285 if ( status != kIOReturnSuccess ) goto scanErr;
286
287 dpmeMap = (dpme *) buffer->getBytesNoCopy();
288 }
289
290 // Determine whether the partition entry signature is present.
291
292 if (OSSwapBigToHostInt16(dpmeMap->dpme_signature) == DPME_SIGNATURE)
293 {
294 dpmeBlockSize = sizeof(dpme); // (old school block size)
295 dpmeOldSchool = true;
296 }
297 }
298
299 // Increase the probe score when a driver map is detected, since we are
300 // more confident in the match when it is present. This will eliminate
301 // conflicts with FDisk when it shares the same block as the driver map.
302
303 *score += 2000;
304 }
305
306 // Scan the media for Apple partition entries.
307
308 for ( dpmeID = 1, dpmeCount = 1; dpmeID <= dpmeCount; dpmeID++ )
309 {
310 UInt32 partitionBlockSize = dpmeBlockSize;
311
312 // Determine whether we've exhausted the current buffer of entries.
313
314 if ( dpmeID * dpmeBlockSize + sizeof(dpme) > bufferReadAt + bufferSize )
315 {
316 // Read the next partition entry into our buffer.
317
318 bufferReadAt = dpmeID * dpmeBlockSize;
319
320///m:2333367:workaround:commented:start
321// status = media->read(this, bufferReadAt, buffer);
322///m:2333367:workaround:commented:stop
323///m:2333367:workaround:added:start
324 status = media->IOStorage::read(this, bufferReadAt, buffer);
325///m:2333367:workaround:added:stop
326 if ( status != kIOReturnSuccess ) goto scanErr;
327 }
328
329 dpmeMap = (dpme *) ( ((UInt8 *) buffer->getBytesNoCopy()) +
330 (dpmeID * dpmeBlockSize) - bufferReadAt );
331
332 // Determine whether the partition entry signature is present.
333
334 if ( OSSwapBigToHostInt16(dpmeMap->dpme_signature) != DPME_SIGNATURE )
335 {
336 goto scanErr;
337 }
338
339 // Obtain an accurate number of entries in the partition map.
340
341 if ( !strcmp(dpmeMap->dpme_type, "Apple_partition_map") ||
342 !strcmp(dpmeMap->dpme_type, "Apple_Partition_Map") ||
343 !strcmp(dpmeMap->dpme_type, "Apple_patition_map" ) )
344 {
345 dpmeCount = OSSwapBigToHostInt32(dpmeMap->dpme_map_entries);
346 dpmeMaxCount = OSSwapBigToHostInt32(dpmeMap->dpme_pblocks);
347 }
348 else if ( dpmeCount == 1 )
349 {
350 dpmeCount = OSSwapBigToHostInt32(dpmeMap->dpme_map_entries);
351 }
352
353 // Obtain an accurate block size for an old school partition map.
354
355 if ( dpmeOldSchool && (dpmeID % 4) == 0 )
356 {
357 if ( !strcmp(dpmeMap->dpme_type, "Apple_Driver" ) ||
358 !strcmp(dpmeMap->dpme_type, "Apple_Driver43" ) ||
359 !strcmp(dpmeMap->dpme_type, "Apple_Driver43_CD" ) ||
360 !strcmp(dpmeMap->dpme_type, "Apple_Driver_ATA" ) ||
361 !strcmp(dpmeMap->dpme_type, "Apple_Driver_ATAPI") ||
362 !strcmp(dpmeMap->dpme_type, "Apple_Patches" ) )
363 {
364 partitionBlockSize = 2048;
365 }
366 }
367
368 // Determine whether the partition is corrupt (fatal).
369
370 if ( isPartitionCorrupt(
371 /* partition */ dpmeMap,
372 /* partitionID */ dpmeID,
373 /* partitionBlockSize */ partitionBlockSize ) )
374 {
375 goto scanErr;
376 }
377
378 // Determine whether the partition is invalid (skipped).
379
380 if ( isPartitionInvalid(
381 /* partition */ dpmeMap,
382 /* partitionID */ dpmeID,
383 /* partitionBlockSize */ partitionBlockSize ) )
384 {
385 continue;
386 }
387
388 // Create a media object to represent this partition.
389
390 IOMedia * newMedia = instantiateMediaObject(
391 /* partition */ dpmeMap,
392 /* partitionID */ dpmeID,
393 /* partitionBlockSize */ partitionBlockSize );
394
395 if ( newMedia )
396 {
397 partitions->setObject(newMedia);
398 newMedia->release();
399 }
400 }
401
402 // Determine whether we ever came accross an Apple_partition_map partition.
403
404 if ( dpmeMaxCount == 0 ) goto scanErr;
405
406 // Release our resources.
407
408 media->close(this);
409 buffer->release();
410
411 return partitions;
412
413scanErr:
414
415 // Release our resources.
416
417 if ( mediaIsOpen ) media->close(this);
418 if ( partitions ) partitions->release();
419 if ( buffer ) buffer->release();
420
421 return 0;
422}
423
424// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
425
426bool IOApplePartitionScheme::isPartitionCorrupt(
427 dpme * /* partition */ ,
428 UInt32 /* partitionID */ ,
429 UInt32 /* partitionBlockSize */ )
430{
431 //
432 // Ask whether the given partition appears to be corrupt. A partition that
433 // is corrupt will cause the failure of the Apple partition map recognition
434 // altogether.
435 //
436
437 return false;
438}
439
440// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
441
442bool IOApplePartitionScheme::isPartitionInvalid( dpme * partition,
443 UInt32 partitionID,
444 UInt32 partitionBlockSize )
445{
446 //
447 // Ask whether the given partition appears to be invalid. A partition that
448 // is invalid will cause it to be skipped in the scan, but will not cause a
449 // failure of the Apple partition map recognition.
450 //
451
452 IOMedia * media = getProvider();
453 UInt64 partitionBase = 0;
454 UInt64 partitionSize = 0;
455
456 // Compute the relative byte position and size of the new partition.
457
458 partitionBase = OSSwapBigToHostInt32(partition->dpme_pblock_start);
459 partitionSize = OSSwapBigToHostInt32(partition->dpme_pblocks);
460 partitionBase *= partitionBlockSize;
461 partitionSize *= partitionBlockSize;
462
463 // Determine whether the partition is a placeholder.
464
465 if ( partitionSize == 0 ) return true;
466
467 // Determine whether the partition starts at (or past) the end-of-media.
468
469 if ( partitionBase >= media->getSize() ) return true;
470
471 return false;
472}
473
474// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
475
476IOMedia * IOApplePartitionScheme::instantiateMediaObject(
477 dpme * partition,
478 UInt32 partitionID,
479 UInt32 partitionBlockSize )
480{
481 //
482 // Instantiate a new media object to represent the given partition.
483 //
484
485 IOMedia * media = getProvider();
486 UInt64 mediaBlockSize = media->getPreferredBlockSize();
487 UInt64 partitionBase = 0;
488 char * partitionHint = partition->dpme_type;
489 bool partitionIsWritable = media->isWritable();
490 char * partitionName = partition->dpme_name;
491 UInt64 partitionSize = 0;
492
493 // Compute the relative byte position and size of the new partition.
494
495 partitionBase = OSSwapBigToHostInt32(partition->dpme_pblock_start);
496 partitionSize = OSSwapBigToHostInt32(partition->dpme_pblocks);
497 partitionBase *= partitionBlockSize;
498 partitionSize *= partitionBlockSize;
499
500 // Clip the size of the new partition if it extends past the end-of-media.
501
502 if ( partitionBase + partitionSize > media->getSize() )
503 {
504 partitionSize = media->getSize() - partitionBase;
505 }
506
507 // Look up a type for the new partition.
508
509 OSDictionary * hintTable = OSDynamicCast(
510 /* type */ OSDictionary,
511 /* instance */ getProperty(kIOApplePartitionSchemeContentTable) );
512
513 if ( hintTable )
514 {
515 OSString * hintValue = OSDynamicCast(
516 /* type */ OSString,
517 /* instance */ hintTable->getObject(partitionHint) );
518
519 if ( hintValue ) partitionHint = (char *) hintValue->getCStringNoCopy();
520 }
521
522 // Look up a name for the new partition.
523
524 while ( *partitionName == ' ' ) { partitionName++; }
525
526 if ( *partitionName == 0 ) partitionName = 0;
527
528 // Determine whether the new partition type is Apple_Free, which we choose
529 // not to publish because it is an internal concept to the partition map.
530
531 if ( !strcmp(partitionHint, "Apple_Free") ) return 0;
532
533 // Determine whether the new partition is read-only.
534 //
535 // Note that we treat the misspelt Apple_patition_map entries as equivalent
536 // to Apple_partition_map entries due to the messed up CDs noted in 2513960.
537
538 if ( !strcmp(partition->dpme_type, "Apple_partition_map") ||
539 !strcmp(partition->dpme_type, "Apple_Partition_Map") ||
540 !strcmp(partition->dpme_type, "Apple_patition_map" ) ||
541 ( ((partition->dpme_flags & DPME_FLAGS_WRITABLE) == 0) &&
542 ((partition->dpme_flags & DPME_FLAGS_VALID ) != 0) ) )
543 {
544 partitionIsWritable = false;
545 }
546
547 // Create the new media object.
548
549 IOMedia * newMedia = instantiateDesiredMediaObject(
550 /* partition */ partition,
551 /* partitionID */ partitionID,
552 /* partitionBlockSize */ partitionBlockSize );
553
554 if ( newMedia )
555 {
556 if ( newMedia->init(
557 /* base */ partitionBase,
558 /* size */ partitionSize,
559 /* preferredBlockSize */ mediaBlockSize,
560 /* isEjectable */ media->isEjectable(),
561 /* isWhole */ false,
562 /* isWritable */ partitionIsWritable,
563 /* contentHint */ partitionHint ) )
564 {
565 // Set a name for this partition.
566
567 char name[24];
568 sprintf(name, "Untitled %ld", partitionID);
569 newMedia->setName(partitionName ? partitionName : name);
570
571 // Set a location value (the partition number) for this partition.
572
573 char location[12];
574 sprintf(location, "%ld", partitionID);
575 newMedia->setLocation(location);
576
577 // Set the "Partition ID" key for this partition.
578
579 newMedia->setProperty(kIOMediaPartitionIDKey, partitionID, 32);
580 }
581 else
582 {
583 newMedia->release();
584 newMedia = 0;
585 }
586 }
587
588 return newMedia;
589}
590
591// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
592
593IOMedia * IOApplePartitionScheme::instantiateDesiredMediaObject(
594 dpme * partition,
595 UInt32 partitionID,
596 UInt32 partitionBlockSize )
597{
598 //
599 // Allocate a new media object (called from instantiateMediaObject).
600 //
601
602 return new IOMedia;
603}
604
605// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
606
607bool IOApplePartitionScheme::attachMediaObjectToDeviceTree( IOMedia * media )
608{
609 //
610 // Attach the given media object to the device tree plane.
611 //
612
613 IOService * service;
614 SInt32 unit = -1;
615
616 for ( service = this; service; service = service->getProvider() )
617 {
618 OSNumber * number;
619
620 if ( (number = OSDynamicCast(OSNumber, service->getProperty("IOUnit"))))
621 {
622 unit = number->unsigned32BitValue();
623 }
624
625 if ( service->inPlane(gIODTPlane) )
626 {
627 IORegistryEntry * child;
628 IORegistryIterator * children;
629
630 if ( unit == -1 ) break;
631
632 children = IORegistryIterator::iterateOver(service, gIODTPlane);
633
634 if ( children == 0 ) break;
635
636 while ( (child = children->getNextObject()) )
637 {
638 const char * location = child->getLocation(gIODTPlane);
639 const char * name = child->getName(gIODTPlane);
640
641 if ( name == 0 || strcmp(name, "" ) != 0 ||
642 location == 0 || strchr(location, ':') == 0 )
643 {
644 child->detachAll(gIODTPlane);
645 }
646 }
647
648 children->release();
649
650 if ( media->attachToParent(service, gIODTPlane) )
651 {
652 char location[ sizeof("hhhhhhhh:dddddddddd") ];
653
654 sprintf(location, "%lx:", unit);
655 strcat(location, media->getLocation());
656 media->setLocation(location, gIODTPlane);
657 media->setName("", gIODTPlane);
658
659 return true;
660 }
661
662 break;
663 }
664 }
665
666 return false;
667}
668
669// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
670
671void IOApplePartitionScheme::detachMediaObjectFromDeviceTree( IOMedia * media )
672{
673 //
674 // Detach the given media object from the device tree plane.
675 //
676
677 IORegistryEntry * parent;
678
679 if ( (parent = media->getParentEntry(gIODTPlane)) )
680 {
681 media->detachFromParent(parent, gIODTPlane);
682 }
683}
684
685// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
686
687OSMetaClassDefineReservedUnused(IOApplePartitionScheme, 0);
688
689// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
690
691OSMetaClassDefineReservedUnused(IOApplePartitionScheme, 1);
692
693// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
694
695OSMetaClassDefineReservedUnused(IOApplePartitionScheme, 2);
696
697// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
698
699OSMetaClassDefineReservedUnused(IOApplePartitionScheme, 3);
700
701// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
702
703OSMetaClassDefineReservedUnused(IOApplePartitionScheme, 4);
704
705// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
706
707OSMetaClassDefineReservedUnused(IOApplePartitionScheme, 5);
708
709// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
710
711OSMetaClassDefineReservedUnused(IOApplePartitionScheme, 6);
712
713// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
714
715OSMetaClassDefineReservedUnused(IOApplePartitionScheme, 7);
716
717// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
718
719OSMetaClassDefineReservedUnused(IOApplePartitionScheme, 8);
720
721// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
722
723OSMetaClassDefineReservedUnused(IOApplePartitionScheme, 9);
724
725// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
726
727OSMetaClassDefineReservedUnused(IOApplePartitionScheme, 10);
728
729// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
730
731OSMetaClassDefineReservedUnused(IOApplePartitionScheme, 11);
732
733// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
734
735OSMetaClassDefineReservedUnused(IOApplePartitionScheme, 12);
736
737// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
738
739OSMetaClassDefineReservedUnused(IOApplePartitionScheme, 13);
740
741// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
742
743OSMetaClassDefineReservedUnused(IOApplePartitionScheme, 14);
744
745// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
746
747OSMetaClassDefineReservedUnused(IOApplePartitionScheme, 15);