Exemplo n.º 1
0
Arquivo: dos.c Projeto: qioixiy/xboot
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;
}
Exemplo n.º 2
0
/*
 * 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;
			}
		}
	}
}