diff options
Diffstat (limited to 'cgpt/cgpt_create.c')
-rw-r--r-- | cgpt/cgpt_create.c | 35 |
1 files changed, 29 insertions, 6 deletions
diff --git a/cgpt/cgpt_create.c b/cgpt/cgpt_create.c index 7d3c0595..6a21a8b0 100644 --- a/cgpt/cgpt_create.c +++ b/cgpt/cgpt_create.c @@ -44,17 +44,40 @@ static int GptCreate(struct drive *drive, CgptCreateParams *params) { h->revision = GPT_HEADER_REVISION; h->size = sizeof(GptHeader); h->my_lba = GPT_PMBR_SECTORS; /* The second sector on drive. */ - h->alternate_lba = drive->gpt.drive_sectors - GPT_HEADER_SECTORS; - h->entries_lba = h->my_lba + GPT_HEADER_SECTORS + params->padding; - h->first_usable_lba = h->entries_lba + GPT_ENTRIES_SECTORS; - h->last_usable_lba = (drive->gpt.drive_sectors - GPT_HEADER_SECTORS - - GPT_ENTRIES_SECTORS - 1); + h->alternate_lba = drive->gpt.gpt_drive_sectors - GPT_HEADER_SECTORS; + h->entries_lba = h->my_lba + GPT_HEADER_SECTORS; + if (drive->gpt.stored_on_device == GPT_STORED_ON_DEVICE) { + h->entries_lba += params->padding; + h->first_usable_lba = h->entries_lba + GPT_ENTRIES_SECTORS; + h->last_usable_lba = (drive->gpt.drive_sectors - GPT_HEADER_SECTORS - + GPT_ENTRIES_SECTORS - 1); + } else { + h->first_usable_lba = 0; + h->last_usable_lba = (drive->gpt.drive_sectors - 1); + } if (CGPT_OK != GenerateGuid(&h->disk_uuid)) { Error("Unable to generate new GUID.\n"); return -1; } - h->number_of_entries = 128; h->size_of_entry = sizeof(GptEntry); + h->number_of_entries = TOTAL_ENTRIES_SIZE / h->size_of_entry; + if (drive->gpt.stored_on_device != GPT_STORED_ON_DEVICE) { + // We might have smaller space for the GPT table. Scale accordingly. + size_t half_size = drive->flash_size / 2; + size_t header_block_size = GPT_HEADER_SECTORS * drive->gpt.sector_bytes; + if (half_size < header_block_size) { + Error("Not enough space for a GPT header.\n"); + return -1; + } + half_size -= header_block_size; + if (half_size < MIN_NUMBER_OF_ENTRIES * h->size_of_entry) { + Error("Not enough space for minimum number of entries.\n"); + return -1; + } + if (128 > half_size / h->size_of_entry) { + h->number_of_entries = half_size / h->size_of_entry; + } + } // Copy to secondary RepairHeader(&drive->gpt, MASK_PRIMARY); |