| srs5694 | e4ac11e | 2009-08-31 10:13:04 -0400 | [diff] [blame] | 1 | /* bsd.cc -- Functions for loading and manipulating legacy BSD disklabel | 
| srs5694 | a0eb11a | 2009-08-29 15:00:08 -0400 | [diff] [blame] | 2 |    data. */ | 
 | 3 |  | 
| srs5694 | e4ac11e | 2009-08-31 10:13:04 -0400 | [diff] [blame] | 4 | /* By Rod Smith, initial coding August, 2009 */ | 
| srs5694 | a0eb11a | 2009-08-29 15:00:08 -0400 | [diff] [blame] | 5 |  | 
 | 6 | /* This program is copyright (c) 2009 by Roderick W. Smith. It is distributed | 
 | 7 |   under the terms of the GNU GPL version 2, as detailed in the COPYING file. */ | 
 | 8 |  | 
 | 9 | #define __STDC_LIMIT_MACROS | 
 | 10 | #define __STDC_CONSTANT_MACROS | 
 | 11 |  | 
 | 12 | #include <stdio.h> | 
| srs5694 | 08bb0da | 2010-02-19 17:19:55 -0500 | [diff] [blame] | 13 | //#include <unistd.h> | 
| srs5694 | a0eb11a | 2009-08-29 15:00:08 -0400 | [diff] [blame] | 14 | #include <stdlib.h> | 
 | 15 | #include <stdint.h> | 
 | 16 | #include <fcntl.h> | 
| srs5694 | a0eb11a | 2009-08-29 15:00:08 -0400 | [diff] [blame] | 17 | #include <sys/stat.h> | 
 | 18 | #include <errno.h> | 
| srs5694 | fed16d0 | 2010-01-27 23:03:40 -0500 | [diff] [blame] | 19 | #include <iostream> | 
 | 20 | #include <string> | 
| srs5694 | a0eb11a | 2009-08-29 15:00:08 -0400 | [diff] [blame] | 21 | #include "support.h" | 
 | 22 | #include "bsd.h" | 
 | 23 |  | 
 | 24 | using namespace std; | 
 | 25 |  | 
 | 26 |  | 
 | 27 | BSDData::BSDData(void) { | 
 | 28 |    state = unknown; | 
 | 29 |    signature = UINT32_C(0); | 
 | 30 |    signature2 = UINT32_C(0); | 
 | 31 |    sectorSize = 512; | 
 | 32 |    numParts = 0; | 
 | 33 |    labelFirstLBA = 0; | 
 | 34 |    labelLastLBA = 0; | 
 | 35 |    labelStart = LABEL_OFFSET1; // assume raw disk format | 
| srs5694 | a0eb11a | 2009-08-29 15:00:08 -0400 | [diff] [blame] | 36 |    partitions = NULL; | 
 | 37 | } // default constructor | 
 | 38 |  | 
 | 39 | BSDData::~BSDData(void) { | 
| srs5694 | 08bb0da | 2010-02-19 17:19:55 -0500 | [diff] [blame] | 40 |    if (partitions != NULL) | 
 | 41 |       delete[] partitions; | 
| srs5694 | a0eb11a | 2009-08-29 15:00:08 -0400 | [diff] [blame] | 42 | } // destructor | 
 | 43 |  | 
| srs5694 | e4ac11e | 2009-08-31 10:13:04 -0400 | [diff] [blame] | 44 | // Read BSD disklabel data from the specified device filename. This function | 
 | 45 | // just opens the device file and then calls an overloaded function to do | 
| srs5694 | fed16d0 | 2010-01-27 23:03:40 -0500 | [diff] [blame] | 46 | // the bulk of the work. Returns 1 on success, 0 on failure. | 
| srs5694 | 0a69731 | 2010-01-28 21:10:52 -0500 | [diff] [blame] | 47 | int BSDData::ReadBSDData(const string & device, uint64_t startSector, uint64_t endSector) { | 
| srs5694 | fed16d0 | 2010-01-27 23:03:40 -0500 | [diff] [blame] | 48 |    int allOK = 1; | 
 | 49 |    DiskIO myDisk; | 
| srs5694 | a0eb11a | 2009-08-29 15:00:08 -0400 | [diff] [blame] | 50 |  | 
| srs5694 | 0a69731 | 2010-01-28 21:10:52 -0500 | [diff] [blame] | 51 |    if (device != "") { | 
 | 52 |       if (myDisk.OpenForRead(device)) { | 
| srs5694 | fed16d0 | 2010-01-27 23:03:40 -0500 | [diff] [blame] | 53 |          allOK = ReadBSDData(&myDisk, startSector, endSector); | 
| srs5694 | e4ac11e | 2009-08-31 10:13:04 -0400 | [diff] [blame] | 54 |       } else { | 
 | 55 |          allOK = 0; | 
 | 56 |       } // if/else | 
 | 57 |  | 
| srs5694 | fed16d0 | 2010-01-27 23:03:40 -0500 | [diff] [blame] | 58 |       myDisk.Close(); | 
| srs5694 | a0eb11a | 2009-08-29 15:00:08 -0400 | [diff] [blame] | 59 |    } else { | 
 | 60 |       allOK = 0; | 
| srs5694 | e4ac11e | 2009-08-31 10:13:04 -0400 | [diff] [blame] | 61 |    } // if/else | 
| srs5694 | a0eb11a | 2009-08-29 15:00:08 -0400 | [diff] [blame] | 62 |    return allOK; | 
 | 63 | } // BSDData::ReadBSDData() (device filename version) | 
 | 64 |  | 
 | 65 | // Load the BSD disklabel data from an already-opened disk | 
 | 66 | // file, starting with the specified sector number. | 
| srs5694 | fed16d0 | 2010-01-27 23:03:40 -0500 | [diff] [blame] | 67 | int BSDData::ReadBSDData(DiskIO *theDisk, uint64_t startSector, uint64_t endSector) { | 
| srs5694 | 08bb0da | 2010-02-19 17:19:55 -0500 | [diff] [blame] | 68 |    int allOK = 1; | 
 | 69 |    int i, foundSig = 0, bigEnd = 0; | 
| srs5694 | a0eb11a | 2009-08-29 15:00:08 -0400 | [diff] [blame] | 70 |    int relative = 0; // assume absolute partition sector numbering | 
| srs5694 | 08bb0da | 2010-02-19 17:19:55 -0500 | [diff] [blame] | 71 |    uint8_t buffer[4096]; // I/O buffer | 
| srs5694 | a0eb11a | 2009-08-29 15:00:08 -0400 | [diff] [blame] | 72 |    uint32_t realSig; | 
 | 73 |    uint32_t* temp32; | 
 | 74 |    uint16_t* temp16; | 
 | 75 |    BSDRecord* tempRecords; | 
| srs5694 | 546a9c7 | 2010-01-26 16:00:26 -0500 | [diff] [blame] | 76 |    int offset[NUM_OFFSETS] = { LABEL_OFFSET1, LABEL_OFFSET2 }; | 
| srs5694 | a0eb11a | 2009-08-29 15:00:08 -0400 | [diff] [blame] | 77 |  | 
 | 78 |    labelFirstLBA = startSector; | 
 | 79 |    labelLastLBA = endSector; | 
| srs5694 | fed16d0 | 2010-01-27 23:03:40 -0500 | [diff] [blame] | 80 |    offset[1] = theDisk->GetBlockSize(); | 
| srs5694 | a0eb11a | 2009-08-29 15:00:08 -0400 | [diff] [blame] | 81 |  | 
| srs5694 | ba00fed | 2010-01-12 18:18:36 -0500 | [diff] [blame] | 82 |    // Read 4096 bytes (eight 512-byte sectors or equivalent) | 
 | 83 |    // into memory; we'll extract data from this buffer. | 
 | 84 |    // (Done to work around FreeBSD limitation on size of reads | 
 | 85 |    // from block devices.) | 
| srs5694 | fed16d0 | 2010-01-27 23:03:40 -0500 | [diff] [blame] | 86 |    allOK = theDisk->Seek(startSector); | 
 | 87 |    if (allOK) allOK = theDisk->Read(buffer, 4096); | 
| srs5694 | a0eb11a | 2009-08-29 15:00:08 -0400 | [diff] [blame] | 88 |  | 
 | 89 |    // Do some strangeness to support big-endian architectures... | 
 | 90 |    bigEnd = (IsLittleEndian() == 0); | 
 | 91 |    realSig = BSD_SIGNATURE; | 
| srs5694 | fed16d0 | 2010-01-27 23:03:40 -0500 | [diff] [blame] | 92 |    if (bigEnd && allOK) | 
| srs5694 | a0eb11a | 2009-08-29 15:00:08 -0400 | [diff] [blame] | 93 |       ReverseBytes(&realSig, 4); | 
 | 94 |  | 
| srs5694 | 546a9c7 | 2010-01-26 16:00:26 -0500 | [diff] [blame] | 95 |    // Look for the signature at any of two locations. | 
| srs5694 | ba00fed | 2010-01-12 18:18:36 -0500 | [diff] [blame] | 96 |    // Note that the signature is repeated at both the original | 
 | 97 |    // offset and 132 bytes later, so we need two checks.... | 
| srs5694 | fed16d0 | 2010-01-27 23:03:40 -0500 | [diff] [blame] | 98 |    if (allOK) { | 
 | 99 |       i = 0; | 
 | 100 |       do { | 
 | 101 |          temp32 = (uint32_t*) &buffer[offset[i]]; | 
 | 102 |          signature = *temp32; | 
 | 103 |          if (signature == realSig) { // found first, look for second | 
 | 104 |             temp32 = (uint32_t*) &buffer[offset[i] + 132]; | 
 | 105 |             signature2 = *temp32; | 
 | 106 |             if (signature2 == realSig) { | 
 | 107 |                foundSig = 1; | 
 | 108 |                labelStart = offset[i]; | 
 | 109 |             } // if found signature | 
 | 110 |          } // if/else | 
 | 111 |          i++; | 
 | 112 |       } while ((!foundSig) && (i < NUM_OFFSETS)); | 
 | 113 |       allOK = foundSig; | 
 | 114 |    } // if | 
| srs5694 | a0eb11a | 2009-08-29 15:00:08 -0400 | [diff] [blame] | 115 |  | 
 | 116 |    // Load partition metadata from the buffer.... | 
| srs5694 | fed16d0 | 2010-01-27 23:03:40 -0500 | [diff] [blame] | 117 |    if (allOK) { | 
 | 118 |       temp32 = (uint32_t*) &buffer[labelStart + 40]; | 
 | 119 |       sectorSize = *temp32; | 
 | 120 |       temp16 = (uint16_t*) &buffer[labelStart + 138]; | 
 | 121 |       numParts = *temp16; | 
 | 122 |    } // if | 
| srs5694 | a0eb11a | 2009-08-29 15:00:08 -0400 | [diff] [blame] | 123 |  | 
 | 124 |    // Make it big-endian-aware.... | 
| srs5694 | fed16d0 | 2010-01-27 23:03:40 -0500 | [diff] [blame] | 125 |    if ((IsLittleEndian() == 0) && allOK) | 
| srs5694 | a0eb11a | 2009-08-29 15:00:08 -0400 | [diff] [blame] | 126 |       ReverseMetaBytes(); | 
 | 127 |  | 
 | 128 |    // Check validity of the data and flag it appropriately.... | 
| srs5694 | fed16d0 | 2010-01-27 23:03:40 -0500 | [diff] [blame] | 129 |    if (foundSig && (numParts <= MAX_BSD_PARTS) && allOK) { | 
| srs5694 | a0eb11a | 2009-08-29 15:00:08 -0400 | [diff] [blame] | 130 |       state = bsd; | 
 | 131 |    } else { | 
 | 132 |       state = bsd_invalid; | 
 | 133 |    } // if/else | 
 | 134 |  | 
 | 135 |    // If the state is good, go ahead and load the main partition data.... | 
 | 136 |    if (state == bsd) { | 
| srs5694 | cb76c67 | 2010-02-11 22:22:22 -0500 | [diff] [blame] | 137 |       partitions = new struct BSDRecord[numParts * sizeof(struct BSDRecord)]; | 
| srs5694 | a0eb11a | 2009-08-29 15:00:08 -0400 | [diff] [blame] | 138 |       for (i = 0; i < numParts; i++) { | 
 | 139 |          // Once again, we use the buffer, but index it using a BSDRecord | 
 | 140 |          // pointer (dangerous, but effective).... | 
 | 141 |          tempRecords = (BSDRecord*) &buffer[labelStart + 148]; | 
 | 142 |          partitions[i].lengthLBA = tempRecords[i].lengthLBA; | 
 | 143 |          partitions[i].firstLBA = tempRecords[i].firstLBA; | 
 | 144 |          partitions[i].fsType = tempRecords[i].fsType; | 
 | 145 |          if (bigEnd) { // reverse data (fsType is a single byte) | 
 | 146 |             ReverseBytes(&partitions[i].lengthLBA, 4); | 
 | 147 |             ReverseBytes(&partitions[i].firstLBA, 4); | 
 | 148 |          } // if big-endian | 
 | 149 |          // Check for signs of relative sector numbering: A "0" first sector | 
 | 150 |          // number on a partition with a non-zero length -- but ONLY if the | 
 | 151 |          // length is less than the disk size, since NetBSD has a habit of | 
 | 152 |          // creating a disk-sized partition within a carrier MBR partition | 
 | 153 |          // that's too small to house it, and this throws off everything.... | 
 | 154 |          if ((partitions[i].firstLBA == 0) && (partitions[i].lengthLBA > 0) | 
 | 155 |              && (partitions[i].lengthLBA < labelLastLBA)) | 
 | 156 |             relative = 1; | 
 | 157 |       } // for | 
 | 158 |       // Some disklabels use sector numbers relative to the enclosing partition's | 
 | 159 |       // start, others use absolute sector numbers. If relative numbering was | 
 | 160 |       // detected above, apply a correction to all partition start sectors.... | 
 | 161 |       if (relative) { | 
 | 162 |          for (i = 0; i < numParts; i++) { | 
| srs5694 | 08bb0da | 2010-02-19 17:19:55 -0500 | [diff] [blame] | 163 |             partitions[i].firstLBA += (uint32_t) startSector; | 
| srs5694 | a0eb11a | 2009-08-29 15:00:08 -0400 | [diff] [blame] | 164 |          } // for | 
 | 165 |       } // if | 
 | 166 |    } // if signatures OK | 
 | 167 | //   DisplayBSDData(); | 
| srs5694 | fed16d0 | 2010-01-27 23:03:40 -0500 | [diff] [blame] | 168 |    return allOK; | 
 | 169 | } // BSDData::ReadBSDData(DiskIO* theDisk, uint64_t startSector) | 
| srs5694 | a0eb11a | 2009-08-29 15:00:08 -0400 | [diff] [blame] | 170 |  | 
 | 171 | // Reverse metadata's byte order; called only on big-endian systems | 
 | 172 | void BSDData::ReverseMetaBytes(void) { | 
 | 173 |    ReverseBytes(&signature, 4); | 
 | 174 |    ReverseBytes(§orSize, 4); | 
 | 175 |    ReverseBytes(&signature2, 4); | 
 | 176 |    ReverseBytes(&numParts, 2); | 
 | 177 | } // BSDData::ReverseMetaByteOrder() | 
 | 178 |  | 
 | 179 | // Display basic BSD partition data. Used for debugging. | 
 | 180 | void BSDData::DisplayBSDData(void) { | 
 | 181 |    int i; | 
 | 182 |  | 
 | 183 |    if (state == bsd) { | 
| srs5694 | fed16d0 | 2010-01-27 23:03:40 -0500 | [diff] [blame] | 184 |       cout << "BSD partitions:\n"; | 
| srs5694 | a0eb11a | 2009-08-29 15:00:08 -0400 | [diff] [blame] | 185 |       for (i = 0; i < numParts; i++) { | 
| srs5694 | fed16d0 | 2010-01-27 23:03:40 -0500 | [diff] [blame] | 186 |          cout.width(4); | 
 | 187 |          cout << i + 1 << "\t"; | 
 | 188 |          cout.width(13); | 
 | 189 |          cout << partitions[i].firstLBA << "\t"; | 
 | 190 |          cout.width(15); | 
 | 191 |          cout << partitions[i].lengthLBA << " \t0x"; | 
 | 192 |          cout.width(2); | 
 | 193 |          cout.fill('0'); | 
 | 194 |          cout.setf(ios::uppercase); | 
 | 195 |          cout << hex << (int) partitions[i].fsType << "\n" << dec; | 
 | 196 |          cout.fill(' '); | 
| srs5694 | a0eb11a | 2009-08-29 15:00:08 -0400 | [diff] [blame] | 197 |       } // for | 
 | 198 |    } // if | 
 | 199 | } // BSDData::DisplayBSDData() | 
 | 200 |  | 
 | 201 | // Displays the BSD disklabel state. Called during program launch to inform | 
 | 202 | // the user about the partition table(s) status | 
 | 203 | int BSDData::ShowState(void) { | 
 | 204 |    int retval = 0; | 
 | 205 |  | 
 | 206 |    switch (state) { | 
 | 207 |       case bsd_invalid: | 
| srs5694 | fed16d0 | 2010-01-27 23:03:40 -0500 | [diff] [blame] | 208 |          cout << "  BSD: not present\n"; | 
| srs5694 | a0eb11a | 2009-08-29 15:00:08 -0400 | [diff] [blame] | 209 |          break; | 
 | 210 |       case bsd: | 
| srs5694 | fed16d0 | 2010-01-27 23:03:40 -0500 | [diff] [blame] | 211 |          cout << "  BSD: present\n"; | 
| srs5694 | a0eb11a | 2009-08-29 15:00:08 -0400 | [diff] [blame] | 212 |          retval = 1; | 
 | 213 |          break; | 
 | 214 |       default: | 
| srs5694 | fed16d0 | 2010-01-27 23:03:40 -0500 | [diff] [blame] | 215 |          cout << "\a  BSD: unknown -- bug!\n"; | 
| srs5694 | a0eb11a | 2009-08-29 15:00:08 -0400 | [diff] [blame] | 216 |          break; | 
 | 217 |    } // switch | 
 | 218 |    return retval; | 
 | 219 | } // BSDData::ShowState() | 
 | 220 |  | 
| srs5694 | a6022b0 | 2010-01-19 16:17:20 -0500 | [diff] [blame] | 221 | // Weirdly, this function has stopped working when defined inline, | 
 | 222 | // but it's OK here.... | 
 | 223 | int BSDData::IsDisklabel(void) { | 
 | 224 |    return (state == bsd); | 
 | 225 | } // BSDData::IsDiskLabel() | 
 | 226 |  | 
| srs5694 | a0eb11a | 2009-08-29 15:00:08 -0400 | [diff] [blame] | 227 | // Returns the BSD table's partition type code | 
 | 228 | uint8_t BSDData::GetType(int i) { | 
 | 229 |    uint8_t retval = 0; // 0 = "unused" | 
 | 230 |  | 
 | 231 |    if ((i < numParts) && (i >= 0) && (state == bsd) && (partitions != 0)) | 
 | 232 |       retval = partitions[i].fsType; | 
 | 233 |  | 
 | 234 |    return(retval); | 
 | 235 | } // BSDData::GetType() | 
 | 236 |  | 
 | 237 | // Returns the number of the first sector of the specified partition | 
 | 238 | uint64_t BSDData::GetFirstSector(int i) { | 
 | 239 |    uint64_t retval = UINT64_C(0); | 
 | 240 |  | 
 | 241 |    if ((i < numParts) && (i >= 0) && (state == bsd) && (partitions != 0)) | 
 | 242 |       retval = (uint64_t) partitions[i].firstLBA; | 
 | 243 |  | 
 | 244 |    return retval; | 
 | 245 | } // BSDData::GetFirstSector | 
 | 246 |  | 
 | 247 | // Returns the length (in sectors) of the specified partition | 
 | 248 | uint64_t BSDData::GetLength(int i) { | 
 | 249 |    uint64_t retval = UINT64_C(0); | 
 | 250 |  | 
 | 251 |    if ((i < numParts) && (i >= 0) && (state == bsd) && (partitions != 0)) | 
 | 252 |       retval = (uint64_t) partitions[i].lengthLBA; | 
 | 253 |  | 
 | 254 |    return retval; | 
 | 255 | } // BSDData::GetLength() | 
 | 256 |  | 
 | 257 | // Returns the number of partitions defined in the current table | 
 | 258 | int BSDData::GetNumParts(void) { | 
 | 259 |    return numParts; | 
 | 260 | } // BSDData::GetNumParts() | 
 | 261 |  | 
 | 262 | // Returns the specified partition as a GPT partition. Used in BSD-to-GPT | 
 | 263 | // conversion process | 
 | 264 | GPTPart BSDData::AsGPT(int i) { | 
 | 265 |    GPTPart guid;                  // dump data in here, then return it | 
 | 266 |    uint64_t sectorOne, sectorEnd; // first & last sectors of partition | 
| srs5694 | a0eb11a | 2009-08-29 15:00:08 -0400 | [diff] [blame] | 267 |    int passItOn = 1;              // Set to 0 if partition is empty or invalid | 
 | 268 |  | 
 | 269 |    guid.BlankPartition(); | 
 | 270 |    sectorOne = (uint64_t) partitions[i].firstLBA; | 
 | 271 |    sectorEnd = sectorOne + (uint64_t) partitions[i].lengthLBA; | 
 | 272 |    if (sectorEnd > 0) sectorEnd--; | 
 | 273 |    // Note on above: BSD partitions sometimes have a length of 0 and a start | 
| srs5694 | e4ac11e | 2009-08-31 10:13:04 -0400 | [diff] [blame] | 274 |    // sector of 0. With unsigned ints, the usual way (start + length - 1) to | 
 | 275 |    // find the end will result in a huge number, which will be confusing. | 
 | 276 |    // Thus, apply the "-1" part only if it's reasonable to do so. | 
| srs5694 | a0eb11a | 2009-08-29 15:00:08 -0400 | [diff] [blame] | 277 |  | 
 | 278 |    // Do a few sanity checks on the partition before we pass it on.... | 
 | 279 |    // First, check that it falls within the bounds of its container | 
 | 280 |    // and that it starts before it ends.... | 
 | 281 |    if ((sectorOne < labelFirstLBA) || (sectorEnd > labelLastLBA) || (sectorOne > sectorEnd)) | 
 | 282 |       passItOn = 0; | 
 | 283 |    // Some disklabels include a pseudo-partition that's the size of the entire | 
 | 284 |    // disk or containing partition. Don't return it. | 
 | 285 |    if ((sectorOne <= labelFirstLBA) && (sectorEnd >= labelLastLBA) && | 
 | 286 |        (GetType(i) == 0)) | 
 | 287 |       passItOn = 0; | 
 | 288 |    // If the end point is 0, it's not a valid partition. | 
| srs5694 | e4ac11e | 2009-08-31 10:13:04 -0400 | [diff] [blame] | 289 |    if ((sectorEnd == 0) || (sectorEnd == labelFirstLBA)) | 
| srs5694 | a0eb11a | 2009-08-29 15:00:08 -0400 | [diff] [blame] | 290 |       passItOn = 0; | 
 | 291 |  | 
 | 292 |    if (passItOn) { | 
 | 293 |       guid.SetFirstLBA(sectorOne); | 
 | 294 |       guid.SetLastLBA(sectorEnd); | 
 | 295 |       // Now set a random unique GUID for the partition.... | 
| srs5694 | 6699b01 | 2010-02-04 00:55:30 -0500 | [diff] [blame] | 296 |       guid.RandomizeUniqueGUID(); | 
| srs5694 | a0eb11a | 2009-08-29 15:00:08 -0400 | [diff] [blame] | 297 |       // ... zero out the attributes and name fields.... | 
 | 298 |       guid.SetAttributes(UINT64_C(0)); | 
 | 299 |       // Most BSD disklabel type codes seem to be archaic or rare. | 
 | 300 |       // They're also ambiguous; a FreeBSD filesystem is impossible | 
 | 301 |       // to distinguish from a NetBSD one. Thus, these code assignment | 
 | 302 |       // are going to be rough to begin with. For a list of meanings, | 
 | 303 |       // see http://fxr.watson.org/fxr/source/sys/dtype.h?v=DFBSD, | 
 | 304 |       // or Google it. | 
 | 305 |       switch (GetType(i)) { | 
 | 306 |          case 1: // BSD swap | 
 | 307 |             guid.SetType(0xa502); break; | 
 | 308 |          case 7: // BSD FFS | 
 | 309 |             guid.SetType(0xa503); break; | 
 | 310 |          case 8: case 11: // MS-DOS or HPFS | 
 | 311 |             guid.SetType(0x0700); break; | 
 | 312 |          case 9: // log-structured fs | 
 | 313 |             guid.SetType(0xa903); break; | 
 | 314 |          case 13: // bootstrap | 
 | 315 |             guid.SetType(0xa501); break; | 
 | 316 |          case 14: // vinum | 
 | 317 |             guid.SetType(0xa505); break; | 
 | 318 |          case 15: // RAID | 
 | 319 |             guid.SetType(0xa903); break; | 
 | 320 |          case 27: // FreeBSD ZFS | 
 | 321 |             guid.SetType(0xa504); break; | 
 | 322 |          default: | 
 | 323 |             guid.SetType(0x0700); break; | 
 | 324 |       } // switch | 
 | 325 |       // Set the partition name to the name of the type code.... | 
| srs5694 | 6699b01 | 2010-02-04 00:55:30 -0500 | [diff] [blame] | 326 |       guid.SetName(guid.GetTypeName()); | 
| srs5694 | a0eb11a | 2009-08-29 15:00:08 -0400 | [diff] [blame] | 327 |    } // if | 
 | 328 |    return guid; | 
 | 329 | } // BSDData::AsGPT() |