hschumann2/TempleOS-Source-Code
0847
1 2#help_index "Info;File/Cmd Line (Typically);Cmd Line (Typically)"3Bool ChkDskConfirm(Bool *_fix,Bool *_confirm)4{5 if (*_fix && *_confirm) {6 "Fix ";7 if (!YorN)8 *_fix=FALSE;9 *_confirm=FALSE;10 }11 return *_fix;12}13 14I64 RedSeaChkDskLst(CDrv *dv,CDirEntry *tmpde1,15 U8 *bits,U8 *bits2,I64 size,I64 bpc)16{17 CDirEntry *tmpde2;18 I64 i,j,errs=0;19 while (tmpde1) {20 tmpde2=tmpde1->next;21 if (tmpde1->attr & RS_ATTR_DIR && tmpde1->sub)22 errs+=RedSeaChkDskLst(dv,tmpde1->sub,bits,bits2,size,bpc);23 j=(tmpde1->size+bpc-1)/bpc;24 for (i=0;i<j;i++) {25 if (i+tmpde1->clus-dv->data_area>size) {26 PrintErr("Invalid Clus:%s Clus:%X\n",tmpde1->full_name,27 i+tmpde1->clus);28 errs++;29 break;30 }31 if (LBts(bits,i+tmpde1->clus-dv->data_area)) {32 PrintErr("Dbl Alloc:%s Clus:%X\n",tmpde1->full_name,33 i+tmpde1->clus);34 errs++;35 }36 if (!LBtr(bits2,i+tmpde1->clus-dv->data_area)) {37 PrintErr("UnAlloc:%s Clus:%X\n",tmpde1->full_name,38 i+tmpde1->clus);39 errs++;40 }41 }42 DirEntryDel(tmpde1);43 tmpde1=tmpde2;44 }45 return errs;46}47 48I64 RedSeaChkDsk(U8 drv_let,Bool *_fix,Bool *_confirm)49{50 I64 i,j,bpc,size,errs=0;51 CDrv *dv=Let2Drv(drv_let),*old_dv=Fs->cur_dv;52 U8 *files_find_mask=MStrPrint("%c:/*",Drv2Let(dv)),53 *old_dir=StrNew(Fs->cur_dir),54 *bits,*bits2;55 CDirEntry *ptr,*ptr2;56 57 Drv(drv_let);58 "Scanning...\n";59 size=(dv->size-(dv->data_area-dv->drv_offset))/dv->spc;60 bpc=dv->spc<<BLK_SIZE_BITS;61 bits=CAlloc((size+7)>>3);62 bits2=CAlloc((size+7)>>3+BLK_SIZE);63 BlkRead(dv,bits2,dv->fat1,((size+7)>>3+BLK_SIZE-1)>>BLK_SIZE_BITS);64 65 //Get Root Dir size66 ptr2=MAlloc(bpc);67 BlkRead(dv,ptr2,dv->root_clus,1);68 ptr=ptr2(U8 *)-offset(CDirEntry.start);69 j=(ptr->size+bpc-1)/bpc;70 Free(ptr2);71 72 for (i=0;i<j;i++) {73 if (i+dv->root_clus-dv->data_area>size) {74 PrintErr("Invalid Clus: RootDir Clus:%X\n",i+dv->root_clus);75 errs++;76 break;77 }78 if (LBts(bits,i+dv->root_clus-dv->data_area)) {79 PrintErr("Dbl Alloc: RootDir Clus:%X\n",i+dv->root_clus);80 errs++;81 }82 if (!LBtr(bits2,i+dv->root_clus-dv->data_area)) {83 PrintErr("UnAlloc: RootDir Clus:%X\n",i+dv->root_clus);84 errs++;85 }86 }87 88 errs+=RedSeaChkDskLst(dv,FilesFind(files_find_mask,FUF_RECURSE),89 bits,bits2,size,bpc);90 for (i=1;i<size;i++)91 if (Bt(bits2,i)) {92 PrintWarn("Shouldn't Alloc Clus:%0X\n",i+dv->data_area);93 errs++;94 if (ChkDskConfirm(_fix,_confirm))95 RedSeaFreeClus(dv,i+dv->data_area,1);96 }97 98 Free(files_find_mask);99 Free(bits);100 Free(bits2);101 Drv(Drv2Let(old_dv));102 Cd(old_dir);103 Free(old_dir);104 return errs;105}106 107I64 FAT32ChkDskLst(CDrv *dv,CDirEntry *tmpde1,108 U8 *bits,U32 *bits2,I64 size,I64 bpc)109{110 CDirEntry *tmpde2;111 I64 i,c,errs=0;112 while (tmpde1) {113 tmpde2=tmpde1->next;114 if (tmpde1->attr & RS_ATTR_DIR && tmpde1->sub)115 errs+=FAT32ChkDskLst(dv,tmpde1->sub,bits,bits2,size,bpc);116 i=0;117 c=tmpde1->clus;118 while (0<c<0x0FFFFFF8) {119 if (c>size) {120 PrintErr("Invalid Clus:%s Clus:%X\n",tmpde1->full_name,c);121 errs++;122 break;123 }124 if (LBts(bits,c)) {125 PrintErr("Dbl Alloc:%s Clus:%X\n",tmpde1->full_name,c);126 errs++;127 }128 if (!bits2[c]) {129 PrintErr("UnAlloc:%s Clus:%X\n",tmpde1->full_name,c);130 errs++;131 } else132 bits2[c]=0;133 c=ClusNumNext(dv,c);134 i++;135 }136 if (!(tmpde1->attr & RS_ATTR_DIR)) {137 i*=bpc;138 if (tmpde1->size>i) {139 PrintErr("Alloced File Too Short:%s\n",tmpde1->full_name);140 errs++;141 }142 if (i>tmpde1->size+bpc-1) {143 PrintWarn("Alloced File Too Long:%s\n",tmpde1->full_name);144 errs++;145 }146 }147 DirEntryDel(tmpde1);148 tmpde1=tmpde2;149 }150 return errs;151}152 153I64 FAT32ChkDsk(U8 drv_let,Bool *_fix,Bool *_confirm)154{155 I64 i,bpc,size,c,errs=0;156 CDrv *dv=Let2Drv(drv_let),*old_dv=Fs->cur_dv;157 U8 *files_find_mask=MStrPrint("%c:/*",Drv2Let(dv)),158 *old_dir=StrNew(Fs->cur_dir),159 *bits;160 U32 *bits2;161 Drv(drv_let);162 "Scanning...\n";163 size=(dv->size-(dv->data_area-dv->drv_offset))/dv->spc;164 bpc=dv->spc<<BLK_SIZE_BITS;165 bits=CAlloc((size+7)>>3);166 bits2=CAlloc(size*4+BLK_SIZE);167 BlkRead(dv,bits2,dv->fat1,(size*4+BLK_SIZE-1)>>BLK_SIZE_BITS);168 169 c=dv->root_clus;170 while (0<c<0x0FFFFFF8) {171 if (c>size) {172 PrintErr("Invalid Clus: RootDir Clus:%X\n",c);173 errs++;174 break;175 }176 if (LBts(bits,c)) {177 PrintErr("Dbl Alloc: RootDir Clus:%X\n",c);178 errs++;179 }180 if (!bits2[c]) {181 PrintErr("UnAlloc: RootDir Clus:%X\n",c);182 errs++;183 } else184 bits2[c]=0;185 c=ClusNumNext(dv,c);186 }187 188 errs+=FAT32ChkDskLst(dv,FilesFind(files_find_mask,FUF_RECURSE),189 bits,bits2,size,bpc);190 191 bits2[1]=0; //See FAT32Fmt()192 for (i=1;i<size;i++)193 if (bits2[i]) {194 PrintWarn("Shouldn't Alloc Clus:%0X\n",i);195 errs++;196 if (ChkDskConfirm(_fix,_confirm))197 FAT32FreeClus(dv,i);198 }199 Free(files_find_mask);200 Free(bits);201 Free(bits2);202 Drv(Drv2Let(old_dv));203 Cd(old_dir);204 Free(old_dir);205 return errs;206}207 208public I64 DskChk(U8 drv_let=0,Bool fix=FALSE,Bool confirm=TRUE)209{//Check disk for allocation errors and, optionally, fix.210//You probably want to reformat and reinstall.211 I64 errs=0;212 CDrv *dv=Let2Drv(drv_let);213 switch (dv->fs_type) {214 case FSt_REDSEA:215 errs=RedSeaChkDsk(drv_let,&fix,&confirm);216 break;217 case FSt_FAT32:218 errs=FAT32ChkDsk(drv_let,&fix,&confirm);219 break;220 default:221 PrintErr("File System Not Supported\n");222 }223 if (errs) {224 if (fix)225 "It might be a little better. ";226 "Copy files to another partition or CD/DVD, "227 "reformat, and copy back. "228 "Or, copy from a back-up.\n";229 }230 return errs;231}232 233U0 RedSeaDrvView(U8 drv_let=0)234{235 CDrv *dv=Let2Drv(drv_let);236 I64 lohi,c1,i,x,y,l=(GR_HEIGHT-3*FONT_HEIGHT)*(GR_WIDTH-FONT_WIDTH<<1),237 s=dv->size+dv->drv_offset-dv->data_area;238 U8 *bitmap;239 CDC *dc=DCAlias;240 241 SettingsPush; //See SettingsPush242 WinMax;243 WinBorder(ON);244 DocCursor;245 DocClear;246 DCFill;247 try {248 i=((s+7)>>3+BLK_SIZE-1)>>BLK_SIZE_BITS;249 bitmap=MAlloc(i<<BLK_SIZE_BITS);250 BlkRead(dv,bitmap,dv->fat1,i);251 i=0;252 for (y=0;y<GR_HEIGHT-3*FONT_HEIGHT;y++) {253 if (ScanKey)254 break;255 for (x=0;x<GR_WIDTH-FONT_WIDTH<<1;x++) {256 lohi=i*s;257 c1=lohi/l;258 if (Bt(bitmap,c1))259 dc->color=ROP_XOR+BLUE^TRANSPARENT;260 else261 dc->color=ROP_XOR+WHITE^TRANSPARENT;262 GrPlot(dc,x,y);263 i++;264 }265 }266 Free(bitmap);267 } catch268 DrvUnlock(dv);269 GetChar;270 271 SettingsPop;272 DCFill;273 DCDel(dc);274}275U0 FAT32DrvView(U8 drv_let=0)276{277 CDrv *dv=Let2Drv(drv_let);278 I64 lohi,c1,i,x,y,l=(GR_HEIGHT-3*FONT_HEIGHT)*(GR_WIDTH-FONT_WIDTH<<1),279 s=(dv->size+dv->spc-1)/dv->spc-(2+dv->data_area-dv->drv_offset);280 U32 *bitmap;281 CDC *dc=DCAlias;282 283 SettingsPush; //See SettingsPush284 WinMax;285 WinBorder(ON);286 DocCursor;287 DocClear;288 DCFill;289 try {290 i=(s*4+BLK_SIZE-1)>>BLK_SIZE_BITS;291 bitmap=MAlloc(i<<BLK_SIZE_BITS);292 BlkRead(dv,bitmap,dv->fat1,i);293 i=0;294 for (y=0;y<GR_HEIGHT-3*FONT_HEIGHT;y++) {295 if (ScanKey)296 break;297 for (x=0;x<GR_WIDTH-FONT_WIDTH<<1;x++) {298 lohi=i*s;299 c1=lohi/l;300 if (bitmap[c1])301 dc->color=ROP_XOR+BLUE^TRANSPARENT;302 else303 dc->color=ROP_XOR+WHITE^TRANSPARENT;304 GrPlot(dc,x,y);305 i++;306 }307 }308 Free(bitmap);309 } catch310 DrvUnlock(dv);311 GetChar;312 313 SettingsPop;314 DCFill;315 DCDel(dc);316}317public U0 DrvView(U8 drv_let=0)318{//Drive view. Graph the allocation map's fragmentation.319 CDrv *dv=Let2Drv(drv_let),*old_dv=Fs->cur_dv;320 Drv(drv_let);321 switch (dv->fs_type) {322 case FSt_REDSEA:323 RedSeaDrvView(drv_let);324 break;325 case FSt_FAT32:326 FAT32DrvView(drv_let);327 break;328 default:329 PrintErr("File System Not Supported\n");330 }331 Drv(Drv2Let(old_dv));332}333 334public U0 DskView(U8 drv_let=0)335{//Disk view. Pie chart of partition sizes.336 I64 i,j,attr,337 h=Fs->pix_width,338 v=Fs->pix_height,339 radius;340 CDrv *dv;341 CBlkDev *bd=Let2BlkDev(drv_let);342 CDC *dc=DCAlias;343 F64 sect_start,sect_end;344 345 SettingsPush; //See SettingsPush346 DocCursor;347 DocClear;348 DCFill;349 if (h<v)350 radius=0.4*h;351 else352 radius=0.4*v;353 dc->color=BLACK;354 GrCircle(dc,h>>1,v>>1,radius);355 356 j=1;357 for (i=0;i<DRVS_NUM;i++) {358 dv=&blkdev.drvs[i];359 if (bd==dv->bd && dv->fs_type) {360 sect_start=-(dv->drv_offset*2*pi/(bd->max_blk+1));361 sect_end =-((dv->drv_offset+dv->size)*2*pi/(bd->max_blk+1));362 dc->color=BLACK;363 GrLine(dc,h>>1,v>>1,364 h>>1+radius*Cos(sect_start),365 v>>1+radius*Sin(sect_start));366 GrLine(dc,h>>1,v>>1,367 h>>1+radius*Cos(sect_end),368 v>>1+radius*Sin(sect_end));369 370 attr=DrvTextAttrGet(Drv2Let(dv));371 dc->color=attr&15;372 GrPrint(dc,0,v-FONT_HEIGHT*j,"%C %-8Z",Drv2Let(dv),373 dv->fs_type,"ST_DRV_TYPES");374 dc->color.c1=attr>>4;375 dc->color|=ROPF_DITHER;376 GrFloodFill(dc,377 h>>1+(radius-4)*Cos((sect_start+sect_end)/2),378 v>>1+(radius-4)*Sin((sect_start+sect_end)/2),FALSE);379 j++;380 }381 }382 383 GetChar(,FALSE);384 SettingsPop;385 DCFill;386 DCDel(dc);387}388 389I64 RedSeaUnusedDrvSpace(U8 drv_let=0)390{391 CDrv *dv=Let2Drv(drv_let);392 I64 res=0,i,l;393 U8 *bitmap;394 try {395 l=dv->size+dv->drv_offset-dv->data_area;396 i=((l+7)>>3+BLK_SIZE-1)>>BLK_SIZE_BITS;397 bitmap=MAlloc(i<<BLK_SIZE_BITS);398 BlkRead(dv,bitmap,dv->fat1,i);399 for (i=0;i<l;i++)400 if (!Bt(bitmap,i))401 res++;402 Free(bitmap);403 } catch404 DrvUnlock(dv);405 return res*BLK_SIZE*dv->spc;406}407I64 FAT32UnusedDrvSpace(U8 drv_let=0)408{409 CDrv *dv=Let2Drv(drv_let);410 I64 res=0,i,l;411 U32 *bitmap;412 try {413 l=(dv->size+dv->spc-1)/dv->spc-(2+dv->data_area-dv->drv_offset);414 i=(l*4+BLK_SIZE-1)>>BLK_SIZE_BITS;415 bitmap=MAlloc(i<<BLK_SIZE_BITS);416 BlkRead(dv,bitmap,dv->fat1,i);417 for (i=0;i<l;i++)418 if (!bitmap[i])419 res++;420 Free(bitmap);421 } catch422 DrvUnlock(dv);423 return res*BLK_SIZE*dv->spc;424}425public I64 DrvUnused(U8 drv_let=0)426{//Returns unused size in bytes.427 CDrv *dv=Let2Drv(drv_let),*old_dv=Fs->cur_dv;428 U8 *old_dir=StrNew(Fs->cur_dir);429 I64 res=0;430 Drv(drv_let);431 switch (dv->fs_type) {432 case FSt_REDSEA:433 res=RedSeaUnusedDrvSpace(drv_let);434 break;435 case FSt_FAT32:436 res=FAT32UnusedDrvSpace(drv_let);437 break;438 default:439 PrintErr("File System Not Supported\n");440 }441 Drv(Drv2Let(old_dv));442 Cd(old_dir);443 Free(old_dir);444 return res;445}446 