finished reformatting ZBlkDev directory

This commit is contained in:
TomAwezome 2020-06-02 16:53:56 -04:00
parent 6d8ecb9251
commit e16edca785
7 changed files with 1083 additions and 879 deletions

View file

@ -28,7 +28,13 @@ StartOS.CC
ZMouse.CC
ZBlkDev/
DiskCheck.CC
DiskPart.CC
FileMgr.CC
MakeZBlkDev.CC
Mount.CC
ZDiskA.CC
ZDiskB.CC
/Kernel/
BlkDev/

View file

@ -1,97 +1,103 @@
#help_index "Info;File/Cmd Line (Typically);Cmd Line (Typically)"
Bool CheckDiskConfirm(Bool *_fix,Bool *_confirm)
Bool CheckDiskConfirm(Bool *_fix, Bool *_confirm)
{
if (*_fix && *_confirm) {
if (*_fix && *_confirm)
{
"Fix ";
if (!YorN)
*_fix=FALSE;
*_confirm=FALSE;
*_fix = FALSE;
*_confirm = FALSE;
}
return *_fix;
}
I64 RedSeaCheckDiskList(CDrive *drive,CDirEntry *tmpde1,
U8 *bits,U8 *bits2,I64 size,I64 bpc)
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;
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 += 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);
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);
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;
tmpde1 = tmpde2;
}
return errs;
}
I64 RedSeaCheckDisk(U8 drv_let,Bool *_fix,Bool *_confirm)
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;
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);
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;
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);
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);
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);
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 += 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);
if (CheckDiskConfirm(_fix, _confirm))
RedSeaFreeClus(drive, i + drive->data_area, 1);
}
Free(files_find_mask);
@ -103,97 +109,110 @@ I64 RedSeaCheckDisk(U8 drv_let,Bool *_fix,Bool *_confirm)
return errs;
}
I64 FAT32CheckDiskList(CDrive *drive,CDirEntry *tmpde1,
U8 *bits,U32 *bits2,I64 size,I64 bpc)
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;
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 += 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);
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);
if (!bits2[c])
{
PrintErr("UnAlloc:%s Clus:%X\n", tmpde1->full_name, c);
errs++;
} else
bits2[c]=0;
c=ClusNumNext(drive,c);
}
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);
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);
if (i > tmpde1->size + bpc - 1)
{
PrintWarn("Alloced File Too Long:%s\n", tmpde1->full_name);
errs++;
}
}
DirEntryDel(tmpde1);
tmpde1=tmpde2;
tmpde1 = tmpde2;
}
return errs;
}
I64 FAT32CheckDisk(U8 drv_let,Bool *_fix,Bool *_confirm)
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;
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);
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);
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);
if (LBts(bits, c))
{
PrintErr("Dbl Alloc: RootDir Clus:%X\n", c);
errs++;
}
if (!bits2[c]) {
PrintErr("UnAlloc: RootDir Clus:%X\n",c);
if (!bits2[c])
{
PrintErr("UnAlloc: RootDir Clus:%X\n", c);
errs++;
} else
bits2[c]=0;
c=ClusNumNext(drive,c);
}
else
bits2[c] = 0;
c = ClusNumNext(drive, c);
}
errs+=FAT32CheckDiskList(drive,FilesFind(files_find_mask,FUF_RECURSE),
bits,bits2,size,bpc);
errs += FAT32CheckDiskList(drive, FilesFind(files_find_mask, FUF_RECURSE), bits, bits2, size, bpc);
bits2[1]=0; //See $LK,"FAT32Format",A="MN:FAT32Format"$()
for (i=1;i<size;i++)
if (bits2[i]) {
PrintWarn("Shouldn't Alloc Clus:%0X\n",i);
bits2[1] = 0; //See $LK,"FAT32Format",A="MN: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);
if (CheckDiskConfirm(_fix, _confirm))
FAT32FreeClus(drive, i);
}
Free(files_find_mask);
Free(bits);
@ -204,38 +223,41 @@ I64 FAT32CheckDisk(U8 drv_let,Bool *_fix,Bool *_confirm)
return errs;
}
public I64 DiskCheck(U8 drv_let=0,Bool fix=FALSE,Bool confirm=TRUE)
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) {
I64 errs = 0;
CDrive *drive = Letter2Drive(drv_let);
switch (drive->fs_type)
{
case FSt_REDSEA:
errs=RedSeaCheckDisk(drv_let,&fix,&confirm);
errs = RedSeaCheckDisk(drv_let, &fix, &confirm);
break;
case FSt_FAT32:
errs=FAT32CheckDisk(drv_let,&fix,&confirm);
errs = FAT32CheckDisk(drv_let, &fix, &confirm);
break;
default:
PrintErr("File System Not Supported\n");
}
if (errs) {
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";
"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;
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;
CDC *dc = DCAlias;
SettingsPush; //See $LK,"SettingsPush",A="MN:SettingsPush"$
WinMax;
@ -243,27 +265,31 @@ U0 RedSeaDriveView(U8 drv_let=0)
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++) {
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;
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);
dc->color = ROP_XOR + WHITE ^ TRANSPARENT;
GrPlot(dc, x, y);
i++;
}
}
Free(bitmap);
} catch
}
catch
DriveUnlock(drive);
CharGet;
@ -273,11 +299,12 @@ U0 RedSeaDriveView(U8 drv_let=0)
}
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);
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;
CDC *dc = DCAlias;
SettingsPush; //See $LK,"SettingsPush",A="MN:SettingsPush"$
WinMax;
@ -285,27 +312,31 @@ U0 FAT32DriveView(U8 drv_let=0)
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++) {
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;
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;
dc->color = ROP_XOR + BLUE ^ TRANSPARENT;
else
dc->color=ROP_XOR+WHITE^TRANSPARENT;
GrPlot(dc,x,y);
dc->color = ROP_XOR + WHITE ^ TRANSPARENT;
GrPlot(dc, x, y);
i++;
}
}
Free(bitmap);
} catch
}
catch
DriveUnlock(drive);
CharGet;
@ -315,9 +346,10 @@ U0 FAT32DriveView(U8 drv_let=0)
}
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;
CDrive *drive = Letter2Drive(drv_let), *old_dv = Fs->cur_dv;
Drive(drv_let);
switch (drive->fs_type) {
switch (drive->fs_type)
{
case FSt_REDSEA:
RedSeaDriveView(drv_let);
break;
@ -332,49 +364,51 @@ public U0 DriveView(U8 drv_let=0)
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;
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;
CBlkDev *bd = Letter2BlkDev(drv_let);
CDC *dc = DCAlias;
F64 sect_start, sect_end;
SettingsPush; //See $LK,"SettingsPush",A="MN:SettingsPush"$
DocCursor;
DocClear;
DCFill;
if (h<v)
radius=0.4*h;
if (h < v)
radius = 0.4 * h;
else
radius=0.4*v;
dc->color=BLACK;
GrCircle(dc,h>>1,v>>1,radius);
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*ã/(bd->max_blk+1));
sect_end =-((drive->drv_offset+drive->size)*2*ã/(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));
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 * ã / (bd->max_blk + 1));
sect_end = -((drive->drv_offset + drive->size) * 2 * ã / (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));
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;
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);
h >> 1 + (radius - 4) * Cos((sect_start + sect_end) / 2),
v >> 1 + (radius - 4) * Sin((sect_start + sect_end) / 2), FALSE);
j++;
}
}
@ -387,52 +421,57 @@ public U0 DiskView(U8 drv_let=0)
I64 RedSeaUnusedDriveSpace(U8 drv_let=0)
{
CDrive *drive=Letter2Drive(drv_let);
I64 res=0,i,l;
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))
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
}
catch
DriveUnlock(drive);
return res*BLK_SIZE*drive->spc;
return res * BLK_SIZE * drive->spc;
}
I64 FAT32UnusedDriveSpace(U8 drv_let=0)
{
CDrive *drive=Letter2Drive(drv_let);
I64 res=0,i,l;
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++)
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
}
catch
DriveUnlock(drive);
return res*BLK_SIZE*drive->spc;
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;
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) {
switch (drive->fs_type)
{
case FSt_REDSEA:
res=RedSeaUnusedDriveSpace(drv_let);
res = RedSeaUnusedDriveSpace(drv_let);
break;
case FSt_FAT32:
res=FAT32UnusedDriveSpace(drv_let);
res = FAT32UnusedDriveSpace(drv_let);
break;
default:
PrintErr("File System Not Supported\n");

View file

@ -1,16 +1,16 @@
#help_index "Install;File/Cmd Line (Typically);Cmd Line (Typically)"
#define ROUND_DRIVE_TO (63*255)
#define DRIVE_HEADER 63
#define ROUND_DRIVE_TO (63 * 255)
#define DRIVE_HEADER 63
class CPlannedDrive
{
CPlannedDrive *next,*last;
CPlannedDrive *next, *last;
I64 size;
Bool pri;
};
public I64 DiskPart(U8 drv_let=0,...)
public I64 DiskPart(U8 drv_let=0, ...)
{/*Partition the disk containing partition drv_let.
drv_let=0 means add new drive that is not already mounted.
@ -19,147 +19,158 @@ drv_let=0 means add new drive that is not already mounted.
*/
CBlkDev *bd;
CPlannedDrive head,*tmppp;
CPlannedDrive head, *tmppp;
CMasterBoot mbr;
Bool pri=TRUE;
I64 ext_base,drv_let2,pri_count=0,i,start_offset,offset,
total,remaining,cur_arg=0;
Bool pri = TRUE;
I64 ext_base, drv_let2, pri_count = 0, i, start_offset, offset, total, remaining, cur_arg = 0;
"This command does not play well\n"
"with other operating systems.\n"
"You really should use another\n"
"operating system's partitioner.\n"
"If you use this, it may, in fact,\n"
"make your hard drive impossible\n"
"to repartition with other operating\n"
"until you set block zero to zero\n"
"with $$LK,\"BootMHDZero\",\"MN:BootMHDZero\"$$()\n\n\n"
"Continue";
if (argc<=cur_arg && !YorN)
"with other operating systems.\n"
"You really should use another\n"
"operating system's partitioner.\n"
"If you use this, it may, in fact,\n"
"make your hard drive impossible\n"
"to repartition with other operating\n"
"until you set block zero to zero\n"
"with $$LK,\"BootMHDZero\",\"MN:BootMHDZero\"$$()\n\n\n"
"Continue";
if (argc <= cur_arg && !YorN)
return 0;
'\n';
if (drv_let && !Letter2BlkDev(drv_let,FALSE))
drv_let=0;
if (!drv_let && !(drv_let=Mount(TRUE)) ||
!(bd=Letter2BlkDev(drv_let,FALSE)) || bd->type!=BDT_ATA)
if (drv_let && !Letter2BlkDev(drv_let, FALSE))
drv_let = 0;
if (!drv_let && !(drv_let = Mount(TRUE)) || !(bd = Letter2BlkDev(drv_let, FALSE)) || bd->type != BDT_ATA)
return 0;
total=bd->max_blk+1;
total = bd->max_blk + 1;
QueueInit(&head);
drv_let2=bd->first_drive_let;
remaining=FloorU64(bd->max_blk+1,ROUND_DRIVE_TO);
while (FloorU64(remaining,ROUND_DRIVE_TO)>=ROUND_DRIVE_TO) {
tmppp=MAlloc(sizeof(CPlannedDrive));
do {
"$$RED$$Partition %C$$FG$$\n",drv_let2;
tmppp->pri=FALSE;
if (pri) {
drv_let2 = bd->first_drive_let;
remaining = FloorU64(bd->max_blk + 1, ROUND_DRIVE_TO);
while (FloorU64(remaining, ROUND_DRIVE_TO) >= ROUND_DRIVE_TO)
{
tmppp = MAlloc(sizeof(CPlannedDrive));
do
{
"$$RED$$Partition %C$$FG$$\n", drv_let2;
tmppp->pri = FALSE;
if (pri)
{
"Primary Partition";
if (argc>cur_arg || YorN) {
if (argc>cur_arg || YorN)
{
pri_count++;
tmppp->pri=TRUE;
if (pri_count==3)
pri=FALSE;
} else
pri=FALSE;
tmppp->pri = TRUE;
if (pri_count == 3)
pri = FALSE;
}
else
pri = FALSE;
}
"\nBlocks Remaining:%d (0x%X)\n",
remaining-DRIVE_HEADER,remaining-DRIVE_HEADER;
if (argc>cur_arg)
tmppp->size=MinI64(CeilU64(MaxI64(remaining,DRIVE_HEADER),ROUND_DRIVE_TO),
CeilU64(argv[cur_arg++](F64)*total,ROUND_DRIVE_TO));
"\nBlocks Remaining:%d (0x%X)\n", remaining - DRIVE_HEADER, remaining - DRIVE_HEADER;
if (argc > cur_arg)
tmppp->size = MinI64(CeilU64(MaxI64(remaining, DRIVE_HEADER), ROUND_DRIVE_TO),
CeilU64(argv[cur_arg++](F64) * total, ROUND_DRIVE_TO));
else
tmppp->size=CeilU64(I64Get("Size in Blocks :",
remaining-DRIVE_HEADER)+DRIVE_HEADER,ROUND_DRIVE_TO);
} while (!(ROUND_DRIVE_TO<=tmppp->size<=FloorU64(remaining,ROUND_DRIVE_TO)));
QueueInsert(tmppp,head.last);
remaining-=tmppp->size;
tmppp->size = CeilU64(I64Get("Size in Blocks :", remaining - DRIVE_HEADER) + DRIVE_HEADER, ROUND_DRIVE_TO);
}
while (!(ROUND_DRIVE_TO <= tmppp->size <= FloorU64(remaining, ROUND_DRIVE_TO)));
QueueInsert(tmppp, head.last);
remaining -= tmppp->size;
drv_let2++;
}
"\n\n!!! Repartition Drive !!!\n\n";
tmppp=head.next;
drv_let2=bd->first_drive_let;
while (tmppp!=&head) {
"Drive %C:%08X ",drv_let2,tmppp->size;
tmppp = head.next;
drv_let2 = bd->first_drive_let;
while (tmppp != &head)
{
"Drive %C:%08X ", drv_let2, tmppp->size;
if (tmppp->pri)
"Primary\n";
else
"Logical\n";
tmppp=tmppp->next;
tmppp = tmppp->next;
drv_let2++;
}
if (!argc && !AreYouSure)
goto pd_done;
remaining=FloorU64(bd->max_blk+1,ROUND_DRIVE_TO)-ROUND_DRIVE_TO;
tmppp=head.next;
MemSet(&mbr,0,BLK_SIZE);
mbr.signature=0xAA55;
offset=0;
for (i=0;i<pri_count;i++) {
mbr.p[i].active=0x80;
mbr.p[i].start_head=0;
mbr.p[i].start_cyl=0x101;
mbr.p[i].type=1; //Will get set different.
mbr.p[i].end_head=0xFE;
mbr.p[i].end_cyl=0xFFFF;
mbr.p[i].offset=DRIVE_HEADER+offset;
mbr.p[i].size=tmppp->size-DRIVE_HEADER;
offset+=tmppp->size;
remaining-=tmppp->size;
tmppp=tmppp->next;
remaining = FloorU64(bd->max_blk + 1, ROUND_DRIVE_TO) - ROUND_DRIVE_TO;
tmppp = head.next;
MemSet(&mbr, 0, BLK_SIZE);
mbr.signature = 0xAA55;
offset = 0;
for (i = 0; i < pri_count; i++)
{
mbr.p[i].active = 0x80;
mbr.p[i].start_head = 0;
mbr.p[i].start_cyl = 0x101;
mbr.p[i].type = 1; //Will get set different.
mbr.p[i].end_head = 0xFE;
mbr.p[i].end_cyl = 0xFFFF;
mbr.p[i].offset = DRIVE_HEADER + offset;
mbr.p[i].size = tmppp->size - DRIVE_HEADER;
offset += tmppp->size;
remaining -= tmppp->size;
tmppp = tmppp->next;
}
if (!i) i++;
if (tmppp!=&head) {
mbr.p[i].active=0x80;
mbr.p[i].start_head=0;
mbr.p[i].start_cyl=0x101;
mbr.p[i].type=0xF;
mbr.p[i].end_head=0xFE;
mbr.p[i].end_cyl=0xFFFF;
mbr.p[i].offset=offset;
mbr.p[i].size=remaining;
ext_base=offset;
if (!i)
i++;
if (tmppp != &head)
{
mbr.p[i].active = 0x80;
mbr.p[i].start_head = 0;
mbr.p[i].start_cyl = 0x101;
mbr.p[i].type = 0xF;
mbr.p[i].end_head = 0xFE;
mbr.p[i].end_cyl = 0xFFFF;
mbr.p[i].offset = offset;
mbr.p[i].size = remaining;
ext_base = offset;
}
ATAWriteBlks(bd,&mbr,0,1);
ATAWriteBlks(bd, &mbr, 0, 1);
while (tmppp!=&head) {
start_offset=offset;
MemSet(&mbr,0,BLK_SIZE);
mbr.signature=0xAA55;
while (tmppp != &head)
{
start_offset = offset;
MemSet(&mbr, 0, BLK_SIZE);
mbr.signature = 0xAA55;
mbr.p[0].active=0x80;
mbr.p[0].start_head=1;
mbr.p[0].start_cyl=0x101;
mbr.p[0].type=1; //Will get set different.
mbr.p[0].end_head=0xFE;
mbr.p[0].end_cyl=0xFFFF;
mbr.p[0].offset=DRIVE_HEADER;
mbr.p[0].size=tmppp->size-DRIVE_HEADER;
offset+=tmppp->size;
tmppp=tmppp->next;
if (tmppp!=&head) {
mbr.p[1].active=0x80;
mbr.p[1].start_head=0;
mbr.p[1].start_cyl=0x101;
mbr.p[1].type=5;
mbr.p[1].end_head=0xFE;
mbr.p[1].end_cyl=0xFFFF;
mbr.p[1].offset=offset-ext_base;
mbr.p[1].size=tmppp->size;
mbr.p[0].active = 0x80;
mbr.p[0].start_head = 1;
mbr.p[0].start_cyl = 0x101;
mbr.p[0].type = 1; //Will get set different.
mbr.p[0].end_head = 0xFE;
mbr.p[0].end_cyl = 0xFFFF;
mbr.p[0].offset = DRIVE_HEADER;
mbr.p[0].size = tmppp->size - DRIVE_HEADER;
offset += tmppp->size;
tmppp = tmppp->next;
if (tmppp != &head)
{
mbr.p[1].active = 0x80;
mbr.p[1].start_head = 0;
mbr.p[1].start_cyl = 0x101;
mbr.p[1].type = 5;
mbr.p[1].end_head = 0xFE;
mbr.p[1].end_cyl = 0xFFFF;
mbr.p[1].offset = offset - ext_base;
mbr.p[1].size = tmppp->size;
}
ATAWriteBlks(bd,&mbr,start_offset,1);
ATAWriteBlks(bd, &mbr, start_offset, 1);
}
bd->flags&=~(BDF_INITIALIZED | BDF_INIT_IN_PROGRESS);
BlkDevAdd(bd,,FALSE,TRUE);
for (i=bd->first_drive_let;i<drv_let2;i++)
Format(i,,FALSE);
bd->flags &= ~(BDF_INITIALIZED | BDF_INIT_IN_PROGRESS);
BlkDevAdd(bd,, FALSE, TRUE);
for (i = bd->first_drive_let; i < drv_let2; i++)
Format(i,, FALSE);
pd_done:
while (head.next!=&head) {
tmppp=head.next;
while (head.next != &head)
{
tmppp = head.next;
QueueRemove(tmppp);
Free(tmppp);
}

File diff suppressed because it is too large Load diff

View file

@ -1,154 +1,175 @@
#help_index "File/Cmd Line (Typically);Cmd Line (Typically)"
public U8 *DBlk(I64 blk,Bool write=FALSE)
public U8 *DBlk(I64 blk, Bool write=FALSE)
{//Dump disk block. Optionally, write.
//If you set write to TRUE, the block will
//be written when you press <ESC>.
//See $LK,"::/Demo/Disk/DiskRaw.CC"$.
U8 *buf=MAlloc(BLK_SIZE);
U8 *buf = MAlloc(BLK_SIZE);
BlkRead(Fs->cur_dv,buf,blk,1);
DocD(buf,BLK_SIZE);
if (write) {
BlkRead(Fs->cur_dv, buf, blk, 1);
DocD(buf, BLK_SIZE);
if (write)
{
"Edit and press <ESC> to write or <SHIFT-ESC>\n";
if (View) {
if (View)
{
"Write\n";
BlkWrite(Fs->cur_dv,buf,blk,1);
BlkWrite(Fs->cur_dv, buf, blk, 1);
}
}
return buf;
}
public U8 *DClus(I64 c,Bool write=FALSE,I64 num=0)
public U8 *DClus(I64 c, Bool write=FALSE, I64 num=0)
{//Dump disk clus. Optionally, write.
//If you set write to TRUE, the clus will
//be written when you press <ESC>.
//See $LK,"::/Demo/Disk/DiskRaw.CC"$.
//Do $LK,"Dir",A="MN:Dir"$("*",TRUE); to get clus numbers of files.
U8 *buf=MAlloc(Fs->cur_dv->spc<<BLK_SIZE_BITS);
c=ClusNumNext(Fs->cur_dv,c,num);
ClusRead(Fs->cur_dv,buf,c,1);
"Clus:%X\n",c;
DocD(buf,Fs->cur_dv->spc<<BLK_SIZE_BITS);
if (write) {
U8 *buf = MAlloc(Fs->cur_dv->spc << BLK_SIZE_BITS);
c = ClusNumNext(Fs->cur_dv, c, num);
ClusRead(Fs->cur_dv, buf, c, 1);
"Clus:%X\n", c;
DocD(buf, Fs->cur_dv->spc << BLK_SIZE_BITS);
if (write)
{
"Edit and press <ESC> to write or <SHIFT-ESC>\n";
if (View) {
if (View)
{
"Write\n";
ClusWrite(Fs->cur_dv,buf,c,1);
ClusWrite(Fs->cur_dv, buf, c, 1);
}
}
return buf;
}
public U8 *Dump(U8 *filename,Bool write=FALSE)
public U8 *Dump(U8 *filename, Bool write=FALSE)
{//Dump file. Optionally, write.
//If you set write to TRUE, the file will
//be written when you press <ESC>.
U8 *buf;
I64 size;
if (buf=FileRead(filename,&size)) {
DocD(buf,size);
if (write) {
if (buf = FileRead(filename,&size))
{
DocD(buf, size);
if (write)
{
"Edit and press <ESC> to write or <SHIFT-ESC>\n";
if (View) {
if (View)
{
"Write\n";
FileWrite(filename,buf,size);
FileWrite(filename, buf, size);
}
}
}
return buf;
}
public Bool Copy(U8 *src_files_find_mask,U8 *dst_files_find_mask=".")
public Bool Copy(U8 *src_files_find_mask, U8 *dst_files_find_mask=".")
{//Copy files.
//If the name ends in ".Z", it will
//be stored compressed. If not ".Z"
//it will be stored uncompressed.
Bool res=TRUE;
Bool res = TRUE;
CDirContext *dirc;
CDirEntry *tmpde,*tmpde1;
CDirEntry *tmpde, *tmpde1;
U8 *st;
if (!(tmpde1=FilesFind(src_files_find_mask,FUF_CLUS_ORDER)))
if (!(tmpde1 = FilesFind(src_files_find_mask, FUF_CLUS_ORDER)))
return FALSE;
if (IsDir(dst_files_find_mask)) {
if (dirc=DirContextNew(dst_files_find_mask,TRUE)) {
tmpde=tmpde1;
while (tmpde) {
if (!(tmpde->attr & RS_ATTR_DIR)) {
st=FileNameAbs(tmpde->name);
if (!CopySingle(tmpde->full_name,st))
res=FALSE;
if (IsDir(dst_files_find_mask))
{
if (dirc = DirContextNew(dst_files_find_mask, TRUE))
{
tmpde = tmpde1;
while (tmpde)
{
if (!(tmpde->attr & RS_ATTR_DIR))
{
st = FileNameAbs(tmpde->name);
if (!CopySingle(tmpde->full_name, st))
res = FALSE;
Free(st);
}
tmpde=tmpde->next;
tmpde = tmpde->next;
}
DirContextDel(dirc);
}
DirTreeDel(tmpde1);
return res;
} else {
}
else
{
DirTreeDel(tmpde1);
return CopySingle(src_files_find_mask,dst_files_find_mask);
return CopySingle(src_files_find_mask, dst_files_find_mask);
}
}
public Bool Move(U8 *f1,U8 *f2)
public Bool Move(U8 *f1, U8 *f2)
{//Move files from one location to another or rename.
if (Copy(f1,f2)) {
if (Copy(f1, f2))
{
Del(f1);
return TRUE;
}
return FALSE;
}
I64 CopyTree2(CDirEntry *tmpde,I64 src_dir_len,I64 dst_dir_len,U8 *dst_dir)
I64 CopyTree2(CDirEntry *tmpde, I64 src_dir_len, I64 dst_dir_len, U8 *dst_dir)
{
U8 *st;
I64 res=1;
while (tmpde) {
st=MAlloc(StrLen(tmpde->full_name)+dst_dir_len+2);
MemCopy(st,dst_dir,dst_dir_len);
StrCopy(st+dst_dir_len,tmpde->full_name+src_dir_len);
if (tmpde->attr & RS_ATTR_DIR) {
DirMake(st,LinkedListCount(tmpde->sub));
res+=CopyTree2(tmpde->sub,src_dir_len,dst_dir_len,dst_dir);
} else
if (CopySingle(tmpde->full_name,st))
I64 res = 1;
while (tmpde)
{
st = MAlloc(StrLen(tmpde->full_name) + dst_dir_len + 2);
MemCopy(st, dst_dir, dst_dir_len);
StrCopy(st + dst_dir_len, tmpde->full_name + src_dir_len);
if (tmpde->attr & RS_ATTR_DIR)
{
DirMake(st, LinkedListCount(tmpde->sub));
res += CopyTree2(tmpde->sub, src_dir_len, dst_dir_len, dst_dir);
}
else
if (CopySingle(tmpde->full_name, st))
res++;
Free(st);
tmpde=tmpde->next;
tmpde = tmpde->next;
}
return res;
}
public I64 CopyTree(U8 *src_files_find_mask,U8 *dst_files_find_mask,
Bool no_mask=TRUE)
public I64 CopyTree(U8 *src_files_find_mask, U8 *dst_files_find_mask, Bool no_mask=TRUE)
{//Copy directory tree.
//Returns the count of copied files (not dirs).
CDirContext *dirc;
CDirEntry *tmpde=NULL;
I64 res=0,i1,i2;
U8 *st1,*st2;
CDirEntry *tmpde = NULL;
I64 res = 0, i1, i2;
U8 *st1, *st2;
st1=DirNameAbs(src_files_find_mask);
st2=DirNameAbs(dst_files_find_mask);
i1=StrLen(st1);
if (!StrNCompare(st1,st2,i1) && (st2[i1]=='/' || !st2[i1]) ) {
st1 = DirNameAbs(src_files_find_mask);
st2 = DirNameAbs(dst_files_find_mask);
i1 = StrLen(st1);
if (!StrNCompare(st1, st2, i1) && (st2[i1] == '/' || !st2[i1]))
{
Free(st1);
Free(st2);
return 0;
}
Free(st1);
Free(st2);
if (dirc=DirContextNew(src_files_find_mask,TRUE,,no_mask)) {
tmpde=FilesFind(dirc->mask,FUF_RECURSE);
st1=DirCur;
if (dirc = DirContextNew(src_files_find_mask, TRUE,, no_mask))
{
tmpde = FilesFind(dirc->mask, FUF_RECURSE);
st1 = DirCur;
DirContextDel(dirc);
i1=StrLen(st1);
if (i1==3) i1--;
if (dirc=DirContextNew(dst_files_find_mask,TRUE,TRUE)) {
st2=DirCur;
i2=StrLen(st2);
if (i2==3) i2--;
res=CopyTree2(tmpde,i1,i2,st2);
i1 = StrLen(st1);
if (i1 == 3)
i1--;
if (dirc = DirContextNew(dst_files_find_mask, TRUE, TRUE))
{
st2 = DirCur;
i2 = StrLen(st2);
if (i2 == 3)
i2--;
res = CopyTree2(tmpde, i1, i2, st2);
DirContextDel(dirc);
Free(st2);
}
@ -160,77 +181,86 @@ public I64 CopyTree(U8 *src_files_find_mask,U8 *dst_files_find_mask,
I64 DelTreeDirs(CDirEntry *tmpde1)
{
I64 res=0;
I64 res = 0;
CDirEntry *tmpde2;
while (tmpde1) {
tmpde2=tmpde1->next;
if (tmpde1->attr & RS_ATTR_DIR) {
while (tmpde1)
{
tmpde2 = tmpde1->next;
if (tmpde1->attr & RS_ATTR_DIR)
{
if (tmpde1->sub)
res+=DelTreeDirs(tmpde1->sub);
res+=Del(tmpde1->full_name,TRUE,TRUE);
res += DelTreeDirs(tmpde1->sub);
res += Del(tmpde1->full_name, TRUE, TRUE);
}
DirEntryDel(tmpde1);
tmpde1=tmpde2;
tmpde1 = tmpde2;
}
return res;
}
I64 DelTreeFiles(CDirEntry *tmpde1)
{
I64 res=0;
I64 res = 0;
CDirEntry *tmpde2;
while (tmpde1) {
tmpde2=tmpde1->next;
if (tmpde1->attr & RS_ATTR_DIR) {
while (tmpde1)
{
tmpde2 = tmpde1->next;
if (tmpde1->attr & RS_ATTR_DIR)
{
if (tmpde1->sub)
res+=DelTreeFiles(tmpde1->sub);
} else
res+=Del(tmpde1->full_name,FALSE,TRUE);
res += DelTreeFiles(tmpde1->sub);
}
else
res += Del(tmpde1->full_name, FALSE, TRUE);
DirEntryDel(tmpde1);
tmpde1=tmpde2;
tmpde1 = tmpde2;
}
return res;
}
public I64 DelTree(U8 *files_find_mask,U8 *fu_flags=NULL)
public I64 DelTree(U8 *files_find_mask, U8 *fu_flags=NULL)
{//Delete directory tree.
I64 res=0,fuf_flags=0;
FlagsScan(&fuf_flags,Define("ST_FILE_UTIL_FLAGS"),"+r");
FlagsScan(&fuf_flags,Define("ST_FILE_UTIL_FLAGS"),fu_flags);
if (IsDir(files_find_mask)) {
res=DelTreeDirs(FilesFind(files_find_mask,fuf_flags));
res+=Del(files_find_mask,TRUE,TRUE);
res+=Del(files_find_mask,FALSE,TRUE);
} else
res=DelTreeFiles(FilesFind(files_find_mask,fuf_flags));
I64 res = 0, fuf_flags = 0;
FlagsScan(&fuf_flags, Define("ST_FILE_UTIL_FLAGS"), "+r");
FlagsScan(&fuf_flags, Define("ST_FILE_UTIL_FLAGS"), fu_flags);
if (IsDir(files_find_mask))
{
res = DelTreeDirs(FilesFind(files_find_mask, fuf_flags));
res += Del(files_find_mask, TRUE, TRUE);
res += Del(files_find_mask, FALSE, TRUE);
}
else
res = DelTreeFiles(FilesFind(files_find_mask, fuf_flags));
return res;
}
U0 TouchFile(U8 *filename,U8 *attr,CDate cdt=I64_MIN)
U0 TouchFile(U8 *filename, U8 *attr, CDate cdt=I64_MIN)
{
CDrive *drive=Letter2Drive(*filename);
CDrive *drive = Letter2Drive(*filename);
CDirEntry de;
U8 *cur_dir=StrNew(filename),buf[STR_LEN];
if (FileFind(filename,&de,FUF_JUST_FILES)) {
U8 *cur_dir = StrNew(filename), buf[STR_LEN];
if (FileFind(filename, &de, FUF_JUST_FILES))
{
Free(de.full_name);
if (!StrCompare(attr,"+?"))
"%-48ts %s\n",filename,FlagsStrPrint(buf,Define("ST_FILE_ATTRS"),de.attr);
else {
StrFirstRemove(cur_dir,":");
StrLastRemove(cur_dir,"/");
if (!StrCompare(attr, "+?"))
"%-48ts %s\n", filename, FlagsStrPrint(buf, Define("ST_FILE_ATTRS"), de.attr);
else
{
StrFirstRemove(cur_dir, ":");
StrLastRemove(cur_dir, "/");
if (!*cur_dir)
StrCopy(cur_dir,"/");
FlagsScan(&de.attr,Define("ST_FILE_ATTRS"),attr);
if (cdt==I64_MIN)
de.datetime=Now;
StrCopy(cur_dir, "/");
FlagsScan(&de.attr, Define("ST_FILE_ATTRS"), attr);
if (cdt == I64_MIN)
de.datetime = Now;
else
de.datetime=cdt;
DirNew(drive,cur_dir,&de,FALSE);
de.datetime = cdt;
DirNew(drive, cur_dir, &de, FALSE);
}
} else
PrintErr("File not found: \"%s\".\n",filename);
}
else
PrintErr("File not found: \"%s\".\n", filename);
Free(cur_dir);
}
public U0 Touch(U8 *files_find_mask="*",U8 *attr="+?",
U8 *fu_flags=NULL,CDate cdt=I64_MIN)
public U0 Touch(U8 *files_find_mask="*", U8 *attr="+?", U8 *fu_flags=NULL, CDate cdt=I64_MIN)
{/*Touch file attributes and DateTime.
Default lists attributes.
attr: "+?" =show current
@ -239,14 +269,15 @@ $LK,"RS_ATTR_READ_ONLY",A="MN:RS_ATTR_READ_ONLY"$ $LK,"ST_FILE_ATTRS",A="MN:ST_
To Set DateL:
Touch(filename,"",,datetime);
*/
I64 fuf_flags=0;
CDirEntry *tmpde,*tmpde1;
FlagsScan(&fuf_flags,Define("ST_FILE_UTIL_FLAGS"),"+f+F");
FlagsScan(&fuf_flags,Define("ST_FILE_UTIL_FLAGS"),fu_flags);
tmpde=tmpde1=FilesFind(files_find_mask,fuf_flags);
while (tmpde) {
TouchFile(tmpde->full_name,attr,cdt);
tmpde=tmpde->next;
I64 fuf_flags = 0;
CDirEntry *tmpde, *tmpde1;
FlagsScan(&fuf_flags, Define("ST_FILE_UTIL_FLAGS"), "+f+F");
FlagsScan(&fuf_flags, Define("ST_FILE_UTIL_FLAGS"), fu_flags);
tmpde=tmpde1 = FilesFind(files_find_mask, fuf_flags);
while (tmpde)
{
TouchFile(tmpde->full_name, attr, cdt);
tmpde = tmpde->next;
}
DirTreeDel(tmpde1);
}

View file

@ -1,79 +1,89 @@
#help_index "File/Internal"
I64 DirTreeSerializeSize(CDirEntry *tmpde)
{
I64 res=0;
while (tmpde) {
res+=CDIR_SIZE+1;
I64 res = 0;
while (tmpde)
{
res += CDIR_SIZE + 1;
if (tmpde->attr & RS_ATTR_DIR)
res+=DirTreeSerializeSize(tmpde->sub);
tmpde=tmpde->next;
res += DirTreeSerializeSize(tmpde->sub);
tmpde = tmpde->next;
}
return res+1;
return res + 1;
}
I64 DirTreeSerializeFill(CDirEntry *tmpde,U8 *dst)
I64 DirTreeSerializeFill(CDirEntry *tmpde, U8 *dst)
{
I64 res=0,i;
while (tmpde) {
*dst++=1;
I64 res = 0, i;
while (tmpde)
{
*dst++ = 1;
res++;
MemCopy(dst,&tmpde->start,CDIR_SIZE);
dst+=CDIR_SIZE;
res+=CDIR_SIZE;
if (tmpde->attr & RS_ATTR_DIR) {
i=DirTreeSerializeFill(tmpde->sub,dst);
dst+=i;
res+=i;
MemCopy(dst, &tmpde->start, CDIR_SIZE);
dst += CDIR_SIZE;
res += CDIR_SIZE;
if (tmpde->attr & RS_ATTR_DIR)
{
i = DirTreeSerializeFill(tmpde->sub, dst);
dst += i;
res += i;
}
tmpde=tmpde->next;
tmpde = tmpde->next;
}
*dst=0;
return res+1;
*dst = 0;
return res + 1;
}
public U8 *DirTreeSerialize(CDirEntry *tmpde,I64 *_size=NULL)
public U8 *DirTreeSerialize(CDirEntry *tmpde, I64 *_size=NULL)
{//Serialize tree returned from $LK,"FilesFind",A="MN:FilesFind"$() into a one contiguous U8 array.
I64 size=DirTreeSerializeSize(tmpde);
U8 *buf=MAlloc(size);
DirTreeSerializeFill(tmpde,buf);
if (_size) *_size=size;
I64 size = DirTreeSerializeSize(tmpde);
U8 *buf = MAlloc(size);
DirTreeSerializeFill(tmpde, buf);
if (_size)
*_size = size;
return buf;
}
U8 *DirTreeUnserialize2(U8 *src,CDirEntry **tmpde)
U8 *DirTreeUnserialize2(U8 *src, CDirEntry **tmpde)
{
CDirEntry *tmpde1;
if (*src++) {
tmpde1=CAlloc(sizeof(CDirEntry));
*tmpde=tmpde1;
MemCopy(&tmpde1->start,src,CDIR_SIZE);
src+=CDIR_SIZE;
if (*src++)
{
tmpde1 = CAlloc(sizeof(CDirEntry));
*tmpde = tmpde1;
MemCopy(&tmpde1->start, src, CDIR_SIZE);
src += CDIR_SIZE;
if (tmpde1->attr & RS_ATTR_DIR)
src=DirTreeUnserialize2(src,&tmpde1->sub);
src=DirTreeUnserialize2(src,&tmpde1->next);
} else
*tmpde=NULL;
src = DirTreeUnserialize2(src, &tmpde1->sub);
src = DirTreeUnserialize2(src, &tmpde1->next);
}
else
*tmpde = NULL;
return src;
}
public CDirEntry *DirTreeUnserialize(U8 *src)
{//Unserialize tree to make it like a tree returned from $LK,"FilesFind",A="MN:FilesFind"$().
CDirEntry *tmpde=NULL;
DirTreeUnserialize2(src,&tmpde);
CDirEntry *tmpde = NULL;
DirTreeUnserialize2(src, &tmpde);
return tmpde;
}
#help_index "File/Program Routines"
U0 FOFlatten(CDirEntry *tmpde,CDirEntry **a,I64 *i)
U0 FOFlatten(CDirEntry *tmpde, CDirEntry **a, I64 *i)
{
CDirEntry *tmpde1;
while (tmpde) {
tmpde1=tmpde->next;
if (tmpde->attr&RS_ATTR_DIR) {
FOFlatten(tmpde->sub,a,i);
while (tmpde)
{
tmpde1 = tmpde->next;
if (tmpde->attr & RS_ATTR_DIR)
{
FOFlatten(tmpde->sub, a, i);
DirEntryDel(tmpde);
} else {
a[*i]=tmpde;
*i=*i+1;
}
tmpde=tmpde1;
else
{
a[*i] = tmpde;
*i = *i + 1;
}
tmpde = tmpde1;
}
}
@ -82,28 +92,28 @@ I64 Size1(CDirEntry *tmpde,I64 round_to)
I64 res = 0, i;
while (tmpde)
{
i=tmpde->size;
i = tmpde->size;
if (round_to)
i = CeilU64(tmpde->size, round_to);
if (tmpde->attr & RS_ATTR_DIR)
i += Size1(tmpde->sub, round_to);
tmpde->user_data=i; //Store size in user_data member
tmpde->user_data = i; //Store size in user_data member
res += i;
tmpde = tmpde->next;
}
return res;
}
public I64 Size(U8 *files_find_mask="/*",U8 *fu_flags=NULL,I64 round_to=0)
public I64 Size(U8 *files_find_mask="/*", U8 *fu_flags=NULL, I64 round_to=0)
{//Total size of files in mask.
//Does not include directory size of base directory, but does include size of sub directories.
I64 fuf_flags=0,res=0;
CDirEntry *tmpde1=NULL;
FlagsScan(&fuf_flags,Define("ST_FILE_UTIL_FLAGS"),"+r");
FlagsScan(&fuf_flags,Define("ST_FILE_UTIL_FLAGS"),fu_flags);
if (tmpde1=FilesFind(files_find_mask,fuf_flags&FUG_FILES_FIND))
I64 fuf_flags = 0, res = 0;
CDirEntry *tmpde1 = NULL;
FlagsScan(&fuf_flags, Define("ST_FILE_UTIL_FLAGS"), "+r");
FlagsScan(&fuf_flags, Define("ST_FILE_UTIL_FLAGS"), fu_flags);
if (tmpde1 = FilesFind(files_find_mask, fuf_flags & FUG_FILES_FIND))
{
res=Size1(tmpde1,round_to);
res = Size1(tmpde1, round_to);
DirTreeDel(tmpde1);
}
return res;
@ -111,30 +121,32 @@ public I64 Size(U8 *files_find_mask="/*",U8 *fu_flags=NULL,I64 round_to=0)
public I64 FileCount(CDirEntry *tmpde)
{//Count of files in $LK,"CDirEntry",A="MN:CDirEntry"$ tree.
I64 count=0;
while (tmpde) {
if (tmpde->attr&RS_ATTR_DIR)
count+=FileCount(tmpde->sub);
I64 count = 0;
while (tmpde)
{
if (tmpde->attr & RS_ATTR_DIR)
count += FileCount(tmpde->sub);
else
count++;
tmpde=tmpde->next;
tmpde = tmpde->next;
}
return count;
}
#help_index "File/Cmd Line (Typically);Cmd Line (Typically)"
public I64 FF(U8 *files_find_mask,U8 *fu_flags=NULL)
public I64 FF(U8 *files_find_mask, U8 *fu_flags=NULL)
{//Files find. List files matching mask.
I64 count=0,fuf_flags=0;
CDirEntry *tmpde,*tmpde1;
FlagsScan(&fuf_flags,Define("ST_FILE_UTIL_FLAGS"),"+r+f+F");
FlagsScan(&fuf_flags,Define("ST_FILE_UTIL_FLAGS"),fu_flags);
tmpde=tmpde1=FilesFind(files_find_mask,fuf_flags);
while (tmpde) {
I64 count = 0, fuf_flags = 0;
CDirEntry *tmpde, *tmpde1;
FlagsScan(&fuf_flags, Define("ST_FILE_UTIL_FLAGS"), "+r+f+F");
FlagsScan(&fuf_flags, Define("ST_FILE_UTIL_FLAGS"), fu_flags);
tmpde=tmpde1 = FilesFind(files_find_mask, fuf_flags);
while (tmpde)
{
PutFileLink(tmpde->full_name);
'\n';
count++;
tmpde=tmpde->next;
tmpde = tmpde->next;
}
DirTreeDel(tmpde1);
return count;