status_t Header::Write(int fd) { // Try to write the protective MBR PartitionMap partitionMap; PrimaryPartition *partition = NULL; uint32 index = 0; while ((partition = partitionMap.PrimaryPartitionAt(index)) != NULL) { if (index == 0) { uint64 deviceSize = fHeader.AlternateBlock() * fBlockSize; partition->SetTo(fBlockSize, deviceSize, 0xEE, false, fBlockSize); } else partition->Unset(); ++index; } PartitionMapWriter writer(fd, fBlockSize); writer.WriteMBR(&partitionMap, true); // We also write the bootcode, so we can boot GPT disks from BIOS status_t status = _Write(fd, fHeader.EntriesBlock() * fBlockSize, fEntries, _EntryArraySize()); if (status != B_OK) return status; // First write the header, so that we have at least one completely correct // data set status = _WriteHeader(fd); // Write backup entries status_t backupStatus = _Write(fd, fBackupHeader.EntriesBlock() * fBlockSize, fEntries, _EntryArraySize()); return status == B_OK ? backupStatus : status; }
// _ParsePrimary status_t PartitionMapParser::_ParsePrimary(const partition_table* table, bool& hadToReFitSize) { if (table == NULL) return B_BAD_VALUE; // check the signature if (table->signature != kPartitionTableSectorSignature) { TRACE(("intel: _ParsePrimary(): invalid PartitionTable signature: %lx\n", (uint32)table->signature)); return B_BAD_DATA; } hadToReFitSize = false; // examine the table for (int32 i = 0; i < 4; i++) { const partition_descriptor* descriptor = &table->table[i]; PrimaryPartition* partition = fMap->PrimaryPartitionAt(i); partition->SetTo(descriptor, 0, fBlockSize); // work-around potential BIOS/OS problems hadToReFitSize |= partition->FitSizeToSession(fSessionSize); // ignore, if location is bad if (!partition->CheckLocation(fSessionSize)) { TRACE(("intel: _ParsePrimary(): partition %ld: bad location, " "ignoring\n", i)); partition->Unset(); } } // allocate a partition_table buffer fPartitionTable = new(nothrow) partition_table; if (fPartitionTable == NULL) return B_NO_MEMORY; // parse extended partitions status_t error = B_OK; for (int32 i = 0; error == B_OK && i < 4; i++) { PrimaryPartition* primary = fMap->PrimaryPartitionAt(i); if (primary->IsExtended()) error = _ParseExtended(primary, primary->Offset()); } // cleanup delete fPartitionTable; fPartitionTable = NULL; return error; }