Пример #1
0
static struct part_iter *pi_gpt_next(struct part_iter *iter)
{
    const struct disk_gpt_part_entry *gpt_part = NULL;

    if (iter->status)
	goto bail;

    while (++iter->index0 < iter->sub.gpt.pe_count) {
	gpt_part = (const struct disk_gpt_part_entry *)
	    (iter->data + iter->index0 * iter->sub.gpt.pe_size);

	if (notsane_gpt(iter)) {
	    iter->status = PI_INSANE;
	    goto bail;
	}

	if (!guid_is0(&gpt_part->type) || iter->stepall)
	    break;
    }
    /* no more partitions ? */
    if (iter->index0 == iter->sub.gpt.pe_count) {
	iter->status = PI_DONE;
	goto bail;
    }
    /* gpt_part is guaranteed to be valid here */
    iter->index = iter->index0 + 1;
    iter->rawindex = iter->index0 + 1;
    iter->start_lba = gpt_part->lba_first;
    iter->length = gpt_part->lba_last - gpt_part->lba_first + 1;
    iter->record = (char *)gpt_part;
    memcpy(&iter->sub.gpt.part_guid, &gpt_part->uid, sizeof(struct guid));
    gpt_conv_label(iter);

#ifdef DEBUG
    disk_gpt_part_dump(gpt_part);
#endif

    return iter;
bail:
    return NULL;
}
Пример #2
0
static int setup_handover(const struct part_iter *iter,
		   struct data_area *data)
{
    struct disk_dos_part_entry *ha;
    uint32_t synth_size = sizeof *ha;

    /*
     * we have to cover both non-iterated but otherwise properly detected
     * gpt/dos schemes as well as raw disks; checking index for 0 covers both
     */
    if (iter->index == 0) {
	uint32_t len;
	/* RAW handover protocol */
	ha = malloc(synth_size);
	if (!ha) {
	    critm();
	    goto bail;
	}
	len = ~0u;
	if (iter->length < len)
	    len = iter->length;
	lba2chs(&ha->start, &iter->di, 0, L2C_CADD);
	lba2chs(&ha->end, &iter->di, len - 1, L2C_CADD);
	ha->active_flag = 0x80;
	ha->ostype = 0xDA;	/* "Non-FS Data", anything is good here though ... */
	ha->start_lba = 0;
	ha->length = len;
    } else if (iter->type == typegpt) {
	uint32_t *plen;
	/* GPT handover protocol */
	synth_size += sizeof *plen + iter->gpt.pe_size;
	ha = malloc(synth_size);
	if (!ha) {
	    critm();
	    goto bail;
	}
	lba2chs(&ha->start, &iter->di, iter->abs_lba, L2C_CADD);
	lba2chs(&ha->end, &iter->di, iter->abs_lba + iter->length - 1, L2C_CADD);
	ha->active_flag = 0x80;
	ha->ostype = 0xED;
	/* All bits set by default */
	ha->start_lba = ~0u;
	ha->length = ~0u;
	/* If these fit the precision, pass them on */
	if (iter->abs_lba < ha->start_lba)
	    ha->start_lba = iter->abs_lba;
	if (iter->length < ha->length)
	    ha->length = iter->length;
	/* Next comes the GPT partition record length */
	plen = (uint32_t *)(ha + 1);
	plen[0] = iter->gpt.pe_size;
	/* Next comes the GPT partition record copy */
	memcpy(plen + 1, iter->record, plen[0]);
#ifdef DEBUG
	dprintf("GPT handover:\n");
	disk_dos_part_dump(ha);
	disk_gpt_part_dump((struct disk_gpt_part_entry *)(plen + 1));
#endif
    /* the only possible case left is dos scheme */
    } else if (iter->type == typedos) {
	/* MBR handover protocol */
	ha = malloc(synth_size);
	if (!ha) {
	    critm();
	    goto bail;
	}
	memcpy(ha, iter->record, synth_size);
	/* make sure these match bios imaginations and are ebr agnostic */
	lba2chs(&ha->start, &iter->di, iter->abs_lba, L2C_CADD);
	lba2chs(&ha->end, &iter->di, iter->abs_lba + iter->length - 1, L2C_CADD);
	ha->start_lba = iter->abs_lba;
	ha->length = iter->length;

#ifdef DEBUG
	dprintf("MBR handover:\n");
	disk_dos_part_dump(ha);
#endif
    } else {
	/* shouldn't ever happen */
	goto bail;
    }

    data->base = 0x7be;
    data->size = synth_size;
    data->data = (void *)ha;

    return 0;
bail:
    return -1;
}