/* * Fetch the first dos and all plan9 partitions out of the MBR partition table. * We return -1 if we did not find a plan9 partition. */ static int mbrpart(PSDunit *unit) { Dospart *dp; uvlong taboffset, start, end; uvlong firstxpart, nxtxpart; int havedos, i, nplan9; char name[10]; taboffset = 0; dp = (Dospart*)&mbrbuf[0x1BE]; { /* get the MBR (allowing for DMDDO) */ if(sdreadblk(unit, &unit->part[0], mbrbuf, (vlong)taboffset * unit->secsize, 1) < 0) return -1; for(i=0; i<4; i++) if(dp[i].type == DMDDO) { if(Trace) print("DMDDO partition found\n"); taboffset = 63; if(sdreadblk(unit, &unit->part[0], mbrbuf, (vlong)taboffset * unit->secsize, 1) < 0) return -1; i = -1; /* start over */ } } /* * Read the partitions, first from the MBR and then * from successive extended partition tables. */ nplan9 = 0; havedos = 0; firstxpart = 0; for(;;) { if(sdreadblk(unit, &unit->part[0], mbrbuf, (vlong)taboffset * unit->secsize, 1) < 0) return -1; if(Trace) { if(firstxpart) print("%s ext %llud ", unit->name, taboffset); else print("%s mbr ", unit->name); } nxtxpart = 0; for(i=0; i<4; i++) { if(Trace) print("dp %d...", dp[i].type); start = taboffset+GLONG(dp[i].start); end = start+GLONG(dp[i].len); if(dp[i].type == PLAN9) { if(nplan9 == 0) strncpy(name, "plan9", sizeof name); else snprint(name, sizeof name, "plan9.%d", nplan9); psdaddpart(unit, name, start, end); p9part(unit, name); nplan9++; } /* * We used to take the active partition (and then the first * when none are active). We have to take the first here, * so that the partition we call ``dos'' agrees with the * partition disk/fdisk calls ``dos''. */ if(havedos==0 && isdos(dp[i].type)){ havedos = 1; psdaddpart(unit, "dos", start, end); } /* nxtxpart is relative to firstxpart (or 0), not taboffset */ if(isextend(dp[i].type)){ nxtxpart = start-taboffset+firstxpart; if(Trace) print("link %llud...", nxtxpart); } } if(Trace) print("\n"); if(!nxtxpart) break; if(!firstxpart) firstxpart = nxtxpart; taboffset = nxtxpart; } return nplan9 ? 0 : -1; }
int mbrpart(Disk *d) { uchar mbrbuf[512]; char name[10]; Dospart *dp; ulong taboffset, start, end; ulong firstxpart, nxtxpart; int i, nplan9, havedos; #define readmbr() \ if(readdisk(d, mbrbuf, (uvlong)taboffset*512, sizeof mbrbuf) == -1 \ || mbrbuf[0x1FE] != 0x55 || mbrbuf[0x1FF] != 0xAA) \ return 0 if(d->secsize > 512) return 0; dp = (Dospart*)&mbrbuf[0x1BE]; taboffset = 0; if(1) { /* get the MBR (allowing for DMDDO) */ readmbr(); for(i = 0; i < 4; i++) { if(dp[i].type == DMDDO) { taboffset = 63; readmbr(); i = -1; /* start over */ } } } /* * Read the partitions, first from the MBR and then * from successive extended partition tables. */ nplan9 = 0; havedos = 0; firstxpart = 0; for(;;) { readmbr(); nxtxpart = 0; for(i = 0; i < 4; i++) { /* partition offsets are relative to taboffset */ start = taboffset+GLONG(dp[i].start); end = start+GLONG(dp[i].len); if(dp[i].type == PLAN9) { if(nplan9 == 0) strcpy(name, "plan9"); else sprint(name, "plan9.%d", nplan9); addpart(d, name, start, end); p9part(d, name, start); nplan9++; } if(!havedos && isdos(dp[i].type)) { havedos = 1; addpart(d, "dos", start, end); } /* nxtxpart is relative to firstxpart (or 0), not taboffset */ if(isextend(dp[i].type)) nxtxpart = start-taboffset+firstxpart; } if(!nxtxpart) break; if(!firstxpart) firstxpart = nxtxpart; taboffset = nxtxpart; } return nplan9 + havedos; }