static bool_t dos_partition(struct disk * disk, size_t sector, size_t relative) { struct dos_partition_mbr mbr; struct partition * part; size_t start; int i; if(!disk || !disk->name) return FALSE; if((disk->sector_size <= 0) || (disk->sector_count <=0)) return FALSE; if((!disk->read_sectors) || (!disk->write_sectors)) return FALSE; if(disk_read(disk, (u8_t *)(&mbr), (loff_t)(sector * disk->sector_size) , sizeof(struct dos_partition_mbr)) != sizeof(struct dos_partition_mbr)) return FALSE; /* * check dos partition's signature */ if((mbr.signature[0] != 0x55) || mbr.signature[1] != 0xaa) return FALSE; for(i=0; i<4; i++) { if((mbr.entry[i].type != 0) && (is_dos_extended(mbr.entry[i].type)==FALSE)) { part = malloc(sizeof(struct partition)); if(!part) return FALSE; strlcpy((char *)part->name, (const char *)"", sizeof(part->name)); part->sector_from = sector + ((mbr.entry[i].start[3] << 24) | (mbr.entry[i].start[2] << 16) | (mbr.entry[i].start[1] << 8) | (mbr.entry[i].start[0] << 0)); part->sector_to = part->sector_from + ((mbr.entry[i].length[3] << 24) | (mbr.entry[i].length[2] << 16) | (mbr.entry[i].length[1] << 8) | (mbr.entry[i].length[0] << 0)) - 1; part->sector_size = disk->sector_size; list_add_tail(&part->entry, &(disk->info.entry)); } } for(i=0; i<4; i++) { if(is_dos_extended(mbr.entry[i].type)==TRUE) { start = ((mbr.entry[i].start[3] << 24) | (mbr.entry[i].start[2] << 16) | (mbr.entry[i].start[1] << 8) | (mbr.entry[i].start[0] << 0)) + relative; return dos_partition(disk, start, (sector == 0) ? start : relative); } } return TRUE; }
/* * Walk partition tables and invoke a callback for each. */ static void walk_partitions(int fd, int startsec, uint_t secsz, int (*f)(void *, int, uint_t, uint_t), void *arg) { uint32_t buf[1024/4]; int bufsize = 1024; struct mboot *mboot = (struct mboot *)&buf[0]; struct ipart ipart[FD_NUMPART]; uint_t sec = startsec; uint_t lastsec = sec + 1; uint_t relsect; int ext = 0; int systid; boolean_t valid; int i; while (sec != lastsec) { if (pread(fd, buf, bufsize, (off_t)sec * secsz) != bufsize) { break; } lastsec = sec; if (ltohs(mboot->signature) != MBB_MAGIC) { break; } bcopy(mboot->parts, ipart, FD_NUMPART * sizeof (struct ipart)); for (i = 0; i < FD_NUMPART; i++) { systid = ipart[i].systid; relsect = sec + ltohi(ipart[i].relsect); if (systid == 0) { continue; } valid = B_TRUE; if (is_dos_extended(systid) && (sec == lastsec)) { sec = startsec + ltohi(ipart[i].relsect); if (ext++ == 0) { relsect = startsec = sec; } else { valid = B_FALSE; } } if (valid && f(arg, ipart[i].systid, relsect, ltohi(ipart[i].numsect)) == WALK_TERMINATE) { return; } } } }