#help_index "Info;File/Cmd Line (Typically);Cmd Line (Typically)" Bool CheckDiskConfirm(Bool *_fix, Bool *_confirm) { if (*_fix && *_confirm) { "Fix "; if (!YorN) *_fix = FALSE; *_confirm = FALSE; } return *_fix; } I64 RedSeaCheckDiskList(CDrive *drive, CDirEntry *tmpde1, U8 *bits, U8 *bits2, I64 size, I64 bpc) { CDirEntry *tmpde2; I64 i, j, errs = 0; while (tmpde1) { tmpde2 = tmpde1->next; if (tmpde1->attr & RS_ATTR_DIR && tmpde1->sub) errs += RedSeaCheckDiskList(drive, tmpde1->sub, bits, bits2, size, bpc); j = (tmpde1->size + bpc - 1) / bpc; for (i = 0; i < j; i++) { if (i + tmpde1->clus-drive->data_area > size) { PrintErr("Invalid Clus:%s Clus:%X\n", tmpde1->full_name, i + tmpde1->clus); errs++; break; } if (LBts(bits, i + tmpde1->clus-drive->data_area)) { PrintErr("Dbl Alloc:%s Clus:%X\n", tmpde1->full_name, i + tmpde1->clus); errs++; } if (!LBtr(bits2, i + tmpde1->clus-drive->data_area)) { PrintErr("UnAlloc:%s Clus:%X\n", tmpde1->full_name, i + tmpde1->clus); errs++; } } DirEntryDel(tmpde1); tmpde1 = tmpde2; } return errs; } I64 RedSeaCheckDisk(U8 drv_let, Bool *_fix, Bool *_confirm) { I64 i, j, bpc, size, errs = 0; CDrive *drive = Letter2Drive(drv_let), *old_dv = Fs->cur_dv; U8 *files_find_mask = MStrPrint("%c:/*", Drive2Letter(drive)), *old_dir = StrNew(Fs->cur_dir), *bits, *bits2; CDirEntry *ptr,*ptr2; Drive(drv_let); "Scanning...\n"; size = (drive->size - (drive->data_area - drive->drv_offset)) / drive->spc; bpc = drive->spc << BLK_SIZE_BITS; bits = CAlloc((size + 7) >> 3); bits2 = CAlloc((size + 7) >> 3 + BLK_SIZE); BlkRead(drive, bits2, drive->fat1, ((size + 7) >> 3 + BLK_SIZE - 1) >> BLK_SIZE_BITS); //Get Root Dir size ptr2 = MAlloc(bpc); BlkRead(drive, ptr2, drive->root_clus, 1); ptr = ptr2(U8 *) - offset(CDirEntry.start); j = (ptr->size + bpc - 1) / bpc; Free(ptr2); for (i = 0; i < j; i++) { if (i + drive->root_clus - drive->data_area > size) { PrintErr("Invalid Clus: RootDir Clus:%X\n", i + drive->root_clus); errs++; break; } if (LBts(bits, i + drive->root_clus - drive->data_area)) { PrintErr("Dbl Alloc: RootDir Clus:%X\n", i + drive->root_clus); errs++; } if (!LBtr(bits2, i + drive->root_clus - drive->data_area)) { PrintErr("UnAlloc: RootDir Clus:%X\n", i + drive->root_clus); errs++; } } errs += RedSeaCheckDiskList(drive, FilesFind(files_find_mask, FUF_RECURSE), bits, bits2, size, bpc); for (i = 1; i < size; i++) if (Bt(bits2, i)) { PrintWarn("Shouldn't Alloc Clus:%0X\n", i + drive->data_area); errs++; if (CheckDiskConfirm(_fix, _confirm)) RedSeaFreeClus(drive, i + drive->data_area, 1); } Free(files_find_mask); Free(bits); Free(bits2); Drive(Drive2Letter(old_dv)); Cd(old_dir); Free(old_dir); return errs; } I64 FAT32CheckDiskList(CDrive *drive, CDirEntry *tmpde1, U8 *bits, U32 *bits2, I64 size, I64 bpc) { CDirEntry *tmpde2; I64 i, c, errs = 0; while (tmpde1) { tmpde2 = tmpde1->next; if (tmpde1->attr & RS_ATTR_DIR && tmpde1->sub) errs += FAT32CheckDiskList(drive, tmpde1->sub, bits, bits2, size, bpc); i = 0; c = tmpde1->clus; while (0 < c < 0x0FFFFFF8) { if (c > size) { PrintErr("Invalid Clus:%s Clus:%X\n", tmpde1->full_name, c); errs++; break; } if (LBts(bits, c)) { PrintErr("Dbl Alloc:%s Clus:%X\n", tmpde1->full_name, c); errs++; } if (!bits2[c]) { PrintErr("UnAlloc:%s Clus:%X\n", tmpde1->full_name, c); errs++; } else bits2[c] = 0; c = ClusNumNext(drive, c); i++; } if (!(tmpde1->attr & RS_ATTR_DIR)) { i *= bpc; if (tmpde1->size>i) { PrintErr("Alloced File Too Short:%s\n", tmpde1->full_name); errs++; } if (i > tmpde1->size + bpc - 1) { PrintWarn("Alloced File Too Long:%s\n", tmpde1->full_name); errs++; } } DirEntryDel(tmpde1); tmpde1 = tmpde2; } return errs; } I64 FAT32CheckDisk(U8 drv_let, Bool *_fix, Bool *_confirm) { I64 i, bpc, size, c, errs = 0; CDrive *drive = Letter2Drive(drv_let), *old_dv = Fs->cur_dv; U8 *files_find_mask = MStrPrint("%c:/*", Drive2Letter(drive)), *old_dir = StrNew(Fs->cur_dir), *bits; U32 *bits2; Drive(drv_let); "Scanning...\n"; size = (drive->size - (drive->data_area - drive->drv_offset)) / drive->spc; bpc = drive->spc << BLK_SIZE_BITS; bits = CAlloc((size + 7) >> 3); bits2 = CAlloc(size * 4 + BLK_SIZE); BlkRead(drive, bits2, drive->fat1, (size * 4 + BLK_SIZE - 1) >> BLK_SIZE_BITS); c = drive->root_clus; while (0 < c < 0x0FFFFFF8) { if (c > size) { PrintErr("Invalid Clus: RootDir Clus:%X\n", c); errs++; break; } if (LBts(bits, c)) { PrintErr("Dbl Alloc: RootDir Clus:%X\n", c); errs++; } if (!bits2[c]) { PrintErr("UnAlloc: RootDir Clus:%X\n", c); errs++; } else bits2[c] = 0; c = ClusNumNext(drive, c); } errs += FAT32CheckDiskList(drive, FilesFind(files_find_mask, FUF_RECURSE), bits, bits2, size, bpc); bits2[1] = 0; //See FAT32Format() for (i = 1; i < size; i++) if (bits2[i]) { PrintWarn("Shouldn't Alloc Clus:%0X\n", i); errs++; if (CheckDiskConfirm(_fix, _confirm)) FAT32FreeClus(drive, i); } Free(files_find_mask); Free(bits); Free(bits2); Drive(Drive2Letter(old_dv)); Cd(old_dir); Free(old_dir); return errs; } public I64 DiskCheck(U8 drv_let=0, Bool fix=FALSE, Bool confirm=TRUE) {//Check disk for allocation errors and, optionally, fix. //You probably want to reformat and reinstall. I64 errs = 0; CDrive *drive = Letter2Drive(drv_let); switch (drive->fs_type) { case FSt_REDSEA: errs = RedSeaCheckDisk(drv_let, &fix, &confirm); break; case FSt_FAT32: errs = FAT32CheckDisk(drv_let, &fix, &confirm); break; default: PrintErr("File System Not Supported\n"); } if (errs) { if (fix) "It might be a little better. "; "Copy files to another partition or CD/DVD, " "reformat, and copy back. " "Or, copy from a back-up.\n"; } return errs; } U0 RedSeaDriveView(U8 drv_let=0) { CDrive *drive = Letter2Drive(drv_let); I64 lohi, c1, i, x, y, l = (GR_HEIGHT - 3 * FONT_HEIGHT) * (GR_WIDTH - FONT_WIDTH << 1), s = drive->size + drive->drv_offset - drive->data_area; U8 *bitmap; CDC *dc = DCAlias; SettingsPush; //See SettingsPush WinMax; WinBorder(ON); DocCursor; DocClear; DCFill; try { i = ((s + 7) >> 3 + BLK_SIZE - 1) >> BLK_SIZE_BITS; bitmap = MAlloc(i << BLK_SIZE_BITS); BlkRead(drive, bitmap, drive->fat1, i); i = 0; for (y = 0; y < GR_HEIGHT - 3 * FONT_HEIGHT; y++) { if (KeyScan) break; for (x = 0; x < GR_WIDTH - FONT_WIDTH << 1; x++) { lohi = i * s; c1 = lohi / l; if (Bt(bitmap, c1)) dc->color = ROP_XOR + BLUE ^ TRANSPARENT; else dc->color = ROP_XOR + WHITE ^ TRANSPARENT; GrPlot(dc, x, y); i++; } } Free(bitmap); } catch DriveUnlock(drive); CharGet; SettingsPop; DCFill; DCDel(dc); } U0 FAT32DriveView(U8 drv_let=0) { CDrive *drive = Letter2Drive(drv_let); I64 lohi, c1, i, x, y, l = (GR_HEIGHT - 3 * FONT_HEIGHT) * (GR_WIDTH - FONT_WIDTH << 1), s = (drive->size + drive->spc - 1) / drive->spc - (2 + drive->data_area - drive->drv_offset); U32 *bitmap; CDC *dc = DCAlias; SettingsPush; //See SettingsPush WinMax; WinBorder(ON); DocCursor; DocClear; DCFill; try { i = (s * 4 + BLK_SIZE - 1) >> BLK_SIZE_BITS; bitmap = MAlloc(i << BLK_SIZE_BITS); BlkRead(drive, bitmap, drive->fat1, i); i = 0; for (y = 0; y < GR_HEIGHT - 3 * FONT_HEIGHT; y++) { if (KeyScan) break; for (x = 0; x < GR_WIDTH - FONT_WIDTH << 1; x++) { lohi = i * s; c1 = lohi / l; if (bitmap[c1]) dc->color = ROP_XOR + BLUE ^ TRANSPARENT; else dc->color = ROP_XOR + WHITE ^ TRANSPARENT; GrPlot(dc, x, y); i++; } } Free(bitmap); } catch DriveUnlock(drive); CharGet; SettingsPop; DCFill; DCDel(dc); } public U0 DriveView(U8 drv_let=0) {//Drive view. Graph the allocation map's fragmentation. CDrive *drive = Letter2Drive(drv_let), *old_dv = Fs->cur_dv; Drive(drv_let); switch (drive->fs_type) { case FSt_REDSEA: RedSeaDriveView(drv_let); break; case FSt_FAT32: FAT32DriveView(drv_let); break; default: PrintErr("File System Not Supported\n"); } Drive(Drive2Letter(old_dv)); } public U0 DiskView(U8 drv_let=0) {//Disk view. Pie chart of partition sizes. I64 i, j, attr, h = Fs->pix_width, v = Fs->pix_height, radius; CDrive *drive; CBlkDev *bd = Letter2BlkDev(drv_let); CDC *dc = DCAlias; F64 sect_start, sect_end; SettingsPush; //See SettingsPush DocCursor; DocClear; DCFill; if (h < v) radius = 0.4 * h; else radius = 0.4 * v; dc->color = BLACK; GrCircle(dc, h >> 1, v >> 1, radius); j = 1; for (i = 0; i < DRIVES_NUM; i++) { drive = &blkdev.drvs[i]; if (bd == drive->bd && drive->fs_type) { sect_start = -(drive->drv_offset * 2 * pi / (bd->max_blk + 1)); sect_end = -((drive->drv_offset + drive->size) * 2 * pi / (bd->max_blk + 1)); dc->color = BLACK; GrLine(dc, h >> 1, v >> 1, h >> 1 + radius * Cos(sect_start), v >> 1 + radius * Sin(sect_start)); GrLine(dc, h >> 1, v >> 1, h >> 1 + radius * Cos(sect_end), v >> 1 + radius * Sin(sect_end)); attr = DriveTextAttrGet(Drive2Letter(drive)); dc->color = attr & 15; GrPrint(dc, 0, v - FONT_HEIGHT * j, "%C %-8Z", Drive2Letter(drive), drive->fs_type, "ST_DRIVE_TYPES"); dc->color.c1 = attr >> 4; dc->color |= ROPF_DITHER; GrFloodFill(dc, h >> 1 + (radius - 4) * Cos((sect_start + sect_end) / 2), v >> 1 + (radius - 4) * Sin((sect_start + sect_end) / 2), FALSE); j++; } } CharGet(,FALSE); SettingsPop; DCFill; DCDel(dc); } I64 RedSeaUnusedDriveSpace(U8 drv_let=0) { CDrive *drive = Letter2Drive(drv_let); I64 res = 0, i, l; U8 *bitmap; try { l = drive->size + drive->drv_offset - drive->data_area; i = ((l + 7) >> 3 + BLK_SIZE - 1) >> BLK_SIZE_BITS; bitmap = MAlloc(i << BLK_SIZE_BITS); BlkRead(drive, bitmap, drive->fat1, i); for (i = 0; i < l; i++) if (!Bt(bitmap, i)) res++; Free(bitmap); } catch DriveUnlock(drive); return res * BLK_SIZE * drive->spc; } I64 FAT32UnusedDriveSpace(U8 drv_let=0) { CDrive *drive = Letter2Drive(drv_let); I64 res = 0, i, l; U32 *bitmap; try { l = (drive->size + drive->spc - 1) / drive->spc - (2 + drive->data_area - drive->drv_offset); i = (l * 4 + BLK_SIZE - 1) >> BLK_SIZE_BITS; bitmap = MAlloc(i << BLK_SIZE_BITS); BlkRead(drive, bitmap, drive->fat1, i); for (i = 0; i < l; i++) if (!bitmap[i]) res++; Free(bitmap); } catch DriveUnlock(drive); return res * BLK_SIZE * drive->spc; } public I64 DriveUnused(U8 drv_let=0) {//Returns unused size in bytes. CDrive *drive = Letter2Drive(drv_let), *old_dv = Fs->cur_dv; U8 *old_dir = StrNew(Fs->cur_dir); I64 res = 0; Drive(drv_let); switch (drive->fs_type) { case FSt_REDSEA: res = RedSeaUnusedDriveSpace(drv_let); break; case FSt_FAT32: res = FAT32UnusedDriveSpace(drv_let); break; default: PrintErr("File System Not Supported\n"); } Drive(Drive2Letter(old_dv)); Cd(old_dir); Free(old_dir); return res; }