/* * Partition editing and picking. * * 09-Dec-87 ml. Added pheader() to take care of placing partition * headers at good sectors. * 14-Jan-88 ml. Added chkpart() to make sure partition scheme does * not map pass end of device. * 02-Dec-88 jye. Change and add codes so that can be used for MS-DOS * * 12-Dec-89 jye. Fixed a bug in stuffamt() so that correctly show three * digits or more in the partitioning deialog box. */ #include "obdefs.h" #include "gemdefs.h" #include "osbind.h" #include "mydefs.h" #include "part.h" #include "bsl.h" #include "hdx.h" #include "addr.h" #include "myerror.h" #include "ipart.h" #define ROLL1 1 /* move the bar one step */ #define ROLL4 4 /* move the bar four steps */ #define NULL 0L /* the nill pointer */ extern int wdesk; extern int hdesk; extern long gbslsiz(); extern long getdsiz(); extern long bslsiz; extern SECTOR badbuf[]; /* bad sectors buffer */ extern long ostack; extern long sptrk; /* sector per track */ extern long disksiz; /* size of disk in blocks */ extern int yesscan; /* the flag for the func. IBMGPART use */ extern int npart; /* number of partitions */ extern int ext; /* the index that point to the extended partition */ extern int sacrfnm; /* the index of the sacrificed partition */ extern int extend; /* the index that point to the end of extended */ extern char ttscsi; /* 1: SCSI bus drive */ extern int kporder[]; /* the orders for copy the kept partition */ /* * Global variables these routines communicate with * */ static PART *pinfo; /* -> partition block */ static int totcyl; /* total # of cylinder */ static long sizleft; /* size of unused disk in blocks */ static long extleft; /* size of unused extended partition in blocks */ static int formw, formh; static int lx, ly, sx, sy; static int ok2draw; /* 0: don't draw PARTPNL boxes */ static char partnames[NAMSIZ]; /* partition name buffer */ static int menuflg; /* negative: never called partmenu */ static int pnlflg; /* 1: partition scheme comes from panel */ static int along; /* 1: will not redraw and clean the box */ static int first; /* flag for add bad and good sectors only one time */ long sumsiz; /* the sum of bytes of root sectors */ int tolpart; /* the total of number partitions */ int epty; /* the y-coordinate of the moving bar */ int uplim; /* index of dialog box */ int lowlim; /* index of dialog box */ int restept; /* 1: rest the moving bar to initial place */ DPART *headptr; /* the head pointer of structure */ long ratio, bps; long nill = (long)NULL; int prevnpart; /* former number of partitions */ int keepnum = 0; /* the number of partitions want to keeped */ NEWHDR newhdr[MAXPART+3]; /* the structure for the header of keeped */ /* partitions */ PRVHDR prvhdr[MAXPART+3]; /* the structure for the header of privous */ /* partitions */ SAVEPART savepart[MAXPART+3]; /* the structure for the keeping */ /* partitions. plus 3 is for the extened */ /* partitions. */ OLDPART oldpart[MAXPART+3]; /* the structure for the original partition */ /* but only keep the kept partition which */ /* extend to the not kept partition */ NEWPART newpart[MAXPART+3]; /* the structure for the original partition */ /* but only keep the kept partition which */ /* extend to the not kept partition */ /* * Figure out partition information; * return OK if xpinfo[] is filled-in, * ERROR on [CANCEL] or something. */ sfigpart(bs, dev, rpinfo) char *bs; int dev; PART **rpinfo; { int ret, i; lowlim = 0; uplim = 4; first = 0; along = 0; /* will redraw and clean the box */ restept = 0; /* Get partition information from disk's root block. */ if ((ret = getroot(dev, bs, (SECTOR)0)) != 0) { if (tsterr(ret) != OK) err(rootread); return ERROR; } yesscan = 0; /* get bad sectors list size */ if ((bslsiz = gbslsiz(dev)) == 0L) { /* no bsl */ return err(oldfmt); } else if (bslsiz < 0L) { /* error occurred */ if (bslsiz == ERROR) /* read error */ err(rootread); return ERROR; /* medium changed error */ } if ((ret = chkroot(dev, bs)) == -3) { /*don't have to show the alert box */ return ERROR; } else if (ret != OK) { return err(cruptfmt); } disksiz = ((RSECT *)(bs + 0x200 - sizeof(RSECT)))->hd_siz; if (stgpart(dev, bs, (PART *)&pinfo) == ERROR) { if (pinfo > 0) Mfree(pinfo); return ERROR; } if (ext != NO_EXT) sortpart(pinfo, USER_ED); /* put partition infomations into the dynamic structure */ if (part2dpart(npart) == ERROR) { return ERROR; } menuflg = -1; /* first time through */ restept = 1; prevnpart = npart; ret = MAXPART + 3; for (i = 0; i < ret; i++) /* initialize the savepart record */ savepart[i].saveflg = 0; /* the structure for the keeping */ for (;;) { switch (sdoscrbar()) { case SPMENU: /* chose from menu */ switch (spartmenu()) { case PPOK: *rpinfo = pinfo; return OK; /* [OK] */ default: case PPCN: if (pinfo > 0) Mfree(pinfo); if (headptr > 0) free(headptr); return BAILOUT; /* [CANCEL] */ case PPEDIT: restept = 1; lowlim = 0; uplim = 4; break; /* continue and edit */ } break; case EXPERT: along = 0; lowlim = 0; uplim = 4; restept = 1; ext = 1; /* set default to 1 */ extend = npart-2; switch (doexpert()) { case NOSEL: if (pinfo > 0) { inipart(pinfo, prevnpart); Mfree(pinfo); } if (headptr > 0) free(headptr); return BAILOUT; /* [CANCEL] */ case SELOK: pnlflg = 1; if (pinfo > 0) { inipart(pinfo, prevnpart); Mfree(pinfo); } if (dpart2part(ext) == ERROR) { if (headptr > 0) free(headptr); if (pinfo > 0) Mfree(pinfo); return ERROR; } if(ckcpkp(pinfo, 1)!= OK){ /* 1: test */ /* initialize the savepart record */ ret = MAXPART + 3; for (i = 0; i < ret; i++) savepart[i].saveflg = 0; form_alert(1, dokpmsg); break; } *rpinfo = pinfo; return OK; default: case TOEDIT: break; } case SCRUP: break; case SCRDN: break; case SCRBAR: break; case SCREPT: break; case SUNDO: ret = MAXPART + 3; /* initialize the savepart record */ for (i = 0; i < ret; i++) savepart[i].saveflg = 0; break; default: case SEPOK: if (ckcpkp(pinfo, 1) != OK) { /* 1: test */ /* initialize the savepart record */ ret = MAXPART + 3; for (i = 0; i < ret; i++) savepart[i].saveflg = 0; form_alert(1, dokpmsg); return BAILOUT; } *rpinfo = pinfo; return OK; case SEPCN: if (pinfo > 0) Mfree(pinfo); if (headptr > 0) free(headptr); return BAILOUT; } } } int objnums[] = { SPARTNM0, SPARTNM1, SPARTNM2, SPARTNM3}; int objkp[] = { KEEP0, KEEP1, KEEP2, KEEP3}; int objups[] = {SEP0UP, SEP1UP, SEP2UP, SEP3UP}; int objdns[] = {SEP0DN, SEP1DN, SEP2DN, SEP3DN}; int objsizs[] = {SEP0SIZ, SEP1SIZ, SEP2SIZ, SEP3SIZ}; char *sizstr[6] = {"1000.0Mb0", "1000.0Mb0", "1000.0Mb0", "1000.0Mb0", "1000.0Mb0", " 999 partition(s)"}; char *numstr[5] = {"#999", "#999", "#999", "#999", "#123"}; int objnum[] = { PART1, PART2, PART3, PART4, PARTX, PARTY, PARTZ}; char *xsizstr[7] = {"1000.0Mb0", "1000.0Mb0", "1000.0Mb0", "1000.0Mb0", "1000.0Mb0", "1000.0Mb0", "1000.0Mb0"}; int objsiz[] = {PART1MB, PART2MB, PART3MB, PART4MB, PARTXMB, PARTYMB, PARTZMB}; char *xnumstr[7] = {"#999", "#999", "#999", "#999", "#999", "#999", "#999"}; int objsel[] = { SELECT1, SELECT2, SELECT3, SELECT4, SELECT5, SELECT6}; char *selstr[6] = {"from #2 to #99", "from #2 to #99", "from #2 to #99", "from #3 to #99", "from #3 to #99", "from #4 to #99" }; doexpert() { int i, lastpno, pno; int run = 1; int erase = 0; int but; ok2draw = 0; exppnl[TOEDIT].ob_state = NORMAL; exppnl[NOSEL].ob_state = NORMAL; exppnl[SELOK].ob_state = NORMAL; drawsel(2, npart-2, 0, exppnl); drawsel(2, npart-1, 1, exppnl); drawsel(2, npart, 2, exppnl); drawsel(3, npart-1, 3, exppnl); drawsel(3, npart, 4, exppnl); drawsel(4, npart, 5, exppnl); for (i = 0; i < 7; i++) { if (npart > 7) { if (i > 3) { if (i == 4) lastpno = npart - i + 1; drawpart(i, lastpno++, exppnl); } else { drawpart(i, i, exppnl); } } else if (npart == 5) { if (i > 4) { pno = -1; drawpart(i, pno, exppnl); } else { drawpart(i, i, exppnl); } } else if (npart == 6) { if (i > 5) { pno = -1; drawpart(i, pno, exppnl); } else { drawpart(i, i, exppnl); } } else { drawpart(i, i, exppnl); } } /* set the default selected */ exppnl[SELECT1].ob_state = NORMAL | SELECTED; exppnl[SELECT2].ob_state = NORMAL; exppnl[SELECT3].ob_state = NORMAL; exppnl[SELECT4].ob_state = NORMAL; exppnl[SELECT5].ob_state = NORMAL; exppnl[SELECT6].ob_state = NORMAL; turnexton(1, npart-2); ARROW_MOUSE; dsplymsg(exppnl); ++ok2draw; while (run) { switch((but = form_do(exppnl, -1))) { case TOEDIT: run = 0; break; case NOSEL: run = 0; erase = 1; break; case SELOK: run = 0; erase = 1; break; case SELECT1: ext = 1; extend = npart - 2; turnexton(1, npart-2); break; case SELECT2: ext = 1; extend = npart - 1; turnexton(1, npart-1); break; case SELECT3: ext = 1; extend = npart; turnexton(1, npart); break; case SELECT4: ext = 2; extend = npart - 1; turnexton(2, npart-1); break; case SELECT5: ext = 2; extend = npart; turnexton(2, npart); break; case SELECT6: ext = 3; extend = npart; turnexton(3, npart); break; } } if (erase) { erasemsg(); BEE_MOUSE; } return but; } turnexton(stnum, endnum) int stnum; /* the number that start to turn on the extended partition */ int endnum; /* the number that end to turn on the extended partition */ { int i; if (npart > 7) { endnum = 7 - (npart - endnum); } for (i = 0; i < 7; i++) { exppnl[objsiz[i]].ob_state = NORMAL; if ((i >= stnum) && (i < endnum)) { exppnl[objsiz[i]].ob_state |= SELECTED; } if (ok2draw) { objc_draw(exppnl, objsiz[i], MAX_DEPTH, 0, 0, wdesk, hdesk); } } ok2draw++; } drawsel(stnum, tonum, num, pnl) int stnum; /* the first extended partition number */ int tonum; /* the last extended partition number */ int num; /* the number of selected extended partition scheme */ OBJECT *pnl; { /* set the select range in the dialog box */ calextnum(stnum, tonum, selstr[num]); (pnl[objsel[num]].ob_spec)->te_ptext = selstr[num]; if (ok2draw) { objc_draw(pnl, objsel[num], MAX_DEPTH, 0, 0, wdesk, hdesk); } } drawpart(num, pno, pnl) int num; /* the number of selected extended partition scheme */ int pno; /* the partition number */ OBJECT *pnl; { DPART *pinfo, *addr(); if (pno == NO_EXT) { /* not exists */ pnl[objsiz[num]].ob_spec = "Unused"; pnl[objsiz[num]].ob_state = NORMAL; pnl[objsiz[num]].ob_flags = TOUCHEXIT; (pnl[objnum[num]].ob_spec)->te_ptext = " "; } else { pinfo = addr(pno); stuffamt(pinfo->siz, xsizstr[num], 0); pnl[objsiz[num]].ob_spec = xsizstr[num]; pnl[objsiz[num]].ob_state = NORMAL; pnl[objsiz[num]].ob_flags = TOUCHEXIT; stpartnum(pno+1, xnumstr[num]); (pnl[objnum[num]].ob_spec)->te_ptext = xnumstr[num]; } if (ok2draw) { objc_draw(pnl, objsiz[num], MAX_DEPTH, 0, 0, wdesk, hdesk); objc_draw(pnl, objnum[num], MAX_DEPTH, 0, 0, wdesk, hdesk); } } sdoscrbar() { int i, j, but, step; int xrun = 1; long usesiz; DPART *temptr, *addr(); ok2draw = (along) ? 1 : 0; /* set form for first display */ scrpnl[SEPOK].ob_state = NORMAL; scrpnl[SEPCN].ob_state = NORMAL; scrpnl[SPMENU].ob_state = NORMAL; scrpnl[SUNDO].ob_state = NORMAL; if (!first++) { /* initialize the ST partition */ temptr = headptr; for (i = 0; i < npart; i++) { if ((temptr->flg & P_EXISTS) && (!((temptr->next)->flg & P_EXISTS))) { temptr->siz += bslsiz + 1; /* add sacrificed space back */ sacrfnm = i; } temptr = temptr->next; } } for (i = -1; i < 4; ++i) sepadj(0L, i, scrpnl); if (restept) { scrpnl[SCREPT].ob_y = 0; restept = 0; } if (!along) { ARROW_MOUSE; dsplymsg(scrpnl); } /* * Edit the thing; * canonical event-driven switch(). */ ++ok2draw; while (xrun) { along = 0; if (npart > 4) { scrpnl[EXPERT].ob_state = NORMAL; scrpnl[EXPERT].ob_flags = TOUCHEXIT; } else { scrpnl[EXPERT].ob_state = DISABLED; scrpnl[EXPERT].ob_flags = NONE; } objc_draw(scrpnl, EXPERT, MAX_DEPTH, 0, 0, wdesk, hdesk); switch ((but = form_do(scrpnl, -1))) { case SEPOK: pnlflg = 1; if (pinfo > 0L) { inipart(pinfo,prevnpart); Mfree(pinfo); } ext = 1; /* set the default extended partition */ extend = npart - 2; if (dpart2part(ext) == ERROR) return ERROR; xrun = 0; break; case SEPCN: xrun = 0; /* return */ break; case EXPERT: if (npart > 4) { xrun = 0; break; } else { xrun = 1; break; } case SCRBAR: if (sdoscrupdn(ROLL4) == ERROR) return ERROR; xrun = 0; break; case SCRUP: if (sdoscrupdn(ROLL1) == ERROR) return ERROR; xrun = 0; break; case SCRDN: if (sdoscrupdn(ROLL1) == ERROR) return ERROR; xrun = 0; break; case SCREPT: if (sdoslidebox(scrpnl) == ERROR) return ERROR; xrun = 0; break; case SPMENU: xrun = 0; break; case SUNDO: /* restore the starting parameters */ lowlim = 0; uplim = 4; if (part2dpart(prevnpart) == ERROR) return ERROR; for (i = -1; i < NPARTS; ++i) sepadj(0L, i, scrpnl); npart = prevnpart; scrpnl[SCREPT].ob_y = 0; objc_draw(scrpnl, SCRBAR, MAX_DEPTH, 0, 0, wdesk, hdesk); break; case SEP0SIZ: xrun = septoggle(0, scrpnl); break; case SEP0UP: sepadj(MEGABYTE, 0, scrpnl); break; case SEP0DN: sepadj(-MEGABYTE, 0, scrpnl); break; case KEEP0: dokeep(scrpnl, 0); break; case SEP1SIZ: xrun = septoggle(1, scrpnl); break; case SEP1UP: sepadj(MEGABYTE, 1, scrpnl); break; case SEP1DN: sepadj(-MEGABYTE, 1, scrpnl); break; case KEEP1: dokeep(scrpnl, 1); break; case SEP2SIZ: xrun = septoggle(2, scrpnl); break; case SEP2UP: sepadj(MEGABYTE, 2, scrpnl); break; case SEP2DN: sepadj(-MEGABYTE, 2, scrpnl); break; case KEEP2: dokeep(scrpnl, 2); break; case SEP3SIZ: xrun = septoggle(3, scrpnl); break; case SEP3UP: sepadj(MEGABYTE, 3, scrpnl); break; case SEP3DN: sepadj(-MEGABYTE, 3, scrpnl); break; case KEEP3: dokeep(scrpnl, 3); break; } } /* * Draw shrinking box and cleanup the screen; * return thing that caused our exit. */ if (!along) { erasemsg(); BEE_MOUSE; } return but; } /* check and see if the partition is a original one or not; return 1 if it is, but return 0 if it is not */ chkeep(num) int num; { DPART *pinfo1, *addr(); pinfo1 = addr(num+lowlim); /* if st = 0, it means the partition infor has been changed */ return (((pinfo1->kpyes & TRUE)||(pinfo1->st == 0)) ? (1) : (0)); } /* put the keep partition infor into the SAVEPART structure and tune on the KEEP bottom in the user desires partition */ dokeep(pnl, num) OBJECT *pnl; int num; { int ret, knum, run=1, savefg; long tmpsiz; DPART *pinfo1, *pinfo2, *addr(); char *selkp = " 9"; if (chkeep(num)) { /* check see if it is a original */ /* partition; return 0: yes; 1: no */ return OK; /* it is not a original partition */ } savefg = ok2draw; ok2draw = 0; keepas[KPASOK].ob_state = NORMAL; keepas[KPASCN].ob_state = NORMAL; keepas[KPASUP].ob_state = NORMAL; keepas[KPASUP].ob_flags = TOUCHEXIT; keepas[KPASDN].ob_state = NORMAL; keepas[KPASDN].ob_flags = TOUCHEXIT; ret = num + lowlim + 1; *selkp = ' '; *(selkp+1) = ret%10 + '0'; if (ret >= 10) { /* it is two digit */ *selkp = ret/10 + '0'; } (keepas[KPNUM].ob_spec)->te_ptext = selkp; knum = keepadj(0, 0, keepas); ARROW_MOUSE; dsplymsg(keepas); ++ok2draw; while (run) { switch((ret = form_do(keepas, -1))) { case KPASUP: knum = keepadj(1, knum, keepas); break; case KPASDN: knum = keepadj(-1, knum, keepas); break; case KPASOK: run = 0; break; case KPASCN: run = 0; break; } } if (ret == KPASOK) { pinfo1 = addr(num + lowlim); pinfo2 = addr(knum); /* save the partition that want to kept */ savepart[knum].savest = pinfo1->st; /* !! */ if (sacrfnm == num + lowlim) /* minus the scarificed sects */ savepart[knum].savend = pinfo1->st + pinfo1->siz - bslsiz - 1; else savepart[knum].savend = pinfo1->st + pinfo1->siz; savepart[knum].saveflg = P_EXISTS; /* swap the pinfo between these two partitions */ pinfo1->st = pinfo2->st; pinfo1->flg = pinfo2->flg; pinfo1->kpyes = FALSE; tmpsiz = pinfo1->siz; pinfo1->siz = pinfo2->siz; /* change the kept partition info into the structure */ pinfo2->flg = P_EXISTS; pinfo2->kpyes = TRUE; pinfo2->siz = tmpsiz; pinfo2->st = savepart[knum].savest; /* if the kept partition is in the current dialog box, do the update */ sepadj(-2L, num+lowlim, pnl); /* update the old one */ if ((knum >= lowlim) && (knum <= lowlim+3)) { sepadj(-2L, knum, pnl); /* update the kept one */ } } ok2draw = savefg; erasemsg(); ARROW_MOUSE; dsplymsg(pnl); } /* update the keeping partition dialog box */ keepadj(num, count, pnl) int num, count; OBJECT *pnl; { DPART *pinfo1, *addr(); int tmp; if ((!count)&&(num == -1)) /* if the number is 0, don't decrease it */ return(count); if ((!count) &&(!num)) { /* if num and count is 0, do nothing */ num = 1; goto kp111; } else if ((count == (npart - 1)) && (num > 0)) { /* don't increament if over the limit */ return(count); } else { tmp = count; count += num; kp111: pinfo1 = addr(count); if (pinfo1->kpyes & TRUE) { count += num; if ((count >= npart) || (count < 0)) /* count over or under limit */ count = tmp; else goto kp111; } } stpartnum(count+1, numstr[4]); (pnl[KPASNM].ob_spec)->te_ptext = numstr[4]; if (ok2draw) { objc_draw(pnl, KPASNM, MAX_DEPTH, 0, 0, wdesk, hdesk); objc_draw(pnl, KPNUM, MAX_DEPTH, 0, 0, wdesk, hdesk); } return(count); } /* * conver the partition number for the dialog box to the string . * */ calextnum(stnum, tonum, str) int stnum,tonum; char *str; { int i = 0; int addspace = 0; char tem[10]; /* set the partition number header */ *str++ = 'f'; *str++ = 'r'; *str++ = 'o'; *str++ = 'm'; *str++ = ' '; *str++ = '#'; *str++ = stnum % 10 + '0'; *str++ = ' '; *str++ = 't'; *str++ = 'o'; *str++ = ' '; *str++ = '#'; /* conver the integer to ASCII */ do { /* generate digits in reverse order */ tem[i++] = tonum % 10 + '0'; /* get next digits */ } while ((tonum /= 10) > 0); /* delete it */ if (i == 1) { addspace = 1; } for (; i > 0; ) { /* reverse string 'str' in place */ *str++ = tem[--i]; } if (addspace) *str++ = ' '; *str = '\0'; } sdoscrupdn(roll) int roll; { int gr_mkmx, gr_mkmy; int gr_mkmstate, gr_mkkstate; int barht, barx, bary; int eptx, eptht; along = 1; barht = scrpnl[SCRBAR].ob_height; eptht = scrpnl[SCREPT].ob_height; graf_mkstate(&gr_mkmx, &gr_mkmy, &gr_mkmstate, &gr_mkkstate); objc_offset(scrpnl, SCREPT, &eptx, &epty); objc_offset(scrpnl, SCRBAR, &barx, &bary); /* check which part of bar was clicked */ if (gr_mkmy > (epty+eptht)) { /* low part of bar was clicked */ if (roll == ROLL4) { if ((eptht > (bary+barht-epty-eptht)) || (lowlim == 20)) { scrpnl[SCREPT].ob_y = barht - eptht; } else { scrpnl[SCREPT].ob_y += eptht; } lowlim = ((24-lowlim) < 4) ? (24) : (lowlim+4); if ((lowlim + 4) > uplim) uplim += 4; if (uplim > npart) { if (creatmem(ROLL4) == ERROR) { return ERROR; } } } else if (lowlim == 24) { /* the empty bar is on the bottom */ return OK; } else { if ((eptht > ((bary+barht-epty-eptht) * 4)) || (lowlim == 23)) { scrpnl[SCREPT].ob_y = barht - eptht; } else { scrpnl[SCREPT].ob_y += eptht / 4; } lowlim++; if ((lowlim + 4) > uplim) uplim++; if (uplim > npart) { if (creatmem(ROLL4) == ERROR) { return ERROR; } } } } else if (gr_mkmy < epty) { /* upper part of bar was clicked */ if (roll == ROLL4) { if ((eptht > (epty - bary)) || (lowlim <= 4)) { scrpnl[SCREPT].ob_y = 0; lowlim = 0; } else { scrpnl[SCREPT].ob_y -= eptht; lowlim -= 4; } } else { if ((eptht > ((epty - bary) * 4)) || (lowlim == 1)) { scrpnl[SCREPT].ob_y = 0; } else { scrpnl[SCREPT].ob_y -= eptht / 4; } if (lowlim) { lowlim--; } } } objc_draw(scrpnl,SCRBAR, MAX_DEPTH, 0, 0, wdesk, hdesk); } #define WHITEBAR 24 /* when the white bar on the bottom, the */ /* 'lowlim' will equal to 24 */ sdoslidebox(tree) OBJECT *tree; { int gr_wreturn, eptatmax; int numofmem; /* # of memories to be allocated */ along = 1; eptatmax = tree[SCRBAR].ob_height - tree[SCREPT].ob_height; gr_wreturn = graf_slidebox(tree, SCRBAR, SCREPT, 1); lowlim = (WHITEBAR * gr_wreturn) / 1000; if ((lowlim >= uplim) || ((lowlim + 4) > uplim)) { uplim = lowlim + 4; if (uplim > npart) { numofmem = uplim - npart; if (creatmem(numofmem) == ERROR) { return ERROR; } } } /* tree[SCREPT].ob_y = (eptatmax * gr_wreturn) / 1000; */ tree[SCREPT].ob_y = (eptatmax * lowlim ) / 24; objc_draw(tree, SCRBAR, MAX_DEPTH, 0, 0, wdesk, hdesk); } /* * Toggle partition in/out of existence. */ septoggle(n, pnl) int n; OBJECT *pnl; { int i; DPART *pinfo, *ppinfo, *npinfo, *addr(); /* * Toggle existance flag, * enforce minimum partition size. */ i = n + lowlim; pinfo = addr(i); /* return the structure pointer */ ppinfo = addr(i-1); /* return the previous structure pointer */ npinfo = addr(i+1); /* return the next structure pointer */ /* if (pinfo->kpyes & TRUE) { this partition is kept, don't change return YES; } */ if ((!(pinfo->flg & P_EXISTS)) && (pinfo->siz) && (ppinfo) && (ppinfo->flg & P_EXISTS)){ if (maxmsg(pnl,i,tolpart) == NOMAX) return ON; pinfo->flg = P_EXISTS; sepadj(0L, n, pnl); } else if (((pinfo->flg ^= P_EXISTS) & P_EXISTS) && !pinfo->siz) { /* make extended partition continue */ if (!i || ((ppinfo) && (ppinfo->flg & P_EXISTS))) { if (maxmsg(pnl,i,tolpart) == NOMAX) return ON; sepadj(MEGABYTE, n, pnl); } else { sepadj(0L, n, pnl); } } else if ((!lowlim) && (!i)&&(!(npinfo->flg & P_EXISTS))) { sepadj(0L, n, pnl); } else if ((!lowlim) && (!i)&&(pinfo->flg & P_EXISTS)) { sepadj(0L, n, pnl); } else { /* do nothing, turn it back to the initial state */ pinfo->flg ^= P_EXISTS; if ((pinfo->flg & P_EXISTS) && (!(npinfo->flg & P_EXISTS))) { pinfo->flg ^= P_EXISTS; sepadj(0L, n, pnl); } } sepadj(0L, -1, pnl); /* update #left field */ return YES; } /* * Adjust partition `pno' size by `amt'; * if `pno' is -1, just recompute and update disk space left indicator. * * A partition of size zero is disabled. */ #define HALFMEGA 1024L sepadj(amt, pno, pnl) long amt; int pno; OBJECT *pnl; { int i; long siz; long sizhas; /* disk size left in sectors */ long totsiz = 0; DPART *pinfo, *npinfo, *addr(); if (amt == -2) { /* when keep the old partition, do redraw only */ pinfo = addr(pno); goto doredraw; } if (pno < 0) /* draw the size left and total partition only */ goto fixleft; pno += lowlim; pinfo = headptr; /* compute total used */ while (pinfo->flg & P_EXISTS) { totsiz += pinfo->siz; pinfo = pinfo->next; } pinfo = addr(pno); npinfo = addr(pno+1); sizhas = disksiz; /* this partition is kept, can't decrease the size */ if ((pinfo->kpyes & TRUE) && (amt == -MEGABYTE)) return YES; /* * If total partition size exceeds the disk's * capacity, reduce `amt' accordingly. */ if (amt >= 0 && totsiz + amt > sizhas) amt = sizhas - totsiz; if (amt > 0) { /* * Enforce maximum partition size. */ siz = sizhas - totsiz; /* siz = #free */ if (amt > siz) amt = siz; /* ensure amt <= siz */ if (pinfo->siz + amt > sizhas) /* ensure partition not */ amt = sizhas - pinfo->siz; /* too big */ /* check the partition size that can't over 256Mb (8K bytes per sect) */ /* for the reason of hardware */ /* Mar-10-93 jye: now it is OK to partition over that limit if ((pinfo->siz + amt) > 256 * 2048) { form_alert(1, maxpsize); return OK; } */ pinfo->siz += amt; /* bump partition size */ pinfo->flg = P_EXISTS; pinfo->st = 0L; } else if (amt < 0) { amt = -amt; pinfo->st = 0L; if (pinfo->siz > amt) { /* reduce partition size */ pinfo->siz -= amt; if ((pinfo->siz < HALFMEGA) && (npinfo->flg & P_EXISTS)) pinfo->siz = amt; } else if ((pinfo->siz <= amt) && (!(npinfo->flg & P_EXISTS))) { /* reduce partition size */ pinfo->siz = 0L; } } /* * Enforce minimum partition size of half mega byte */ if (pinfo->siz < HALFMEGA) pinfo->siz = 0L; /* * Disable partitions of zero size */ if (!pinfo->siz) { pinfo->flg &= ~P_EXISTS; } doredraw: /* * Redraw the thing; * if partition is disabled, shadow it and disable UP/DOWN buttons; * otherwise setup the buttons, setup size string, and so on... */ pno -= lowlim; if (!(pinfo->flg & P_EXISTS)) { pnl[objsizs[pno]].ob_spec = "Unused"; pnl[objsizs[pno]].ob_state = NORMAL; pnl[objsizs[pno]].ob_flags = TOUCHEXIT; pnl[objups[pno]].ob_state = DISABLED; pnl[objups[pno]].ob_flags = NONE; pnl[objdns[pno]].ob_state = DISABLED; pnl[objdns[pno]].ob_flags = NONE; pnl[objkp[pno]].ob_flags = TOUCHEXIT; pnl[objkp[pno]].ob_state = DISABLED; } else { stuffamt(pinfo->siz, sizstr[pno], 0); pnl[objsizs[pno]].ob_spec = sizstr[pno]; pnl[objsizs[pno]].ob_state = NORMAL; pnl[objsizs[pno]].ob_flags = TOUCHEXIT; pnl[objups[pno]].ob_state = NORMAL; pnl[objups[pno]].ob_flags = TOUCHEXIT; pnl[objdns[pno]].ob_state = NORMAL; pnl[objdns[pno]].ob_flags = TOUCHEXIT; pnl[objkp[pno]].ob_flags = TOUCHEXIT; pnl[objkp[pno]].ob_state = DISABLED; if (pinfo->kpyes & TRUE) { pnl[objkp[pno]].ob_state = NORMAL; } } /* set the partition numbers in the dialog box */ stpartnum(lowlim+pno+1, numstr[pno]); (pnl[objnums[pno]].ob_spec)->te_ptext = numstr[pno]; if (ok2draw) { objc_draw(pnl, objsizs[pno], MAX_DEPTH, 0, 0, wdesk, hdesk); objc_draw(pnl, objups[pno], MAX_DEPTH, 0, 0, wdesk, hdesk); objc_draw(pnl, objdns[pno], MAX_DEPTH, 0, 0, wdesk, hdesk); objc_draw(pnl, objnums[pno], MAX_DEPTH, 0, 0, wdesk, hdesk); objc_draw(pnl, objkp[pno], MAX_DEPTH, 0, 0, wdesk, hdesk); } if (amt == -2) /* don't draw the rest if update the kept partition */ return YES; fixleft: /* * Compute and redraw 'space left' indicator and * calculat the total partitions number */ sizleft = disksiz; pinfo = headptr; tolpart = 0; while ((pinfo->flg & P_EXISTS) && (pinfo->siz > 0)) { sizleft -= pinfo->siz; tolpart++; pinfo = pinfo->next; } npart = tolpart; stuffamt(sizleft, sizstr[4], 1); (pnl[SEPLEFT].ob_spec)->te_ptext = sizstr[4]; totalpart(tolpart, sizstr[5]); (pnl[STOLPART].ob_spec)->te_ptext = sizstr[5]; if (ok2draw) { objc_draw(pnl, SEPLEFT, MAX_DEPTH, 0, 0, wdesk, hdesk); objc_draw(pnl, STOLPART, MAX_DEPTH, 0, 0, wdesk, hdesk); } } /* * Atoi `amt', #blocks, into 999.9Mb (or something like that); * assumes enough space in `str'. */ stuffamt(amt, str, flag) long amt; char *str; int flag; /* 1: for Memory left box. */ { long mb, frac; int i=0; mb = amt / 2048; frac = amt - (2048 * mb); if (frac / 16) frac /= 205; /* that's MEGABYTE / 10 */ else frac = 0; if (frac < 0) frac = -frac; if (mb < 0) mb = frac = 0; if (mb > 999) { *str++ = (mb / 1000) + '0'; i++; mb -= 1000 * (mb / 1000); if ((!mb) || (mb < 10)) { /* take care mb=1000 or 1001 case */ *str++ = '0'; *str++ = '0'; i += 2; } else if (mb < 100) { /* take care mb=1099 case */ *str++ = '0'; i++; } } if (mb > 99) { *str++ = (mb / 100) + '0'; i++; mb -= 100 * (mb / 100); if ((!mb) || (mb < 10)) { /* take care mb=100 or 101 cases */ *str++ = '0'; i++; } } if (mb > 9) { *str++ = (mb / 10) + '0'; mb -= 10 * (mb / 10); i++; } *str++ = mb + '0'; i++; if (frac) { *str++ = '.'; *str++ = frac + '0'; i += 2; } *str++ = 'M'; *str++ = 'b'; i += 2; if (flag) { /* for the Memory left box */ for (; i < 8; i++) *str++ = ' '; } *str = '\0'; } /* * Partitin button number-to-object translation table. */ int ppart[] = { PPART0, PPART1, PPART2, PPART3, PPART4, PPART5, PPART6, PPART7, PPART8, PPART9 }; /* * Throw up menu of canned partitions; * Return PPOK on [OK], * PPCN on [CANCEL], * PPEDIT on [EDIT==>], * ERROR on some error. * if `flag' < 0, this is the first time * putting up the menu. */ spartmenu() { int i, but, tem; char *s, *pnam, pr_id[10]; /* Figure out partition scheme id */ /* figprid(disksiz, pr_id); */ if (menuflg < 0) { menuflg = 1; figprid(disksiz, pr_id); /*Get all available partition schemes from wincap 'ID' entries*/ wallents(partnames, pr_id); if (!*partnames) { setschm(disksiz, partnames); } /* if (ttscsi) { setschm(disksiz, partnames); } else { Get all available partition schemes from wincap 'ID' entries wallents(partnames, pr_id); } */ } for (i = 0, s = partnames; i < 10 && *s; ++i) { p[ppart[i]].ob_type = G_BUTTON; p[ppart[i]].ob_spec = (long)s; p[ppart[i]].ob_state = NORMAL; p[ppart[i]].ob_flags = SELECTABLE | RBUTTON; while (*s++) ; } /* rest of buttons are invisible and untouchable */ for (; i < 10; ++i) { p[ppart[i]].ob_type = G_IBOX; p[ppart[i]].ob_spec = 0L; /* no thickness */ p[ppart[i]].ob_state = DISABLED; /* nobody home */ p[ppart[i]].ob_flags = NONE; /* disabled */ } /* clean up rest of the form and throw it up */ p[PPOK].ob_state = NORMAL; p[PPCN].ob_state = NORMAL; p[PPEDIT].ob_state = NORMAL; if((but = execform(p)) == PPCN || but == PPEDIT) return; /* search for partition they picked */ pnlflg = 0; /* partition scheme from menu */ for (i = 0; i < 10; ++i) if (p[ppart[i]].ob_state & SELECTED) break; if (i >= 10) return but; /* nothing changed */ pnam = p[ppart[i]].ob_spec; /* if (!ttscsi) { i = wgetent(pnam, pr_id); ; (floppy access) if (i != OK) { nopart[NOSCHPOK].ob_state = NORMAL; (nopart[NOSCHPR].ob_spec)->te_ptext = p[ppart[i]].ob_spec; execform(nopart); return ERROR; } } */ npart = 4; ext = NO_EXT; /* set no extended partition */ if (headptr > 0) free(headptr); if ((pinfo = (PART *)Malloc((long)sizeof(PART)*npart)) <= 0) { err(nomemory); if (pinfo > 0) Mfree(pinfo); return ERROR; } inipart(&pinfo[0], npart); /* initialized the 'pinfo' */ npart = 0; msetpart(pinfo, pnam, disksiz); /* if (ttscsi) { msetpart(pinfo, pnam, disksiz); } else { for (i = 0; i < 4; ++i) fillpart(i, &pinfo[i]); } */ return but; } /* * conver the partition number for the dialog box to the string . * */ stpartnum(num, str) int num; char *str; { int i = 0, j=0; char tem[20]; /* set the partition number header */ *str++ = '#'; j++; /* conver the integer to ASCII */ do { /* generate digits in reverse order */ tem[i++] = num % 10 + '0'; /* get next digits */ } while ((num /= 10) > 0); /* delete it */ for (; i > 0; ) { /* reverse string 'str' in place */ *str++ = tem[--i]; j++; } for (; j < 4; j++) *str++ = ' '; *str = '\0'; } /* * Place partition headers at the appropiate sectors. * Input: * pdev - physical device partitions belong to. * part - partition structure containing the partitions' * information. * Return: * OK - if everything is fine. * ERROR - error occurs when testing header sectors. * Comments: * Making sure that the headers occupy consecutive good * sectors. If necessary, sizes of partitions are adjusted to * achieve the above. * If any size adjustment make a partition bigger than * the maximum size, the partition will be adjusted to the maximum * size leaving the excessive sectors wasted. */ spheader(pdev, part) int pdev; /* physical device number */ PART *part; /* partition info */ { /* Maximum sizes for FAT, root directory and header */ long maxdent; /* max num entries in root dir */ long start; /* starting sector number of a partition */ long entries, nument(); long movehdr, temstart, moved, psiz; UWORD maxfsiz, maxdsiz, hdrsiz; long currbsiz; /* size of BSL b4 pheader is executed */ int pno; /* partition being dealt with */ int done; /* tell if location of header is found */ int curr; /* current sector of header being checked */ int ret; /* return code from testing header sectors */ int spc; /* sectors per cluster */ int kindfat; /* 12 bits fat or 16 bits fat */ int step; /* the index for check the partitions */ long bigsect(), nsect; long stbigsect(); long temsect, remain; long cell(); /* get the BSL ready ofr later */ entries = nument(MEDIA); sortbsl(entries); currbsiz = bslsiz; /* Determine actual sizes and starting sectors for all partitions */ for (pno = 0; pno < npart; pno++) { /* Partition 0 starts right after root sect. The rest starts right after its previous partition ???*/ if (pno == 0) start = 1 + currbsiz; else if (pno == 4) start = part[ext].p_st; /* start in extened partition */ else start = part[pno-1].p_st + part[pno-1].p_siz; /* Check if partition exists. If it doesn't, move on to next one */ /* ??? if ((!(part[pno].p_flg & P_EXISTS)) || (pno == ext) || (savepart[pno].saveflg & P_EXISTS)) { part[pno].p_st = start; continue; } */ if ((!(part[pno].p_flg & P_EXISTS)) || (pno == ext)) { part[pno].p_st = start; continue; } if ((savepart[pno].saveflg) && (pno > 3)) if (pno == npart - 1){/*!last partition, add the sacrificed & root*/ part[pno].p_siz += currbsiz + 2L; part[ext].p_siz += currbsiz + 2L; } else { /* in case of req to ext kept cp, +1 for root sector */ part[pno].p_siz += 1L; part[ext].p_siz += 1L; } if (pno > 3) { psiz = part[pno].p_siz - ROOTSECT; } else { psiz = part[pno].p_siz; } /* estimate the bps */ /* MAXSECT = 16MB - 8 */ bps = cell((psiz-7)*BPS, (long)MAXSECT); /* the real pbs */ bps = BPS * n2power((UWORD)cell(bps, (long)BPS)); ratio = bps / BPS; nsect = psiz / ratio; /* Detail of calculations in part.c dopart() */ /* find max FAT size. FAT16: 16 bits fat; FAT12: 12bits fat */ maxfsiz = ((((nsect / SPC) + 2)*2) / bps) + 1; /* find max root dir entries */ if (nsect < 0x5000L) maxdent = NUMEN; else maxdent = nsect / 80; maxdent = (maxdent + (bps/BPDIR -1)) & ~(bps/BPDIR -1); /* find max root dir size */ maxdsiz = (maxdent * BPDIR) / bps + 1; if (pno > 3) { /* they are extended partitions */ /*-------------------------------------------------------* * Biggest possible header for a extended partition * = Root sector + Boot Sector + 2 FATs + Root Dir *-------------------------------------------------------*/ /* convert it back to 512 bps size */ hdrsiz = 1 + ratio + ((maxfsiz * 2) + maxdsiz) * ratio; } else /*-------------------------------------------------------* * Biggest possible header for a partition * * = Boot Sector + 2 FATs + Root Dir * *-------------------------------------------------------*/ /* convert it back to 512 bps size */ hdrsiz = (1 + (maxfsiz * 2) + maxdsiz) * ratio; /*-----------------------------------------------------------------* * Look for a chunk of sectors starting at "start" (or after, but * * as close as possible) which is big enough to hold the biggest * * possible header. * *-----------------------------------------------------------------*/ done = 0; /* assume correct location not found yet */ moved = 0; while (!done) { /*----------------------------------------------------------* * Find out if header contains any bad sectors by checking * * range of sectors to be occupied by the header against * * the BSL. * *----------------------------------------------------------*/ for (curr = 0; curr < hdrsiz; curr++) { if (srchbsl(start+curr, entries) == YES) break; } if (curr < hdrsiz) { /* bad sector found in header */ /* move header to start after the bad sector */ moved += curr + 1; start += curr + 1; } else { if ((ret = testhdr(pdev, start, hdrsiz)) < 0) return ERROR; if (ret) { /* some bad sectors found in header */ entries = nument(MEDIA); sortbsl(entries); } else { /* all sectors belong ot header are good */ done = 1; } } } if (moved) { /* header has been moved */ /*-------------------------------------------------------* * Expand previous partition (except if the current one * * is partition 0, then there is no previous partition), * * and enforce maximum partition size on it. * *-------------------------------------------------------*/ if (ratio > 1) { /* big sector */ start -= moved; moved = stbigsect(moved); start += moved; } if (pno > 0) { if (part[pno-1].p_siz + moved > disksiz) part[pno-1].p_siz = disksiz; else part[pno-1].p_siz += moved; } /* Shrink size of current partition */ part[pno].p_siz -= moved; } /* Where current partition should start */ part[pno].p_st = start; /* add the waist sectors of big partition to the next partition */ /* partition #3 in the pinfo is the last partition */ /* partition # npart-1 in the pinfo is the last partition in the extended partition */ if ((pno != 3) && (pno != npart - 1) && (part[pno].p_siz >= MB16)) { /* big partition */ temsect = part[pno].p_siz; if (pno > 3) { /* extended big partition */ part[pno].p_siz = ROOTSECT + bigsect(part[pno].p_siz-ROOTSECT); } else { /* prime big partition */ part[pno].p_siz = bigsect(part[pno].p_siz); } remain = temsect - part[pno].p_siz; if (remain) { part[pno+1].p_siz += remain; part[pno+1].p_st -= remain; } } } /* last existing partition has to sacrifice some space for the BSL */ /* and the root sector of device. */ if ((ext == 3) || ((!(part[2].p_flg & P_EXISTS)) && (!(part[3].p_flg & P_EXISTS)))) { /* the last partition is inside the extended partitions */ step = npart; /* the total extended partition should not inculde the bad sector */ /* list and root sector */ part[ext].p_siz -= (currbsiz + 1); } else { /* the last partition is in the prime partitions */ step = NPARTS; } for (pno = step-1; pno >= 0; pno--) { if (part[pno].p_flg & P_EXISTS) { part[pno].p_siz -= (currbsiz + 1); break; } } /* have to move partitions (existing or not) which start right after the BSL if BSL has been expanded */ if (bslsiz > currbsiz) { /* BSL becomes bigger? */ for (pno = 0; pno < NPARTS; pno++) { if (part[pno].p_st == currbsiz + 1) { part[pno].p_st = bslsiz + 1; if (part[pno].p_siz > 0) part[pno].p_siz -= (bslsiz - currbsiz); } } } return OK; /* everything is fine */ } long stbigsect(amt) long amt; { long numsect; if (ratio > 1) { numsect = (amt % ratio) ? (amt / ratio + 1) : (amt /ratio); return(numsect * ratio); } else { return(amt); } } long bigsect(amt) long amt; { if (ratio > 1) { return((amt / ratio) * ratio); } else { return(amt); } } /* * Given size of a hard disk, figure out * the partition scheme ID to look for. * ID is 2 or more characters long. */ figprid(hdsiz, pr_id) long hdsiz; char pr_id[]; { UWORD mega, over; char numbuf[10]; /* Round off disk size in megabytes */ mega = hdsiz / MEGABYTE; /* Round off disk size to nearest 10Mb */ /* over = mega % 10; if (over >= 5) mega += (10 - over); else mega -= over; */ itoa(mega, numbuf); strcpy(pr_id, numbuf); } /* * Check if partition scheme selected is _legal_. * _Legal_ means the scheme does not map to non-existing memory. * If it is not, prompt user to pick partition again. * Input: * pdev - physical unit we're trying to partition. * xpinfo - partition block user selected. * Return: * OK - if partition scheme is _legal_. * ERROR - if partition scheme is illegal. */ chkpart(pdev, xpinfo) int pdev; PART *xpinfo; { char bs[512]; SECTOR totsiz; int i, ret; /* Get partition information from disk's root block.*/ if ((ret = getroot(pdev, bs, (SECTOR)0)) != 0) { if (tsterr(ret) != OK) err(rootread); return (1); /* return error but it is not a size too big */ } disksiz = ((RSECT *)(bs + 0x200 - sizeof(RSECT)))->hd_siz; totsiz = 0; for (i = 0; i < NPARTS; i++) { if (xpinfo[i].p_flg & P_EXISTS) { totsiz += xpinfo[i].p_siz; } if (totsiz > disksiz) return ERROR; /* size too big */ } return OK; } ckcpkp(xpinfo, test) PART *xpinfo; int test; { int i, j, k=0, num, cnbedone; SAVEPART tmp[MAXPART+3]; for (i=0; i < npart; i++) { kporder[i] = 0; tmp[i].saveflg = savepart[i].saveflg; tmp[i].savest = savepart[i].savest; tmp[i].savend = savepart[i].savend; } if(!(num = ckhaskp(npart)))/* check how many kept partitions */ return OK; /* yes, there is no kept partition */ mknew(xpinfo, test); while(num) { cnbedone = TRUE; for(i=0; i < npart; i++) { if ((newpart[i].n_done) || (!newpart[i].n_end)) continue; for(j=0; j < npart; j++) { if ((j == i) || (!tmp[j].saveflg)) continue; if ((newpart[i].n_st <= tmp[j].savest) && (newpart[i].n_end > tmp[j].savest)) { break; } if ((newpart[i].n_st > tmp[j].savest) && (newpart[i].n_end <= tmp[j].savend)) { break; } if ((newpart[i].n_st > tmp[j].savest) && (newpart[i].n_st < tmp[j].savend)) { break; } } if (j == npart) { num--; newpart[i].n_done = 1; kporder[k] = i; k++; tmp[i].saveflg = 0; cnbedone = FALSE; } } if (cnbedone) /* can't be dont */ return ERROR; } return OK; } /* check the 'savepart' structure and see if there is any kept partition, */ /* return 0: no kept partition, 1: only one, x: x kept partition */ ckhaskp(n) int n; { int i, num=0; for (i=0; i < n; i++) { if (savepart[i].saveflg) num++; } return num; } /* construct the 'oldpart' structure from the 'savepart' structure */ mkold(n, xpinfo) int n; PART *xpinfo; { int i, j, index, num=0; long tmpnm; SAVEPART tmp[MAXPART+3]; /* initial the oldpart structure */ for (i=0; i < n; i++) { oldpart[i].o_st = 0; oldpart[i].o_end = 0; oldpart[i].o_done = 0; } for (i=0; i < n; i++) { /* cp the structure info into the tmp one */ tmp[i].savest = savepart[i].savest; tmp[i].savend = savepart[i].savend; tmp[i].saveflg = savepart[i].saveflg; } for (i=0; i < n; i++) { index = -1; tmpnm = 0x7fffffff; for (j=0; j < n; j++) { if (!tmp[j].saveflg) continue; if (tmp[j].savest < tmpnm) { tmpnm = tmp[j].savest; index = j; } } if (index != -1) { /* there is a small number */ tmp[index].saveflg = 0; oldpart[i].o_st = tmpnm; oldpart[i].o_end = tmp[index].savend; num++; } } } /* copy the kept partitions in the new partition structure into */ /* the 'newpart' */ mknew(xpinfo, test) PART *xpinfo; int test; { int i, j; PART tmp[MAXPART+3]; /* initial the newpart structure */ for (i=0; i < npart; i++) { newpart[i].n_st = 0; newpart[i].n_end = 0; newpart[i].n_done = 0; } for (i=0; i < npart; i++) { if (!xpinfo[i].p_flg) break; tmp[i].p_flg = xpinfo[i].p_flg; tmp[i].p_st = xpinfo[i].p_st; tmp[i].p_siz = xpinfo[i].p_siz; } if (test) { tmp[0].p_st = 2L; for (i=1; i < npart; i++) { /* make up the start field */ if (i == 4) { tmp[4].p_st = tmp[ext].p_st; } else { tmp[i].p_st = tmp[i-1].p_st + tmp[i-1].p_siz; } } } for (i=0; i < npart; i++) { if (savepart[i].saveflg) { newpart[i].n_st = tmp[i].p_st; newpart[i].n_end = tmp[i].p_st + tmp[i].p_siz; } } } /* copy the keeped partition to the new partition skim */ docpkeep(dev, part) int dev; PART *part; { int num, i=0, j; /* check are there more then two kept partitions */ if(!(num = ckhaskp(npart))) return OK; /* yes, there is no kept partition */ if (ckcpkp(part, 0) != OK) /* 1: test, 0: for real */ return ERROR; while (num) { j = kporder[i++]; /* calculate the new header size of the keep partition */ if (calhdr(dev, 1, j, part[j].p_siz) != OK) return ERROR; /* calculate the old header size of the keep partition */ if (calhdr(dev, 0, j, savepart[j].savend - savepart[j].savest) != OK) return ERROR; if (cpkeep(dev, j, part[j].p_st) != OK) return ERROR; num--; } return OK; } calhdr(dev, new, pnum, psiz) int dev; int new; /* flag. 1: calculate the new partition header*/ /* 0: calculate the previous header*/ int pnum; /* partition number */ long psiz; /* partition size */ { /* Maximum sizes for FAT, root directory and header */ long maxdent; /* max num entries in root dir */ UWORD maxfsiz, maxdsiz, hdrsiz; int spc; /* sectors per cluster */ int ret, oldext=0; long nsect; long cell(); long ratio, bps; char bs[512]; PART *tmpart; if (!new) { /* it is a kept partition */ if ((ret = getroot(dev, bs, savepart[pnum].savest)) != 0) { if (tsterr(ret) != OK) err(rootread); return ERROR; } tmpart = &((RSECT *)(bs + 0x200 - sizeof(RSECT)))->hd_p[0]; /* p_id in the first scheme only can be GEM or XGM. So, if stored in*/ /* the sector of stsrc and p_id is XGM, we know it is a ext part.*/ if ((tmpart->p_id[0] == 'G' || tmpart->p_id[0] == 'X') && (tmpart->p_id[2] == 'M')) { psiz -= ROOTSECT; oldext = 1; } } else { if (pnum > 3) { psiz -= ROOTSECT; } } /* estimate the bps */ /* MAXSECT = 16MB - 8 */ bps = cell((psiz-7)*BPS, (long)MAXSECT); /* the real pbs */ bps = BPS * n2power((UWORD)cell(bps, (long)BPS)); ratio = bps / BPS; nsect = psiz / ratio; /* Detail of calculations in part.c dopart() */ /* find max FAT size. FAT16: 16 bits fat; FAT12: 12bits fat */ maxfsiz = ((((nsect / SPC) + 2)*2) / bps) + 1; /* find max root dir entries */ if (nsect < 0x5000L) maxdent = NUMEN; else maxdent = nsect / 80; maxdent = (maxdent + (bps/BPDIR -1)) & ~(bps/BPDIR -1); /* find max root dir size */ maxdsiz = (maxdent * BPDIR) / bps + 1; if (((pnum > 3) && (new)) || (oldext)) { /* they are ext partitions */ /*-------------------------------------------------------* * Biggest possible header for a extended partition * = Root sector + Boot Sector + 2 FATs + Root Dir *-------------------------------------------------------*/ /* convert it back to 512 bps size */ hdrsiz = 1 + ratio + ((maxfsiz * 2) + maxdsiz) * ratio; } else /*-------------------------------------------------------* * Biggest possible header for a partition * * = Boot Sector + 2 FATs + Root Dir * *-------------------------------------------------------*/ /* convert it back to 512 bps size */ hdrsiz = (1 + (maxfsiz * 2) + maxdsiz) * ratio; if (new) { newhdr[pnum].fatsize = maxfsiz * ratio; newhdr[pnum].dirsize = maxdsiz * ratio; } else { prvhdr[pnum].fatsiz = maxfsiz * ratio; prvhdr[pnum].dirsiz = maxdsiz * ratio; } return OK; /* everything is fine */ } /* copy one keeped partition to the ith partition in the new skim */ cpkeep(dev, n, stdes) int dev, n; long stdes; { char *buf, bs[512]; PART *tmpart; int ret; long stsrc, endsrc, siz; long siz1, siz2; siz = (long )Malloc(-1L); if ((siz/512L) > MAXBUFSECT) /* the max sects for the rdsects is 254 */ siz = MAXBUFSECT * 512; if ((buf = (char *)Malloc(siz)) <=0) { err(nomemory); ret = NOMEM; goto cpjj; } stsrc = savepart[n].savest; endsrc = savepart[n].savend; siz /= 512L; /* there are four cases for the copy. 1.ext to ext which need no further */ /* attention. 2. ext to reqular which copy start from the bs to stdes. */ /* 3. req to req which need no further attention. 4. req to ext which */ /* copy start from stsrc to the (stdes - rootsect). */ if ((ret = getroot(dev, bs, stsrc)) != 0) { if (tsterr(ret) != OK) err(rootread); goto cpjj; } tmpart = &((RSECT *)(bs + 0x200 - sizeof(RSECT)))->hd_p[0]; /* p_id in the first scheme only can be GEM or XGM. So, if stored in */ /* the sector of stsrc and p_id is one of them, we know it is a ext part.*/ if ((tmpart->p_id[0] == 'G' || tmpart->p_id[0] == 'X') && (tmpart->p_id[2] == 'M')) { if ((ext != NO_EXT) && (n > 3)) { ; /* it is ext to ext case, which do nothing */ } else { /* it is the ext to req case */ stsrc += 1; } } else { if ((ext != NO_EXT) && (n >3)) { stdes += 1; /* it is the req to ext case */ } /* else it is the req to req case, do nothing */ } if (prvhdr[n].fatsiz == newhdr[n].fatsize) { /* the kept partition had not size increase, so do */ /* copy the data only */ if (stsrc > stdes) { /* copy the data from begining to ending */ if ((ret = fcpsects(dev, stsrc, stdes, endsrc, buf, siz)) != 0) { if (tsterr(ret) == OK) { ret = ERROR; } } } else { /* copy the back way */ if ((ret = cpsects(dev, stsrc, stdes, endsrc, buf, siz)) != 0) { if (tsterr(ret) == OK) { ret = ERROR; } } } goto cpjj; } if (stsrc > stdes) { /* copy the data from beginning to ending */ ret = fcpkeep(dev, n, stsrc, stdes, endsrc, buf, siz); } else { /* copy the date from the ending to beginning */ ret = bcpkeep(dev, n, stsrc, stdes, endsrc, buf, siz); } cpjj: if (buf > 0) Mfree((long)buf); if (ret < 0) return ret; return OK; } /* copy the whole partition in the forward way */ fcpkeep(dev, n, stsrc, stdes, endsrc, buf, siz) int dev, n; long stsrc, stdes, endsrc; char *buf; long siz; { long siz1, siz2; int ret; /* copy the FAT1 */ if ((ret = fcpfats(dev, n, stsrc, stdes, buf, siz)) != 0) { if (tsterr(ret) == OK) { return ERROR; } } /* copy the directory */ if ((ret = fcpdir(dev, n, stsrc, stdes, buf, siz)) != 0) { if (tsterr(ret) == OK) { return ERROR; } } /* copy the data */ siz1 = stsrc + 1 + 2 * prvhdr[n].fatsiz + prvhdr[n].dirsiz; siz2 = stdes + 1 + 2 * newhdr[n].fatsize + newhdr[n].dirsize; if ((ret =fcpsects(dev, siz1, siz2, endsrc, buf, siz)) != 0) { if (tsterr(ret) == OK) { return ERROR; } } return OK; } /* copy the whole partition backward */ bcpkeep(dev, n, stsrc, stdes, endsrc, buf, siz) int dev, n; long stsrc, stdes, endsrc; char *buf; long siz; { long siz1, siz2; int ret; /* copy the data */ siz1 = stsrc + 1 + 2 * prvhdr[n].fatsiz + prvhdr[n].dirsiz; siz2 = stdes + 1 + 2 * newhdr[n].fatsize + newhdr[n].dirsize; if ((ret = cpsects(dev, siz1, siz2, endsrc, buf, siz)) != 0) { if (tsterr(ret) == OK) { return ERROR; } } /* copy the directory */ if ((ret = cpdir(dev, n, stsrc, stdes, buf, siz)) != 0) { if (tsterr(ret) == OK) { return ERROR; } } /* copy the FAT1 */ if ((ret = cpfats(dev, n, stsrc, stdes, buf, siz)) != 0) { if (tsterr(ret) == OK) { return ERROR; } } return OK; } /* copy the two fats into the new partition */ cpfats(dev, n, stsrc, stdes, buf, siz) int dev; int n; long stsrc; long stdes; char *buf; long siz; { int ret, fat1=1; long endsrc, tmpstsrc, tmpstdes , enddes; /* copy the fat2 first */ tmpstsrc = 1 + stsrc + prvhdr[n].fatsiz;/* 1 sector is for the boot sect */ tmpstdes = 1 + stdes + newhdr[n].fatsize; endsrc = tmpstsrc + prvhdr[n].fatsiz; enddes = tmpstdes + prvhdr[n].fatsiz; cpfat: while (endsrc != tmpstsrc) { if ((endsrc - siz) < tmpstsrc) siz = endsrc - tmpstsrc; if ((ret = rdsects(dev,(UWORD)siz, buf, endsrc-siz)) != 0) { if (tsterr(ret) == OK) { return(ERROR); } } if ((ret = wrsects(dev,(UWORD)siz, buf, enddes-siz)) != 0) { if (tsterr(ret) == OK) { return(ERROR); } } endsrc -= siz; enddes -= siz; } if (prvhdr[n].fatsiz != newhdr[n].fatsize) { zerosect(dev, tmpstdes + prvhdr[n].fatsiz, newhdr[n].fatsize - prvhdr[n].fatsiz); } if (fat1) { fat1 = 0; tmpstdes = stdes + 1; tmpstsrc = stsrc + 1; endsrc = tmpstsrc + prvhdr[n].fatsiz; enddes = tmpstdes + prvhdr[n].fatsiz; goto cpfat; } return(OK); } /* copy the directory into the new partition */ cpdir(dev, n, stsrc, stdes, buf, siz) int dev; int n; long stsrc; long stdes; char *buf; long siz; { int ret; long endsrc; long enddes; stsrc = 1 + stsrc + 2 * prvhdr[n].fatsiz;/* 1 sector is for the boot sect */ endsrc = stsrc + prvhdr[n].dirsiz; /* 1 sector is for the boot sect */ stdes = 1 + stdes + 2 * newhdr[n].fatsize; enddes = stdes + endsrc - stsrc; while (endsrc != stsrc) { if ((endsrc - siz) < stsrc) siz = endsrc - stsrc; if ((ret = rdsects(dev,(UWORD)siz, buf, endsrc-siz)) != 0) { if (tsterr(ret) == OK) { return(ERROR); } } if ((ret = wrsects(dev,(UWORD)siz, buf, enddes-siz)) != 0) { if (tsterr(ret) == OK) { return(ERROR); } } endsrc -= siz; enddes -= siz; } if ((ret = (newhdr[n].dirsize - prvhdr[n].dirsiz))) { /* directory size is not same */ zerosect(dev, stdes+prvhdr[n].dirsiz, ret); } return(OK); } /* do the copy for the header from the previous partition to the new one */ /* read backward for the reason of not overwrite the old data */ cpsects(dev, stsrc, stdes, endsrc, buf, siz) int dev; long stsrc; long stdes; long endsrc; char *buf; long siz; { int ret; long enddes; enddes = stdes + endsrc - stsrc; while (endsrc != stsrc) { if ((endsrc - siz) < stsrc) siz = endsrc - stsrc; if ((ret = rdsects(dev,(UWORD)siz, buf, endsrc-siz)) != 0) { if (tsterr(ret) == OK) { return(ERROR); } } if ((ret = wrsects(dev,(UWORD)siz, buf, enddes-siz)) != 0) { if (tsterr(ret) == OK) { return(ERROR); } } endsrc -= siz; enddes -= siz; } return(OK); } /* copy the two fats into the new partition */ fcpfats(dev, n, stsrc, stdes, buf, siz) int dev; int n; long stsrc; long stdes; char *buf; long siz; { int ret, fat2=1; long endsrc, tmpstsrc, tmpstdes ; tmpstdes = stdes + 1; /* 1 sector is for the boot sect */ tmpstsrc = stsrc + 1; endsrc = tmpstsrc + prvhdr[n].fatsiz; /* 1 sector is for the boot sect */ cpfat: while (tmpstsrc != endsrc) { if ((tmpstsrc + siz) > endsrc) siz = endsrc - tmpstsrc; if ((ret = rdsects(dev,(UWORD)siz, buf, tmpstsrc)) != 0) { if (tsterr(ret) == OK) { return(ERROR); } } if ((ret = wrsects(dev,(UWORD)siz, buf, tmpstdes)) != 0) { if (tsterr(ret) == OK) { return(ERROR); } } tmpstsrc += siz; tmpstdes += siz; } zerosect(dev, tmpstdes, newhdr[n].fatsize - prvhdr[n].fatsiz); if (fat2) { fat2 = 0; tmpstsrc = 1 + stsrc + prvhdr[n].fatsiz; tmpstdes = 1 + stdes + newhdr[n].fatsize; endsrc = tmpstsrc + prvhdr[n].fatsiz; goto cpfat; } return(OK); } /* copy the directory into the new partition */ fcpdir(dev, n, stsrc, stdes, buf, siz) int dev; int n; long stsrc; long stdes; char *buf; long siz; { int ret; long endsrc; stsrc = 1 + stsrc + 2 * prvhdr[n].fatsiz;/* 1 sector is for the boot sect */ endsrc = stsrc + prvhdr[n].dirsiz; /* 1 sector is for the boot sect */ stdes = 1 + stdes + 2 * newhdr[n].fatsize; while (stsrc != endsrc) { if ((stsrc + siz) > endsrc) siz = endsrc - stsrc; if ((ret = rdsects(dev,(UWORD)siz, buf, stsrc)) != 0) { if (tsterr(ret) == OK) { return(ERROR); } } if ((ret = wrsects(dev,(UWORD)siz, buf, stdes)) != 0) { if (tsterr(ret) == OK) { return(ERROR); } } stsrc += siz; stdes += siz; } if ((ret = (newhdr[n].dirsize - prvhdr[n].dirsiz))) { /* directory size is not same */ zerosect(dev, stdes, ret); } return(OK); } /* do the copy for the header from the previous partition to the new one */ fcpsects(dev, stsrc, stdes, endsrc, buf, siz) int dev; long stsrc; long stdes; long endsrc; char *buf; long siz; { int ret; while (stsrc != endsrc) { if ((stsrc + siz) > endsrc) siz = endsrc - stsrc; if ((ret = rdsects(dev,(UWORD)siz, buf, stsrc)) != 0) { if (tsterr(ret) == OK) { return(ERROR); } } if ((ret = wrsects(dev,(UWORD)siz, buf, stdes)) != 0) { if (tsterr(ret) == OK) { return(ERROR); } } stsrc += siz; stdes += siz; } return(OK); } /* * Make sure that sectors assigned to a partition header are GOOD. * Input: * pdev - physical device number partition belongs to. * start - starting (physical) sector number header starts. * hdrsiz - number of sectors header occupies. * Return: * OK - if all sectors in header are good. * positive number - if entries are added to BSL in testing * the header. * ERROR - if somewhere the process went wrong. * Comments: * Bad Sectors found are added as USER bad sectors. * First, because we can't expand the VENDOR list while preserving * the USER list. Second, this is ok, because even if the USER list * is full, the user should reformat the disk anyway, and if the * sector is REALLY bad, it would be discovered again then. * * jye: deleted the writting checking for the bad sectors for the * reason of added the function of keeping the old partition in the * new partition scheme. */ testhdr(pdev, start, hdrsiz) int pdev; SECTOR start; UWORD hdrsiz; { long size, pattern; extern long longrandom(); extern int tformat; /* flag */ UWORD sectcnt, list; int ret, nbad, clean=1; SECTOR sect; char *buf; /* buffer with test data */ size = (long)hdrsiz << 9; if ((buf = (char *)Malloc(size)) <= 0) { err(nomemory); ret = NOMEM; goto wrapup; } /* * Try to write to header's sectors. */ pattern = longrandom(); fillbuf(buf, size, pattern); sectcnt = hdrsiz; sect = start; nbad = 0; /* Omited this checking, for the reason of this kind of checks will erase the data in the hard disk if ((ret = wrsects(pdev, sectcnt, buf, sect)) != 0) { if (tsterr(ret) == OK) { ret = ERROR; goto wrapup; } clean = 0; while (sectcnt) { find out which sector is indeed bad if ((ret = wrsects(pdev, 1, 0L, sect)) != 0) { if (tsterr(ret) == OK) { ret = ERROR; goto wrapup; } if (sect < 3) { ret = err(rsrvbad); goto wrapup; } badbuf[nbad++] = sect; store bad sector num buffer is filled up, have to add bad sectors found so far to the BSL before continuing. if (nbad == WARNBADSECTS) { Decide which list to add to if (tformat == TRUE) list = VENDOR; else list = USER; if ((ret=addbsl(pdev, list, nbad)) < 0) { ret = err(rsrvbad); goto wrapup; } nbad = 0; start counting again } } sect++; sectcnt--; } if (nbad) { there are bad sectors found not added to BSL yet Decide which list to add to if (tformat == TRUE) list = VENDOR; else list = USER; if ((ret = addbsl(pdev, list, nbad)) < 0) { ret = ERROR; goto wrapup; } nbad = 0; } } */ /* Try to read header's sectors */ sectcnt = hdrsiz; sect = start; nbad = 0; if ((ret = rdsects(pdev, sectcnt, buf, sect)) != 0) { if (tsterr(ret) == OK) { ret = ERROR; goto wrapup; } clean = 0; while (sectcnt) { /* find out which sector is indeed bad */ if ((ret = rdsects(pdev, 1, buf, sect)) != 0) { if (tsterr(ret) == OK) { ret = ERROR; goto wrapup; } if (sect < 3) { ret = err(rsrvbad); goto wrapup; } badbuf[nbad++] = sect; /* store bad sector num */ /* buffer is filled up, have to add bad sectors found so far to the BSL before continuing. */ if (nbad == WARNBADSECTS) { /* Decide which list to add to */ if (tformat == TRUE) list = VENDOR; else list = USER; if ((ret = addbsl(pdev, list, nbad)) < 0) { ret = ERROR; goto wrapup; } nbad = 0; /* start counting again */ } } sect++; sectcnt--; } if (nbad) { /* there are bad sectors found not added to BSL yet */ /* Decide which list to add to */ if (tformat == TRUE) list = VENDOR; else list = USER; if ((ret = addbsl(pdev, list, nbad)) < 0) { ret = ERROR; goto wrapup; } nbad = 0; } } wrapup: if (buf > 0) Mfree((long)buf); if (ret < 0) return ret; if (!clean) { /* write new bsl back to disk */ if (wrbsl(pdev) != OK) { return ERROR; } return 1; } return OK; } long cell(top, bottom) long top; long bottom; { return ((top % bottom) ? (top / bottom + 1) : (top / bottom)); } n2power(num) UWORD num; { UWORD power = 1; for (;;) { if (num <= power ) { return (power); } power <<= 1; } } DPART *addr(index) int index; { DPART *temptr; int i; if (index < 0) return nill; if (!index) return (headptr); temptr = headptr->next; for (i = 1; i < index; i++) { temptr = temptr->next; } return (temptr); } DPART *last() { DPART *temptr; int i; if (!headptr) return (headptr); temptr = headptr; while (temptr->next) temptr = temptr->next; return (temptr); } creatmem(num) int num; /* number of block to malloc */ { DPART *temptr; DPART *last(); int i; if (headptr == nill) { if ((headptr = (DPART *)mymalloc((int)sizeof(DPART))) <= 0) {; err(nomemory); if (headptr > 0) free(headptr); return ERROR; } headptr->next = nill; headptr->siz = 0L; headptr->flg = 0; } temptr = last(); for (i = 0; i < num; i++) { if ((temptr->next = (DPART *)mymalloc((int)sizeof(DPART))) <= 0) { err(nomemory); if (headptr > 0) free(headptr); return ERROR; } temptr = temptr->next; temptr->next = nill; temptr->siz = 0L; temptr->flg = 0; } } dpart2part(extpart) int extpart ; /* set the extended pointer in the 4th place */ { int i; DPART *temptr; /* if npart > 4; need 1 more space for the extended partition */ if (npart > 4) { npart += NPARTS-extpart; /*add 1 extra space for the extended */ /*partition and 0 or 1 or 2 space for the*/ /*prime partition in the root move 2 space*/ extend += NPARTS - extpart; /*space for 2 prime partition in the root.*/ } else { /* set the extpart to -1 */ npart = 4; extpart = -1; ext = NO_EXT; } if ((pinfo = (PART *)Malloc((long)sizeof(PART)*npart)) <= 0) { err(nomemory); if (pinfo > 0) Mfree(pinfo); free(headptr); return ERROR; } inipart(pinfo, npart); temptr = headptr; for (i = 0; i < npart; i++) { if (!(temptr->flg & P_EXISTS)) { if (sizleft > 0) { if (temptr->siz > sizleft) { pinfo[i].p_siz = sizleft; } sizleft -= temptr->siz; } } else { pinfo[i].p_siz = temptr->siz; pinfo[i].p_flg = P_EXISTS; if (i == extpart) { pinfo[i].p_id[0] = 'X'; pinfo[i].p_id[1] = 'G'; pinfo[i].p_id[2] = 'M'; pinfo[i].p_siz = 0L; } else if ((extpart == 1) && ((i == 2) || (i==3))) { pinfo[i].p_flg = 0; pinfo[i].p_siz = 0L; } else if ((extpart == 2) && (i==3)) { pinfo[i].p_flg = 0; pinfo[i].p_siz = 0L; } else if (temptr->siz < MB16) { pinfo[i].p_id[0] = 'G'; pinfo[i].p_id[1] = 'E'; pinfo[i].p_id[2] = 'M'; temptr = temptr->next; } else { pinfo[i].p_id[0] = 'B'; pinfo[i].p_id[1] = 'G'; pinfo[i].p_id[2] = 'M'; temptr = temptr->next; } } } free(headptr); if (extpart != NO_EXT) { mvkeep(ext); asmpart(extpart); } return OK; } /* move the keep partition dates according to the extened partition scheme*/ mvkeep(ext) int ext; { /* the structure for the keeping partitions */ SAVEPART tmpsave[MAXPART+3]; /* +3 is for the extened partition */ int i, j, tmp, np; tmp = MAXPART + 3; for (i=0; i < tmp; i++) tmpsave[i].saveflg = 0; for (i=ext, j=4; i < npart; i++, j++) { if (savepart[i].saveflg & P_EXISTS) { tmpsave[j].saveflg = P_EXISTS; tmpsave[j].savest = savepart[i].savest; tmpsave[j].savend = savepart[i].savend; savepart[i].saveflg = 0; /* clean it */ } } if (ext == 3) { /* do nothing */ ; } else { /* copy back the rest the prime partitions */ if (tmpsave[extend].saveflg) { /* extend point to 1st prime part */ savepart[ext+1].saveflg = P_EXISTS; savepart[ext+1].savest = tmpsave[extend].savest; savepart[ext+1].savend = tmpsave[extend].savend; tmpsave[extend].saveflg = 0; /* clean it */ } if ((ext == 1) && (tmpsave[extend+1].saveflg)) { savepart[3].saveflg = P_EXISTS; savepart[3].savest = tmpsave[extend+1].savest; savepart[3].savend = tmpsave[extend+1].savend; tmpsave[extend+1].saveflg = 0; /* clean it */ } } /* copy the dates back to the savepart */ for (i=4; i < extend; i++) { if (tmpsave[i].saveflg & P_EXISTS) { savepart[i].saveflg = P_EXISTS; savepart[i].savest = tmpsave[i].savest; savepart[i].savend = tmpsave[i].savend; } } } /* put the information into the extened partition pointer and the */ /* prime partition after the extend partition */ asmpart(extpart) int extpart ; /* the extended partition pointer */ { int i; /* # of extened partition to add up */ for (i = 4; i < extend; i++) { pinfo[extpart].p_siz += pinfo[i].p_siz; } if (extpart == 3) { return OK; /* done */ } else { /* put the last (npart-extend-1) partitions to */ /* the 3rd or 4th place as prime partitions */ i = extend; if (i < npart) { pinfo[extpart+1].p_siz = pinfo[i].p_siz; pinfo[extpart+1].p_flg = P_EXISTS; if (pinfo[extpart+1].p_siz < MB16) { pinfo[extpart+1].p_id[0] = 'G'; pinfo[extpart+1].p_id[1] = 'E'; pinfo[extpart+1].p_id[2] = 'M'; } else { pinfo[extpart+1].p_id[0] = 'B'; pinfo[extpart+1].p_id[1] = 'G'; pinfo[extpart+1].p_id[2] = 'M'; } pinfo[i].p_flg = 0; pinfo[i].p_siz = 0L; pinfo[i].p_id[0] = '0'; pinfo[i].p_id[1] = '0'; pinfo[i].p_id[2] = '0'; npart--; } if (i++ < npart) { pinfo[extpart+2].p_siz = pinfo[i].p_siz; pinfo[extpart+2].p_flg = P_EXISTS; if (pinfo[extpart+2].p_siz < MB16) { pinfo[extpart+2].p_id[0] = 'G'; pinfo[extpart+2].p_id[1] = 'E'; pinfo[extpart+2].p_id[2] = 'M'; } else { pinfo[extpart+2].p_id[0] = 'B'; pinfo[extpart+2].p_id[1] = 'G'; pinfo[extpart+2].p_id[2] = 'M'; } pinfo[i].p_flg = 0; pinfo[i].p_siz = 0L; pinfo[i].p_id[0] = '0'; pinfo[i].p_id[1] = '0'; pinfo[i].p_id[2] = '0'; npart--; } } } part2dpart(numpart) int numpart; { int i; DPART *temptr; headptr = nill; if (creatmem(numpart) == ERROR) { return ERROR; } temptr = headptr; for (i = 0; i < numpart; i++) { if (pinfo[i].p_flg & P_EXISTS) { temptr->st = pinfo[i].p_st; temptr->siz = pinfo[i].p_siz; temptr->flg = P_EXISTS; temptr->kpyes = FALSE; } temptr = temptr->next; } }