1/* 2 * Copyright (c) 2007 Apple Inc. All rights reserved. 3 * 4 * @APPLE_LICENSE_HEADER_START@ 5 * 6 * This file contains Original Code and/or Modifications of Original Code 7 * as defined in and that are subject to the Apple Public Source License 8 * Version 2.0 (the 'License'). You may not use this file except in 9 * compliance with the License. Please obtain a copy of the License at 10 * http://www.opensource.apple.com/apsl/ and read it before using this 11 * file. 12 * 13 * The Original Code and all software distributed under the License are 14 * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER 15 * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, 16 * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, 17 * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. 18 * Please see the License for the specific language governing rights and 19 * limitations under the License. 20 * 21 * @APPLE_LICENSE_HEADER_END@ 22 */ 23/* 24 * BLBootRootIdentifyDevice.c 25 * bless 26 * 27 * Created by Shantonu Sen on 7/16/07. 28 * Copyright 2007 Apple Inc. All rights reserved. 29 * 30 */ 31#if 0 32#include <IOKit/IOKitLib.h> 33#include <IOKit/IOKitKeys.h> 34#include <IOKit/storage/IOMedia.h> 35 36#include <CoreFoundation/CoreFoundation.h> 37 38#include <sys/param.h> 39#include <sys/stat.h> 40#include <sys/errno.h> 41 42#include "bless.h" 43#include "bless_private.h" 44 45// classify the role of a partition 46 47int _verifyIsPhysicalPartition(BLContextPtr context, 48 io_service_t partition, 49 io_service_t *parentWholeMedia, 50 BLPartitionType *partType); 51 52int BLBootRootIdentifyDevice(BLContextPtr context, 53 const char *bsdName, 54 BLBootRootRole *role) 55{ 56 int ret; 57 io_service_t service = IO_OBJECT_NULL, parentWholeMedia = IO_OBJECT_NULL; 58 BLPartitionType partType = kBLPartitionType_None; 59 60 if (bsdName == NULL || role == NULL) { 61 return EINVAL; 62 } 63 64 *role = kBLBootRootRole_Unknown; 65 66 ret = BLGetIOServiceForDeviceName(context, bsdName, &service); 67 if (ret) { 68 contextprintf(context, kBLLogLevelError, "No IOMedia for %s\n", bsdName); 69 return ENOENT; 70 } 71 72 ret = _verifyIsPhysicalPartition(context, service, &parentWholeMedia, &partType); 73 if (ret) { 74 if (service != IO_OBJECT_NULL) IOObjectRelease(service); 75 if (parentWholeMedia != IO_OBJECT_NULL) IOObjectRelease(parentWholeMedia); 76 77 contextprintf(context, kBLLogLevelError, "Can't determine topology for IOMedia %s\n", bsdName); 78 return EINVAL; 79 } 80 81 if (parentWholeMedia != IO_OBJECT_NULL) { 82 // XXX 83 } 84 85 return 0; 86} 87 88// do a topology check to make sure this partition is a leaf, its 89// grandparent is a whole partition, the GP doesn't have an IOMedia 90// ancestor 91int _verifyIsPhysicalPartition(BLContextPtr context, 92 io_service_t partition, 93 io_service_t *parentWholeMedia, 94 BLPartitionType *partitionType) 95{ 96 CFBooleanRef isLeaf, isWhole; 97 CFStringRef content; 98 io_service_t parent = IO_OBJECT_NULL, grandparent = IO_OBJECT_NULL; 99 kern_return_t kret; 100 101 isLeaf = IORegistryEntryCreateCFProperty(partition, CFSTR(kIOMediaLeafKey), kCFAllocatorDefault, 0); 102 if (!isLeaf || CFGetTypeID(isLeaf) != CFBooleanGetTypeID()) { 103 if (isLeaf) CFRelease(isLeaf); 104 return ENOATTR; 105 } 106 107 if (!CFEqual(isLeaf, kCFBooleanTrue)) { 108 CFRelease(isLeaf); 109 return 0; // not failure, just not a physical partition 110 } 111 112 CFRelease(isLeaf); 113 114 kret = IORegistryEntryGetParentEntry(partition, kIOServicePlane, &parent); 115 if (kret) { 116 return ENOENT; 117 } 118 119 kret = IORegistryEntryGetParentEntry(parent, kIOServicePlane, &grandparent); 120 if (kret) { 121 IOObjectRelease(parent); 122 return ENOENT; 123 } 124 125 IOObjectRelease(parent); 126 127 if (!IOObjectConformsTo(grandparent, kIOMediaClass)) { 128 IOObjectRelease(grandparent); 129 return 0; // not a failure, just not a physical partition 130 } 131 132 isWhole = IORegistryEntryCreateCFProperty(grandparent, CFSTR(kIOMediaWholeKey), kCFAllocatorDefault, 0); 133 if (!isWhole || CFGetTypeID(isWhole) != CFBooleanGetTypeID()) { 134 if (isWhole) CFRelease(isWhole); 135 IOObjectRelease(grandparent); 136 return ENOATTR; 137 } 138 139 if (!CFEqual(isWhole, kCFBooleanTrue)) { 140 CFRelease(isWhole); 141 IOObjectRelease(grandparent); 142 return 0; // not failure, just not a physical partition 143 } 144 145 CFRelease(isWhole); 146 147 *parentWholeMedia = grandparent; 148 149 content = IORegistryEntryCreateCFProperty(grandparent, 150 CFSTR(kIOMediaContentKey), 151 kCFAllocatorDefault, 0); 152 153 154 if(!content || CFGetTypeID(content) != CFStringGetTypeID()) { 155 if (content) CFRelease(content); 156 return ENOATTR; 157 } 158 159 if(CFStringCompare(content, CFSTR("Apple_partition_scheme"), 0) 160 == kCFCompareEqualTo) { 161 if(partitionType) *partitionType = kBLPartitionType_APM; 162 } else if(CFStringCompare(content, CFSTR("FDisk_partition_scheme"), 0) 163 == kCFCompareEqualTo) { 164 if(partitionType) *partitionType = kBLPartitionType_MBR; 165 } else if(CFStringCompare(content, CFSTR("GUID_partition_scheme"), 0) 166 == kCFCompareEqualTo) { 167 if(partitionType) *partitionType = kBLPartitionType_GPT; 168 } else { 169 if(partitionType) *partitionType = kBLPartitionType_None; 170 } 171 172 return 0; 173} 174#endif 175