Files
TempleOS-Rijn/LT/Utils/Disk20.APZ
T
2018-09-08 21:45:20 +02:00

470 lines
11 KiB
Plaintext

#help_index "File/Program Routines/Utils"
U8 SizeFlattenLTDirTree(LTDirEntry *tempm)
{
U8 result=0;
while (tempm) {
result+=LT_DIR_ENTRY_SIZE+1;
if (tempm->attr & LT_ATTR_DIR)
result+=SizeFlattenLTDirTree(tempm->sub);
tempm=tempm->next;
}
return result+1;
}
U8 FillFlattenLTDirTree(LTDirEntry *tempm,U1 *dst)
{
U8 result=0,i;
while (tempm) {
*dst++=1;
result++;
i=LT_DIR_ENTRY_SIZE;
MemCpy(dst,&tempm->start,i);
dst+=i;
result+=i;
if (tempm->attr & LT_ATTR_DIR) {
i=FillFlattenLTDirTree(tempm->sub,dst);
dst+=i;
result+=i;
}
tempm=tempm->next;
}
*dst=0;
return result+1;
}
public U1 *FlattenLTDirTree(LTDirEntry *tempm,U8 *size=NULL)
{
U8 i=SizeFlattenLTDirTree(tempm);
U1 *buf=MAlloc(i);
FillFlattenLTDirTree(tempm,buf);
if (size) *size=i;
return buf;
}
U1 *DoUnflattenLTDirTree(U1 *src,LTDirEntry **tempm)
{
U8 i;
LTDirEntry *tempm1;
if (*src++) {
tempm1=MAllocZ(sizeof(LTDirEntry));
*tempm=tempm1;
i=LT_DIR_ENTRY_SIZE;
MemCpy(&tempm1->start,src,i);
src+=i;
if (tempm1->attr & LT_ATTR_DIR)
src=DoUnflattenLTDirTree(src,&tempm1->sub);
src=DoUnflattenLTDirTree(src,&tempm1->next);
} else
*tempm=NULL;
return src;
}
public LTDirEntry *UnflattenLTDirTree(U1 *src)
{
LTDirEntry *tempm=NULL;
DoUnflattenLTDirTree(src,&tempm);
return tempm;
}
#help_index "Install;File/Install Related"
#help_file "::/LT/Doc/Install.TXZ"
public void PartitionDrive(I1 drive=0)
//drive=0 means add new device
{
LTBlkDev *bd;
MasterBootStruct mbr;
I8 ext_base=0,size,
i=0,start_offset,offset=0,remaining,
num_partition;
if (!drive) {
AddDrives(TRUE);
return;
}
bd=DriveToBlkDev(drive);
remaining=bd->max_blk,
num_partition=bd->partition_base;
if (!bd || bd->type!=LTBDT_ATA)
return;
coutln "\r\n\r\n!!! Repartition Drive !!!\r\n";
while (remaining>0) {
start_offset=offset;
MemSet(&mbr,0,BLK_SIZE);
mbr.signature=0xAA55;
do {
PrintF( "Partition %c :\r\n",num_partition);
PrintF( "Blocks Remaining:%d (0x%X)\r\n",remaining,remaining);
size=PmtI8("Size in Blocks :",remaining);
} while (size<=0 || size>remaining);
mbr.p[0].active=0x80;
mbr.p[0].size=size;
mbr.p[0].type=1;
mbr.p[0].offset=1;
offset+=1+size;
remaining-=1+size;
if (remaining>0) {
mbr.p[1].active=0x80;
mbr.p[1].size=remaining;
mbr.p[1].type=0xF;
mbr.p[1].offset=offset-ext_base;
if (!ext_base)
ext_base=offset;
}
ATAWriteBlks(bd,&mbr,start_offset,1);
num_partition++;
}
bd->flags&=~(LTBDF_INITIALIZED | LTBDF_INIT_IN_PROGRESS|LTBDF_HAS_BEEN_RESET);
AddBlkDev(bd,FALSE);
for (i=bd->partition_base;i<num_partition;i++)
Format(i,TRUE,FALSE);
}
#help_index "File/Cmd Line (Typically)"
void DrawIt(TssStruct *tss)
{
ClearWinText(tss);
}
public void ViewDrive(I1 drive=0)
{
LTPartition *p=DriveToPartition(drive);
void *old_update=Fs->update_win;
Ltf *old_ltf=Fs->cur_ltf;
U8 lohi,c1,i,x,y,
l=(GR_HEIGHT-3*FONT_HEIGHT)*(GR_WIDTH-FONT_WIDTH<<1),
s=(p->size+p->spc-1)/p->spc;
U8 ch=0;
U1 *bitmap;
GrBitMap *base=GrAlias(Gs->grbase,Fs);
if (p->type!=PT_LT) {
GrDel(base);
return;
}
WinMax;
Fs->update_win=&DrawIt;
Fs->cur_ltf=NULL;
GrClear;
try {
i=((s+7)>>3+BLK_SIZE-1)>>BLK_SIZE_BITS;
bitmap=MAlloc(i<<BLK_SIZE_BITS);
RBlks(p,bitmap,p->MAP1,i,TRUE);
i=0;
for (y=0;y<(GR_HEIGHT-3*FONT_HEIGHT);y++) {
if (ScanKey(&ch))
break;
for (x=0;x<(GR_WIDTH-FONT_WIDTH<<1);x++) {
lohi=i*s;
c1=lohi/l;
if (Bt(bitmap,c1))
base->color=ROP_XOR+(BLUE^WHITE);
else
base->color=ROP_XOR+(WHITE^WHITE);
GrPlot(base,x,y);
i++;
}
}
Free(bitmap);
} catch
UnlockPartition(p);
while (ch!=CH_ESC && ch!=CH_CTRLQ)
ch=GetChar;
Fs->update_win=old_update;
GrClear;
Fs->cur_ltf=old_ltf;
GrDel(base);
}
void DrawIt(TssStruct *tss)
{
ClearWinText(tss);
}
public void ViewDisk(I1 drive=0)
{
I8 i,j,
h=Fs->win_pixel_right-Fs->win_pixel_left,
v=Fs->win_pixel_bottom-Fs->win_pixel_top,
radius;
LTPartition *p;
LTBlkDev *bdev=DriveToBlkDev(drive);
void *old_update=Fs->update_win;
Ltf *old_ltf=Fs->cur_ltf;
GrBitMap *base=GrAlias(Gs->grbase,Fs);
double sector_start,sector_end;
I1 buf[32];
Fs->update_win=&DrawIt;
Fs->cur_ltf=NULL;
GrClear;
if (h<v)
radius=0.4*h;
else
radius=0.4*v;
base->color=ROP_OR+BLACK^WHITE;
GrCircle(base,h>>1,v>>1,radius);
j=1;
for (i=0;i<32;i++) {
p=&local_partitions[i];
if (bdev==p->bdev && p->type) {
sector_start=-(p->offset*pi2/bdev->max_blk);
sector_end =-((p->offset+p->size-1)*pi2/bdev->max_blk);
base->color=ROP_OR+BLACK^WHITE;
GrLine(base,h>>1,v>>1,
h>>1+radius*Cos(sector_start),
v>>1+radius*Sin(sector_start));
GrLine(base,h>>1,v>>1,
h>>1+radius*Cos(sector_end),
v>>1+radius*Sin(sector_end));
base->color=ROP_XOR+j^WHITE;
base->bkcolor=BLACK;
SPrintF(buf,"%C ",PartitionToDrive(p));
if (p->type==PT_LT)
StrCat(buf,"LT ");
else if (p->type==PT_FAT12)
StrCat(buf,"FAT12 ");
else if (p->type==PT_FAT32)
StrCat(buf,"FAT32 ");
else if (p->type==PT_ISO9660)
StrCat(buf,"ISO9660");
else
StrCat(buf,"-------");
GrText(base,0,v-FONT_HEIGHT*j,buf);
GrFloodFill(base,
h>>1+(radius-4)*Cos((sector_start+sector_end)/2),
v>>1+(radius-4)*Sin((sector_start+sector_end)/2),FALSE);
j++;
}
}
GetChar(NULL,FALSE);
Fs->update_win=old_update;
GrClear;
Fs->cur_ltf=old_ltf;
GrDel(base);
}
void ChkDskList(LTDirEntry *tempm1,U1 *bits,U1 *bits2,U8 size,U8 bpc)
{
LTDirEntry *tempm2;
U8 i,j;
while (tempm1) {
tempm2=tempm1->next;
if (tempm1->attr & LT_ATTR_DIR) {
if (tempm1->sub) {
coutln SysText("ST_SCANNING_DIRECTORY"),tempm1->full_name;
ChkDskList(tempm1->sub,bits,bits2,size,bpc);
}
}
j=(tempm1->size+bpc-1)/bpc;
for (i=0;i<j;i++) {
if (i+tempm1->cluster>size) {
PrintFErr("Invalid Cluster:%s Cluster:%X\r\n",tempm1->full_name,
i+tempm1->cluster);
break;
}
if (Bts(bits,i+tempm1->cluster))
PrintFErr("Double Alloc:%s Cluster:%X\r\n",tempm1->full_name,
i+tempm1->cluster);
if (!Btr(bits2,i+tempm1->cluster))
PrintFErr("UnAlloc:%s Cluster:%X\r\n",tempm1->full_name,
i+tempm1->cluster);
}
DelLTDirEntry(tempm1);
tempm1=tempm2;
}
}
public void ChkDsk(I1 drive=0)
{
U8 i,j,bpc,size;
LTPartition *p=DriveToPartition(drive);
I1 *mask=MSPrintF("%c:/*",PartitionToDrive(p));
U1 *bits,*bits2;
if (p->type!=PT_LT) {
PutSysTextErr("ST_NOT_LT");
return;
}
size=(p->size-(p->data-p->offset))/p->spc;
bpc=p->spc<<BLK_SIZE_BITS;
bits=MAllocZ((size+7)>>3);
bits2=MAllocZ((size+7)>>3+BLK_SIZE);
RBlks(p,bits2,p->MAP1,((size+7)>>3+BLK_SIZE-1)>>BLK_SIZE_BITS,TRUE);
j=1; //TODO: get rootdir size
for (i=0;i<j;i++) {
if (i+p->root_cluster>size) {
PrintFErr("Invalid Cluster: RootDir Cluster:%X\r\n",i+p->root_cluster);
break;
}
if (Bts(bits,i+p->root_cluster))
PrintFErr("Double Alloc: RootDir Cluster:%X\r\n",i+p->root_cluster);
if (!Btr(bits2,i+p->root_cluster))
PrintFErr("UnAlloc: RootDir Cluster:%X\r\n",i+p->root_cluster);
}
ChkDskList(FindFiles(mask,1<<FUf_RECURSE),bits,bits2,size,bpc);
for (i=1;i<size;i++)
if (Bt(bits2,i))
coutln "Shouldn't Alloc Cluster:",i;
Free(mask);
Free(bits);
Free(bits2);
}
#help_index "Install;File/Install Related"
#define SC_BLK_CNT 2048
public U8 ScanNonLT(I8 drive,U4 signature)
{
// See $LK,"::/LT/Doc/LTZ.TXZ","FI:::/LT/Doc/LTZ.TXZ"$
U1 *buf=MAllocZ(BLK_SIZE*SC_BLK_CNT),*b;
U4 *d;
U8 *dd;
LTBlkDev *bd=DriveToBlkDev(drive);
LTPartition *p=DriveToPartition(drive);
I8 blk=p->offset;
U8 result=0,start=0,i,j,n,to_go,size,
contiguous=0,new_drive_letter;
BoolU4 good,proceed=FALSE;
try {
while (!result) {
cout "-";
n=p->size+p->offset-blk;
if (n>SC_BLK_CNT)
n=SC_BLK_CNT;
if (!n)
break;
RBlks(p,buf,blk,1,TRUE);
d=buf;
dd=d;
if (d[127]==signature) {
b=d;
good=TRUE;
for (j=16;j<BLK_SIZE-4;j++)
if (b[j]!=j.u1[0]) {
good=FALSE;
break;
}
if (good) {
result=blk;
break;
}
}
blk+=n;
}
if (result) {
blk=result-(SC_BLK_CNT-1);
if (blk<0) blk=0;
result=0;
n=p->size+p->offset-blk;
if (n>SC_BLK_CNT)
n=SC_BLK_CNT;
RBlks(p,buf,blk,n,TRUE);
for (i=0;i<n;i++) {
d=buf+BLK_SIZE*i;
dd=d;
if (d[127]==signature && !dd[0]) {
b=d;
good=TRUE;
for (j=16;j<BLK_SIZE-4;j++)
if (b[j]!=j.u1[0]) {
good=FALSE;
break;
}
if (good) {
result=blk+i;
size=dd[1];
break;
}
}
}
}
if (result) {
start=result;
CrLf;
coutln "Start :0x",result," Size:0x",size;
to_go=size;
blk=result;
while (to_go && result) {
cout "+";
n=to_go;
if (n>SC_BLK_CNT)
n=SC_BLK_CNT;
RBlks(p,buf,blk,n,TRUE);
for (i=0;i<n;i++) {
d=buf+BLK_SIZE*i;
dd=d;
if (d[127]==signature && dd[0]==blk-result+i &&
dd[1]==size) {
b=d;
for (j=16;j<BLK_SIZE-4;j++)
if (b[j]!=j.u1[0]) {
result=0;
break;
}
if (result)
contiguous++;
else
break;
} else {
result=0;
break;
}
}
to_go-=n;
blk+=n;
}
}
coutln "Start: 0x",result;
if (result) {
CrLf;
coutln "Success";
proceed=TRUE;
} else {
CrLf;
coutln "Failed, but found ",contiguous," contiguous.";
if (contiguous) {
cout "Proceed Anyway ";
proceed=YorN;
}
}
} catch
Fs->catch_except=TRUE;
Cd("HOME");
Free(buf);
if (proceed) {
cout "New Drive Letter:";
new_drive_letter=ToUpper(GetChar);
CrLf;
bd=local_blkdevs+sizeof(LTBlkDev)*(num_blkdevs++);
bd->partition_base=new_drive_letter;
bd->blk_size=BLK_SIZE;
bd->min_blk=start;
bd->max_blk=start+contiguous-1;
bd->non_lt_drive=drive;
bd->non_lt_offset=start;
bd->type=LTBDT_NON_LT_FILE;
bd->flags=LTBDF_FORMAT;
if (!AddBlkDev(bd,FALSE))
PutSysText("ST_FAILED");
Drive(new_drive_letter);
coutln "File Blk: 0x",start;
result=start;
} else
result=0;
return result;
}
#help_index ""