static struct part_iter *pi_dos_next(struct part_iter *iter) { uint32_t start_lba = 0; struct disk_dos_part_entry *dos_part = NULL; if (iter->status) goto bail; /* look for primary partitions */ if (iter->index0 < 4 && pi_dos_next_mbr(iter, &start_lba, &dos_part)) goto bail; /* look for logical partitions */ if (iter->index0 >= 4 && pi_dos_next_ebr(iter, &start_lba, &dos_part)) goto bail; /* * note special index handling, if we have stepall set - * this is made to keep index consistent with non-stepall * iterators */ if (iter->index0 >= 4 && !dos_part->ostype) iter->index = -1; else iter->index = iter->index0 - iter->sub.dos.skipcnt + 1; iter->rawindex = iter->index0 + 1; iter->start_lba = start_lba; iter->length = dos_part->length; iter->record = (char *)dos_part; #ifdef DEBUG disk_dos_part_dump(dos_part); #endif return iter; bail: return NULL; }
static int pi_dos_next(struct part_iter *iter) { uint32_t abs_lba = 0; struct disk_dos_part_entry *dos_part = NULL; if (iter->status) return iter->status; /* look for primary partitions */ if (iter->index0 < 4 && dos_next_mbr(iter, &abs_lba, &dos_part) < 0) return iter->status; /* look for logical partitions */ if (iter->index0 >= 4 && dos_next_ebr(iter, &abs_lba, &dos_part) < 0) return iter->status; /* * note special index handling: * in case PIF_STEPALL is set - this makes the index consistent with * non-PIF_STEPALL iterators */ if (!dos_part->ostype) iter->index = -1; else iter->index = iter->index0 + 1 - iter->dos.logskipcnt; iter->abs_lba = abs_lba; iter->length = dos_part->length; iter->record = (char *)dos_part; #ifdef DEBUG disk_dos_part_dump(dos_part); #endif return iter->status; }
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; }