2 * Copyright (c) 1998-2000 Apple Computer, Inc. All rights reserved.
4 * @APPLE_LICENSE_HEADER_START@
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.
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
20 * @APPLE_LICENSE_HEADER_END@
23 #include <IOKit/assert.h>
24 #include <IOKit/IOBufferMemoryDescriptor.h>
25 #include <IOKit/IOLib.h>
26 #include <IOKit/storage/IOCDPartitionScheme.h>
28 #define super IOPartitionScheme
29 OSDefineMetaClassAndStructors(IOCDPartitionScheme
, IOPartitionScheme
);
31 // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
33 #define kIOCDPartitionSchemeContentTable "Content Table"
35 // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
37 IOCDMedia
* IOCDPartitionScheme::getProvider() const
40 // Obtain this object's provider. We override the superclass's method
41 // to return a more specific subclass of OSObject -- IOCDMedia. This
42 // method serves simply as a convenience to subclass developers.
45 return (IOCDMedia
*) IOService::getProvider();
48 // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
50 bool IOCDPartitionScheme::init(OSDictionary
* properties
= 0)
53 // Initialize this object's minimal state.
56 // State our assumptions.
58 assert(sizeof(CDTOC
) == 4); // (compiler/platform check)
59 assert(sizeof(CDTOCDescriptor
) == 11); // (compiler/platform check)
61 // Ask our superclass' opinion.
63 if (super::init(properties
) == false) return false;
65 // Initialize our state.
72 // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
74 void IOCDPartitionScheme::free()
77 // Free all of this object's outstanding resources.
80 if ( _partitions
) _partitions
->release();
85 // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
87 IOService
* IOCDPartitionScheme::probe(IOService
* provider
, SInt32
* score
)
90 // Determine whether the provider media contains CD partitions.
93 // State our assumptions.
95 assert(OSDynamicCast(IOCDMedia
, provider
));
97 // Ask superclass' opinion.
99 if (super::probe(provider
, score
) == 0) return 0;
101 // Scan the provider media for CD partitions.
103 _partitions
= scan(score
);
105 return ( _partitions
) ? this : 0;
108 // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
110 bool IOCDPartitionScheme::start(IOService
* provider
)
113 // Publish the new media objects which represent our partitions.
117 OSIterator
* partitionIterator
;
119 // State our assumptions.
123 // Ask our superclass' opinion.
125 if ( super::start(provider
) == false ) return false;
127 // Attach and register the new media objects representing our partitions.
129 partitionIterator
= OSCollectionIterator::withCollection(_partitions
);
130 if ( partitionIterator
== 0 ) return false;
132 while ( (partition
= (IOMedia
*) partitionIterator
->getNextObject()) )
134 if ( partition
->attach(this) )
136 partition
->registerService();
140 partitionIterator
->release();
145 // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
147 OSSet
* IOCDPartitionScheme::scan(SInt32
* score
)
150 // Scan the provider media for CD partitions (in TOC). Returns the set
151 // of media objects representing each of the partitions (the retain for
152 // the set is passed to the caller), or null should no CD partitions be
153 // found. The default probe score can be adjusted up or down, based on
154 // the confidence of the scan.
166 CDSectorSize blockSize
;
167 CDSectorType blockType
;
168 CDTOCDescriptor
* descriptor
;
172 #define kCDSessionMaxIndex 0x63
174 #define kCDTrackMinIndex 0x01
175 #define kCDTrackMaxIndex 0x63
177 IOBufferMemoryDescriptor
* buffer
= 0;
178 IOCDMedia
* media
= getProvider();
179 UInt64 mediaBlockSize
= media
->getPreferredBlockSize();
180 bool mediaIsOpen
= false;
181 OSSet
* partitions
= 0;
182 CDSession
* sessions
= 0;
183 UInt32 sessionMinIndex
= kCDSessionMaxIndex
+ 1;
184 UInt32 sessionMaxIndex
= 0;
187 CDTrack
* tracks
= 0;
188 UInt32 trackMinIndex
= kCDTrackMaxIndex
+ 1;
189 UInt32 trackMaxIndex
= 0;
190 CDTrack
* trackMaxLinked
= 0;
192 // State our assumptions.
194 assert(mediaBlockSize
== kCDSectorSizeWhole
);
196 // Determine whether this media is formatted.
198 if ( media
->isFormatted() == false ) goto scanErr
;
200 // Allocate a buffer large enough to hold a whole 2352-byte sector.
202 buffer
= IOBufferMemoryDescriptor::withCapacity(
203 /* capacity */ mediaBlockSize
,
204 /* withDirection */ kIODirectionIn
);
205 if ( buffer
== 0 ) goto scanErr
;
207 // Allocate a set to hold the set of media objects representing partitions.
209 partitions
= OSSet::withCapacity(2);
210 if ( partitions
== 0 ) goto scanErr
;
212 // Open the media with read access.
214 mediaIsOpen
= media
->open(this, 0, kIOStorageAccessReader
);
215 if ( mediaIsOpen
== false ) goto scanErr
;
217 // Obtain the table of contents.
219 toc
= media
->getTOC();
220 if ( toc
== 0 ) goto scanErr
;
222 tocCount
= (toc
->length
- sizeof(UInt16
)) / sizeof(CDTOCDescriptor
);
224 // Allocate a list large enough to hold information about each session.
226 sessions
= IONew(CDSession
, kCDSessionMaxIndex
+ 1);
227 if ( sessions
== 0 ) goto scanErr
;
229 bzero(sessions
, (kCDSessionMaxIndex
+ 1) * sizeof(CDSession
));
231 // Allocate a list large enough to hold information about each track.
233 tracks
= IONew(CDTrack
, kCDTrackMaxIndex
+ 1);
234 if ( tracks
== 0 ) goto scanErr
;
236 bzero(tracks
, (kCDTrackMaxIndex
+ 1) * sizeof(CDTrack
));
238 // Scan the table of contents, gathering information about the sessions
239 // and tracks on the CD, but without making assumptions about the order
240 // of the entries in the table.
242 for ( unsigned index
= 0; index
< tocCount
; index
++ )
244 CDTOCDescriptor
* descriptor
= toc
->descriptors
+ index
;
246 // Determine whether this is an audio or data track descriptor.
248 if ( descriptor
->point
>= kCDTrackMinIndex
&&
249 descriptor
->point
<= kCDTrackMaxIndex
&&
250 descriptor
->adr
== 0x01 &&
251 descriptor
->session
<= kCDSessionMaxIndex
)
253 CDTrack
* track
= tracks
+ descriptor
->point
;
255 // Record the relevant information about this track.
257 track
->block
= CDConvertMSFToLBA(descriptor
->p
);
258 track
->descriptor
= descriptor
;
259 track
->session
= descriptor
->session
;
261 if ( (descriptor
->control
& 0x04) ) // (data track?)
263 track
->blockSize
= kCDSectorSizeMode1
;
264 track
->blockType
= kCDSectorTypeMode1
;
266 else // (audio track?)
268 track
->blockSize
= kCDSectorSizeCDDA
;
269 track
->blockType
= kCDSectorTypeCDDA
;
272 trackMinIndex
= min(descriptor
->point
, trackMinIndex
);
273 trackMaxIndex
= max(descriptor
->point
, trackMaxIndex
);
276 // Determine whether this is a lead-in (A0) descriptor.
278 else if ( descriptor
->point
== 0xA0 &&
279 descriptor
->adr
== 0x01 &&
280 descriptor
->session
<= kCDSessionMaxIndex
)
282 CDSession
* session
= sessions
+ descriptor
->session
;
284 // Record whether the session has "form 1" or "form 2" tracks.
286 session
->isFormX
= (descriptor
->p
.second
) ? true : false;
289 // Determine whether this is a lead-out (A2) descriptor.
291 else if ( descriptor
->point
== 0xA2 &&
292 descriptor
->adr
== 0x01 &&
293 descriptor
->session
<= kCDSessionMaxIndex
)
295 CDSession
* session
= sessions
+ descriptor
->session
;
297 // Record the position of the session lead-out.
299 session
->leadOut
= CDConvertMSFToLBA(descriptor
->p
);
301 sessionMinIndex
= min(descriptor
->session
, sessionMinIndex
);
302 sessionMaxIndex
= max(descriptor
->session
, sessionMaxIndex
);
306 if ( sessionMinIndex
> kCDSessionMaxIndex
) // (no sessions?)
311 if ( trackMinIndex
> kCDTrackMaxIndex
) // (no tracks?)
316 // Pre-scan the ordered list of tracks.
318 for ( unsigned index
= trackMinIndex
; index
<= trackMaxIndex
; index
++ )
320 CDTrack
* track
= tracks
+ index
;
322 // Validate the existence of this track (and its session).
324 if ( track
->descriptor
== 0 || sessions
[track
->session
].leadOut
== 0 )
329 // Determine the block type, and linkage requirement, for this track.
331 if ( track
->blockType
== kCDSectorTypeMode1
) // (data track?)
335 // Read a whole sector from the data track into our buffer.
337 ///m:2333367:workaround:commented:start
338 // status = media->read( /* client */ this,
339 ///m:2333367:workaround:commented:stop
340 ///m:2333367:workaround:added:start
341 status
= media
->IOStorage::read( /* client */ this,
342 ///m:2333367:workaround:added:stop
343 /* byteStart */ track
->block
* mediaBlockSize
,
344 /* buffer */ buffer
);
346 if ( status
== kIOReturnSuccess
)
348 UInt8
* sector
= (UInt8
*) buffer
->getBytesNoCopy();
350 // Determine whether this is a "mode 2" data track.
352 if ( sector
[15] == 0x02 )
354 // Determine whether this is a "mode 2 formless",
355 // "mode 2 form 1" or "mode 2 form 2" data track.
357 if ( sessions
[track
->session
].isFormX
)
359 if ( (sector
[18] & 0x20) )
361 track
->blockSize
= kCDSectorSizeMode2Form2
;
362 track
->blockType
= kCDSectorTypeMode2Form2
;
366 track
->blockSize
= kCDSectorSizeMode2Form1
;
367 track
->blockType
= kCDSectorTypeMode2Form1
;
369 // Determine whether this is a linked data track.
371 if ( track
->block
&& memcmp(sector
+ 24, "ER", 2) )
373 trackMaxLinked
= track
;
379 track
->blockSize
= kCDSectorSizeMode2
;
380 track
->blockType
= kCDSectorTypeMode2
;
384 // Determine whether this is a linked "mode 1" data track.
386 else if ( track
->block
&& memcmp(sector
+ 16, "ER", 2) )
388 trackMaxLinked
= track
;
394 // Create a media object to represent the linked data tracks, the hidden
395 // pre-gap-area data track, or even both, if it is applicable to this CD.
397 if ( trackMaxLinked
|| tracks
[trackMinIndex
].block
)
399 CDTOCDescriptor descriptor
;
400 UInt32 trackBlockNext
;
401 CDSectorSize trackBlockSize
;
402 CDSectorType trackBlockType
;
405 descriptor
.session
= sessionMinIndex
;
406 descriptor
.control
= 0x04;
407 descriptor
.adr
= 0x01;
408 descriptor
.tno
= 0x00;
409 descriptor
.point
= 0x00;
410 descriptor
.address
.minute
= 0x00;
411 descriptor
.address
.second
= 0x00;
412 descriptor
.address
.frame
= 0x00;
413 descriptor
.zero
= 0x00;
414 descriptor
.p
= CDConvertLBAToMSF(0);
416 if ( trackMaxLinked
)
418 descriptor
.session
= sessionMaxIndex
;
419 descriptor
.control
= trackMaxLinked
->descriptor
->control
;
421 trackBlockNext
= sessions
[sessionMaxIndex
].leadOut
;
422 trackBlockSize
= trackMaxLinked
->blockSize
;
423 trackBlockType
= trackMaxLinked
->blockType
;
427 trackBlockNext
= tracks
[trackMinIndex
].block
;
428 trackBlockSize
= kCDSectorSizeMode1
;
429 trackBlockType
= kCDSectorTypeMode1
;
432 trackSize
= trackBlockNext
* trackBlockSize
;
434 // Create a media object to represent this partition.
436 IOMedia
* newMedia
= instantiateMediaObject(
437 /* partition */ &descriptor
,
438 /* partitionSize */ trackSize
,
439 /* partitionBlockSize */ trackBlockSize
,
440 /* partitionBlockType */ trackBlockType
,
445 partitions
->setObject(newMedia
);
450 // Scan the ordered list of tracks.
452 for ( unsigned index
= trackMinIndex
; index
<= trackMaxIndex
; index
++ )
454 CDTrack
* track
= tracks
+ index
;
455 UInt32 trackBlockNext
;
458 // Determine whether this is a linked data track (skipped).
460 if ( ( trackMaxLinked
) &&
461 ( track
->blockType
== kCDSectorTypeMode1
||
462 track
->blockType
== kCDSectorTypeMode2Form1
) )
467 // Determine where the partitions ends.
469 if ( index
< trackMaxIndex
&& track
->session
== (track
+ 1)->session
)
471 trackBlockNext
= (track
+ 1)->block
;
475 trackBlockNext
= sessions
[track
->session
].leadOut
;
478 if ( track
->block
>= trackBlockNext
)
483 trackSize
= (trackBlockNext
- track
->block
) * track
->blockSize
;
485 // Determine whether the partition is corrupt (fatal).
487 if ( isPartitionCorrupt( /* partition */ track
->descriptor
,
488 /* partitionSize */ trackSize
,
489 /* partitionBlockSize */ track
->blockSize
,
490 /* partitionBlockType */ track
->blockType
,
496 // Determine whether the partition is invalid (skipped).
498 if ( isPartitionInvalid( /* partition */ track
->descriptor
,
499 /* partitionSize */ trackSize
,
500 /* partitionBlockSize */ track
->blockSize
,
501 /* partitionBlockType */ track
->blockType
,
507 // Create a media object to represent this partition.
509 IOMedia
* newMedia
= instantiateMediaObject(
510 /* partition */ track
->descriptor
,
511 /* partitionSize */ trackSize
,
512 /* partitionBlockSize */ track
->blockSize
,
513 /* partitionBlockType */ track
->blockType
,
518 partitions
->setObject(newMedia
);
523 // Release our resources.
527 IODelete(tracks
, CDTrack
, kCDTrackMaxIndex
+ 1);
528 IODelete(sessions
, CDSession
, kCDSessionMaxIndex
+ 1);
534 // Release our resources.
536 if ( mediaIsOpen
) media
->close(this);
537 if ( partitions
) partitions
->release();
538 if ( buffer
) buffer
->release();
539 if ( tracks
) IODelete(tracks
, CDTrack
, kCDTrackMaxIndex
+ 1);
540 if ( sessions
) IODelete(sessions
, CDSession
, kCDSessionMaxIndex
+ 1);
545 // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
547 bool IOCDPartitionScheme::isPartitionCorrupt(
548 CDTOCDescriptor
* /* partition */ ,
549 UInt64
/* partitionSize */ ,
550 UInt32
/* partitionBlockSize */ ,
551 CDSectorType
/* partitionBlockType */ ,
555 // Ask whether the given partition appears to be corrupt. A partition that
556 // is corrupt will cause the failure of the CD partition scheme altogether.
562 // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
564 bool IOCDPartitionScheme::isPartitionInvalid(
565 CDTOCDescriptor
* partition
,
566 UInt64 partitionSize
,
567 UInt32 partitionBlockSize
,
568 CDSectorType partitionBlockType
,
572 // Ask whether the given partition appears to be invalid. A partition that
573 // is invalid will cause it to be skipped in the scan, but will not cause a
574 // failure of the CD partition scheme.
577 IOMedia
* media
= getProvider();
578 UInt64 mediaBlockSize
= media
->getPreferredBlockSize();
579 UInt64 partitionBase
= 0;
581 // Compute the relative byte position and size of the new partition,
582 // relative to the provider media's natural blocking factor of 2352.
584 partitionBase
= CDConvertMSFToLBA(partition
->p
) * mediaBlockSize
;
585 partitionSize
= (partitionSize
/ partitionBlockSize
) * mediaBlockSize
;
587 // Determine whether the partition begins before the 00:02:00 mark.
589 if ( partition
->p
.minute
== 0 && partition
->p
.second
< 2 ) return true;
591 // Determine whether the partition leaves the confines of the container.
593 if ( partitionBase
+ partitionSize
> media
->getSize() ) return true;
598 // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
600 IOMedia
* IOCDPartitionScheme::instantiateMediaObject(
601 CDTOCDescriptor
* partition
,
602 UInt64 partitionSize
,
603 UInt32 partitionBlockSize
,
604 CDSectorType partitionBlockType
,
608 // Instantiate a new media object to represent the given partition.
611 IOMedia
* media
= getProvider();
612 UInt64 partitionBase
= 0;
613 char * partitionHint
= 0;
615 // Compute the relative byte position of the new partition and encode it
616 // into the designated "logical space", given the partition's block type.
618 // 0x0000000000 through 0x00FFFFFFFF is the "don't care" space.
619 // 0x0100000000 through 0x01FFFFFFFF is the "audio" space.
620 // 0x0200000000 through 0x02FFFFFFFF is the "mode 1" space.
621 // 0x0300000000 through 0x03FFFFFFFF is the "mode 2 formless" space.
622 // 0x0400000000 through 0x04FFFFFFFF is the "mode 2 form 1" space.
623 // 0x0500000000 through 0x05FFFFFFFF is the "mode 2 form 2" space.
625 partitionBase
= CDConvertMSFToLBA(partition
->p
) * partitionBlockSize
;
626 partitionBase
+= ((UInt64
) partitionBlockType
) << 32;
628 // Look up a type for the new partition.
630 OSDictionary
* hintTable
= OSDynamicCast(
631 /* type */ OSDictionary
,
632 /* instance */ getProperty(kIOCDPartitionSchemeContentTable
) );
637 OSString
* hintValue
;
639 sprintf(hintIndex
, "0x%02X", partitionBlockType
& 0xFF);
641 hintValue
= OSDynamicCast(OSString
, hintTable
->getObject(hintIndex
));
643 if ( hintValue
) partitionHint
= (char *) hintValue
->getCStringNoCopy();
646 // Create the new media object.
648 IOMedia
* newMedia
= instantiateDesiredMediaObject(
649 /* partition */ partition
,
650 /* partitionSize */ partitionSize
,
651 /* partitionBlockSize */ partitionBlockSize
,
652 /* partitionBlockType */ partitionBlockType
,
658 /* base */ partitionBase
,
659 /* size */ partitionSize
,
660 /* preferredBlockSize */ partitionBlockSize
,
661 /* isEjectable */ media
->isEjectable(),
663 /* isWritable */ media
->isWritable(),
664 /* contentHint */ partitionHint
) )
666 // Set a name for this partition.
669 sprintf(name
, "Untitled %d", partition
->point
);
670 newMedia
->setName(name
);
672 // Set a location value (the partition number) for this partition.
675 sprintf(location
, "%d", partition
->point
);
676 newMedia
->setLocation(location
);
678 // Set the "Partition ID" key for this partition.
680 newMedia
->setProperty(kIOMediaPartitionIDKey
, partition
->point
, 32);
682 // Set the "Session ID" key for this partition.
684 newMedia
->setProperty(kIOMediaSessionIDKey
, partition
->session
, 32);
696 // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
698 IOMedia
* IOCDPartitionScheme::instantiateDesiredMediaObject(
699 CDTOCDescriptor
* /* partition */ ,
700 UInt64
/* partitionSize */ ,
701 UInt32
/* partitionBlockSize */ ,
702 CDSectorType
/* partitionBlockType */ ,
706 // Allocate a new media object (called from instantiateMediaObject).
712 // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
714 void IOCDPartitionScheme::read( IOService
* client
,
716 IOMemoryDescriptor
* buffer
,
717 IOStorageCompletion completion
)
720 // Read data from the storage object at the specified byte offset into the
721 // specified buffer, asynchronously. When the read completes, the caller
722 // will be notified via the specified completion action.
724 // The buffer will be retained for the duration of the read.
726 // For the CD partition scheme, we convert the read from a partition
727 // object into the appropriate readCD command to our provider media.
730 getProvider()->readCD( /* client */ this,
731 /* byteStart */ (byteStart
& 0xFFFFFFFF),
733 /* sectorArea */ (CDSectorArea
) kCDSectorAreaUser
,
734 /* sectorType */ (CDSectorType
) (byteStart
>> 32),
735 /* completion */ completion
);
738 // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
740 OSMetaClassDefineReservedUnused(IOCDPartitionScheme
, 0);
742 // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
744 OSMetaClassDefineReservedUnused(IOCDPartitionScheme
, 1);
746 // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
748 OSMetaClassDefineReservedUnused(IOCDPartitionScheme
, 2);
750 // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
752 OSMetaClassDefineReservedUnused(IOCDPartitionScheme
, 3);
754 // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
756 OSMetaClassDefineReservedUnused(IOCDPartitionScheme
, 4);
758 // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
760 OSMetaClassDefineReservedUnused(IOCDPartitionScheme
, 5);
762 // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
764 OSMetaClassDefineReservedUnused(IOCDPartitionScheme
, 6);
766 // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
768 OSMetaClassDefineReservedUnused(IOCDPartitionScheme
, 7);
770 // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
772 OSMetaClassDefineReservedUnused(IOCDPartitionScheme
, 8);
774 // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
776 OSMetaClassDefineReservedUnused(IOCDPartitionScheme
, 9);
778 // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
780 OSMetaClassDefineReservedUnused(IOCDPartitionScheme
, 10);
782 // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
784 OSMetaClassDefineReservedUnused(IOCDPartitionScheme
, 11);
786 // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
788 OSMetaClassDefineReservedUnused(IOCDPartitionScheme
, 12);
790 // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
792 OSMetaClassDefineReservedUnused(IOCDPartitionScheme
, 13);
794 // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
796 OSMetaClassDefineReservedUnused(IOCDPartitionScheme
, 14);
798 // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
800 OSMetaClassDefineReservedUnused(IOCDPartitionScheme
, 15);