]>
Commit | Line | Data |
---|---|---|
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 <sys/param.h> | |
24 | #include <IOKit/assert.h> | |
25 | #include <IOKit/IOBufferMemoryDescriptor.h> | |
26 | #include <IOKit/IOLib.h> | |
27 | #include <IOKit/storage/IONeXTPartitionScheme.h> | |
28 | #include <libkern/OSByteOrder.h> | |
29 | ||
30 | #define super IOPartitionScheme | |
31 | OSDefineMetaClassAndStructors(IONeXTPartitionScheme, IOPartitionScheme); | |
32 | ||
33 | // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - | |
34 | // Notes | |
35 | // | |
36 | // o the on-disk structure's fields are: 16-bit packed, big-endian formatted | |
37 | // o the on-disk structure is stored four times in succession, each takes up | |
38 | // sizeof(disk_label_t) bytes rounded up to the drive's natural block size | |
39 | // o the dl_label_blkno block value assumes the drive's natural block size | |
40 | // o the dl_part[].p_base, dl_part[].p_size and dl_front block values assume | |
41 | // a dl_secsize byte block size | |
42 | // o the dl_part[].p_base and dl_label_blkno block values are absolute, with | |
43 | // respect to the whole disk | |
44 | // o the dl_part[].p_base block value doesn't take into account the dl_front | |
45 | // offset, which is required in order to compute the actual start position | |
46 | // of the partition on the disk | |
47 | // o note that CDs often suffer from the mastering-with-a-different-natural- | |
48 | // block-size problem, but we can assume that the first map will always be | |
49 | // valid in those cases, and that we'll never need to compute the position | |
50 | // of the next map correctly | |
51 | // o note that bootable i386 disks will never have a valid first map, due to | |
52 | // the boot code that lives in block zero, however the second map is valid | |
53 | // o this implementation checks for the existence of the first map only; it | |
54 | // does not bother with the last three maps, since backwards compatibility | |
55 | // with unreleased NeXT-style i386 disks is a non-goal, and for reasons of | |
56 | // minimizing access to the media during probe | |
57 | // | |
58 | ||
59 | // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - | |
60 | ||
61 | #define kIONeXTPartitionSchemeContentTable "Content Table" | |
62 | ||
63 | // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - | |
64 | ||
65 | bool IONeXTPartitionScheme::init(OSDictionary * properties = 0) | |
66 | { | |
67 | // | |
68 | // Initialize this object's minimal state. | |
69 | // | |
70 | ||
71 | // State our assumptions. | |
72 | ||
73 | assert(sizeof(disktab_t) == 514); // (compiler/platform check) | |
74 | assert(sizeof(partition_t) == 46); // (compiler/platform check) | |
75 | assert(sizeof(disk_label_t) == 7240); // (compiler/platform check) | |
76 | ||
77 | // Ask our superclass' opinion. | |
78 | ||
79 | if ( super::init(properties) == false ) return false; | |
80 | ||
81 | // Initialize our state. | |
82 | ||
83 | _partitions = 0; | |
84 | ||
85 | return true; | |
86 | } | |
87 | ||
88 | // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - | |
89 | ||
90 | void IONeXTPartitionScheme::free() | |
91 | { | |
92 | // | |
93 | // Free all of this object's outstanding resources. | |
94 | // | |
95 | ||
96 | if ( _partitions ) _partitions->release(); | |
97 | ||
98 | super::free(); | |
99 | } | |
100 | ||
101 | // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - | |
102 | ||
103 | IOService * IONeXTPartitionScheme::probe(IOService * provider, SInt32 * score) | |
104 | { | |
105 | // | |
106 | // Determine whether the provider media contains a NeXT partition map. If | |
107 | // it does, we return "this" to indicate success, otherwise we return zero. | |
108 | // | |
109 | ||
110 | // State our assumptions. | |
111 | ||
112 | assert(OSDynamicCast(IOMedia, provider)); | |
113 | ||
114 | // Ask our superclass' opinion. | |
115 | ||
116 | if ( super::probe(provider, score) == 0 ) return 0; | |
117 | ||
118 | // Scan the provider media for a NeXT partition map. | |
119 | ||
120 | _partitions = scan(score); | |
121 | ||
122 | return ( _partitions ) ? this : 0; | |
123 | } | |
124 | ||
125 | // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - | |
126 | ||
127 | bool IONeXTPartitionScheme::start(IOService * provider) | |
128 | { | |
129 | // | |
130 | // Publish the new media objects which represent our partitions. | |
131 | // | |
132 | ||
133 | IOMedia * partition; | |
134 | OSIterator * partitionIterator; | |
135 | ||
136 | // State our assumptions. | |
137 | ||
138 | assert(_partitions); | |
139 | ||
140 | // Ask our superclass' opinion. | |
141 | ||
142 | if ( super::start(provider) == false ) return false; | |
143 | ||
144 | // Attach and register the new media objects representing our partitions. | |
145 | ||
146 | partitionIterator = OSCollectionIterator::withCollection(_partitions); | |
147 | if ( partitionIterator == 0 ) return false; | |
148 | ||
149 | while ( (partition = (IOMedia *) partitionIterator->getNextObject()) ) | |
150 | { | |
151 | if ( partition->attach(this) ) | |
152 | { | |
153 | partition->registerService(); | |
154 | } | |
155 | } | |
156 | ||
157 | partitionIterator->release(); | |
158 | ||
159 | return true; | |
160 | } | |
161 | ||
162 | ||
163 | // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - | |
164 | ||
165 | OSSet * IONeXTPartitionScheme::scan(SInt32 * score) | |
166 | { | |
167 | // | |
168 | // Scan the provider media for a NeXT partition map. Returns the set | |
169 | // of media objects representing each of the partitions (the retain for | |
170 | // the set is passed to the caller), or null should no partition map be | |
171 | // found. The default probe score can be adjusted up or down, based on | |
172 | // the confidence of the scan. | |
173 | // | |
174 | ||
175 | IOBufferMemoryDescriptor * buffer = 0; | |
176 | UInt32 bufferSize = 0; | |
177 | UInt64 labelBase = 0; | |
178 | UInt32 labelBlock = 0; | |
179 | UInt16 * labelCheckPtr = 0; | |
180 | UInt32 labelCheckSize = 0; | |
181 | bool labelFound = false; | |
182 | UInt32 labelIndex = 0; | |
183 | disk_label_t * labelMap = 0; | |
184 | IOMedia * media = getProvider(); | |
185 | UInt64 mediaBlockSize = media->getPreferredBlockSize(); | |
186 | bool mediaIsOpen = false; | |
187 | OSSet * partitions = 0; | |
188 | IOReturn status = kIOReturnError; | |
189 | ||
190 | // Determine whether this media is formatted. | |
191 | ||
192 | if ( media->isFormatted() == false ) goto scanErr; | |
193 | ||
194 | // Determine whether this media has an appropriate block size. | |
195 | ||
196 | if ( (mediaBlockSize % DEV_BSIZE) ) goto scanErr; | |
197 | ||
198 | // Allocate a buffer large enough to hold one map, rounded to a media block. | |
199 | ||
200 | bufferSize = IORound(sizeof(disk_label_t), mediaBlockSize); | |
201 | buffer = IOBufferMemoryDescriptor::withCapacity( | |
202 | /* capacity */ bufferSize, | |
203 | /* withDirection */ kIODirectionIn ); | |
204 | if ( buffer == 0 ) goto scanErr; | |
205 | ||
206 | // Allocate a set to hold the set of media objects representing partitions. | |
207 | ||
208 | partitions = OSSet::withCapacity(1); | |
209 | if ( partitions == 0 ) goto scanErr; | |
210 | ||
211 | // Open the media with read access. | |
212 | ||
213 | mediaIsOpen = media->open(this, 0, kIOStorageAccessReader); | |
214 | if ( mediaIsOpen == false ) goto scanErr; | |
215 | ||
216 | // Compute this partition's absolute offset with respect to the whole media, | |
217 | // since the disk_label structure requires this information; we go down the | |
218 | // service hierarchy summing bases until we reach the whole media object. | |
219 | ||
220 | for (IOService * service = media; service; service = service->getProvider()) | |
221 | { | |
222 | if ( OSDynamicCast(IOMedia, service) ) // (is this a media object?) | |
223 | { | |
224 | labelBase += ((IOMedia *)service)->getBase(); | |
225 | if ( ((IOMedia *)service)->isWhole() ) break; | |
226 | } | |
227 | } | |
228 | ||
229 | // Scan the media for a NeXT partition map. | |
230 | // | |
231 | // In the spirit of minimizing reads, we only check the first of the four | |
232 | // possible label positions. Backwards compatibility with old NeXT-style | |
233 | // i386 disks, including redundancy for NeXT-style disks in general, is a | |
234 | // non-goal. | |
235 | ||
236 | for ( labelIndex = 0; labelIndex < 1; labelIndex++ ) // (first map only) | |
237 | { | |
238 | // Read the next NeXT map into our buffer. | |
239 | ||
240 | ///m:2333367:workaround:commented:start | |
241 | // status = media->read(this, labelIndex * bufferSize, buffer); | |
242 | ///m:2333367:workaround:commented:stop | |
243 | ///m:2333367:workaround:added:start | |
244 | status = media->IOStorage::read(this, labelIndex * bufferSize, buffer); | |
245 | ///m:2333367:workaround:added:stop | |
246 | if ( status != kIOReturnSuccess ) goto scanErr; | |
247 | ||
248 | labelBlock = ((labelIndex * bufferSize) + labelBase) / mediaBlockSize; | |
249 | labelMap = (disk_label_t *) buffer->getBytesNoCopy(); | |
250 | ||
251 | // Determine whether the partition map signature is present. | |
252 | ||
253 | if ( OSSwapBigToHostInt32(labelMap->dl_version) == DL_V3 ) | |
254 | { | |
255 | labelCheckPtr = &(labelMap->dl_v3_checksum); | |
256 | } | |
257 | else if ( OSSwapBigToHostInt32(labelMap->dl_version) == DL_V2 || | |
258 | OSSwapBigToHostInt32(labelMap->dl_version) == DL_V1 ) | |
259 | { | |
260 | labelCheckPtr = &(labelMap->dl_checksum); | |
261 | } | |
262 | else | |
263 | { | |
264 | continue; | |
265 | } | |
266 | ||
267 | labelCheckSize = (UInt8 *) labelCheckPtr - | |
268 | (UInt8 *) labelMap - sizeof(UInt16); | |
269 | ||
270 | // Determine whether the partition map block position is correct. | |
271 | ||
272 | if ( OSSwapBigToHostInt32(labelMap->dl_label_blkno) != labelBlock ) | |
273 | { | |
274 | continue; | |
275 | } | |
276 | ||
277 | // Determine whether the partition map checksum is correct. | |
278 | ||
279 | labelMap->dl_label_blkno = OSSwapHostToBigInt32(0); | |
280 | ||
281 | if ( checksum16(labelMap, labelCheckSize) != *labelCheckPtr ) | |
282 | { | |
283 | continue; | |
284 | } | |
285 | ||
286 | labelMap->dl_label_blkno = labelBlock; | |
287 | ||
288 | labelFound = true; | |
289 | break; | |
290 | } | |
291 | ||
292 | if ( labelFound == false ) | |
293 | { | |
294 | goto scanErr; | |
295 | } | |
296 | ||
297 | // Scan for valid partition entries in the partition map. | |
298 | ||
299 | for ( unsigned index = 0; index < NPART; index++ ) | |
300 | { | |
301 | if ( isPartitionUsed(labelMap->dl_part + index) ) | |
302 | { | |
303 | // Determine whether the partition is corrupt (fatal). | |
304 | ||
305 | if ( isPartitionCorrupt( | |
306 | /* partition */ labelMap->dl_part + index, | |
307 | /* partitionID */ index + 1, | |
308 | /* labelBase */ labelBase, | |
309 | /* labelMap */ labelMap ) ) | |
310 | { | |
311 | goto scanErr; | |
312 | } | |
313 | ||
314 | // Determine whether the partition is invalid (skipped). | |
315 | ||
316 | if ( isPartitionInvalid( | |
317 | /* partition */ labelMap->dl_part + index, | |
318 | /* partitionID */ index + 1, | |
319 | /* labelBase */ labelBase, | |
320 | /* labelMap */ labelMap ) ) | |
321 | { | |
322 | continue; | |
323 | } | |
324 | ||
325 | // Create a media object to represent this partition. | |
326 | ||
327 | IOMedia * newMedia = instantiateMediaObject( | |
328 | /* partition */ labelMap->dl_part + index, | |
329 | /* partitionID */ index + 1, | |
330 | /* labelBase */ labelBase, | |
331 | /* labelMap */ labelMap ); | |
332 | ||
333 | if ( newMedia ) | |
334 | { | |
335 | partitions->setObject(newMedia); | |
336 | newMedia->release(); | |
337 | } | |
338 | } | |
339 | } | |
340 | ||
341 | // Release our resources. | |
342 | ||
343 | media->close(this); | |
344 | buffer->release(); | |
345 | ||
346 | return partitions; | |
347 | ||
348 | scanErr: | |
349 | ||
350 | // Release our resources. | |
351 | ||
352 | if ( mediaIsOpen ) media->close(this); | |
353 | if ( partitions ) partitions->release(); | |
354 | if ( buffer ) buffer->release(); | |
355 | ||
356 | return 0; | |
357 | } | |
358 | ||
359 | // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - | |
360 | ||
361 | bool IONeXTPartitionScheme::isPartitionUsed(partition_t * partition) | |
362 | { | |
363 | // | |
364 | // Ask whether the given partition is used. | |
365 | // | |
366 | ||
367 | return ( (SInt32) OSSwapBigToHostInt32(partition->p_base) >= 0 && | |
368 | (SInt32) OSSwapBigToHostInt32(partition->p_size) > 0 ); | |
369 | } | |
370 | ||
371 | // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - | |
372 | ||
373 | bool IONeXTPartitionScheme::isPartitionCorrupt( | |
374 | partition_t * /* partition */ , | |
375 | UInt32 /* partitionID */ , | |
376 | UInt64 /* labelBase */ , | |
377 | disk_label_t * /* labelMap */ ) | |
378 | { | |
379 | // | |
380 | // Ask whether the given partition appears to be corrupt. A partition that | |
381 | // is corrupt will cause the failure of the NeXT partition map recognition | |
382 | // altogether. | |
383 | // | |
384 | ||
385 | return false; | |
386 | } | |
387 | ||
388 | // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - | |
389 | ||
390 | bool IONeXTPartitionScheme::isPartitionInvalid( partition_t * partition, | |
391 | UInt32 partitionID, | |
392 | UInt64 labelBase, | |
393 | disk_label_t * labelMap ) | |
394 | { | |
395 | // | |
396 | // Ask whether the given partition appears to be invalid. A partition that | |
397 | // is invalid will cause it to be skipped in the scan, but will not cause a | |
398 | // failure of the NeXT partition map recognition. | |
399 | // | |
400 | ||
401 | IOMedia * media = getProvider(); | |
402 | UInt64 partitionBase = 0; | |
403 | UInt64 partitionSize = 0; | |
404 | ||
405 | // Compute the absolute byte position and size of the new partition. | |
406 | ||
407 | partitionBase = OSSwapBigToHostInt32(partition->p_base) + | |
408 | OSSwapBigToHostInt16(labelMap->dl_front); | |
409 | partitionSize = OSSwapBigToHostInt32(partition->p_size); | |
410 | partitionBase *= OSSwapBigToHostInt32(labelMap->dl_secsize); | |
411 | partitionSize *= OSSwapBigToHostInt32(labelMap->dl_secsize); | |
412 | ||
413 | // Determine whether the new partition leaves the confines of the container. | |
414 | ||
415 | if ( partitionBase < labelBase ) return true; // (absolute partitionBase) | |
416 | ||
417 | // Compute the relative byte position of the new partition. | |
418 | ||
419 | partitionBase -= labelBase; // (relative partitionBase) | |
420 | ||
421 | // Determine whether the new partition leaves the confines of the container. | |
422 | ||
423 | if ( partitionBase + partitionSize > media->getSize() ) return true; | |
424 | ||
425 | return false; | |
426 | } | |
427 | ||
428 | // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - | |
429 | ||
430 | IOMedia * IONeXTPartitionScheme::instantiateMediaObject( | |
431 | partition_t * partition, | |
432 | UInt32 partitionID, | |
433 | UInt64 labelBase, | |
434 | disk_label_t * labelMap ) | |
435 | { | |
436 | // | |
437 | // Instantiate a new media object to represent the given partition. | |
438 | // | |
439 | ||
440 | IOMedia * media = getProvider(); | |
441 | UInt64 partitionBase = 0; | |
442 | UInt64 partitionBlockSize = OSSwapBigToHostInt32(labelMap->dl_secsize); | |
443 | char * partitionHint = 0; | |
444 | char * partitionName = 0; | |
445 | UInt64 partitionSize = 0; | |
446 | ||
447 | // Compute the relative byte position and size of the new partition. | |
448 | ||
449 | partitionBase = OSSwapBigToHostInt32(partition->p_base) + | |
450 | OSSwapBigToHostInt16(labelMap->dl_front); | |
451 | partitionSize = OSSwapBigToHostInt32(partition->p_size); | |
452 | partitionBase *= OSSwapBigToHostInt32(labelMap->dl_secsize); | |
453 | partitionSize *= OSSwapBigToHostInt32(labelMap->dl_secsize); | |
454 | partitionBase -= labelBase; | |
455 | ||
456 | // Look up a type for the new partition. | |
457 | ||
458 | OSDictionary * hintTable = OSDynamicCast( | |
459 | /* type */ OSDictionary, | |
460 | /* instance */ getProperty(kIONeXTPartitionSchemeContentTable) ); | |
461 | ||
462 | if ( hintTable ) | |
463 | { | |
464 | OSString * hintValue = OSDynamicCast( | |
465 | /* type */ OSString, | |
466 | /* instance */ hintTable->getObject(partition->p_type) ); | |
467 | ||
468 | if ( hintValue ) partitionHint = (char *) hintValue->getCStringNoCopy(); | |
469 | } | |
470 | ||
471 | // Look up a name for the new partition. | |
472 | ||
473 | if ( partition->p_mountpt[0] ) | |
474 | partitionName = partition->p_mountpt; | |
475 | else if ( labelMap->dl_label[0] ) | |
476 | partitionName = labelMap->dl_label; | |
477 | ||
478 | // Create the new media object. | |
479 | ||
480 | IOMedia * newMedia = instantiateDesiredMediaObject( | |
481 | /* partition */ partition, | |
482 | /* partitionID */ partitionID, | |
483 | /* labelBase */ labelBase, | |
484 | /* labelMap */ labelMap ); | |
485 | ||
486 | if ( newMedia ) | |
487 | { | |
488 | if ( newMedia->init( | |
489 | /* base */ partitionBase, | |
490 | /* size */ partitionSize, | |
491 | /* preferredBlockSize */ partitionBlockSize, | |
492 | /* isEjectable */ media->isEjectable(), | |
493 | /* isWhole */ false, | |
494 | /* isWritable */ media->isWritable(), | |
495 | /* contentHint */ partitionHint ) ) | |
496 | { | |
497 | // Set a name for this partition. | |
498 | ||
499 | char name[24]; | |
500 | sprintf(name, "Untitled %ld", partitionID); | |
501 | newMedia->setName(partitionName ? partitionName : name); | |
502 | ||
503 | // Set a location value (the partition number) for this partition. | |
504 | ||
505 | char location[12]; | |
506 | sprintf(location, "%ld", partitionID); | |
507 | newMedia->setLocation(location); | |
508 | ||
509 | // Set the "Partition ID" key for this partition. | |
510 | ||
511 | newMedia->setProperty(kIOMediaPartitionIDKey, partitionID, 32); | |
512 | } | |
513 | else | |
514 | { | |
515 | newMedia->release(); | |
516 | newMedia = 0; | |
517 | } | |
518 | } | |
519 | ||
520 | return newMedia; | |
521 | } | |
522 | ||
523 | // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - | |
524 | ||
525 | IOMedia * IONeXTPartitionScheme::instantiateDesiredMediaObject( | |
526 | partition_t * partition, | |
527 | UInt32 partitionID, | |
528 | UInt64 labelBase, | |
529 | disk_label_t * labelMap ) | |
530 | { | |
531 | // | |
532 | // Allocate a new media object (called from instantiateMediaObject). | |
533 | // | |
534 | ||
535 | return new IOMedia; | |
536 | } | |
537 | ||
538 | // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - | |
539 | ||
540 | UInt16 IONeXTPartitionScheme::checksum16(void * data, UInt32 bytes) const | |
541 | { | |
542 | // | |
543 | // Compute a big-endian, 16-bit checksum over the specified data range. | |
544 | // | |
545 | ||
546 | UInt32 sum1 = 0; | |
547 | UInt32 sum2; | |
548 | UInt16 * wp = (UInt16 *) data; | |
549 | ||
550 | while ( bytes >= 2 ) | |
551 | { | |
552 | sum1 += OSSwapBigToHostInt16(*wp); | |
553 | bytes -= sizeof(UInt16); | |
554 | wp++; | |
555 | } | |
556 | ||
557 | sum2 = ((sum1 & 0xFFFF0000) >> 16) + (sum1 & 0xFFFF); | |
558 | ||
559 | if ( sum2 > 65535 ) | |
560 | sum2 -= 65535; | |
561 | ||
562 | return sum2; | |
563 | } | |
564 | ||
565 | // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - | |
566 | ||
567 | OSMetaClassDefineReservedUnused(IONeXTPartitionScheme, 0); | |
568 | ||
569 | // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - | |
570 | ||
571 | OSMetaClassDefineReservedUnused(IONeXTPartitionScheme, 1); | |
572 | ||
573 | // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - | |
574 | ||
575 | OSMetaClassDefineReservedUnused(IONeXTPartitionScheme, 2); | |
576 | ||
577 | // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - | |
578 | ||
579 | OSMetaClassDefineReservedUnused(IONeXTPartitionScheme, 3); | |
580 | ||
581 | // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - | |
582 | ||
583 | OSMetaClassDefineReservedUnused(IONeXTPartitionScheme, 4); | |
584 | ||
585 | // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - | |
586 | ||
587 | OSMetaClassDefineReservedUnused(IONeXTPartitionScheme, 5); | |
588 | ||
589 | // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - | |
590 | ||
591 | OSMetaClassDefineReservedUnused(IONeXTPartitionScheme, 6); | |
592 | ||
593 | // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - | |
594 | ||
595 | OSMetaClassDefineReservedUnused(IONeXTPartitionScheme, 7); | |
596 | ||
597 | // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - | |
598 | ||
599 | OSMetaClassDefineReservedUnused(IONeXTPartitionScheme, 8); | |
600 | ||
601 | // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - | |
602 | ||
603 | OSMetaClassDefineReservedUnused(IONeXTPartitionScheme, 9); | |
604 | ||
605 | // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - | |
606 | ||
607 | OSMetaClassDefineReservedUnused(IONeXTPartitionScheme, 10); | |
608 | ||
609 | // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - | |
610 | ||
611 | OSMetaClassDefineReservedUnused(IONeXTPartitionScheme, 11); | |
612 | ||
613 | // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - | |
614 | ||
615 | OSMetaClassDefineReservedUnused(IONeXTPartitionScheme, 12); | |
616 | ||
617 | // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - | |
618 | ||
619 | OSMetaClassDefineReservedUnused(IONeXTPartitionScheme, 13); | |
620 | ||
621 | // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - | |
622 | ||
623 | OSMetaClassDefineReservedUnused(IONeXTPartitionScheme, 14); | |
624 | ||
625 | // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - | |
626 | ||
627 | OSMetaClassDefineReservedUnused(IONeXTPartitionScheme, 15); |